Salome HOME
PAL17091 ("Mesh Infos" dlg shows wrong number of quadrangles of the computed mesh)
authoreap <eap@opencascade.com>
Tue, 2 Oct 2007 12:45:45 +0000 (12:45 +0000)
committereap <eap@opencascade.com>
Tue, 2 Oct 2007 12:45:45 +0000 (12:45 +0000)
    take into account element type change at merging nodes

src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_MeshInfo.hxx

index 1416ba66c75df9935e2556c45f959ffb94cba0f5..44d4259b219dde3ba1266b1496f394ff18d4c8c2 100644 (file)
@@ -43,7 +43,6 @@ using namespace std;
 #include <sys/sysinfo.h>
 #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<const SMDS_MeshElement*> 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<SMDS_MeshElement*>(element);
   switch ( elem->GetType() )
   {
   case SMDSAbs_Edge: {
     if ( nbnodes == 2 ) {
-      const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
-      if ( edge )
-        Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
+      if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
+        Ok = edge->ChangeNodes( nodes[0], nodes[1] );
     }
     else if ( nbnodes == 3 ) {
-      const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
-      if ( edge )
-        Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+      if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
+        Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
     }
     break;
   }
   case SMDSAbs_Face: {
-    const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
-    if ( face ) {
-      Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
-    }
-    else {
-      const SMDS_QuadraticFaceOfNodes* QF =
-        dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
-      if ( QF ) {
-        Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
-      }
-      else {
-        /// ??? begin
-        const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
-        if (face) {
-          Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
-        }
-        /// ??? end
-      }
-    }
+    if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
+      Ok = face->ChangeNodes( nodes, nbnodes );
+    else
+      if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
+        Ok = QF->ChangeNodes( nodes, nbnodes );
+      else
+        if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
+          Ok = face->ChangeNodes(nodes, nbnodes);
     break;
   }
-  //case SMDSAbs_PolygonalFace: {
-  //  const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
-  //  if (face) {
-  //    Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
-  //  }
-  //  break;
-  //}
   case SMDSAbs_Volume: {
-    const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
-    if ( vol ) {
-      Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
-    }
-    else {
-      const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
-      if ( QV ) {
-        Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
-      }
-    }
+    if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
+      Ok = vol->ChangeNodes( nodes, nbnodes );
+    else 
+      if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( 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<const SMDS_MeshElement*>::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<SMDS_MeshNode*>( 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<const SMDS_MeshElement*>::iterator it;
     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
     {
       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
@@ -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<const SMDS_MeshNode*> nodes,
-                                       std::vector<int>                  quantities)
+bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
+                                       const vector<const SMDS_MeshNode*>& nodes,
+                                       const vector<int>                 & 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<const SMDS_MeshElement*>::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<SMDS_MeshNode*>(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<const SMDS_MeshElement*>::iterator it;
   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
       (const_cast<SMDS_MeshElement *>( *it ));
index f95cfc40f33ff10f6b9b393f35b9b45c7cb584fd..c4c0098c2bf8bce9c6953bb51638fe779335e479 100644 (file)
@@ -433,12 +433,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<const SMDS_MeshNode*> nodes,
-                                    std::vector<int>                  quantities);
+  bool ChangeElementNodes(const SMDS_MeshElement * elem,
+                          const SMDS_MeshNode    * nodes[],
+                          const int                nbnodes);
+  bool ChangePolyhedronNodes(const SMDS_MeshElement *                 elem,
+                             const std::vector<const SMDS_MeshNode*>& nodes,
+                             const std::vector<int> &                 quantities);
 
   virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
   // Renumber all nodes or elements.
index 134768673498a55c5d716efd28eca2717fb2a419..d980de9b35cf3ac2ae21f0f889792f9a36115e83 100644 (file)
@@ -6,9 +6,11 @@
 #ifndef SMDS_MeshInfo_HeaderFile
 #define SMDS_MeshInfo_HeaderFile
 
+#include "SMESH_SMDS.hxx"
+
 #include "SMDS_MeshElement.hxx"
 
-class SMDS_MeshInfo
+class SMDS_EXPORT SMDS_MeshInfo
 {
 public:
 
@@ -32,6 +34,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 +55,9 @@ private:
   int myNbPyramids, myNbQuadPyramids;
   int myNbPrisms  , myNbQuadPrisms  ;
   int myNbPolyhedrons;
-  
+
+  vector<int*> myNb; // pointers to myNb... fields
+  vector<int>  myShift; // shift to get an index in myNb by elem->NbNodes()
 };
 
 inline SMDS_MeshInfo::SMDS_MeshInfo():
@@ -62,7 +71,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 +185,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