Make TNodeXYZ public, which together with SMDS_StdIterator allows getting coordinates of all nodes of mesh element in a couple of lines of code:

typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
  vector<gp_Pnt> coords( TXyzIterator( elem->nodesIterator()), TXyzIterator() );



class SMESH_EXPORT SMESH_MeshEditor
{
public:
+  //------------------------------------------
+  /*!
+   * \brief SMDS_MeshNode -> gp_XYZ convertor
+   */
+  //------------------------------------------
+  struct TNodeXYZ : public gp_XYZ
This commit is contained in:
eap 2010-02-09 11:13:23 +00:00
parent c8050ec0d5
commit 2536cb0c1b
2 changed files with 133 additions and 190 deletions

View File

@ -89,28 +89,6 @@ using namespace SMESH::Controls;
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> > TElemOfNodeListMap;
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
//typedef map<const SMDS_MeshNode*, vector<const SMDS_MeshNode*> > TNodeOfNodeVecMap;
//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr;
//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> > TElemOfVecOfMapNodesMap;
//=======================================================================
/*!
* \brief SMDS_MeshNode -> gp_XYZ convertor
*/
//=======================================================================
struct TNodeXYZ : public gp_XYZ
{
TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
double Distance( const SMDS_MeshNode* n )
{
return gp_Vec( *this, TNodeXYZ( n )).Magnitude();
}
double SquareDistance( const SMDS_MeshNode* n )
{
return gp_Vec( *this, TNodeXYZ( n )).SquareMagnitude();
}
};
//=======================================================================
//function : SMESH_MeshEditor
@ -5224,7 +5202,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
const SMDS_MeshNode* closestNode = 0;
list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
for ( ; nIt != nodes.end(); ++nIt ) {
double sqDist = thePnt.SquareDistance( TNodeXYZ( *nIt ) );
double sqDist = thePnt.SquareDistance( SMESH_MeshEditor::TNodeXYZ( *nIt ) );
if ( minSqDist > sqDist ) {
closestNode = *nIt;
minSqDist = sqDist;
@ -5418,7 +5396,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
_refCount = 1;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() )
Add( TNodeXYZ( cast2Node( nIt->next() )));
Add( SMESH_MeshEditor::TNodeXYZ( cast2Node( nIt->next() )));
Enlarge( NodeRadius );
}
@ -5445,13 +5423,14 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
}
/*!
* \brief Return elements of given type where the given point is IN or ON.
* \brief Find elements of given type where the given point is IN or ON.
* Returns nb of found elements and elements them-selves.
*
* 'ALL' type means elements of any type excluding nodes and 0D elements
*/
void FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElements)
int FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElements)
{
foundElements.clear();
@ -5478,7 +5457,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
while ( complexType > SMDSAbs_All &&
meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 )
--complexType;
if ( complexType == SMDSAbs_All ) return; // empty mesh
if ( complexType == SMDSAbs_All ) return foundElements.size(); // empty mesh
double elemSize;
if ( complexType == int( SMDSAbs_Node ))
@ -5486,14 +5465,14 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
SMDS_NodeIteratorPtr nodeIt = _mesh->nodesIterator();
elemSize = 1;
if ( meshInfo.NbNodes() > 2 )
elemSize = TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() );
elemSize = SMESH_MeshEditor::TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() );
}
else
{
const SMDS_MeshElement* elem =
_mesh->elementsIterator( SMDSAbs_ElementType( complexType ))->next();
SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
TNodeXYZ n1( cast2Node( nodeIt->next() ));
SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() ));
while ( nodeIt->more() )
{
double dist = n1.Distance( cast2Node( nodeIt->next() ));
@ -5510,10 +5489,10 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
_nodeSearcher = new SMESH_NodeSearcherImpl( _mesh );
const SMDS_MeshNode* closeNode = _nodeSearcher->FindClosestTo( point );
if ( !closeNode ) return;
if ( !closeNode ) return foundElements.size();
if ( point.Distance( TNodeXYZ( closeNode )) > tolerance )
return; // to far from any node
if ( point.Distance( SMESH_MeshEditor::TNodeXYZ( closeNode )) > tolerance )
return foundElements.size(); // to far from any node
if ( type == SMDSAbs_Node )
{
@ -5541,6 +5520,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
if ( !SMESH_MeshEditor::isOut( *elem, point, tolerance ))
foundElements.push_back( *elem );
}
return foundElements.size();
}
}; // struct SMESH_ElementSearcherImpl
@ -6498,83 +6478,65 @@ void SMESH_MeshEditor::MergeEqualElements()
//purpose : Return a face having linked nodes n1 and n2 and which is
// - not in avoidSet,
// - in elemSet provided that !elemSet.empty()
// i1 and i2 optionally returns indices of n1 and n2
//=======================================================================
const SMDS_MeshElement*
SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const TIDSortedElemSet& elemSet,
const TIDSortedElemSet& avoidSet)
const TIDSortedElemSet& avoidSet,
int* n1ind,
int* n2ind)
{
int i1, i2;
const SMDS_MeshElement* face = 0;
SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
while ( invElemIt->more() ) { // loop on inverse elements of n1
while ( invElemIt->more() && !face ) // loop on inverse faces of n1
{
const SMDS_MeshElement* elem = invElemIt->next();
if (avoidSet.find( elem ) != avoidSet.end() )
if (avoidSet.count( elem ))
continue;
if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
if ( !elemSet.empty() && !elemSet.count( elem ))
continue;
// get face nodes and find index of n1
int i1, nbN = elem->NbNodes(), iNode = 0;
//const SMDS_MeshNode* faceNodes[ nbN ], *n;
vector<const SMDS_MeshNode*> faceNodes( nbN );
const SMDS_MeshNode* n;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() ) {
faceNodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
if ( faceNodes[ iNode++ ] == n1 )
i1 = iNode - 1;
}
// index of n1
i1 = elem->GetNodeIndex( n1 );
// find a n2 linked to n1
if(!elem->IsQuadratic()) {
for ( iNode = 0; iNode < 2; iNode++ ) {
if ( iNode ) // node before n1
n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
else // node after n1
n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
if ( n == n2 )
return elem;
int nbN = elem->IsQuadratic() ? elem->NbNodes()/2 : elem->NbNodes();
for ( int di = -1; di < 2 && !face; di += 2 )
{
i2 = (i1+di+nbN) % nbN;
if ( elem->GetNode( i2 ) == n2 )
face = elem;
}
if ( !face && elem->IsQuadratic())
{
// analysis for quadratic elements using all nodes
const SMDS_QuadraticFaceOfNodes* F =
static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
// use special nodes iterator
SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
const SMDS_MeshNode* prevN = cast2Node( anIter->next() );
for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
{
const SMDS_MeshNode* n = cast2Node( anIter->next() );
if ( n1 == prevN && n2 == n )
{
face = elem;
}
else if ( n2 == prevN && n1 == n )
{
face = elem; swap( i1, i2 );
}
prevN = n;
}
}
else { // analysis for quadratic elements
bool IsFind = false;
// check using only corner nodes
for ( iNode = 0; iNode < 2; iNode++ ) {
if ( iNode ) // node before n1
n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ];
else // node after n1
n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ];
if ( n == n2 )
IsFind = true;
}
if(IsFind) {
return elem;
}
else {
// check using all nodes
const SMDS_QuadraticFaceOfNodes* F =
static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
// use special nodes iterator
iNode = 0;
SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
while ( anIter->more() ) {
faceNodes[iNode] = static_cast<const SMDS_MeshNode*>(anIter->next());
if ( faceNodes[ iNode++ ] == n1 )
i1 = iNode - 1;
}
for ( iNode = 0; iNode < 2; iNode++ ) {
if ( iNode ) // node before n1
n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
else // node after n1
n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
if ( n == n2 ) {
return elem;
}
}
}
} // end analysis for quadratic elements
}
return 0;
if ( n1ind ) *n1ind = i1;
if ( n2ind ) *n2ind = i2;
return face;
}
//=======================================================================
@ -8913,7 +8875,7 @@ namespace {
gp_XYZ centerXYZ (0, 0, 0);
SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator();
while (aNodeItr->more())
centerXYZ += TNodeXYZ(cast2Node( aNodeItr->next()));
centerXYZ += SMESH_MeshEditor::TNodeXYZ(cast2Node( aNodeItr->next()));
gp_Pnt aPnt = centerXYZ / theElem->NbNodes();
theClassifier.Perform(aPnt, theTol);

View File

@ -36,6 +36,8 @@
#include "SMESH_SequenceOfElemPtr.hxx"
#include "SMESH_SequenceOfNode.hxx"
#include <utilities.h>
#include <TColStd_HSequenceOfReal.hxx>
#include <gp_Dir.hxx>
@ -74,7 +76,8 @@ struct SMESH_NodeSearcher
//=======================================================================
/*!
* \brief Return elements of given type where the given point is IN or ON.
* \brief Find elements of given type where the given point is IN or ON.
* Returns nb of found elements and elements them-selves.
*
* 'ALL' type means elements of any type excluding nodes and 0D elements
*/
@ -82,9 +85,9 @@ struct SMESH_NodeSearcher
struct SMESH_ElementSearcher
{
virtual void FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems)=0;
virtual int FindElementsByPoint(const gp_Pnt& point,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems)=0;
};
//=======================================================================
@ -103,51 +106,6 @@ struct SMESH_TLink: public NLink
const SMDS_MeshNode* node2() const { return second; }
};
//=======================================================================
/*!
* auxiliary class
*/
//=======================================================================
class SMESH_MeshEditor_PathPoint {
public:
SMESH_MeshEditor_PathPoint() {
myPnt.SetCoord(99., 99., 99.);
myTgt.SetCoord(1.,0.,0.);
myAngle=0.;
myPrm=0.;
}
void SetPnt(const gp_Pnt& aP3D){
myPnt=aP3D;
}
void SetTangent(const gp_Dir& aTgt){
myTgt=aTgt;
}
void SetAngle(const double& aBeta){
myAngle=aBeta;
}
void SetParameter(const double& aPrm){
myPrm=aPrm;
}
const gp_Pnt& Pnt()const{
return myPnt;
}
const gp_Dir& Tangent()const{
return myTgt;
}
double Angle()const{
return myAngle;
}
double Parameter()const{
return myPrm;
}
protected:
gp_Pnt myPnt;
gp_Dir myTgt;
double myAngle;
double myPrm;
};
// ============================================================
/*!
@ -155,7 +113,28 @@ protected:
*/
// ============================================================
class SMESH_EXPORT SMESH_MeshEditor {
class SMESH_EXPORT SMESH_MeshEditor
{
public:
//------------------------------------------
/*!
* \brief SMDS_MeshNode -> gp_XYZ convertor
*/
//------------------------------------------
struct TNodeXYZ : public gp_XYZ
{
const SMDS_MeshNode* _node;
TNodeXYZ( const SMDS_MeshElement* e):_node(0) {
if (e) {
ASSERT( e->GetType() == SMDSAbs_Node );
_node = static_cast<const SMDS_MeshNode*>(e);
SetCoord( _node->X(), _node->Y(), _node->Z() );
}
}
double Distance(const SMDS_MeshNode* n) const { return (TNodeXYZ( n )-*this).Modulus(); }
double SquareDistance(const SMDS_MeshNode* n) const { return (TNodeXYZ( n )-*this).SquareModulus(); }
bool operator==(const TNodeXYZ& other) const { return _node == other._node; }
};
public:
@ -520,18 +499,6 @@ public:
//converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing
//them with ordinary mesh elements with the same id.
// static int SortQuadNodes (const SMDS_Mesh * theMesh,
// int theNodeIds[] );
// // Set 4 nodes of a quadrangle face in a good order.
// // Swap 1<->2 or 2<->3 nodes and correspondingly return
// // 1 or 2 else 0.
//
// static bool SortHexaNodes (const SMDS_Mesh * theMesh,
// int theNodeIds[] );
// // Set 8 nodes of a hexahedron in a good order.
// // Return success status
static void AddToSameGroups (const SMDS_MeshElement* elemToAdd,
const SMDS_MeshElement* elemInGroups,
SMESHDS_Mesh * aMesh);
@ -553,14 +520,16 @@ public:
TIDSortedElemSet & linkedNodes,
SMDSAbs_ElementType type = SMDSAbs_All );
static const SMDS_MeshElement*
FindFaceInSet(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const TIDSortedElemSet& elemSet,
const TIDSortedElemSet& avoidSet);
static const SMDS_MeshElement* FindFaceInSet(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const TIDSortedElemSet& elemSet,
const TIDSortedElemSet& avoidSet,
int* i1=0,
int* i2=0);
// Return a face having linked nodes n1 and n2 and which is
// - not in avoidSet,
// - in elemSet provided that !elemSet.empty()
// i1 and i2 optionally returns indices of n1 and n2
/*!
* \brief Find corresponding nodes in two sets of faces
@ -575,11 +544,11 @@ public:
*/
static Sew_Error FindMatchingNodes(std::set<const SMDS_MeshElement*>& theSide1,
std::set<const SMDS_MeshElement*>& theSide2,
const SMDS_MeshNode* theFirstNode1,
const SMDS_MeshNode* theFirstNode2,
const SMDS_MeshNode* theSecondNode1,
const SMDS_MeshNode* theSecondNode2,
TNodeNodeMap & nReplaceMap);
const SMDS_MeshNode* theFirstNode1,
const SMDS_MeshNode* theFirstNode2,
const SMDS_MeshNode* theSecondNode1,
const SMDS_MeshNode* theSecondNode2,
TNodeNodeMap & theNodeReplaceMap);
/*!
* \brief Returns true if given node is medium
@ -684,30 +653,42 @@ private:
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements);
/*!
* auxilary for ExtrusionAlongTrack
*/
Extrusion_Error MakeEdgePathPoints(std::list<double>& aPrms,
const TopoDS_Edge& aTrackEdge,
bool FirstIsStart,
list<SMESH_MeshEditor_PathPoint>& LPP);
Extrusion_Error MakeExtrElements(TIDSortedElemSet& theElements,
list<SMESH_MeshEditor_PathPoint>& fullList,
const bool theHasAngles,
list<double>& theAngles,
const bool theLinearVariation,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint,
const bool theMakeGroups);
void LinearAngleVariation(const int NbSteps,
struct SMESH_MeshEditor_PathPoint
{
gp_Pnt myPnt;
gp_Dir myTgt;
double myAngle, myPrm;
SMESH_MeshEditor_PathPoint(): myPnt(99., 99., 99.), myTgt(1.,0.,0.), myAngle(0), myPrm(0) {}
void SetPnt (const gp_Pnt& aP3D) { myPnt =aP3D; }
void SetTangent (const gp_Dir& aTgt) { myTgt =aTgt; }
void SetAngle (const double& aBeta) { myAngle=aBeta; }
void SetParameter(const double& aPrm) { myPrm =aPrm; }
const gp_Pnt& Pnt ()const { return myPnt; }
const gp_Dir& Tangent ()const { return myTgt; }
double Angle ()const { return myAngle; }
double Parameter ()const { return myPrm; }
};
Extrusion_Error MakeEdgePathPoints(std::list<double>& aPrms,
const TopoDS_Edge& aTrackEdge,
bool aFirstIsStart,
std::list<SMESH_MeshEditor_PathPoint>& aLPP);
Extrusion_Error MakeExtrElements(TIDSortedElemSet& theElements,
std::list<SMESH_MeshEditor_PathPoint>& theFullList,
const bool theHasAngles,
std::list<double>& theAngles,
const bool theLinearVariation,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint,
const bool theMakeGroups);
void LinearAngleVariation(const int NbSteps,
list<double>& theAngles);
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems,
const TIDSortedElemSet& theNodesNot,
std::map< const SMDS_MeshNode*,
const SMDS_MeshNode* >& theNodeNodeMap,
const bool theIsDoubleElem );
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems,
const TIDSortedElemSet& theNodesNot,
std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap,
const bool theIsDoubleElem );
private: