mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-03-01 00:15:36 +05:00
Implement MakePolyLine()
for ASERIS module
Modified sources = master(223c5b7
) + new development.
This commit is contained in:
parent
eae69d8712
commit
61a2444799
@ -57,6 +57,24 @@ module SMESH
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// structure used in MakePolyLine() to define a cutting plane
|
||||||
|
struct PolySegment
|
||||||
|
{
|
||||||
|
// point 1: if node1ID2 > 0, then the point is in the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at node1ID1
|
||||||
|
long node1ID1;
|
||||||
|
long node1ID2;
|
||||||
|
|
||||||
|
// point 2: if node2ID2 > 0, then the point is in the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at node2ID1
|
||||||
|
long node2ID1;
|
||||||
|
long node2ID2;
|
||||||
|
|
||||||
|
DirStruct vector; // vector on the plane; to use a default plane set vector = (0,0,0)
|
||||||
|
};
|
||||||
|
typedef sequence<PolySegment> ListOfPolySegments;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
* This interface makes modifications on the Mesh - removing elements and nodes etc.
|
||||||
*/
|
*/
|
||||||
@ -93,7 +111,7 @@ module SMESH
|
|||||||
void ClearLastCreated() raises (SALOME::SALOME_Exception);
|
void ClearLastCreated() raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns description of an error/warning occured during the last operation
|
* \brief Returns description of an error/warning occurred during the last operation
|
||||||
*/
|
*/
|
||||||
ComputeError GetLastError() raises (SALOME::SALOME_Exception);
|
ComputeError GetLastError() raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
@ -689,7 +707,8 @@ module SMESH
|
|||||||
raises (SALOME::SALOME_Exception);
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
void MergeNodes (in array_of_long_array GroupsOfNodes,
|
void MergeNodes (in array_of_long_array GroupsOfNodes,
|
||||||
in SMESH::ListOfIDSources NodesToKeep)
|
in SMESH::ListOfIDSources NodesToKeep,
|
||||||
|
in boolean AvoidMakingHoles)
|
||||||
raises (SALOME::SALOME_Exception);
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1185,6 +1204,27 @@ module SMESH
|
|||||||
in double_array theNodesCoords,
|
in double_array theNodesCoords,
|
||||||
out array_of_long_array GroupsOfNodes)
|
out array_of_long_array GroupsOfNodes)
|
||||||
raises (SALOME::SALOME_Exception);
|
raises (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector which goes from the middle point to its projection.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine(inout ListOfPolySegments segments,
|
||||||
|
in string groupName)
|
||||||
|
raises (SALOME::SALOME_Exception);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,9 +21,10 @@
|
|||||||
#define _OBJECTPOOL_HXX_
|
#define _OBJECTPOOL_HXX_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
//#include <stack>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "SMDS_Iterator.hxx"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// assure deallocation of memory of a vector
|
// assure deallocation of memory of a vector
|
||||||
@ -33,19 +34,23 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class X> class ObjectPoolIterator;
|
||||||
|
|
||||||
template<class X> class ObjectPool
|
template<class X> class ObjectPool
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<X*> _chunkList;
|
std::vector<X*> _chunkList;
|
||||||
std::vector<bool> _freeList;
|
std::vector<bool> _freeList;
|
||||||
int _nextFree;
|
int _nextFree; // either the 1st hole or last added
|
||||||
int _maxAvail;
|
int _maxAvail; // nb allocated elements
|
||||||
int _chunkSize;
|
int _chunkSize;
|
||||||
int _maxOccupied;
|
int _maxOccupied; // max used ID
|
||||||
int _nbHoles;
|
int _nbHoles;
|
||||||
int _lastDelChunk;
|
int _lastDelChunk;
|
||||||
|
|
||||||
|
friend class ObjectPoolIterator<X>;
|
||||||
|
|
||||||
int getNextFree()
|
int getNextFree()
|
||||||
{
|
{
|
||||||
// Don't iterate on the _freeList if all the "holes"
|
// Don't iterate on the _freeList if all the "holes"
|
||||||
@ -76,16 +81,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectPool(int nblk)
|
ObjectPool(int nblk = 1024)
|
||||||
{
|
{
|
||||||
_chunkSize = nblk;
|
_chunkSize = nblk;
|
||||||
_nextFree = 0;
|
_nextFree = 0;
|
||||||
_maxAvail = 0;
|
_maxAvail = 0;
|
||||||
_maxOccupied = 0;
|
_maxOccupied = -1;
|
||||||
_nbHoles = 0;
|
_nbHoles = 0;
|
||||||
|
_lastDelChunk = 0;
|
||||||
_chunkList.clear();
|
_chunkList.clear();
|
||||||
_freeList.clear();
|
_freeList.clear();
|
||||||
_lastDelChunk = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ObjectPool()
|
virtual ~ObjectPool()
|
||||||
@ -105,16 +110,16 @@ public:
|
|||||||
_freeList.insert(_freeList.end(), _chunkSize, true);
|
_freeList.insert(_freeList.end(), _chunkSize, true);
|
||||||
_maxAvail += _chunkSize;
|
_maxAvail += _chunkSize;
|
||||||
_freeList[_nextFree] = false;
|
_freeList[_nextFree] = false;
|
||||||
obj = newChunk; // &newChunk[0];
|
obj = newChunk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int chunkId = _nextFree / _chunkSize;
|
int chunkId = _nextFree / _chunkSize;
|
||||||
int rank = _nextFree - chunkId * _chunkSize;
|
int rank = _nextFree - chunkId * _chunkSize;
|
||||||
_freeList[_nextFree] = false;
|
_freeList[_nextFree] = false;
|
||||||
obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
|
obj = _chunkList[chunkId] + rank;
|
||||||
}
|
}
|
||||||
if (_nextFree < _maxOccupied)
|
if (_nextFree <= _maxOccupied)
|
||||||
{
|
{
|
||||||
_nbHoles-=1;
|
_nbHoles-=1;
|
||||||
}
|
}
|
||||||
@ -122,7 +127,6 @@ public:
|
|||||||
{
|
{
|
||||||
_maxOccupied = _nextFree;
|
_maxOccupied = _nextFree;
|
||||||
}
|
}
|
||||||
//obj->init();
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +152,10 @@ public:
|
|||||||
if (toFree < _nextFree)
|
if (toFree < _nextFree)
|
||||||
_nextFree = toFree;
|
_nextFree = toFree;
|
||||||
if (toFree < _maxOccupied)
|
if (toFree < _maxOccupied)
|
||||||
_nbHoles += 1;
|
++_nbHoles;
|
||||||
|
else
|
||||||
|
--_maxOccupied;
|
||||||
_lastDelChunk = i;
|
_lastDelChunk = i;
|
||||||
//obj->clean();
|
|
||||||
//checkDelete(i); compactage non fait
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
@ -167,6 +171,37 @@ public:
|
|||||||
clearVector( _freeList );
|
clearVector( _freeList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nb allocated elements
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return _freeList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// nb used elements
|
||||||
|
size_t nbElements() const
|
||||||
|
{
|
||||||
|
return _maxOccupied + 1 - _nbHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return an element w/o any check
|
||||||
|
const X* operator[]( size_t i ) const // i < size()
|
||||||
|
{
|
||||||
|
int chunkId = i / _chunkSize;
|
||||||
|
int rank = i - chunkId * _chunkSize;
|
||||||
|
return _chunkList[ chunkId ] + rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return only being used element
|
||||||
|
const X* at( size_t i ) const // i < size()
|
||||||
|
{
|
||||||
|
if ( i >= size() || _freeList[ i ] )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int chunkId = i / _chunkSize;
|
||||||
|
int rank = i - chunkId * _chunkSize;
|
||||||
|
return _chunkList[ chunkId ] + rank;
|
||||||
|
}
|
||||||
|
|
||||||
// void destroy(int toFree)
|
// void destroy(int toFree)
|
||||||
// {
|
// {
|
||||||
// // no control 0<= toFree < _freeList.size()
|
// // no control 0<= toFree < _freeList.size()
|
||||||
@ -177,4 +212,41 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
|
||||||
|
{
|
||||||
|
const ObjectPool<X>& _pool;
|
||||||
|
int _i, _nbFound;
|
||||||
|
public:
|
||||||
|
|
||||||
|
ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
|
||||||
|
{
|
||||||
|
if ( more() && _pool._freeList[ _i ] == true )
|
||||||
|
{
|
||||||
|
next();
|
||||||
|
--_nbFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool more()
|
||||||
|
{
|
||||||
|
return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const X* next()
|
||||||
|
{
|
||||||
|
const X* x = 0;
|
||||||
|
if ( more() )
|
||||||
|
{
|
||||||
|
x = _pool[ _i ];
|
||||||
|
|
||||||
|
++_nbFound;
|
||||||
|
|
||||||
|
for ( ++_i; _i <= _pool._maxOccupied; ++_i )
|
||||||
|
if ( _pool._freeList[ _i ] == false )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -46,8 +46,10 @@
|
|||||||
class SMDS_MeshElement;
|
class SMDS_MeshElement;
|
||||||
class SMDS_MeshFace;
|
class SMDS_MeshFace;
|
||||||
class SMDS_MeshNode;
|
class SMDS_MeshNode;
|
||||||
|
class SMESHDS_Group;
|
||||||
class SMESHDS_Mesh;
|
class SMESHDS_Mesh;
|
||||||
class SMESHDS_SubMesh;
|
class SMESHDS_SubMesh;
|
||||||
|
class SMESH_ElementSearcher;
|
||||||
class SMESH_Group;
|
class SMESH_Group;
|
||||||
class SMESH_Mesh;
|
class SMESH_Mesh;
|
||||||
class SMESH_MesherHelper;
|
class SMESH_MesherHelper;
|
||||||
@ -88,6 +90,7 @@ public:
|
|||||||
int myID;
|
int myID;
|
||||||
double myBallDiameter;
|
double myBallDiameter;
|
||||||
std::vector<int> myPolyhedQuantities;
|
std::vector<int> myPolyhedQuantities;
|
||||||
|
std::vector<const SMDS_MeshNode*> myNodes; // not managed by ElemFeatures
|
||||||
|
|
||||||
SMESH_EXPORT ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false )
|
SMESH_EXPORT ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false )
|
||||||
:myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {}
|
:myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {}
|
||||||
@ -471,7 +474,8 @@ public:
|
|||||||
// Return list of group of nodes close to each other within theTolerance.
|
// Return list of group of nodes close to each other within theTolerance.
|
||||||
// Search among theNodes or in the whole mesh if theNodes is empty.
|
// Search among theNodes or in the whole mesh if theNodes is empty.
|
||||||
|
|
||||||
void MergeNodes (TListOfListOfNodes & theNodeGroups);
|
void MergeNodes (TListOfListOfNodes & theNodeGroups,
|
||||||
|
const bool theAvoidMakingHoles = false);
|
||||||
// In each group, the cdr of nodes are substituted by the first one
|
// In each group, the cdr of nodes are substituted by the first one
|
||||||
// in all elements.
|
// in all elements.
|
||||||
|
|
||||||
@ -540,7 +544,7 @@ public:
|
|||||||
// additional nodes are inserted on a link provided that no
|
// additional nodes are inserted on a link provided that no
|
||||||
// volume elements share the splitted link.
|
// volume elements share the splitted link.
|
||||||
// The side 2 is a free border if theSide2IsFreeBorder == true.
|
// The side 2 is a free border if theSide2IsFreeBorder == true.
|
||||||
// Sewing is peformed between the given first, second and last
|
// Sewing is performed between the given first, second and last
|
||||||
// nodes on the sides.
|
// nodes on the sides.
|
||||||
// theBorderFirstNode is merged with theSide2FirstNode.
|
// theBorderFirstNode is merged with theSide2FirstNode.
|
||||||
// if (!theSide2IsFreeBorder) then theSide2SecondNode gives
|
// if (!theSide2IsFreeBorder) then theSide2SecondNode gives
|
||||||
@ -705,6 +709,42 @@ public:
|
|||||||
bool toAddExistingBondary = false,
|
bool toAddExistingBondary = false,
|
||||||
bool aroundElements = false);
|
bool aroundElements = false);
|
||||||
|
|
||||||
|
|
||||||
|
// structure used in MakePolyLine() to define a cutting plane
|
||||||
|
struct PolySegment
|
||||||
|
{
|
||||||
|
// 2 points: if myNode2 != 0, then the point is the middle of a face edge defined
|
||||||
|
// by two nodes, else it is at myNode1
|
||||||
|
const SMDS_MeshNode* myNode1[2];
|
||||||
|
const SMDS_MeshNode* myNode2[2];
|
||||||
|
|
||||||
|
gp_Vec myVector; // vector on the plane; to use a default plane set vector = (0,0,0)
|
||||||
|
|
||||||
|
// point to return coordinates of a middle of the two points, projected to mesh
|
||||||
|
gp_Pnt myMidProjPoint;
|
||||||
|
};
|
||||||
|
typedef std::vector<PolySegment> TListOfPolySegments;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] group - an optional group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine( TListOfPolySegments& segments,
|
||||||
|
SMESHDS_Group* group=0,
|
||||||
|
SMESH_ElementSearcher* searcher=0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -749,6 +789,20 @@ public:
|
|||||||
const size_t nbSteps,
|
const size_t nbSteps,
|
||||||
SMESH_SequenceOfElemPtr& srcElements);
|
SMESH_SequenceOfElemPtr& srcElements);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Computes new connectivity of an element after merging nodes
|
||||||
|
* \param [in] elems - the element
|
||||||
|
* \param [out] newElemDefs - definition(s) of result element(s)
|
||||||
|
* \param [inout] nodeNodeMap - nodes to merge
|
||||||
|
* \param [in] avoidMakingHoles - if true and and the element becomes invalid
|
||||||
|
* after merging (but not degenerated), removes nodes causing
|
||||||
|
* the invalidity from \a nodeNodeMap.
|
||||||
|
* \return bool - true if the element should be removed
|
||||||
|
*/
|
||||||
|
bool applyMerge( const SMDS_MeshElement* elems,
|
||||||
|
std::vector< ElemFeatures >& newElemDefs,
|
||||||
|
TNodeNodeMap& nodeNodeMap,
|
||||||
|
const bool avoidMakingHoles );
|
||||||
/*!
|
/*!
|
||||||
* \brief Create 1D and 2D elements around swept elements
|
* \brief Create 1D and 2D elements around swept elements
|
||||||
* \param mapNewNodes - source nodes and ones generated from them
|
* \param mapNewNodes - source nodes and ones generated from them
|
||||||
@ -781,11 +835,11 @@ public:
|
|||||||
double Angle ()const { return myAngle; }
|
double Angle ()const { return myAngle; }
|
||||||
double Parameter ()const { return myPrm; }
|
double Parameter ()const { return myPrm; }
|
||||||
};
|
};
|
||||||
Extrusion_Error MakeEdgePathPoints(std::list<double>& aPrms,
|
Extrusion_Error makeEdgePathPoints(std::list<double>& aPrms,
|
||||||
const TopoDS_Edge& aTrackEdge,
|
const TopoDS_Edge& aTrackEdge,
|
||||||
bool aFirstIsStart,
|
bool aFirstIsStart,
|
||||||
std::list<SMESH_MeshEditor_PathPoint>& aLPP);
|
std::list<SMESH_MeshEditor_PathPoint>& aLPP);
|
||||||
Extrusion_Error MakeExtrElements(TIDSortedElemSet theElements[2],
|
Extrusion_Error makeExtrElements(TIDSortedElemSet theElements[2],
|
||||||
std::list<SMESH_MeshEditor_PathPoint>& theFullList,
|
std::list<SMESH_MeshEditor_PathPoint>& theFullList,
|
||||||
const bool theHasAngles,
|
const bool theHasAngles,
|
||||||
std::list<double>& theAngles,
|
std::list<double>& theAngles,
|
||||||
@ -793,7 +847,7 @@ public:
|
|||||||
const bool theHasRefPoint,
|
const bool theHasRefPoint,
|
||||||
const gp_Pnt& theRefPoint,
|
const gp_Pnt& theRefPoint,
|
||||||
const bool theMakeGroups);
|
const bool theMakeGroups);
|
||||||
static void LinearAngleVariation(const int NbSteps,
|
static void linearAngleVariation(const int NbSteps,
|
||||||
std::list<double>& theAngles);
|
std::list<double>& theAngles);
|
||||||
|
|
||||||
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
|
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
|
||||||
@ -812,7 +866,7 @@ private:
|
|||||||
// Nodes and elements created during last operation
|
// Nodes and elements created during last operation
|
||||||
SMESH_SequenceOfElemPtr myLastCreatedNodes, myLastCreatedElems;
|
SMESH_SequenceOfElemPtr myLastCreatedNodes, myLastCreatedElems;
|
||||||
|
|
||||||
// Description of error/warning occured during last operation
|
// Description of error/warning occurred during last operation
|
||||||
SMESH_ComputeErrorPtr myError;
|
SMESH_ComputeErrorPtr myError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,6 +191,9 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
|||||||
SeparateCornersAndMedium = new QCheckBox(tr("SEPARATE_CORNERS_AND_MEDIUM"), NodeSpecWidget );
|
SeparateCornersAndMedium = new QCheckBox(tr("SEPARATE_CORNERS_AND_MEDIUM"), NodeSpecWidget );
|
||||||
SeparateCornersAndMedium->setEnabled( false );
|
SeparateCornersAndMedium->setEnabled( false );
|
||||||
|
|
||||||
|
AvoidMakingHoles = new QCheckBox(tr("AVOID_MAKING_HOLES"), NodeSpecWidget );
|
||||||
|
AvoidMakingHoles->setChecked( false );
|
||||||
|
|
||||||
QGridLayout* NodeSpecLayout = new QGridLayout(NodeSpecWidget);
|
QGridLayout* NodeSpecLayout = new QGridLayout(NodeSpecWidget);
|
||||||
NodeSpecLayout->setSpacing(SPACING);
|
NodeSpecLayout->setSpacing(SPACING);
|
||||||
NodeSpecLayout->setMargin(0);
|
NodeSpecLayout->setMargin(0);
|
||||||
@ -198,6 +201,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
|||||||
NodeSpecLayout->addWidget(TextLabelTolerance, 0, 0 );
|
NodeSpecLayout->addWidget(TextLabelTolerance, 0, 0 );
|
||||||
NodeSpecLayout->addWidget(SpinBoxTolerance, 0, 1 );
|
NodeSpecLayout->addWidget(SpinBoxTolerance, 0, 1 );
|
||||||
NodeSpecLayout->addWidget(SeparateCornersAndMedium, 1, 0, 1, 2 );
|
NodeSpecLayout->addWidget(SeparateCornersAndMedium, 1, 0, 1, 2 );
|
||||||
|
NodeSpecLayout->addWidget(AvoidMakingHoles, 2, 0, 1, 2 );
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
// Exclude groups
|
// Exclude groups
|
||||||
@ -585,7 +589,7 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( myAction == MERGE_NODES )
|
if( myAction == MERGE_NODES )
|
||||||
aMeshEditor->MergeNodes (aGroupsOfElements.inout(), nodesToKeep);
|
aMeshEditor->MergeNodes( aGroupsOfElements.inout(), nodesToKeep, AvoidMakingHoles->isChecked() );
|
||||||
else
|
else
|
||||||
aMeshEditor->MergeElements( aGroupsOfElements.inout() );
|
aMeshEditor->MergeElements( aGroupsOfElements.inout() );
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ private:
|
|||||||
QWidget* NodeSpecWidget;
|
QWidget* NodeSpecWidget;
|
||||||
SMESHGUI_SpinBox* SpinBoxTolerance;
|
SMESHGUI_SpinBox* SpinBoxTolerance;
|
||||||
QCheckBox* SeparateCornersAndMedium;
|
QCheckBox* SeparateCornersAndMedium;
|
||||||
|
QCheckBox* AvoidMakingHoles;
|
||||||
|
|
||||||
QGroupBox* GroupCoincident;
|
QGroupBox* GroupCoincident;
|
||||||
//QWidget* GroupCoincidentWidget;
|
//QWidget* GroupCoincidentWidget;
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#include "SMDS_VolumeTool.hxx"
|
#include "SMDS_VolumeTool.hxx"
|
||||||
#include "SMESH_OctreeNode.hxx"
|
#include "SMESH_OctreeNode.hxx"
|
||||||
|
|
||||||
|
#include <Utils_SALOME_Exception.hxx>
|
||||||
|
|
||||||
#include <GC_MakeSegment.hxx>
|
#include <GC_MakeSegment.hxx>
|
||||||
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
||||||
#include <Geom_Line.hxx>
|
#include <Geom_Line.hxx>
|
||||||
@ -228,15 +230,16 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
SMDSAbs_ElementType elemType,
|
SMDSAbs_ElementType elemType,
|
||||||
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
|
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
|
||||||
double tolerance = NodeRadius );
|
double tolerance = NodeRadius );
|
||||||
void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
|
void prepare(); // !!!call it before calling the following methods!!!
|
||||||
void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
|
void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
|
||||||
|
void getElementsNearLine ( const gp_Ax1& line, vector<const SMDS_MeshElement*>& foundElems);
|
||||||
void getElementsInSphere ( const gp_XYZ& center,
|
void getElementsInSphere ( const gp_XYZ& center,
|
||||||
const double radius, TIDSortedElemSet& foundElems);
|
const double radius,
|
||||||
size_t getSize() { return std::max( _size, _elements.size() ); }
|
vector<const SMDS_MeshElement*>& foundElems);
|
||||||
virtual ~ElementBndBoxTree();
|
ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ElementBndBoxTree():_size(0) {}
|
ElementBndBoxTree() {}
|
||||||
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
|
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
|
||||||
void buildChildrenData();
|
void buildChildrenData();
|
||||||
Bnd_B3d* buildRootBox();
|
Bnd_B3d* buildRootBox();
|
||||||
@ -245,11 +248,25 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
struct ElementBox : public Bnd_B3d
|
struct ElementBox : public Bnd_B3d
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* _element;
|
const SMDS_MeshElement* _element;
|
||||||
int _refCount; // an ElementBox can be included in several tree branches
|
bool _isMarked;
|
||||||
ElementBox(const SMDS_MeshElement* elem, double tolerance);
|
void init(const SMDS_MeshElement* elem, double tolerance);
|
||||||
};
|
};
|
||||||
vector< ElementBox* > _elements;
|
vector< ElementBox* > _elements;
|
||||||
size_t _size;
|
|
||||||
|
typedef ObjectPool< ElementBox > TElementBoxPool;
|
||||||
|
|
||||||
|
//!< allocator of ElementBox's and SMESH_TreeLimit
|
||||||
|
struct LimitAndPool : public SMESH_TreeLimit
|
||||||
|
{
|
||||||
|
TElementBoxPool _elBoPool;
|
||||||
|
std::vector< ElementBox* > _markedElems;
|
||||||
|
LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
|
||||||
|
};
|
||||||
|
LimitAndPool* getLimitAndPool() const
|
||||||
|
{
|
||||||
|
SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
|
||||||
|
return static_cast< LimitAndPool* >( limitAndPool );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -258,30 +275,25 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
|
ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh,
|
||||||
:SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
|
SMDSAbs_ElementType elemType,
|
||||||
|
SMDS_ElemIteratorPtr theElemIt,
|
||||||
|
double tolerance)
|
||||||
|
:SMESH_Octree( new LimitAndPool() )
|
||||||
{
|
{
|
||||||
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
|
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
|
||||||
_elements.reserve( nbElems );
|
_elements.reserve( nbElems );
|
||||||
|
|
||||||
|
TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
|
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
|
||||||
while ( elemIt->more() )
|
while ( elemIt->more() )
|
||||||
_elements.push_back( new ElementBox( elemIt->next(),tolerance ));
|
|
||||||
|
|
||||||
compute();
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Destructor
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
ElementBndBoxTree::~ElementBndBoxTree()
|
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
ElementBox* eb = elBoPool.getNew();
|
||||||
if ( --_elements[i]->_refCount <= 0 )
|
eb->init( elemIt->next(), tolerance );
|
||||||
delete _elements[i];
|
_elements.push_back( eb );
|
||||||
|
}
|
||||||
|
compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -311,14 +323,10 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
for (int j = 0; j < 8; j++)
|
for (int j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
|
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
|
||||||
{
|
|
||||||
_elements[i]->_refCount++;
|
|
||||||
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
|
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_elements[i]->_refCount--;
|
//_size = _elements.size();
|
||||||
}
|
|
||||||
_size = _elements.size();
|
|
||||||
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
|
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++)
|
for (int j = 0; j < 8; j++)
|
||||||
@ -327,11 +335,24 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
|
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
|
||||||
child->myIsLeaf = true;
|
child->myIsLeaf = true;
|
||||||
|
|
||||||
if ( child->_elements.capacity() - child->_elements.size() > 1000 )
|
if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
|
||||||
SMESHUtils::CompactVector( child->_elements );
|
SMESHUtils::CompactVector( child->_elements );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Un-mark all elements
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void ElementBndBoxTree::prepare()
|
||||||
|
{
|
||||||
|
// TElementBoxPool& elBoPool = getElementBoxPool();
|
||||||
|
// for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
|
||||||
|
// const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return elements which can include the point
|
* \brief Return elements which can include the point
|
||||||
@ -339,21 +360,36 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
|
void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( point.XYZ() ))
|
if ( getBox()->IsOut( point.XYZ() ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( point.XYZ() ))
|
if ( !_elements[i]->IsOut( point.XYZ() ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,21 +400,36 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
|
void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( line ))
|
if ( getBox()->IsOut( line ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( line ))
|
if ( !_elements[i]->IsOut( line ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,23 +441,62 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
|
|
||||||
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
|
void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
|
||||||
const double radius,
|
const double radius,
|
||||||
TIDSortedElemSet& foundElems)
|
vector<const SMDS_MeshElement*>& foundElems)
|
||||||
{
|
{
|
||||||
if ( getBox()->IsOut( center, radius ))
|
if ( getBox()->IsOut( center, radius ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( isLeaf() )
|
if ( isLeaf() )
|
||||||
{
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
|
||||||
for ( size_t i = 0; i < _elements.size(); ++i )
|
for ( size_t i = 0; i < _elements.size(); ++i )
|
||||||
if ( !_elements[i]->IsOut( center, radius ))
|
if ( !_elements[i]->IsOut( center, radius ) &&
|
||||||
foundElems.insert( _elements[i]->_element );
|
!_elements[i]->_isMarked )
|
||||||
|
{
|
||||||
|
foundElems.push_back( _elements[i]->_element );
|
||||||
|
_elements[i]->_isMarked = true;
|
||||||
|
pool->_markedElems.push_back( _elements[i] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
|
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
|
||||||
|
|
||||||
|
if ( level() == 0 )
|
||||||
|
{
|
||||||
|
LimitAndPool* pool = getLimitAndPool();
|
||||||
|
for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
|
||||||
|
pool->_markedElems[i]->_isMarked = false;
|
||||||
|
pool->_markedElems.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Return a leaf including a point
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
ElementBndBoxTree* ElementBndBoxTree::getLeafAtPoint( const gp_XYZ& point )
|
||||||
|
{
|
||||||
|
if ( getBox()->IsOut( point ))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( isLeaf() )
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
if ( ElementBndBoxTree* l = ((ElementBndBoxTree*) myChildren[i])->getLeafAtPoint( point ))
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
@ -414,13 +504,13 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
|
void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
|
||||||
{
|
{
|
||||||
_element = elem;
|
_element = elem;
|
||||||
_refCount = 1;
|
_isMarked = false;
|
||||||
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
||||||
while ( nIt->more() )
|
while ( nIt->more() )
|
||||||
Add( SMESH_TNodeXYZ( nIt->next() ));
|
Add( SMESH_NodeXYZ( nIt->next() ));
|
||||||
Enlarge( tolerance );
|
Enlarge( tolerance );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,8 +531,8 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
{
|
{
|
||||||
SMDS_Mesh* _mesh;
|
SMDS_Mesh* _mesh;
|
||||||
SMDS_ElemIteratorPtr _meshPartIt;
|
SMDS_ElemIteratorPtr _meshPartIt;
|
||||||
ElementBndBoxTree* _ebbTree;
|
ElementBndBoxTree* _ebbTree [SMDSAbs_NbElementTypes];
|
||||||
int _ebbTreeHeight;
|
int _ebbTreeHeight[SMDSAbs_NbElementTypes];
|
||||||
SMESH_NodeSearcherImpl* _nodeSearcher;
|
SMESH_NodeSearcherImpl* _nodeSearcher;
|
||||||
SMDSAbs_ElementType _elementType;
|
SMDSAbs_ElementType _elementType;
|
||||||
double _tolerance;
|
double _tolerance;
|
||||||
@ -452,10 +542,21 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh,
|
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh,
|
||||||
double tol=-1,
|
double tol=-1,
|
||||||
SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
|
||||||
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_ebbTreeHeight(-1),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) {}
|
: _mesh(&mesh),_meshPartIt(elemIt),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false)
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
|
||||||
|
{
|
||||||
|
_ebbTree[i] = NULL;
|
||||||
|
_ebbTreeHeight[i] = -1;
|
||||||
|
}
|
||||||
|
_elementType = SMDSAbs_All;
|
||||||
|
}
|
||||||
virtual ~SMESH_ElementSearcherImpl()
|
virtual ~SMESH_ElementSearcherImpl()
|
||||||
{
|
{
|
||||||
if ( _ebbTree ) delete _ebbTree; _ebbTree = 0;
|
for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
|
||||||
|
{
|
||||||
|
delete _ebbTree[i]; _ebbTree[i] = NULL;
|
||||||
|
}
|
||||||
if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0;
|
if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0;
|
||||||
}
|
}
|
||||||
virtual int FindElementsByPoint(const gp_Pnt& point,
|
virtual int FindElementsByPoint(const gp_Pnt& point,
|
||||||
@ -465,13 +566,16 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point,
|
virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point,
|
||||||
SMDSAbs_ElementType type );
|
SMDSAbs_ElementType type );
|
||||||
|
|
||||||
void GetElementsNearLine( const gp_Ax1& line,
|
virtual void GetElementsNearLine( const gp_Ax1& line,
|
||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems);
|
vector< const SMDS_MeshElement* >& foundElems);
|
||||||
void GetElementsInSphere( const gp_XYZ& center,
|
virtual void GetElementsInSphere( const gp_XYZ& center,
|
||||||
const double radius,
|
const double radius,
|
||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems);
|
vector< const SMDS_MeshElement* >& foundElems);
|
||||||
|
virtual gp_XYZ Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestElem);
|
||||||
double getTolerance();
|
double getTolerance();
|
||||||
bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
|
bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
|
||||||
const double tolerance, double & param);
|
const double tolerance, double & param);
|
||||||
@ -482,9 +586,9 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
|
|||||||
}
|
}
|
||||||
int getTreeHeight()
|
int getTreeHeight()
|
||||||
{
|
{
|
||||||
if ( _ebbTreeHeight < 0 )
|
if ( _ebbTreeHeight[ _elementType ] < 0 )
|
||||||
_ebbTreeHeight = _ebbTree->getHeight();
|
_ebbTreeHeight[ _elementType ] = _ebbTree[ _elementType ]->getHeight();
|
||||||
return _ebbTreeHeight;
|
return _ebbTreeHeight[ _elementType ];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState())
|
struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState())
|
||||||
@ -528,9 +632,9 @@ double SMESH_ElementSearcherImpl::getTolerance()
|
|||||||
double boxSize = _nodeSearcher->getTree()->maxSize();
|
double boxSize = _nodeSearcher->getTree()->maxSize();
|
||||||
_tolerance = 1e-8 * boxSize/* / meshInfo.NbNodes()*/;
|
_tolerance = 1e-8 * boxSize/* / meshInfo.NbNodes()*/;
|
||||||
}
|
}
|
||||||
else if ( _ebbTree && meshInfo.NbElements() > 0 )
|
else if ( _ebbTree[_elementType] && meshInfo.NbElements() > 0 )
|
||||||
{
|
{
|
||||||
double boxSize = _ebbTree->maxSize();
|
double boxSize = _ebbTree[_elementType]->maxSize();
|
||||||
_tolerance = 1e-8 * boxSize/* / meshInfo.NbElements()*/;
|
_tolerance = 1e-8 * boxSize/* / meshInfo.NbElements()*/;
|
||||||
}
|
}
|
||||||
if ( _tolerance == 0 )
|
if ( _tolerance == 0 )
|
||||||
@ -551,8 +655,7 @@ double SMESH_ElementSearcherImpl::getTolerance()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SMDS_ElemIteratorPtr elemIt =
|
SMDS_ElemIteratorPtr elemIt = _mesh->elementsIterator( SMDSAbs_ElementType( complexType ));
|
||||||
_mesh->elementsIterator( SMDSAbs_ElementType( complexType ));
|
|
||||||
const SMDS_MeshElement* elem = elemIt->next();
|
const SMDS_MeshElement* elem = elemIt->next();
|
||||||
SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
|
SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
|
||||||
SMESH_TNodeXYZ n1( nodeIt->next() );
|
SMESH_TNodeXYZ n1( nodeIt->next() );
|
||||||
@ -594,7 +697,7 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& lin
|
|||||||
anExtCC.Init( lineCurve, edge.Value() );
|
anExtCC.Init( lineCurve, edge.Value() );
|
||||||
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
|
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
|
||||||
{
|
{
|
||||||
Quantity_Parameter pl, pe;
|
Standard_Real pl, pe;
|
||||||
anExtCC.LowerDistanceParameters( pl, pe );
|
anExtCC.LowerDistanceParameters( pl, pe );
|
||||||
param += pl;
|
param += pl;
|
||||||
if ( ++nbInts == 2 )
|
if ( ++nbInts == 2 )
|
||||||
@ -679,7 +782,7 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
|
|||||||
outerFace2 = angle2Face.begin()->second;
|
outerFace2 = angle2Face.begin()->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// store the found outer face and add its links to continue seaching from
|
// store the found outer face and add its links to continue searching from
|
||||||
if ( outerFace2 )
|
if ( outerFace2 )
|
||||||
{
|
{
|
||||||
_outerFaces.insert( outerFace2 );
|
_outerFaces.insert( outerFace2 );
|
||||||
@ -723,6 +826,7 @@ FindElementsByPoint(const gp_Pnt& point,
|
|||||||
vector< const SMDS_MeshElement* >& foundElements)
|
vector< const SMDS_MeshElement* >& foundElements)
|
||||||
{
|
{
|
||||||
foundElements.clear();
|
foundElements.clear();
|
||||||
|
_elementType = type;
|
||||||
|
|
||||||
double tolerance = getTolerance();
|
double tolerance = getTolerance();
|
||||||
|
|
||||||
@ -756,14 +860,17 @@ FindElementsByPoint(const gp_Pnt& point,
|
|||||||
// =================================================================================
|
// =================================================================================
|
||||||
else // elements more complex than 0D
|
else // elements more complex than 0D
|
||||||
{
|
{
|
||||||
if ( !_ebbTree || _elementType != type )
|
if ( !_ebbTree[type] )
|
||||||
{
|
{
|
||||||
if ( _ebbTree ) delete _ebbTree;
|
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
|
||||||
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance );
|
|
||||||
}
|
}
|
||||||
TIDSortedElemSet suspectElems;
|
else
|
||||||
_ebbTree->getElementsNearPoint( point, suspectElems );
|
{
|
||||||
TIDSortedElemSet::iterator elem = suspectElems.begin();
|
_ebbTree[ type ]->prepare();
|
||||||
|
}
|
||||||
|
vector< const SMDS_MeshElement* > suspectElems;
|
||||||
|
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
|
||||||
|
vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
|
||||||
for ( ; elem != suspectElems.end(); ++elem )
|
for ( ; elem != suspectElems.end(); ++elem )
|
||||||
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
|
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
|
||||||
foundElements.push_back( *elem );
|
foundElements.push_back( *elem );
|
||||||
@ -784,35 +891,38 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
|
|||||||
SMDSAbs_ElementType type )
|
SMDSAbs_ElementType type )
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* closestElem = 0;
|
const SMDS_MeshElement* closestElem = 0;
|
||||||
|
_elementType = type;
|
||||||
|
|
||||||
if ( type == SMDSAbs_Face || type == SMDSAbs_Volume )
|
if ( type == SMDSAbs_Face || type == SMDSAbs_Volume )
|
||||||
{
|
{
|
||||||
if ( !_ebbTree || _elementType != type )
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
{
|
if ( !ebbTree )
|
||||||
if ( _ebbTree ) delete _ebbTree;
|
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
|
||||||
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
|
else
|
||||||
}
|
ebbTree->prepare();
|
||||||
TIDSortedElemSet suspectElems;
|
|
||||||
_ebbTree->getElementsNearPoint( point, suspectElems );
|
|
||||||
|
|
||||||
if ( suspectElems.empty() && _ebbTree->maxSize() > 0 )
|
vector<const SMDS_MeshElement*> suspectElems;
|
||||||
|
ebbTree->getElementsNearPoint( point, suspectElems );
|
||||||
|
|
||||||
|
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
|
||||||
{
|
{
|
||||||
gp_Pnt boxCenter = 0.5 * ( _ebbTree->getBox()->CornerMin() +
|
gp_Pnt boxCenter = 0.5 * ( ebbTree->getBox()->CornerMin() +
|
||||||
_ebbTree->getBox()->CornerMax() );
|
ebbTree->getBox()->CornerMax() );
|
||||||
double radius = -1;
|
double radius = -1;
|
||||||
if ( _ebbTree->getBox()->IsOut( point.XYZ() ))
|
if ( ebbTree->getBox()->IsOut( point.XYZ() ))
|
||||||
radius = point.Distance( boxCenter ) - 0.5 * _ebbTree->maxSize();
|
radius = point.Distance( boxCenter ) - 0.5 * ebbTree->maxSize();
|
||||||
if ( radius < 0 )
|
if ( radius < 0 )
|
||||||
radius = _ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
|
radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
|
||||||
while ( suspectElems.empty() )
|
while ( suspectElems.empty() )
|
||||||
{
|
{
|
||||||
_ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
|
ebbTree->prepare();
|
||||||
|
ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
|
||||||
radius *= 1.1;
|
radius *= 1.1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double minDist = std::numeric_limits<double>::max();
|
double minDist = std::numeric_limits<double>::max();
|
||||||
multimap< double, const SMDS_MeshElement* > dist2face;
|
multimap< double, const SMDS_MeshElement* > dist2face;
|
||||||
TIDSortedElemSet::iterator elem = suspectElems.begin();
|
vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
|
||||||
for ( ; elem != suspectElems.end(); ++elem )
|
for ( ; elem != suspectElems.end(); ++elem )
|
||||||
{
|
{
|
||||||
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
|
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
|
||||||
@ -869,12 +979,16 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point,
|
|||||||
|
|
||||||
TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
|
TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
|
||||||
{
|
{
|
||||||
|
_elementType = SMDSAbs_Face;
|
||||||
|
|
||||||
double tolerance = getTolerance();
|
double tolerance = getTolerance();
|
||||||
if ( !_ebbTree || _elementType != SMDSAbs_Face )
|
|
||||||
{
|
ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
|
||||||
if ( _ebbTree ) delete _ebbTree;
|
if ( !ebbTree )
|
||||||
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
}
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
// Algo: analyse transition of a line starting at the point through mesh boundary;
|
// Algo: analyse transition of a line starting at the point through mesh boundary;
|
||||||
// try three lines parallel to axis of the coordinate system and perform rough
|
// try three lines parallel to axis of the coordinate system and perform rough
|
||||||
// analysis. If solution is not clear perform thorough analysis.
|
// analysis. If solution is not clear perform thorough analysis.
|
||||||
@ -889,13 +1003,14 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
|
|||||||
gp_Ax1 lineAxis( point, axisDir[axis]);
|
gp_Ax1 lineAxis( point, axisDir[axis]);
|
||||||
gp_Lin line ( lineAxis );
|
gp_Lin line ( lineAxis );
|
||||||
|
|
||||||
TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
|
vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
|
||||||
_ebbTree->getElementsNearLine( lineAxis, suspectFaces );
|
if ( axis > 0 ) ebbTree->prepare();
|
||||||
|
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
|
||||||
|
|
||||||
// Intersect faces with the line
|
// Intersect faces with the line
|
||||||
|
|
||||||
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
|
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
|
||||||
TIDSortedElemSet::iterator face = suspectFaces.begin();
|
vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
|
||||||
for ( ; face != suspectFaces.end(); ++face )
|
for ( ; face != suspectFaces.end(); ++face )
|
||||||
{
|
{
|
||||||
// get face plane
|
// get face plane
|
||||||
@ -1098,14 +1213,14 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
|
|||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems)
|
vector< const SMDS_MeshElement* >& foundElems)
|
||||||
{
|
{
|
||||||
if ( !_ebbTree || _elementType != type )
|
_elementType = type;
|
||||||
{
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
if ( _ebbTree ) delete _ebbTree;
|
if ( !ebbTree )
|
||||||
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
}
|
else
|
||||||
TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
|
ebbTree->prepare();
|
||||||
_ebbTree->getElementsNearLine( line, suspectFaces );
|
|
||||||
foundElems.assign( suspectFaces.begin(), suspectFaces.end());
|
ebbTree->getElementsNearLine( line, foundElems );
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1119,14 +1234,63 @@ void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ&
|
|||||||
SMDSAbs_ElementType type,
|
SMDSAbs_ElementType type,
|
||||||
vector< const SMDS_MeshElement* >& foundElems)
|
vector< const SMDS_MeshElement* >& foundElems)
|
||||||
{
|
{
|
||||||
if ( !_ebbTree || _elementType != type )
|
_elementType = type;
|
||||||
{
|
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
|
||||||
if ( _ebbTree ) delete _ebbTree;
|
if ( !ebbTree )
|
||||||
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
|
||||||
|
else
|
||||||
|
ebbTree->prepare();
|
||||||
|
|
||||||
|
ebbTree->getElementsInSphere( center, radius, foundElems );
|
||||||
}
|
}
|
||||||
TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
|
|
||||||
_ebbTree->getElementsInSphere( center, radius, suspectFaces );
|
//=======================================================================
|
||||||
foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
|
/*
|
||||||
|
* \brief Return a projection of a given point to a mesh.
|
||||||
|
* Optionally return the closest element
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestElem)
|
||||||
|
{
|
||||||
|
_elementType = type;
|
||||||
|
if ( _mesh->GetMeshInfo().NbElements( _elementType ) == 0 )
|
||||||
|
throw SALOME_Exception( LOCALIZED( "No elements of given type in the mesh" ));
|
||||||
|
|
||||||
|
ElementBndBoxTree*& ebbTree = _ebbTree[ _elementType ];
|
||||||
|
if ( !ebbTree )
|
||||||
|
ebbTree = new ElementBndBoxTree( *_mesh, _elementType );
|
||||||
|
|
||||||
|
gp_XYZ p = point.XYZ();
|
||||||
|
ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p );
|
||||||
|
const Bnd_B3d* box = ebbLeaf->getBox();
|
||||||
|
double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
|
||||||
|
|
||||||
|
vector< const SMDS_MeshElement* > elems;
|
||||||
|
ebbTree->getElementsInSphere( p, radius, elems );
|
||||||
|
while ( elems.empty() )
|
||||||
|
{
|
||||||
|
radius *= 1.5;
|
||||||
|
ebbTree->getElementsInSphere( p, radius, elems );
|
||||||
|
}
|
||||||
|
gp_XYZ proj, bestProj;
|
||||||
|
const SMDS_MeshElement* elem = 0;
|
||||||
|
double minDist = 2 * radius;
|
||||||
|
for ( size_t i = 0; i < elems.size(); ++i )
|
||||||
|
{
|
||||||
|
double d = SMESH_MeshAlgos::GetDistance( elems[i], p, &proj );
|
||||||
|
if ( d < minDist )
|
||||||
|
{
|
||||||
|
bestProj = proj;
|
||||||
|
elem = elems[i];
|
||||||
|
minDist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( closestElem ) *closestElem = elem;
|
||||||
|
|
||||||
|
return bestProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -1163,8 +1327,8 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
gp_Vec edge2( xyz[i+1], xyz[(i+2)%nbNodes] );
|
gp_Vec edge2( xyz[i+1], xyz[(i+2)%nbNodes] );
|
||||||
faceNorm += edge1 ^ edge2;
|
faceNorm += edge1 ^ edge2;
|
||||||
}
|
}
|
||||||
double normSize = faceNorm.Magnitude();
|
double fNormSize = faceNorm.Magnitude();
|
||||||
if ( normSize <= tol )
|
if ( fNormSize <= tol )
|
||||||
{
|
{
|
||||||
// degenerated face: point is out if it is out of all face edges
|
// degenerated face: point is out if it is out of all face edges
|
||||||
for ( i = 0; i < nbNodes; ++i )
|
for ( i = 0; i < nbNodes; ++i )
|
||||||
@ -1175,7 +1339,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
faceNorm /= normSize;
|
faceNorm /= fNormSize;
|
||||||
|
|
||||||
// check if the point lays on face plane
|
// check if the point lays on face plane
|
||||||
gp_Vec n2p( xyz[0], point );
|
gp_Vec n2p( xyz[0], point );
|
||||||
@ -1204,9 +1368,10 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
// to find intersections of the ray with the boundary.
|
// to find intersections of the ray with the boundary.
|
||||||
gp_Vec ray = n2p;
|
gp_Vec ray = n2p;
|
||||||
gp_Vec plnNorm = ray ^ faceNorm;
|
gp_Vec plnNorm = ray ^ faceNorm;
|
||||||
normSize = plnNorm.Magnitude();
|
double n2pSize = plnNorm.Magnitude();
|
||||||
if ( normSize <= tol ) return false; // point coincides with the first node
|
if ( n2pSize <= tol ) return false; // point coincides with the first node
|
||||||
plnNorm /= normSize;
|
if ( n2pSize * n2pSize > fNormSize * 100 ) return true; // point is very far
|
||||||
|
plnNorm /= n2pSize;
|
||||||
// for each node of the face, compute its signed distance to the cutting plane
|
// for each node of the face, compute its signed distance to the cutting plane
|
||||||
vector<double> dist( nbNodes + 1);
|
vector<double> dist( nbNodes + 1);
|
||||||
for ( i = 0; i < nbNodes; ++i )
|
for ( i = 0; i < nbNodes; ++i )
|
||||||
@ -1252,7 +1417,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
|
|||||||
if ( rClosest > 0. && rClosest < 1. ) // not node intersection
|
if ( rClosest > 0. && rClosest < 1. ) // not node intersection
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
// ray pass through a face node; analyze transition through an adjacent edge
|
// the ray passes through a face node; analyze transition through an adjacent edge
|
||||||
gp_Pnt p1 = xyz[ (rClosest == 0.) ? ((iClosest+nbNodes-1) % nbNodes) : (iClosest+1) ];
|
gp_Pnt p1 = xyz[ (rClosest == 0.) ? ((iClosest+nbNodes-1) % nbNodes) : (iClosest+1) ];
|
||||||
gp_Pnt p2 = xyz[ (rClosest == 0.) ? iClosest : ((iClosest+2) % nbNodes) ];
|
gp_Pnt p2 = xyz[ (rClosest == 0.) ? iClosest : ((iClosest+2) % nbNodes) ];
|
||||||
gp_Vec edgeAdjacent( p1, p2 );
|
gp_Vec edgeAdjacent( p1, p2 );
|
||||||
@ -1375,17 +1540,19 @@ namespace
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
||||||
const gp_Pnt& point )
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
switch ( elem->GetType() )
|
switch ( elem->GetType() )
|
||||||
{
|
{
|
||||||
case SMDSAbs_Volume:
|
case SMDSAbs_Volume:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Face:
|
case SMDSAbs_Face:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Edge:
|
case SMDSAbs_Edge:
|
||||||
return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point);
|
return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point, closestPnt );
|
||||||
case SMDSAbs_Node:
|
case SMDSAbs_Node:
|
||||||
|
if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem );
|
||||||
return point.Distance( SMESH_TNodeXYZ( elem ));
|
return point.Distance( SMESH_TNodeXYZ( elem ));
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -1401,9 +1568,10 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
||||||
const gp_Pnt& point )
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
double badDistance = -1;
|
const double badDistance = -1;
|
||||||
if ( !face ) return badDistance;
|
if ( !face ) return badDistance;
|
||||||
|
|
||||||
// coordinates of nodes (medium nodes, if any, ignored)
|
// coordinates of nodes (medium nodes, if any, ignored)
|
||||||
@ -1447,7 +1615,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
trsf.Transforms( tmpPnt );
|
trsf.Transforms( tmpPnt );
|
||||||
gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
|
gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
|
||||||
|
|
||||||
// loop on segments of the face to analyze point position ralative to the face
|
// loop on edges of the face to analyze point position ralative to the face
|
||||||
set< PointPos > pntPosSet;
|
set< PointPos > pntPosSet;
|
||||||
for ( size_t i = 1; i < xy.size(); ++i )
|
for ( size_t i = 1; i < xy.size(); ++i )
|
||||||
{
|
{
|
||||||
@ -1457,31 +1625,40 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
|
|
||||||
// compute distance
|
// compute distance
|
||||||
PointPos pos = *pntPosSet.begin();
|
PointPos pos = *pntPosSet.begin();
|
||||||
// cout << "Face " << face->GetID() << " DIST: ";
|
|
||||||
switch ( pos._name )
|
switch ( pos._name )
|
||||||
{
|
{
|
||||||
case POS_LEFT: {
|
case POS_LEFT:
|
||||||
// point is most close to a segment
|
{
|
||||||
gp_Vec p0p1( point, xyz[ pos._index ] );
|
// point is most close to an edge
|
||||||
gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector
|
gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
|
||||||
p1p2.Normalize();
|
gp_Vec n1p ( xyz[ pos._index ], point );
|
||||||
double projDist = p0p1 * p1p2; // distance projected to the segment
|
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
||||||
gp_Vec projVec = p1p2 * projDist;
|
// projection of the point on the edge
|
||||||
gp_Vec distVec = p0p1 - projVec;
|
gp_XYZ proj = ( 1. - u ) * xyz[ pos._index ] + u * xyz[ pos._index+1 ];
|
||||||
// cout << distVec.Magnitude() << ", SEG " << face->GetNode(pos._index)->GetID()
|
if ( closestPnt ) *closestPnt = proj;
|
||||||
// << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl;
|
return point.Distance( proj );
|
||||||
return distVec.Magnitude();
|
|
||||||
}
|
}
|
||||||
case POS_RIGHT: {
|
case POS_RIGHT:
|
||||||
|
{
|
||||||
// point is inside the face
|
// point is inside the face
|
||||||
double distToFacePlane = tmpPnt.Y();
|
double distToFacePlane = tmpPnt.Y();
|
||||||
// cout << distToFacePlane << ", INSIDE " << endl;
|
if ( closestPnt )
|
||||||
|
{
|
||||||
|
if ( distToFacePlane < std::numeric_limits<double>::min() ) {
|
||||||
|
*closestPnt = point.XYZ();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmpPnt.SetY( 0 );
|
||||||
|
trsf.Inverted().Transforms( tmpPnt );
|
||||||
|
*closestPnt = tmpPnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Abs( distToFacePlane );
|
return Abs( distToFacePlane );
|
||||||
}
|
}
|
||||||
case POS_VERTEX: {
|
case POS_VERTEX:
|
||||||
|
{
|
||||||
// point is most close to a node
|
// point is most close to a node
|
||||||
gp_Vec distVec( point, xyz[ pos._index ]);
|
gp_Vec distVec( point, xyz[ pos._index ]);
|
||||||
// cout << distVec.Magnitude() << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
|
|
||||||
return distVec.Magnitude();
|
return distVec.Magnitude();
|
||||||
}
|
}
|
||||||
default:;
|
default:;
|
||||||
@ -1495,7 +1672,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
|
|||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& point )
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg,
|
||||||
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
double dist = Precision::Infinite();
|
double dist = Precision::Infinite();
|
||||||
if ( !seg ) return dist;
|
if ( !seg ) return dist;
|
||||||
@ -1514,13 +1693,16 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi
|
|||||||
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
|
||||||
if ( u <= 0. ) {
|
if ( u <= 0. ) {
|
||||||
dist = Min( dist, n1p.SquareMagnitude() );
|
dist = Min( dist, n1p.SquareMagnitude() );
|
||||||
|
if ( closestPnt ) *closestPnt = xyz[i-1];
|
||||||
}
|
}
|
||||||
else if ( u >= 1. ) {
|
else if ( u >= 1. ) {
|
||||||
dist = Min( dist, point.SquareDistance( xyz[i] ));
|
dist = Min( dist, point.SquareDistance( xyz[i] ));
|
||||||
|
if ( closestPnt ) *closestPnt = xyz[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
|
gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
|
||||||
dist = Min( dist, point.SquareDistance( proj ));
|
dist = Min( dist, point.SquareDistance( proj ));
|
||||||
|
if ( closestPnt ) *closestPnt = proj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Sqrt( dist );
|
return Sqrt( dist );
|
||||||
@ -1534,7 +1716,9 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& poi
|
|||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point )
|
double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume,
|
||||||
|
const gp_Pnt& point,
|
||||||
|
gp_XYZ* closestPnt )
|
||||||
{
|
{
|
||||||
SMDS_VolumeTool vTool( volume );
|
SMDS_VolumeTool vTool( volume );
|
||||||
vTool.SetExternalNormal();
|
vTool.SetExternalNormal();
|
||||||
@ -1542,6 +1726,8 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt
|
|||||||
|
|
||||||
double n[3], bc[3];
|
double n[3], bc[3];
|
||||||
double minDist = 1e100, dist;
|
double minDist = 1e100, dist;
|
||||||
|
gp_XYZ closeP = point.XYZ();
|
||||||
|
bool isOut = false;
|
||||||
for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
|
for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
|
||||||
{
|
{
|
||||||
// skip a facet with normal not "looking at" the point
|
// skip a facet with normal not "looking at" the point
|
||||||
@ -1558,25 +1744,36 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
|
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
|
SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
|
vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
|
||||||
SMDS_PolygonalFaceOfNodes tmpFace( nvec );
|
SMDS_PolygonalFaceOfNodes tmpFace( nvec );
|
||||||
dist = GetDistance( &tmpFace, point );
|
dist = GetDistance( &tmpFace, point, closestPnt );
|
||||||
}
|
}
|
||||||
minDist = Min( minDist, dist );
|
if ( dist < minDist )
|
||||||
|
{
|
||||||
|
minDist = dist;
|
||||||
|
isOut = true;
|
||||||
|
if ( closestPnt ) closeP = *closestPnt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( isOut )
|
||||||
|
{
|
||||||
|
if ( closestPnt ) *closestPnt = closeP;
|
||||||
return minDist;
|
return minDist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0; // point is inside the volume
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns barycentric coordinates of a point within a triangle.
|
* \brief Returns barycentric coordinates of a point within a triangle.
|
||||||
@ -1765,3 +1962,12 @@ SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh&
|
|||||||
{
|
{
|
||||||
return new SMESH_ElementSearcherImpl( mesh, tolerance, elemIt );
|
return new SMESH_ElementSearcherImpl( mesh, tolerance, elemIt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TMP for ASERIS in V8_2_BR -- to remove when merging to master
|
||||||
|
void SMESH_MeshAlgos::DeMerge(const SMDS_MeshElement* elem,
|
||||||
|
std::vector< const SMDS_MeshNode* >& newNodes,
|
||||||
|
std::vector< const SMDS_MeshNode* >& noMergeNodes)
|
||||||
|
{
|
||||||
|
// TMP for ASERIS in V8_2_BR -- to remove when merging to master
|
||||||
|
}
|
||||||
|
// TMP for ASERIS in V8_2_BR -- to remove when merging to master
|
||||||
|
@ -100,6 +100,15 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher
|
|||||||
* \brief Find out if the given point is out of closed 2D mesh.
|
* \brief Find out if the given point is out of closed 2D mesh.
|
||||||
*/
|
*/
|
||||||
virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
|
virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a projection of a given point to a 2D mesh.
|
||||||
|
* Optionally return the closest face
|
||||||
|
*/
|
||||||
|
virtual gp_XYZ Project(const gp_Pnt& point,
|
||||||
|
SMDSAbs_ElementType type,
|
||||||
|
const SMDS_MeshElement** closestFace= 0) = 0;
|
||||||
|
|
||||||
virtual ~SMESH_ElementSearcher();
|
virtual ~SMESH_ElementSearcher();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,16 +121,16 @@ namespace SMESH_MeshAlgos
|
|||||||
bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
|
bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point );
|
double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point, gp_XYZ* closestPnt = 0 );
|
||||||
|
|
||||||
SMESHUtils_EXPORT
|
SMESHUtils_EXPORT
|
||||||
void GetBarycentricCoords( const gp_XY& point,
|
void GetBarycentricCoords( const gp_XY& point,
|
||||||
@ -206,6 +215,16 @@ namespace SMESH_MeshAlgos
|
|||||||
CoincidentFreeBorders & foundFreeBordes);
|
CoincidentFreeBorders & foundFreeBordes);
|
||||||
|
|
||||||
|
|
||||||
} // SMESH_MeshAlgos
|
/*!
|
||||||
|
* \brief Find nodes whose merge makes the element invalid
|
||||||
|
*
|
||||||
|
* (Implemented in SMESH_DeMerge.cxx)
|
||||||
|
*/
|
||||||
|
SMESHUtils_EXPORT
|
||||||
|
void DeMerge(const SMDS_MeshElement* elem,
|
||||||
|
std::vector< const SMDS_MeshNode* >& newNodes,
|
||||||
|
std::vector< const SMDS_MeshNode* >& noMergeNodes);
|
||||||
|
|
||||||
|
} // namespace SMESH_MeshAlgos
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,12 @@ void SMESH::doNothing(const char* txt)
|
|||||||
{
|
{
|
||||||
MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ );
|
MESSAGE( txt << " " << __FILE__ << ": " << __LINE__ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* SMESH::returnError(const char* txt)
|
||||||
|
{
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
#include "SMESH_ComputeError.hxx"
|
#include "SMESH_ComputeError.hxx"
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ namespace SMESH
|
|||||||
{
|
{
|
||||||
SMESHUtils_EXPORT void throwSalomeEx(const char* txt);
|
SMESHUtils_EXPORT void throwSalomeEx(const char* txt);
|
||||||
SMESHUtils_EXPORT void doNothing(const char* txt);
|
SMESHUtils_EXPORT void doNothing(const char* txt);
|
||||||
|
SMESHUtils_EXPORT const char* returnError(const char* txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -169,6 +169,7 @@ struct SMESH_TNodeXYZ : public gp_XYZ
|
|||||||
double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); }
|
double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); }
|
||||||
bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; }
|
bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; }
|
||||||
};
|
};
|
||||||
|
typedef SMESH_TNodeXYZ SMESH_NodeXYZ;
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
/*!
|
/*!
|
||||||
|
@ -184,7 +184,7 @@ namespace MeshEditor_I {
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Deleter of theNodeSearcher at any compute event occured
|
* \brief Deleter of theNodeSearcher at any compute event occurred
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
@ -467,9 +467,9 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Increment mesh modif time and optionally record that the performed
|
* \brief Increment mesh modif time and optionally record that the performed
|
||||||
* modification may influence futher mesh re-compute.
|
* modification may influence further mesh re-compute.
|
||||||
* \param [in] isReComputeSafe - true if the modification does not influence
|
* \param [in] isReComputeSafe - true if the modification does not influence
|
||||||
* futher mesh re-compute
|
* further mesh re-compute
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
@ -501,7 +501,7 @@ void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
|
|||||||
* \brief Initialize and return myPreviewMesh
|
* \brief Initialize and return myPreviewMesh
|
||||||
* \param previewElements - type of elements to show in preview
|
* \param previewElements - type of elements to show in preview
|
||||||
*
|
*
|
||||||
* WARNING: call it once par a method!
|
* WARNING: call it once per method!
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
@ -669,7 +669,7 @@ void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
|
|||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
/*
|
/*
|
||||||
* Returns description of an error/warning occured during the last operation
|
* Returns description of an error/warning occurred during the last operation
|
||||||
* WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
|
* WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
|
||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -4159,7 +4159,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
|
void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
|
||||||
const SMESH::ListOfIDSources& NodesToKeep)
|
const SMESH::ListOfIDSources& NodesToKeep,
|
||||||
|
CORBA::Boolean AvoidMakingHoles)
|
||||||
throw (SALOME::SALOME_Exception)
|
throw (SALOME::SALOME_Exception)
|
||||||
{
|
{
|
||||||
SMESH_TRY;
|
SMESH_TRY;
|
||||||
@ -4203,9 +4204,9 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
|
|||||||
aTPythonDump << aNodeGroup;
|
aTPythonDump << aNodeGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEditor().MergeNodes( aListOfListOfNodes );
|
getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles );
|
||||||
|
|
||||||
aTPythonDump << "], " << NodesToKeep << ")";
|
aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")";
|
||||||
|
|
||||||
declareMeshModified( /*isReComputeSafe=*/false );
|
declareMeshModified( /*isReComputeSafe=*/false );
|
||||||
|
|
||||||
@ -5117,7 +5118,6 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
|
|||||||
TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
|
TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
|
||||||
<< ide << ", " << newIDs << " )";
|
<< ide << ", " << newIDs << " )";
|
||||||
|
|
||||||
MESSAGE("ChangeElementNodes");
|
|
||||||
bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
|
bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
|
||||||
|
|
||||||
declareMeshModified( /*isReComputeSafe=*/ !res );
|
declareMeshModified( /*isReComputeSafe=*/ !res );
|
||||||
@ -6280,7 +6280,6 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
|
|||||||
throw (SALOME::SALOME_Exception)
|
throw (SALOME::SALOME_Exception)
|
||||||
{
|
{
|
||||||
SMESH_TRY;
|
SMESH_TRY;
|
||||||
MESSAGE("AffectedElemGroupsInRegion");
|
|
||||||
SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
|
SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
|
||||||
bool isEdgeGroup = false;
|
bool isEdgeGroup = false;
|
||||||
bool isFaceGroup = false;
|
bool isFaceGroup = false;
|
||||||
@ -6309,7 +6308,6 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
|
|||||||
if (aResult)
|
if (aResult)
|
||||||
{
|
{
|
||||||
int lg = anAffected.size();
|
int lg = anAffected.size();
|
||||||
MESSAGE("lg="<< lg);
|
|
||||||
SMESH::long_array_var volumeIds = new SMESH::long_array;
|
SMESH::long_array_var volumeIds = new SMESH::long_array;
|
||||||
volumeIds->length(lg);
|
volumeIds->length(lg);
|
||||||
SMESH::long_array_var faceIds = new SMESH::long_array;
|
SMESH::long_array_var faceIds = new SMESH::long_array;
|
||||||
@ -6658,7 +6656,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
|
|||||||
else
|
else
|
||||||
pyDump << mesh_var << ", ";
|
pyDump << mesh_var << ", ";
|
||||||
if ( group_var->_is_nil() )
|
if ( group_var->_is_nil() )
|
||||||
pyDump << "_NoneGroup = "; // assignment to None is forbiden
|
pyDump << "_NoneGroup = "; // assignment to None is forbidden
|
||||||
else
|
else
|
||||||
pyDump << group_var << " = ";
|
pyDump << group_var << " = ";
|
||||||
pyDump << this << ".MakeBoundaryMesh( "
|
pyDump << this << ".MakeBoundaryMesh( "
|
||||||
@ -6722,7 +6720,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
|
|||||||
else
|
else
|
||||||
groupsOfThisMesh[ nbGroups++ ] = groups[i];
|
groupsOfThisMesh[ nbGroups++ ] = groups[i];
|
||||||
if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
|
if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
|
||||||
THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
|
THROW_SALOME_CORBA_EXCEPTION("expected a group but received a mesh", SALOME::BAD_PARAM);
|
||||||
}
|
}
|
||||||
groupsOfThisMesh->length( nbGroups );
|
groupsOfThisMesh->length( nbGroups );
|
||||||
groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
|
groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
|
||||||
@ -6816,7 +6814,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
|
|||||||
else
|
else
|
||||||
pyDump << mesh_var << ", ";
|
pyDump << mesh_var << ", ";
|
||||||
if ( group_var->_is_nil() )
|
if ( group_var->_is_nil() )
|
||||||
pyDump << "_NoneGroup = "; // assignment to None is forbiden
|
pyDump << "_NoneGroup = "; // assignment to None is forbidden
|
||||||
else
|
else
|
||||||
pyDump << group_var << " = ";
|
pyDump << group_var << " = ";
|
||||||
pyDump << this << ".MakeBoundaryElements( "
|
pyDump << this << ".MakeBoundaryElements( "
|
||||||
@ -6833,3 +6831,128 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
|
|||||||
SMESH_CATCH( SMESH::throwCorbaException );
|
SMESH_CATCH( SMESH::throwCorbaException );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments,
|
||||||
|
const char* theGroupName)
|
||||||
|
throw (SALOME::SALOME_Exception)
|
||||||
|
{
|
||||||
|
if ( theSegments.length() == 0 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM );
|
||||||
|
if ( myMesh->NbFaces() == 0 )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM );
|
||||||
|
|
||||||
|
SMESH_TRY;
|
||||||
|
initData(/*deleteSearchers=*/false);
|
||||||
|
|
||||||
|
SMESHDS_Group* groupDS = 0;
|
||||||
|
if ( myIsPreviewMode ) // copy faces to the tmp mesh
|
||||||
|
{
|
||||||
|
TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge );
|
||||||
|
SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face );
|
||||||
|
while ( faceIt->more() )
|
||||||
|
tmpMesh->Copy( faceIt->next() );
|
||||||
|
}
|
||||||
|
else if ( theGroupName[0] ) // find/create a group of segments
|
||||||
|
{
|
||||||
|
SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups();
|
||||||
|
while ( !groupDS && grpIt->more() )
|
||||||
|
{
|
||||||
|
SMESH_Group* group = grpIt->next();
|
||||||
|
if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge &&
|
||||||
|
strcmp( group->GetName(), theGroupName ) == 0 )
|
||||||
|
{
|
||||||
|
groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !groupDS )
|
||||||
|
{
|
||||||
|
SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName );
|
||||||
|
|
||||||
|
if ( SMESH_Group_i* groupImpl = SMESH::DownCast<SMESH_Group_i*>( groupVar ))
|
||||||
|
groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert input polySegments
|
||||||
|
::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() );
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segIn = theSegments[ i ];
|
||||||
|
::SMESH_MeshEditor::PolySegment& segOut = segments[ i ];
|
||||||
|
segOut.myNode1[0] = getMeshDS()->FindNode( segIn.node1ID1 );
|
||||||
|
segOut.myNode2[0] = getMeshDS()->FindNode( segIn.node1ID2 );
|
||||||
|
segOut.myNode1[1] = getMeshDS()->FindNode( segIn.node2ID1 );
|
||||||
|
segOut.myNode2[1] = getMeshDS()->FindNode( segIn.node2ID2 );
|
||||||
|
segOut.myVector.SetCoord( segIn.vector.PS.x,
|
||||||
|
segIn.vector.PS.y,
|
||||||
|
segIn.vector.PS.z );
|
||||||
|
if ( !segOut.myNode1[0] )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1,
|
||||||
|
SALOME::BAD_PARAM );
|
||||||
|
if ( !segOut.myNode1[1] )
|
||||||
|
THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1,
|
||||||
|
SALOME::BAD_PARAM );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a static ElementSearcher
|
||||||
|
SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() );
|
||||||
|
theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE ));
|
||||||
|
if ( !theElementSearcher )
|
||||||
|
theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
|
||||||
|
|
||||||
|
// compute
|
||||||
|
getEditor().MakePolyLine( segments, groupDS, theElementSearcher );
|
||||||
|
|
||||||
|
// return vectors
|
||||||
|
if ( myIsPreviewMode )
|
||||||
|
{
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segOut = theSegments[ i ];
|
||||||
|
::SMESH_MeshEditor::PolySegment& segIn = segments[ i ];
|
||||||
|
segOut.vector.PS.x = segIn.myVector.X();
|
||||||
|
segOut.vector.PS.y = segIn.myVector.Y();
|
||||||
|
segOut.vector.PS.z = segIn.myVector.Z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TPythonDump() << "_segments = []";
|
||||||
|
for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
|
||||||
|
{
|
||||||
|
SMESH::PolySegment& segIn = theSegments[ i ];
|
||||||
|
TPythonDump() << "_segments.append( SMESH.PolySegment( "
|
||||||
|
<< segIn.node1ID1 << ", "
|
||||||
|
<< segIn.node1ID2 << ", "
|
||||||
|
<< segIn.node2ID1 << ", "
|
||||||
|
<< segIn.node2ID2 << ", "
|
||||||
|
<< "smeshBuilder.MakeDirStruct( "
|
||||||
|
<< segIn.vector.PS.x << ", "
|
||||||
|
<< segIn.vector.PS.y << ", "
|
||||||
|
<< segIn.vector.PS.z << ")))";
|
||||||
|
}
|
||||||
|
TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')";
|
||||||
|
}
|
||||||
|
|
||||||
|
SMESH_CATCH( SMESH::throwCorbaException );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@ -83,7 +83,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void ClearLastCreated() throw (SALOME::SALOME_Exception);
|
void ClearLastCreated() throw (SALOME::SALOME_Exception);
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns description of an error/warning occured during the last operation
|
* \brief Returns description of an error/warning occurred during the last operation
|
||||||
*/
|
*/
|
||||||
SMESH::ComputeError* GetLastError() throw (SALOME::SALOME_Exception);
|
SMESH::ComputeError* GetLastError() throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
@ -495,7 +495,8 @@ public:
|
|||||||
CORBA::Boolean SeparateCornersAndMedium)
|
CORBA::Boolean SeparateCornersAndMedium)
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
|
void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
|
||||||
const SMESH::ListOfIDSources& NodesToKeep )
|
const SMESH::ListOfIDSources& NodesToKeep,
|
||||||
|
CORBA::Boolean AvoidMakingHoles )
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
void FindEqualElements(SMESH::SMESH_IDSource_ptr Object,
|
void FindEqualElements(SMESH::SMESH_IDSource_ptr Object,
|
||||||
SMESH::array_of_long_array_out GroupsOfElementsID)
|
SMESH::array_of_long_array_out GroupsOfElementsID)
|
||||||
@ -843,6 +844,27 @@ public:
|
|||||||
SMESH::SMESH_Group_out group)
|
SMESH::SMESH_Group_out group)
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
|
||||||
|
* the initial mesh. Positions of new nodes are found by cutting the mesh by the
|
||||||
|
* plane passing through pairs of points specified by each PolySegment structure.
|
||||||
|
* If there are several paths connecting a pair of points, the shortest path is
|
||||||
|
* selected by the module. Position of the cutting plane is defined by the two
|
||||||
|
* points and an optional vector lying on the plane specified by a PolySegment.
|
||||||
|
* By default the vector is defined by Mesh module as following. A middle point
|
||||||
|
* of the two given points is computed. The middle point is projected to the mesh.
|
||||||
|
* The vector goes from the middle point to the projection point. In case of planar
|
||||||
|
* mesh, the vector is normal to the mesh.
|
||||||
|
* \param [inout] segments - PolySegment's defining positions of cutting planes.
|
||||||
|
* Return the used vector and position of the middle point.
|
||||||
|
* \param [in] groupName - optional name of a group where created mesh segments will
|
||||||
|
* be added.
|
||||||
|
*/
|
||||||
|
void MakePolyLine(SMESH::ListOfPolySegments& segments,
|
||||||
|
const char* groupName)
|
||||||
|
throw (SALOME::SALOME_Exception);
|
||||||
|
|
||||||
|
|
||||||
private: //!< private methods
|
private: //!< private methods
|
||||||
|
|
||||||
::SMESH_MeshEditor& getEditor();
|
::SMESH_MeshEditor& getEditor();
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user