From dbb7f1bf697baab6230a998f21467a1ecf49482b Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 2 Oct 2007 12:12:45 +0000 Subject: [PATCH] PAL17091 ("Mesh Infos" dlg shows wrong number of quadrangles of the computed mesh) take into account element type change at merging nodes --- src/SMDS/SMDS_Mesh.cxx | 97 ++++++++++++------------------ src/SMDS/SMDS_Mesh.hxx | 12 ++-- src/SMDS/SMDS_MeshInfo.hxx | 119 ++++++++++++++++++++++++++----------- 3 files changed, 130 insertions(+), 98 deletions(-) diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 1416ba66c..44d4259b2 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -43,7 +43,6 @@ using namespace std; #include #endif - //================================================================================ /*! * \brief Raise an exception if free memory (ram+swap) too low @@ -1177,73 +1176,52 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) //purpose : //======================================================================= -bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, const SMDS_MeshNode * nodes[], const int nbnodes) { // keep current nodes of elem set oldNodes; - SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + SMDS_ElemIteratorPtr itn = element->nodesIterator(); while(itn->more()) oldNodes.insert( itn->next() ); + if ( !element->IsPoly() ) + myInfo.remove( element ); // element may change type + // change nodes bool Ok = false; + SMDS_MeshElement* elem = const_cast(element); switch ( elem->GetType() ) { case SMDSAbs_Edge: { if ( nbnodes == 2 ) { - const SMDS_MeshEdge* edge = dynamic_cast( elem ); - if ( edge ) - Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); + if ( SMDS_MeshEdge* edge = dynamic_cast( elem )) + Ok = edge->ChangeNodes( nodes[0], nodes[1] ); } else if ( nbnodes == 3 ) { - const SMDS_QuadraticEdge* edge = dynamic_cast( elem ); - if ( edge ) - Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + if ( SMDS_QuadraticEdge* edge = dynamic_cast( elem )) + Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] ); } break; } case SMDSAbs_Face: { - const SMDS_FaceOfNodes* face = dynamic_cast( elem ); - if ( face ) { - Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); - } - else { - const SMDS_QuadraticFaceOfNodes* QF = - dynamic_cast( elem ); - if ( QF ) { - Ok = const_cast( QF )->ChangeNodes( nodes, nbnodes ); - } - else { - /// ??? begin - const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - if (face) { - Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); - } - /// ??? end - } - } + if ( SMDS_FaceOfNodes* face = dynamic_cast( elem )) + Ok = face->ChangeNodes( nodes, nbnodes ); + else + if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast( elem )) + Ok = QF->ChangeNodes( nodes, nbnodes ); + else + if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem)) + Ok = face->ChangeNodes(nodes, nbnodes); break; } - //case SMDSAbs_PolygonalFace: { - // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); - // if (face) { - // Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); - // } - // break; - //} case SMDSAbs_Volume: { - const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); - if ( vol ) { - Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); - } - else { - const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem ); - if ( QV ) { - Ok = const_cast( QV )->ChangeNodes( nodes, nbnodes ); - } - } + if ( SMDS_VolumeOfNodes* vol = dynamic_cast( elem )) + Ok = vol->ChangeNodes( nodes, nbnodes ); + else + if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem )) + Ok = QV->ChangeNodes( nodes, nbnodes ); break; } default: @@ -1252,18 +1230,19 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, if ( Ok ) { // update InverseElements + set::iterator it; + // AddInverseElement to new nodes - for ( int i = 0; i < nbnodes; i++ ) - if ( oldNodes.find( nodes[i] ) == oldNodes.end() ) + for ( int i = 0; i < nbnodes; i++ ) { + it = oldNodes.find( nodes[i] ); + if ( it == oldNodes.end() ) // new node const_cast( nodes[i] )->AddInverseElement( elem ); else // remove from oldNodes a node that remains in elem - oldNodes.erase( nodes[i] ); - - + oldNodes.erase( it ); + } // RemoveInverseElement from the nodes removed from elem - set::iterator it; for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) { SMDS_MeshNode * n = static_cast @@ -1272,7 +1251,8 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, } } - //MESSAGE ( "::ChangeNodes() Ok = " << Ok); + if ( !element->IsPoly() ) + myInfo.add( element ); // element may change type return Ok; } @@ -1281,9 +1261,9 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, //function : ChangePolyhedronNodes //purpose : to change nodes of polyhedral volume //======================================================================= -bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities) +bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + const vector& nodes, + const vector & quantities) { if (elem->GetType() != SMDSAbs_Volume) { MESSAGE("WRONG ELEM TYPE"); @@ -1312,18 +1292,19 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, // AddInverseElement to new nodes int nbnodes = nodes.size(); + set::iterator it; for (int i = 0; i < nbnodes; i++) { - if (oldNodes.find(nodes[i]) == oldNodes.end()) { + it = oldNodes.find(nodes[i]); + if (it == oldNodes.end()) { // new node const_cast(nodes[i])->AddInverseElement(elem); } else { // remove from oldNodes a node that remains in elem - oldNodes.erase(nodes[i]); + oldNodes.erase(it); } } // RemoveInverseElement from the nodes removed from elem - set::iterator it; for (it = oldNodes.begin(); it != oldNodes.end(); it++) { SMDS_MeshNode * n = static_cast (const_cast( *it )); diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index abecf8be4..fb8f67a03 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -442,12 +442,12 @@ public: virtual bool RemoveFromParent(); virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); - static bool ChangeElementNodes(const SMDS_MeshElement * elem, - const SMDS_MeshNode * nodes[], - const int nbnodes); - static bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities); + bool ChangeElementNodes(const SMDS_MeshElement * elem, + const SMDS_MeshNode * nodes[], + const int nbnodes); + bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, + const std::vector& nodes, + const std::vector & quantities); virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. diff --git a/src/SMDS/SMDS_MeshInfo.hxx b/src/SMDS/SMDS_MeshInfo.hxx index 134768673..38a1dea23 100644 --- a/src/SMDS/SMDS_MeshInfo.hxx +++ b/src/SMDS/SMDS_MeshInfo.hxx @@ -32,6 +32,11 @@ public: private: friend class SMDS_Mesh; + // methods to count NOT POLY elements + inline void remove(const SMDS_MeshElement* el); + inline void add (const SMDS_MeshElement* el); + inline int index(SMDSAbs_ElementType type, int nbNodes); + // methods to remove elements of ANY kind inline void RemoveEdge(const SMDS_MeshElement* el); inline void RemoveFace(const SMDS_MeshElement* el); inline void RemoveVolume(const SMDS_MeshElement* el); @@ -48,7 +53,9 @@ private: int myNbPyramids, myNbQuadPyramids; int myNbPrisms , myNbQuadPrisms ; int myNbPolyhedrons; - + + vector myNb; // pointers to myNb... fields + vector myShift; // shift to get an index in myNb by elem->NbNodes() }; inline SMDS_MeshInfo::SMDS_MeshInfo(): @@ -62,7 +69,83 @@ inline SMDS_MeshInfo::SMDS_MeshInfo(): myNbPyramids(0), myNbQuadPyramids(0), myNbPrisms (0), myNbQuadPrisms (0), myNbPolyhedrons(0) -{} +{ + // Number of nodes in standard element types + // n v f e + // o o a d + // d l c g + // e e e + // ----------- + // 1 + // 2 * + // 3 * + // 4 * * * + // 5 * + // 6 * * + // 7 + // 8 * * + // 9 + // 10 * + // 11 + // 12 + // 13 * + // 14 + // 15 * + // 16 + // 17 + // 18 + // 19 + // 20 * + // + // So to have a unique index for each type basing on nb of nodes, we use a shift: + myShift.resize(SMDSAbs_Volume + 1, 0); + myShift[ SMDSAbs_Face ] = +8; // 3->11, 4->12, 6->14, 8->16 + myShift[ SMDSAbs_Edge ] = -2; // 2->0, 4->2 + + myNb.resize( index( SMDSAbs_Volume,20 ) + 1, NULL); + myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes; + + myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges; + myNb[ index( SMDSAbs_Edge,4 )] = & myNbQuadEdges; + + myNb[ index( SMDSAbs_Face,3 )] = & myNbTriangles; + myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles; + myNb[ index( SMDSAbs_Face,6 )] = & myNbQuadTriangles; + myNb[ index( SMDSAbs_Face,8 )] = & myNbQuadQuadrangles; + + myNb[ index( SMDSAbs_Volume, 4)] = & myNbTetras; + myNb[ index( SMDSAbs_Volume, 5)] = & myNbPyramids; + myNb[ index( SMDSAbs_Volume, 6)] = & myNbPrisms; + myNb[ index( SMDSAbs_Volume, 8)] = & myNbHexas; + myNb[ index( SMDSAbs_Volume, 10)] = & myNbQuadTetras; + myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids; + myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms; + myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas; +} + +inline int // index +SMDS_MeshInfo::index(SMDSAbs_ElementType type, int nbNodes) +{ return nbNodes + myShift[ type ]; } + +inline void // remove +SMDS_MeshInfo::remove(const SMDS_MeshElement* el) +{ --(*myNb[ index(el->GetType(), el->NbNodes()) ]); } + +inline void // add +SMDS_MeshInfo::add(const SMDS_MeshElement* el) +{ ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); } + +inline void // RemoveEdge +SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el) +{ if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; } + +inline void // RemoveFace +SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) +{ if ( el->IsPoly() ) --myNbPolygons; else remove( el ); } + +inline void // RemoveVolume +SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el) +{ if ( el->IsPoly() ) --myNbPolyhedrons; else remove( el ); } inline int // NbEdges SMDS_MeshInfo::NbEdges (SMDSAbs_ElementOrder order) const @@ -100,36 +183,4 @@ inline int // NbPrisms SMDS_MeshInfo::NbPrisms (SMDSAbs_ElementOrder order) const { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; } -// RemoveEdge -inline void SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el) -{ - if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; -} - -// RemoveFace -inline void SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) -{ - int nbnode = el->NbNodes(); - if ( el->IsPoly() ) --myNbPolygons; - else if (nbnode == 3) --myNbTriangles; - else if (nbnode == 4) --myNbQuadrangles; - else if (nbnode == 6) --myNbQuadTriangles; - else if (nbnode == 8) --myNbQuadQuadrangles; -} - -// RemoveVolume -inline void SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el) -{ - int nbnode = el->NbNodes(); - if ( el->IsPoly() ) --myNbPolyhedrons; - else if (nbnode == 4) --myNbTetras; - else if (nbnode == 5) --myNbPyramids; - else if (nbnode == 6) --myNbPrisms; - else if (nbnode == 8) --myNbHexas; - else if (nbnode == 10) --myNbQuadTetras; - else if (nbnode == 13) --myNbQuadPyramids; - else if (nbnode == 15) --myNbQuadPrisms; - else if (nbnode == 20) --myNbQuadHexas; -} - #endif -- 2.30.2