Files
Extern/C3d/Include/topology_faceset.h
T
SaraP 12eac5a4f2 Extern :
- C3d aggiornamento delle librerie ( 117957).
2023-09-12 15:07:38 +02:00

2028 lines
125 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Множество граней или оболочка.
\en Shell or set of faces. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __TOPOLOGY_FACESET_H
#define __TOPOLOGY_FACESET_H
#include <templ_s_array.h>
#include <templ_sptr.h>
#include <mb_operation_result.h>
#include <mb_data.h>
#include <name_item.h>
#include <tool_multithreading.h>
#include <topology.h>
#include <op_binding_data.h>
#include <vector>
#include <set>
class MATH_CLASS MbCube;
class MATH_CLASS MbFunction;
struct MATH_CLASS MbEdgeFacesIndexes;
class MATH_CLASS MbShellHistory;
class MATH_CLASS MbPntLoc;
struct MATH_CLASS MbEdgeFunction;
class MATH_CLASS MbCheckTopologyParams;
class MATH_CLASS MbFaceShell;
class MATH_CLASS MbShellsDistanceData;
struct MATH_CLASS MbUnitInfo;
class MbFaceSetTemp;
namespace c3d // namespace C3D
{
typedef SPtr<MbFaceShell> ShellSPtr;
typedef SPtr<const MbFaceShell> ConstShellSPtr;
typedef std::pair<size_t, MbFaceShell *> IndexShell;
typedef std::pair<size_t, const MbFaceShell *> IndexConstShell;
typedef std::pair<size_t, ShellSPtr> IndexShellSPtr;
typedef std::pair<size_t, ConstShellSPtr> IndexConstShellSPtr;
typedef std::vector<MbFaceShell *> ShellsVector;
typedef std::vector<const MbFaceShell *> ConstShellsVector;
typedef std::vector<ShellSPtr> ShellsSPtrVector;
typedef std::vector<ConstShellSPtr> ConstShellsSPtrVector;
typedef std::set<MbFaceShell *> ShellsSet;
typedef ShellsSet::iterator ShellsSetIt;
typedef ShellsSet::const_iterator ShellsSetConstIt;
typedef std::pair<ShellsSetConstIt, bool> ShellsSetRet;
typedef std::set<const MbFaceShell *> ConstShellsSet;
typedef ConstShellsSet::iterator ConstShellsSetIt;
typedef ConstShellsSet::const_iterator ConstShellsSetConstIt;
typedef std::pair<ConstShellsSetConstIt, bool> ConstShellsSetRet;
}
template <class FacesVector, class EdgesVector>
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
{
public:
//------------------------------------------------------------------------------
/** \brief \ru Вспомогательные данные для множества граней.
\en Auxiliary data for a face set. \~
\details \ru Вспомогательные данные служат для ускорения работы объекта.
\en Auxiliary data are used for fast calculations. \n \~
*/
// ---
struct MATH_CLASS MbFaceShellAuxiliaryData : public AuxiliaryData
{
MbFaceSetTemp * _temporal; ///< \ru Объект сопровождения множества граней (для скорости). \en An object for maintenance of a set of faces (to improve speed).
MbFaceShellAuxiliaryData();
MbFaceShellAuxiliaryData( const MbFaceShellAuxiliaryData & );
virtual ~MbFaceShellAuxiliaryData();
};
protected:
RPArray<MbFace> faceSet; ///< \ru Множество граней. \en A set of faces.
bool closed; ///< \ru Признак замкнутости указывает на отсутствие края. \en An attribute of closedness indicates the absence of boundary.
mutable CacheManager<MbFaceShellAuxiliaryData> * cache; ///< \ru Вспомогательные данные для множества граней. \en Auxiliary data for the face set.
public :
/// \ru Конструктор без параметров. \en Constructor without parameters.
MbFaceShell();
/// \ru Конструктор по набору граней. \en Constructor by a set of faces.
template <class FacesVector>
MbFaceShell( const FacesVector & 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.
MbeTopologyType IsA() const override; // \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. \~
\param[in] iReg - \ru Регистратор копирования.
\en Copy registrator. \~
\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 = nullptr, MbRegDuplicate * iReg = nullptr );
/** \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 = nullptr ) 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 <class FacesVector>
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 == nullptr )
continue;
if ( justAdd || ( std::find( faceSet.begin(), faceSet.end(), newFace ) == faceSet.end() ) ) {
faceSet.push_back( const_cast<MbFace *>(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.
bool ChangeFace( size_t index, const MbFace & );
/// \ru Удалить грань с заданным индексом. \en Delete a face at the given index.
bool DeleteFace( size_t index );
/// \ru Удалить грань. \en Delete a face.
bool 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 Detach all faces from shell.
template <class FacesVector>
void DetachFaces( FacesVector & detachFaces )
{
size_t facesCnt = faceSet.size();
detachFaces.reserve( detachFaces.size() + facesCnt );
c3d::FaceSPtr face;
for ( size_t k = 0; k < facesCnt; ++k ) {
face = faceSet[k];
::DecRefItem( faceSet[k] );
faceSet[k] = nullptr;
detachFaces.push_back( face );
::DetachItem( face );
}
faceSet.clear();
RemoveTemporal();
}
/// \ru Поменять местами грани оболочки. \en Swap shell faces.
bool 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 = nullptr );
/** \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 = nullptr );
/** \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 = nullptr );
/// \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 * = nullptr ) 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 * = nullptr );
/// \ru Забрать в оболочку множество граней из оболочки faces. \en Move a set of faces to the shell from another shell.
bool UnionWith( MbFaceShell & faces, c3d::FacesSet * sharedSet = nullptr );
/// \ru Установить заданную метку всем вершинам оболочки. \en Set the given label for all vertices of the shell.
size_t SetVerticesLabel( MbeLabelState, void * = nullptr) const;
/// \ru Установить заданную метку всем рёбрам оболочки. \en Set the given label for all edges of the shell.
size_t SetEdgesLabel ( MbeLabelState, void * = nullptr) const;
/// \ru Установить заданную метку всем граням оболочки. \en Set the given label for all faces of the shell.
void SetFacesLabel ( MbeLabelState, void * = nullptr) const;
/// \ru Выдать множество вершин оболочки. \en Get a set of vertices of the shell.
template <class VerticesVector>
void GetVertices( VerticesVector & ) const;
/// \ru Выдать множество ребер оболочки. \en Get a set of edges of the shell.
template <class EdgesSet>
void GetEdgesSet( EdgesSet & edges ) const {
size_t i, facesCnt = faceSet.size();
for ( i = 0; i < facesCnt; ++i ) {
if ( faceSet[i] != nullptr )
faceSet[i]->GetEdgesSet<EdgesSet>( edges );
}
}
/// \ru Выдать множество уникальных ребер оболочки. \en Get a set of unique edges of the shell.
template <class EdgesVector, class EdgesSet>
void GetEdges( EdgesVector & edges, EdgesSet & edgesCache ) const {
size_t i, facesCnt = faceSet.size();
for ( i = 0; i < facesCnt; ++i ) {
if ( faceSet[i] != nullptr )
faceSet[i]->GetEdges<EdgesVector, EdgesSet>( edges, edgesCache );
}
}
/// \ru Выдать множество ребер оболочки. \en Get a set of edges of the shell.
template <class EdgesVector>
void GetEdges( EdgesVector & edges ) const
{
if ( edges.size() < 1 )
::GetEdges< RPArray<MbFace>, EdgesVector >( faceSet, edges );
else {
size_t i, facesCnt = faceSet.size();
size_t allEdgesCnt = 0;
for ( i = 0; i < facesCnt; ++i ) {
const MbFace * face = faceSet[i];
if ( face != nullptr ) {
size_t loopsCnt = face->GetLoopsCount();
for ( size_t j = 0; j < loopsCnt; ++j ) {
const MbLoop * loop = face->_GetLoop( j );
if ( loop != nullptr )
allEdgesCnt += loop->GetEdgesCount();
}
}
}
edges.reserve( edges.size() + allEdgesCnt );
for ( i = 0; i < facesCnt; ++i ) {
if ( faceSet[i] != nullptr )
faceSet[i]->GetEdges<EdgesVector>( edges );
}
}
}
/// \ru Выдать множество граней оболочки. \en Get a set of faces of the shell.
template <class FacesVector>
void GetFaces( FacesVector & faces ) const
{
faces.reserve( faces.size() + faceSet.size() );
c3d::FaceSPtr face;
for ( size_t k = 0, kcnt = faceSet.size(); k < kcnt; ++k ) {
face = const_cast<MbFace *>( faceSet[k] );
faces.push_back( face );
::DetachItem( face );
}
}
/// \ru Выдать множество граней оболочки. \en Get a set of faces of the shell.
template <class FacesSet>
void GetFacesSet( FacesSet & faces ) const
{
for ( size_t k = 0, kcnt = faceSet.size(); k < kcnt; ++k ) {
if ( faceSet[k] != nullptr )
faces.insert( faceSet[k] );
}
}
/// \ru Выдать множество вершин и множество ребер оболочки. \en Get a set of vertices and a set of edges of the shell.
template <class VerticesVector, class EdgesVector>
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.
template <class TopologyItemsVector>
void GetItems( TopologyItemsVector & ) 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<MbShellsDistanceData> & 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<size_t> & nums, SArray<MbCartPoint> & 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<size_t> & nums, SArray<MbCartPoint> & 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<size_t> & nn,
SArray<MbCartPoint> & uv, SArray<double> & tt ) const;
/** \brief \ru Добавить свой габарит в габаритный куб.
\en Add your own bounding box into bounding cube. \~
\details \ru Добавить свой габарит в габаритный куб.
\en Add your own bounding box into bounding cube. \~
\param[out] gab -\ru Габаритный куб для добавления габарита оболочки.
\en Bounding box for adding a bounding box of the shell. \~
\param[out] extTolCubes - \ru Контейнер для расширенных габаритов граней оболочки с неточными ребрам.
\en Container of extended bounding boxes of shell faces that contain inexact edges. \~
*/
void AddYourGabaritTo( MbCube & gab, c3d::IndexCubeVector * extTolCubes = nullptr ) 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 & );
/** \brief \ru Установить главное имя и вставить старое в индекс копирования.
\en Set the main name and insert an old name to the copy index. \~
\details \ru Установить главное имя элементам оболочки и вставить старое в индекс копирования. Объекты с пустыми имена пропускаются.
\en Set the main name of topology items and insert an old name to the copy index. Objects with empty names are skipped. \~
\param[in] newNameMaker - \ru Именователь с новым главным именем.
\en Name maker with a new main name. \~
\param[in] addOldMainName - \ru Вставить старое в индекс копирования.
\en Insert an old name to the copy index. \~
*/
void SetItemsMainName( const MbSNameMaker & newNameMaker, bool addOldMainName );
/** \brief \ru Вставить индекс копирования.
\en Insert copying index. \~
\details \ru Вставить индекс копирования.
\en Insert copying index. \~
\param[in] index - \ru Индекс копирования.
\en Copying index. \~
*/
void SetNamesCopyIndex( SimpleName index );
/** \brief \ru Заменить главное имя, вставить старое главное имя и индекс копирования в индексы копирования.
\en Replace main name by new one, insert old main name and given copy index into name copy indices. \~
\details \ru Заменить главное имя, вставить старое главное имя и индекс копирования в индексы копирования. Объекты с пустыми имена пропускаются.
\en Replace main name by new one, insert old main name and given copy index into name copy indices. Objects with empty names are skipped. \~
\param[in] index - \ru Индекс копирования.
\en Copying index. \~
\param[in] newMainName - \ru Именователь с новым главным именем.
\en A name maker with a new main name. \~
*/
void SetNamesCopyIndex( SimpleName index, const MbSNameMaker & newNameMaker );
/// \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 MakeItemsNewNames( const MbSNameMaker &, 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 MakeFacesNewNames( const MbSNameMaker &, SimpleName modifier );
/// \ru Проименовать грани, рёбра и вершины оболочки. \en Rename faces, edges and vertices of the shell.
void SetShellNames( const MbSNameMaker & );
/// \ru Проименовать элементы оболочки именами оболочки s. \en Name shell elements by names of the shell 's'.
void SetShellNames( const MbFaceShell & );
/** \brief \ru Очистить все имена в оболочке.
\en Clear all shell names. \~
\details \ru Очистить имена всех элементов оболочки : граней, ребер и вершин.
\en Clear the names of all shell elements: faces, edges, and vertices. \~
*/
void ClearShellNames();
/** \brief \ru Очистить имена ребер в оболочке.
\en Clear all shell edges names. \~
\details \ru Очистить имена ребер (и вершин) в оболочке.
\en Clear all shell edges (and vertices) names. \~
\param[in] clearVerticesNames - \ru Очистить также и имена вершин.
\en Clean up also names of vertices. \~
*/
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.
template <class ConstEdgesVector>
bool GetBoundaryEdges( ConstEdgesVector & ) const;
// \ru Для множества рёбер найти множество их номеров. \en For a set of edges find a set of their indices.
template <class CurvesArray, class ItemIndices>
bool FindIndexByEdges( const CurvesArray & init, ItemIndices & indices ) const;
/// \ru Для множества ребер найти номера ребер и номера ее граней. \en For a set of edges find their indices and indices of their faces.
template<class CurvesArray, class IndexesArray>
bool FindFacesIndexByEdges( const CurvesArray & init, IndexesArray & indexes, bool any = false ) const;
/// \ru Для множества ребер найти номера ребер и номера ее граней. \en For a set of edges find their indices and indices of their faces.
bool FindFacesIndexByEdges( const RPArray<MbCurveEdge> & init, SArray<MbEdgeFacesIndexes> & indexes, bool any = false ) const;
/** \brief \ru Для множества структур (ребер, функций изменения радиусов и опорных кривых скругления) найти номера ребер и номера смежных граней.
\en For a set of structures (edges, functions of radii changing, and suppoirt curves for fillets) find indices of edges and their faces. \~
\details \ru Проверка оболочки: вершин (удаление совпадающих и лишних), ребер (со слиянием).
\en Validation of the shell: vertices (deletion of coincident and extra), edges (with merge). \~
\param[in] init - \ru Структуры, несущие ребра, функции изменения радиуса и опорные кривые скруглений.
\en Structures with edges, radius change functions and support curves of fillets. \~
\param[out] functions - \ru Функции изменения радиуса.
\en The radius change functions. \~
\param[out] slideways - \ru Опорные кривые скруглений.
\en The support curves of fillets. \~
\param[out] indexes - \ru Индексы рёбер и смежных граней теле.
\en The edges and fsces indeces. \~
*/
bool FindFacesIndexByEdges( const SArray<MbEdgeFunction> & init,
RPArray<MbFunction> & functions, RPArray<MbCurve3D> & slideways, SArray<MbEdgeFacesIndexes> & indexes ) const;
/// \ru Для множества структур (ребер, функций изменения радиусов и опорных кривых скругления) найти номера ребер и номера смежных граней.
/// \en For a set of structures (edges, functions of radii changing, and suppoirt curves for fillets) find indices of edges and their faces.
template<class EdgeFuncsArray, class FuncsArray, class CurvesArray, class IndexesArray>
bool FindFacesIndexByEdges( const EdgeFuncsArray & init,
FuncsArray & functions, CurvesArray & slideways, IndexesArray & indexes ) const;
/** \brief Для множества номеров ребер и номеров смежных граней найти ребра. \en For a set of edge indices and indices of their faces find edges.
\details \ru
\en . \~
\param[in] indexes - \ru Индексы рёбер и смежных граней теле.
\en The edges and fsces indeces. \~
\param[in] functions - \ru Функции изменения радиуса (может быть nullptr).
\en The radius change functions (may be nullptr). \~
\param[in] slideways - \ru Опорные кривые скруглений (может быть nullptr).
\en The support curves of fillets (may be nullptr). \~
\param[out] eEdges - \ru Ребра.
\en Edges. \~
\param[out] eFunctions - \ru Функции изменения радиуса для рёбер, если functions != nullptr.
\en The radius change functions from functions, if functions != nullptr. \~
\param[out] eSlideways - \ru Опорные кривые скруглений для рёбер, если slideways != nullptr.
\en The support curves of fillets from slideways, if slideways != nullptr. \~
*/
bool FindEdgesByFacesIndex( const SArray<MbEdgeFacesIndexes> & indexes, const RPArray<MbFunction> * functions, const RPArray<MbCurve3D> * slideways,
RPArray<MbCurveEdge> & eEdges, RPArray<MbFunction> & eFunctions, RPArray<MbCurve3D> & eSlideways ) 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<MbFace> & init, SArray<size_t> & ind0 ) const;
/// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices.
template <class FacesPointersVector, class ItemIndices> // ItemIndices - MbItemIndex vector
bool FindIndexByFaces( const FacesPointersVector &, ItemIndices &, size_t mapThreshold = 50 ) const;
/// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices.
template <class FacesPointersVector, class ItemIndices> // ItemIndices - MbItemIndex vector
bool FindIndexBySameFaces( const FacesPointersVector &, ItemIndices &, double accuracy = LENGTH_EPSILON ) const;
/// \ru Найти множество граней по множеству комбинированных индексов. \en Find a set of faces by a set of combined indices.
template <class ItemIndices, class ConstFacesPointersVector> // ItemIndices - MbItemIndex vector
bool FindConstFacesByIndex( const ItemIndices &, ConstFacesPointersVector & ) const;
template <class ItemIndices, class FacesPointersVector> // ItemIndices - MbItemIndex vector
bool FindFacesByIndex( const ItemIndices &, FacesPointersVector & ) const;
bool FindItemIndexByIndex( const std::vector<c3d::IndicesPair> & indexes,
std::vector< std::pair<MbItemIndex,MbItemIndex> > & ind0 ) const;
/// \ru Для множества вершин найти множество их комбинированных номеров. \en For a set of vertices find a set of their combined indices.
template <class ConstVertexPointers, class ItemIndices>
bool FindIndexByVertices( const ConstVertexPointers & init, ItemIndices & indexes ) const;
/// \ru Найти множество вершин по множеству комбинированных индексов. \en Find a set of vertices by a set of combined indices.
bool FindVerticesByIndex( const SArray<MbItemIndex> & indexes, RPArray<MbVertex> & 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 an edge by combined index.
const MbCurveEdge * FindEdgeByIndex( MbItemIndex & ) const;
/// \ru Найти ребро по комбинированному индексу. \en Find an edge by combined index.
MbCurveEdge * FindEdgeByIndex( MbItemIndex & );
/// \ru Найти ребрa по номерам. \en Find edges by the indices.
bool FindEdgesByIndex( const std::vector<MbItemIndex> & indexes, std::vector<MbCurveEdge *> & initCurves ) const;
/// \ru Найти множество ребер с общей заданной вершиной. \en Find a set of edges with the common given vertex.
void FindEdgesForVertex( const MbVertex & vertex, RPArray<MbCurveEdge> & findEdges ) const;
/// \ru Найти множество граней с общей заданной вершиной. \en Find a set of faces with the common given vertex.
void FindFacesForVertex( const MbVertex & vertex, RPArray<MbFace> & 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 Find vertex by hash of a name.
const MbVertex * FindVertexByHash( const SimpleName h ) const;
/// \ru Найти ребро по хешу имени. \en Find edge by hash of a name.
const MbCurveEdge * FindEdgeByHash ( const SimpleName h ) const;
/// \ru Найти грань по хешу имени. \en Find face by hash of a name.
const MbFace * FindFaceByHash ( const SimpleName h ) const;
/** \brief \ru Объединить подобные грани.
\en Merge similar faces. \~
\details \ru Объединить подобные грани.
\en Merge similar faces. \~
\param[in] simMainName - \ru Новое главное имя для объединенных граней (если не равно c3d::SIMPLENAME_MAX).
\en The new primary name for the merged faces (if it is not equal to c3d::SIMPLENAME_MAX). \~
*/
bool MergeSimilarFaces( SimpleName simMainName = c3d::SIMPLENAME_MAX );
/// \ru Создан ли временный объект сопровождения? \en Is a temporary object for the maintenance created?
bool IsTemporal() const { return cache != nullptr ? (*cache)()->_temporal != nullptr : false; }
/// \ru Удалить временный объект сопровождения. \en Delete a temporary maintenance object.
void RemoveTemporal( bool removeFacesTemporal = false ) 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<MbFace> & 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 <class FacesVector>
MbFaceShell::MbFaceShell( const FacesVector & initFaces )
: MbTopItem()
, faceSet ( initFaces.size(), 1 )
, closed ( true )
, cache ( nullptr )
{
for ( size_t i = 0, cnt = initFaces.size(); i < cnt; ++i ) {
if ( initFaces[i] != nullptr )
AddFace( *initFaces[i] );
}
}
//------------------------------------------------------------------------------
// \ru Выдать множество вершин оболочки. \en Get a set of vertices of the shell.
// ---
template <class VerticesVector>
void MbFaceShell::GetVertices( VerticesVector & vertices ) const
{
if ( vertices.size() == 0 ) {
// set label
ptrdiff_t maxCount = SetVerticesLabel( ls_Used );
vertices.reserve( vertices.size() + maxCount );
c3d::VertexSPtr 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<MbVertex *>(&edge->GetBegVertex());
if ( vertex->GetLabel() == ls_Used ) {
vertices.push_back( vertex );
vertex->SetOwnLabel( ls_Null );
}
::DetachItem( vertex );
vertex = const_cast<MbVertex *>(&edge->GetEndVertex());
if ( vertex->GetLabel() == ls_Used ) {
vertices.push_back( vertex );
vertex->SetOwnLabel( ls_Null );
}
::DetachItem( vertex );
}
}
}
}
else {
size_t facesCnt = faceSet.size();
vertices.reserve( vertices.size() + facesCnt * 2 );
for ( size_t i = 0; i < facesCnt; ++i )
faceSet[i]->GetVertices( vertices );
}
}
//------------------------------------------------------------------------------
// \ru Выдать множество вершин и множество ребер оболочки. \en Get a set of vertices and a set of edges of the shell.
// ---
template <class VerticesVector, class EdgesVector>
void MbFaceShell::GetItems( VerticesVector & vertices, EdgesVector & edges ) const
{
if ( edges.empty() && vertices.empty() ) {
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 ) {
const MbCurveEdge * edge = const_cast<MbCurveEdge *>(&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 );
c3d::EdgeSPtr edge;
c3d::VertexSPtr vertex;
for ( size_t k = 0, ecount = loop->GetEdgesCount(); k < ecount; ++k ) {
edge = const_cast<MbCurveEdge *>(&loop->_GetOrientedEdge( k )->GetCurveEdge());
if ( edge->GetLabel() == ls_Used ) {
edges.push_back( edge );
edge->SetOwnLabel( ls_Null );
}
vertex = const_cast<MbVertex *>(&edge->GetBegVertex());
if ( vertex->GetLabel() == ls_Used ) {
vertices.push_back( vertex );
vertex->SetOwnLabel( ls_Null );
}
::DetachItem( vertex );
vertex = const_cast<MbVertex *>(&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 Get a set of vertices, a set of edges and a set of faces of the shell.
// ---
template <class TopologyItemsVector>
void MbFaceShell::GetItems( TopologyItemsVector & list ) const
{
size_t maxCount = 1;
// поднимаем флаг // set up labels
size_t i, fcount = faceSet.size();
for ( i = 0; i < fcount; ++i ) {
const MbFace * face = faceSet[i];
if ( face == nullptr )
continue;
for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) {
const MbLoop * loop = face->_GetLoop(j);
if ( loop == nullptr )
continue;
size_t ecount = loop->GetEdgesCount();
for ( size_t k = 0; k < ecount; ++k ) {
const MbCurveEdge * edge = &loop->_GetOrientedEdge(k)->GetCurveEdge();
edge->SetOwnLabel( ls_Used );
edge->GetBegVertex().SetOwnLabel( ls_Used );
edge->GetEndVertex().SetOwnLabel( ls_Used );
}
maxCount += 2 * ecount;
}
}
list.reserve( list.size() + faceSet.size() + maxCount );
// опускаем флаг // reset labels
for ( i = 0; i < fcount; ++i ) {
MbFace * face = faceSet[i];
if ( face == nullptr )
continue;
list.push_back( face );
c3d::EdgeSPtr edge;
c3d::VertexSPtr vertex;
for ( size_t j = 0, lcount = face->GetLoopsCount(); j < lcount; ++j ) {
const MbLoop * loop = face->_GetLoop(j);
if ( loop == nullptr )
continue;
for ( size_t k = 0, ecount = loop->GetEdgesCount(); k < ecount; ++k ) {
edge = &loop->_GetOrientedEdge(k)->GetCurveEdge();
if ( edge->GetLabel() == ls_Used ) {
list.push_back( edge );
edge->SetOwnLabel( ls_Null );
}
vertex = const_cast<MbVertex *>( &edge->GetBegVertex() );
if ( vertex->GetLabel() == ls_Used ) {
list.push_back( vertex );
vertex->SetOwnLabel( ls_Null );
}
::DetachItem( vertex );
vertex = const_cast<MbVertex *>( &edge->GetEndVertex() );
if ( vertex->GetLabel() == ls_Used ) {
list.push_back( vertex );
vertex->SetOwnLabel( ls_Null );
}
::DetachItem( vertex );
::DetachItem( edge );
}
}
}
}
//------------------------------------------------------------------------------
// \ru Предикат для сравнения граней. \en A predicate for comparing faces.
// ---
struct CompareSameFaces
{
const MbFace * _face;
double _eps;
CompareSameFaces( double eps ) : _face( nullptr ), _eps( eps ) {}
bool operator()( const MbFace * f ) const {
return _face == f || _face->IsSame( *f, _eps );
}
};
//------------------------------------------------------------------------------
// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices.
// ---
template <class FacesPointersVector, class ItemIndices>
bool MbFaceShell::FindIndexBySameFaces( const FacesPointersVector & initFaces, ItemIndices & indices, double accuracy ) const
{
const size_t initFacesCount = initFaces.size();
if ( initFacesCount > 0 ) {
indices.reserve( indices.size() + initFacesCount );
MbItemIndex index;
CompareSameFaces comp( accuracy );
for ( size_t i = 0; i < initFacesCount; ++i ) {
const MbFace * face = initFaces[i];
if ( face != nullptr ) {
comp._face = face;
size_t i0 = SYS_MAX_T;
const RPArray<MbFace>::TPtr * it = std::find_if( faceSet.begin(), faceSet.end(), comp );
if ( it != faceSet.end() )
i0 = std::distance( faceSet.begin(), it );
if ( i0 != SYS_MAX_T ) {
index.Init( *(*it), i0 );
indices.push_back( index );
}
}
}
}
return ( indices.size() > 0 );
}
//------------------------------------------------------------------------------
// \ru Для множества граней найти множество их комбинированных номеров. \en For a set of faces find a set of their combined indices.
// ---
template <class FacesPointersVector, class ItemIndices>
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 != nullptr ) {
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 != nullptr ) {
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 <class ItemIndices, class ConstFacesPointersVector>
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<MbItemIndex &>(indices[j]); // у stl доступ честный как const, у SArray дает на редактирование
findFace = FindFaceByIndex( index );
if ( findFace != nullptr ) {
initFaces.push_back( findFace );
::DetachItem( findFace );
}
}
return initFaces.size() > 0;
}
//------------------------------------------------------------------------------
// \ru Найти множество граней по множеству комбинированных индексов. \en Find a set of faces by a set of combined indices.
// ---
template <class ItemIndices, class FacesPointersVector>
bool MbFaceShell::FindFacesByIndex( const ItemIndices & indices, FacesPointersVector & initFaces ) const
{
c3d::FaceSPtr findFace;
initFaces.reserve( initFaces.size() + indices.size() );
for ( size_t j = 0, indicesCnt = indices.size(); j < indicesCnt; ++j ) {
MbItemIndex & index = const_cast<MbItemIndex &>(indices[j]); // у stl доступ честный как const, у SArray дает на редактирование
findFace = const_cast<MbFace *>(FindFaceByIndex( index ));
if ( findFace != nullptr ) {
initFaces.push_back( findFace );
::DetachItem( findFace );
}
}
return initFaces.size() > 0;
}
//------------------------------------------------------------------------------
// \ru Получить краевые ребра оболочки. \en Get boundary edges of the shell.
// ---
template <class ConstEdgesVector>
bool MbFaceShell::GetBoundaryEdges( ConstEdgesVector & boundaryEdges ) const
{
const size_t boundaryCnt = boundaryEdges.size();
for ( size_t i = 0, facesCnt = faceSet.size(); i < facesCnt; ++i ) {
const MbFace * face = faceSet[i];
if ( face == nullptr )
continue;
for ( size_t j = 0, loopsCnt = face->GetLoopsCount(); j < loopsCnt; ++j ) {
const MbLoop * loop = face->_GetLoop( j );
if ( loop == nullptr )
continue;
for ( size_t k = 0, edgesCnt = loop->GetEdgesCount(); k < edgesCnt; ++k ) {
const MbOrientedEdge * orientEdge = loop->_GetOrientedEdge( k );
if ( orientEdge != nullptr ) {
c3d::ConstEdgeSPtr edge( &orientEdge->GetCurveEdge() );
if ( edge->IsBoundaryFace() )
boundaryEdges.push_back( edge );
}
}
}
}
if ( boundaryEdges.size() > boundaryCnt )
return true;
return false;
}
//------------------------------------------------------------------------------
// \ru Для множества рёбер найти множество их номеров. \en For a set of edges find a set of their indices.
// ---
template <class CurvesArray, class ItemIndices>
bool MbFaceShell::FindIndexByEdges( const CurvesArray & init, ItemIndices & indices ) const
{
size_t foundCount = 0;
if ( init.size() > 0 ) {
std::vector<c3d::EdgeSPtr> edges;
GetEdges<std::vector<c3d::EdgeSPtr>>( edges );
size_t initCount, i, edgesCount = edges.size();
MbItemIndex index;
for ( i = 0, initCount = init.size(); i < initCount; i++ ) {
size_t i0 = SYS_MAX_T;
const MbCurveEdge * init_i = init[i];
for ( size_t j = 0; j < edgesCount; j++ )
if ( init_i == edges[j] ) {
i0 = j;
break;
}
if ( i0 != SYS_MAX_T && (init_i != nullptr) ) {
index.Init( *init_i, i0 );
index.SetName( init_i->GetNameHash() );
indices.push_back( index );
foundCount++;
}
}
foundCount = indices.size();
}
return foundCount > 0;
}
//------------------------------------------------------------------------------
// \ru Для множества ребер найти номера ребер и номера ее граней. \en For a set of edges find their indices and indices of their faces.
// ---
template<class CurvesArray, class IndexesArray>
bool MbFaceShell::FindFacesIndexByEdges( const CurvesArray & init, IndexesArray & indexes, bool any ) const
{
size_t foundCount = 0;
if ( init.size() > 0 ) {
std::vector<c3d::EdgeSPtr> edges;
GetEdges<std::vector<c3d::EdgeSPtr>>( edges );
size_t initCount, i, edgesCount = edges.size();
for ( i = 0, initCount = init.size(); i < initCount; i++ ) {
size_t i0 = SYS_MAX_T, i1 = SYS_MAX_T, i2 = SYS_MAX_T;
const MbCurveEdge * init_i = init[i];
for ( size_t j = 0; j < edgesCount; j++ )
if ( init_i == edges[j] ) {
i0 = j;
break;
}
if ( i0 != SYS_MAX_T && (init_i != nullptr) && FindFacesIndexByEdge(*init_i, i1, i2, any) ) {
indexes.push_back( MbEdgeFacesIndexes() );
MbEdgeFacesIndexes & index = indexes[indexes.size() - 1];
index.edgeIndex = i0;
index.facePIndex = i1;
index.faceMIndex = i2;
init_i->Point( 0.5, index.point );
index.itemName = init_i->GetNameHash();
foundCount++;
}
}
foundCount = indexes.size();
}
return foundCount > 0;
}
//------------------------------------------------------------------------------
// \ru Для множества структур (ребер и функций изменения радиусов) найти номера ребер и номера ее граней. \en For a set of structures (edges and functions of radii changing) find indices of edges and their faces.
// ---
template<class EdgeFuncsArray, class FuncsArray, class CurvesArray, class IndexesArray>
bool MbFaceShell::FindFacesIndexByEdges( const EdgeFuncsArray & init,
FuncsArray & functions, CurvesArray & slideways, IndexesArray & indexes ) const
{
size_t foundCount = 0;
if ( init.size() > 0 ) {
size_t i;
std::vector<c3d::EdgeSPtr> edges;
GetEdges<std::vector<c3d::EdgeSPtr>>( edges );
size_t initCount, edgesCount = edges.size();
for ( i = 0, initCount = init.size(); i < initCount; i++ ) {
size_t i0 = SYS_MAX_T;
const MbCurveEdge * init_i = init[i].Edge();
for ( size_t j = 0; j < edgesCount; j++ )
if ( init_i == edges[j] ) {
i0 = j;
break;
}
size_t i1 = SYS_MAX_T;
size_t i2 = SYS_MAX_T;
if ( i0 != SYS_MAX_T && ( init_i != nullptr ) && FindFacesIndexByEdge(*init_i, i1, i2) ) {
indexes.push_back( MbEdgeFacesIndexes() );
MbEdgeFacesIndexes & index = indexes[indexes.size() - 1];
index.edgeIndex = i0;
index.facePIndex = i1;
index.faceMIndex = i2;
init_i->Point( 0.5, index.point );
index.itemName = init_i->GetNameHash();
const MbFunction * func = init[i].Function();
const MbCurve3D * curv = init[i].Slideway();
if ( func != nullptr )
functions.push_back( const_cast<MbFunction *>( func ) );
if ( curv != nullptr )
slideways.push_back( const_cast<MbCurve3D *>( curv ) );
foundCount++;
}
}
foundCount = indexes.size();
}
return foundCount > 0;
}
//------------------------------------------------------------------------------
// \ru Для множества вершин найти множество их комбинированных номеров. \en For a set of vertices find a set of their combined indices.
// ---
template <class ConstVertexPointers, class ItemIndices>
bool MbFaceShell::FindIndexByVertices( const ConstVertexPointers & init, ItemIndices & indexes ) const
{
if ( init.size() > 0 ) {
std::vector<MbVertex*> vertices;
GetVertices( vertices );
size_t verticesCount = vertices.size();
for ( size_t i = 0, initCount = init.size(); i < initCount; i++ ) {
size_t i0 = SYS_MAX_T;
const MbVertex * init_i = init[i];
for ( size_t j = 0; j < verticesCount; j++ )
if ( init_i == vertices[j] ) {
i0 = j;
break;
}
if ( i0 != SYS_MAX_T && ( init_i != nullptr ) ) {
indexes.push_back( MbItemIndex() );
MbCartPoint3D point;
init_i->GetCartPoint( point );
indexes.back().Init( i0, point, init_i->GetName().Hash() );
}
}
}
return indexes.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
*/
//---
class MATH_CLASS MbCheckTopologyParams : public MbPrecision {
protected:
bool mergeEdges; ///< \ru Флаг слияния ребер. \en Merge flag for edges.
SPtr<MbSNameMaker> nameMaker; ///< \ru Именователь с версией операции. \en Names maker with operation version.
SimpleName lastMainName; ///< \ru Главное имя именователя последней операции. \en Main name of the last operation name maker.
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 & nMaker,
double tolerance = Math::paramAccuracy )
: MbPrecision ( tolerance, ANGLE_REGION )
, mergeEdges ( doMergingEdges )
, nameMaker ( &nMaker.Duplicate() )
, lastMainName ( c3d::SIMPLENAME_MAX ) // \ru Неизвестно. \en Unknown.
, controlFaces ( )
, boundaryEdges( )
{
}
template <class Faces>
explicit MbCheckTopologyParams( bool doMergingEdges,
const MbSNameMaker & nMaker,
const Faces & faces,
double tolerance = Math::paramAccuracy )
: MbPrecision ( tolerance, ANGLE_REGION )
, mergeEdges ( doMergingEdges )
, nameMaker ( &nMaker.Duplicate() )
, lastMainName ( c3d::SIMPLENAME_MAX ) // \ru Неизвестно. \en Unknown.
, 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 <class Faces>
explicit MbCheckTopologyParams( bool doMergingEdges,
const MbSNameMaker & nMaker,
const Faces & faces,
const c3d::ConstEdgesVector & edges,
double tolerance = Math::paramAccuracy )
: MbPrecision ( tolerance, ANGLE_REGION )
, mergeEdges ( doMergingEdges )
, nameMaker ( &nMaker.Duplicate() )
, lastMainName ( c3d::SIMPLENAME_MAX ) // \ru Неизвестно. \en Unknown.
, 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:
const MbSNameMaker & NameMaker() const { return *nameMaker; }
public:
bool MergeEdges () const { return mergeEdges; }
bool AddNameAttributes() const { return nameMaker->GetParentNamesAttributes(); }
VERSION MathVersion () const { return nameMaker->GetMathVersion(); }
SimpleName LastMainName() const { return lastMainName; }
void SetLastMainName( const SimpleName & lmn ) { lastMainName = lmn; }
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] = nullptr;
res = true;
}
}
if ( res ) {
std::sort( controlFaces.begin(), controlFaces.end() );
controlFaces.erase( std::unique( controlFaces.begin(), controlFaces.end() ), controlFaces.end() );
if ( controlFaces.front() == nullptr )
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 or supporting curve. \~
\details \ru Структура передаёт информацию о ребре и функции изменения радиуса скругления ребра или об опорной кривой для скругления.
Структура используется в алгоритмах скругления ребер переменным радиусом. \n
Начальный параметр функции изменения радиуса соответствует начальной вершине ребра.
Конечный параметр функции изменения радиуса соответствует конечной вершине ребра. \n
\en A structure transmits an information about an edge and a function of edge fillet radius changing or supporting curve for filliting.
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.
const MbCurve3D * slideway; ///< \ru Опорная кривая скругления. \en A supporting curve for fillet.
public:
/// \ru Конструктор по умолчанию \en Default constructor
MbEdgeFunction () : edge(nullptr), function(nullptr), slideway(nullptr) {}
/// \ru Конструктор по ребру и функции. \en Constructor by an edge and function.
MbEdgeFunction ( const MbCurveEdge * e, const MbFunction * f ) : edge(e), function(f), slideway(nullptr) {}
/// \ru Конструктор по ребру и опорной кривой. \en Constructor by an edge and a supporting curve.
MbEdgeFunction ( const MbCurveEdge * e, const MbCurve3D * c ) : edge(e), function(nullptr), slideway(c) {}
/// \ru Конструктор по другому ребру с функцией. \en Constructor by other edge with a function.
MbEdgeFunction ( const MbEdgeFunction & other ) : edge(other.edge), function(other.function), slideway(other.slideway) {}
~MbEdgeFunction() {}
public:
/// \ru Инициализация по ребру и функции. \en Initialization by an edge and a function.
void Init( const MbCurveEdge * e, const MbFunction * f ) { edge = e; function = f; slideway = nullptr; }
/// \ru Инициализация по ребру и опорной кривой. \en Initialization by an edge and a supporting curve.
void Init( const MbCurveEdge * e, const MbCurve3D * c ) { edge = e; function = nullptr; slideway = c; }
/// \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 Get a supporting curve for fillet.
const MbCurve3D * Slideway() const { return slideway; }
/// \ru Оператор присваивания. \en Assignment operator.
void operator = ( const MbEdgeFunction & other ) { edge = other.edge; function = other.function; slideway = other.slideway; }
};
//------------------------------------------------------------------------------
/** \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, ShellDetail> 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 Information about arbitrary element. \~
\details \ru В качестве произвольного элемента может выступить элемент массива. \n
\en Array element may be arbitrary element. \n \~
\ingroup Data_Structures
*/
//---
struct MATH_CLASS MbUnitInfo {
public:
MbeItemLocation location; ///< \ru Положение элемента. \en Element location.
size_t index; ///< \ru Индекс элемента. \en Index of element.
public:
/// \ru Конструктор по умолчанию. \en Default constructor.
MbUnitInfo()
: location( iloc_Undefined )
, index ( SYS_MAX_T )
{}
/// \ru Конструктор копирования. \en Copy-constructor.
MbUnitInfo( const MbUnitInfo & obj )
: location( obj.location )
, index ( obj.index )
{}
/// \ru Конструктор по индексу. \en Constructor by index.
MbUnitInfo( size_t ind )
: location( iloc_InItem )
, index ( ind )
{}
/// \ru Конструктор по положению элемента. \en Constructor by element location.
MbUnitInfo( MbeItemLocation loc )
: location( loc )
, index ( SYS_MAX_T )
{}
public:
/// \ru Сброс параметров. \en Parameter reset.
void Reset() { location = iloc_Undefined; index = SYS_MAX_T; }
/// \ru Оператор присваивания. \en Assignment operator.
MbUnitInfo & operator = ( const MbUnitInfo & unitInfo )
{
location = unitInfo.location;
index = unitInfo.index;
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). It describes the angle between the rejection vector and the face normal.
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 ( nullptr )
, 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 != nullptr) && (ind < shell->GetFacesCount()) && (shell->GetFace(ind) != nullptr)); }
/// \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) : nullptr); }
/// \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() : nullptr); }
/// \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 = nullptr;
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 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 <class FacesVector>
size_t SetEdgesLabel( const FacesVector & faceSet, MbeLabelState label, void * key = nullptr )
{
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 <class FacesVector, class EdgesVector>
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<MbCurveEdge> 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<MbCurveEdge *>( &loop->_GetOrientedEdge( k )->GetCurveEdge() );
if ( edge->GetLabel() == ls_Used ) {
edge->SetOwnLabel( ls_Null );
edges.push_back( edge );
}
::DetachItem( edge );
}
}
}
}
#endif // __TOPOLOGY_FACESET_H