12eac5a4f2
- C3d aggiornamento delle librerie ( 117957).
2028 lines
125 KiB
C++
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
|