]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMDS/SMDS_MeshElement.cxx
Salome HOME
Revert "23418: [OCC] Mesh: Minimization of memory usage of SMESH"
[modules/smesh.git] / src / SMDS / SMDS_MeshElement.cxx
index 48221c7c6861dda72d67072bf44434508399b404..31119a8eda8abc03dfd6cb094b9c797cf14bb73c 100644 (file)
 #endif
 
 #include "SMDS_MeshElement.hxx"
-
-#include "SMDS_Mesh.hxx"
-#include "SMDS_ElementFactory.hxx"
-
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshEdge.hxx"
+#include "SMDS_MeshFace.hxx"
+#include "SMDS_MeshVolume.hxx"
 #include "utilities.h"
 
-//================================================================================
-/*!
- * \brief Constructor of a non-used element
- */
-//================================================================================
+using namespace std;
 
-SMDS_MeshElement::SMDS_MeshElement(): myHolder(0)
+SMDS_MeshElement::SMDS_MeshElement(int ID)
 {
+  init(ID);
 }
 
-//================================================================================
-/*!
- * \brief Check if a node is a medium node of a quadratic cell
- */
-//================================================================================
-
-bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
+SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, LongType shapeId)
 {
-  return !( GetNodeIndex( node ) < NbCornerNodes() );
+  init(id, meshId, shapeId);
 }
 
-//================================================================================
-/*!
- * \brief Return true if index of node is valid (0 <= ind < NbNodes())
- *  \param ind - node index
- *  \retval bool - index check result
- */
-//================================================================================
-
-bool SMDS_MeshElement::IsValidIndex(const int ind) const
+void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId )
 {
-  return ( ind>-1 && ind<NbNodes() );
+  myID = id;
+  myMeshId = meshId;
+  myShapeId = shapeId;
+  myIdInShape = -1;
 }
 
-//================================================================================
-/*!
- * \brief Return a valid corner node index, fixing the given one if necessary
- * \param ind - node index
- * \retval int - valid node index
- */
-//================================================================================
-
-int SMDS_MeshElement::WrappedIndex(const int ind) const
+void SMDS_MeshElement::Print(ostream & OS) const
 {
-  if ( ind < 0 ) return NbCornerNodes() + ind % NbCornerNodes();
-  if ( ind >= NbCornerNodes() ) return ind % NbCornerNodes();
-  return ind;
+  OS << "dump of mesh element" << endl;
 }
 
-//================================================================================
-/*!
- * \brief Check if a node belongs to the element
- * \param node - the node to check
- * \retval int - node index within the element, -1 if not found
- */
-//================================================================================
+ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME)
+{
+  ME->Print(OS);
+  return OS;
+}
 
-int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const
+///////////////////////////////////////////////////////////////////////////////
+/// Create an iterator which iterate on nodes owned by the element.
+/// This method call elementsIterator().
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
 {
-  SMDS_ElemIteratorPtr nIt = nodesIterator();
-  for ( int i = 0; nIt->more(); ++i )
-    if ( nIt->next() == node )
-      return i;
-  return -1;
+  return elementsIterator(SMDSAbs_Node);
 }
 
-//================================================================================
-/*!
- * \brief Return ID of an element
- */
-//================================================================================
+///////////////////////////////////////////////////////////////////////////////
+/// Create an iterator which iterate on edges linked with or owned by the element.
+/// This method call elementsIterator().
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
+{
+  return elementsIterator(SMDSAbs_Edge);
+}
 
-int SMDS_MeshElement::GetID() const
+///////////////////////////////////////////////////////////////////////////////
+/// Create an iterator which iterate on faces linked with or owned by the element.
+/// This method call elementsIterator().
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
 {
-  return myHolder ? myHolder->GetID( this ) : -1;
+  return elementsIterator(SMDSAbs_Face);
 }
 
-//================================================================================
-/*!
- * \brief Set ID of a shape this element was generated on
- */
-//================================================================================
+///////////////////////////////////////////////////////////////////////////////
+///Return The number of nodes owned by the current element
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_MeshElement::NbNodes() const
+{
+  int nbnodes=0;
+  SMDS_ElemIteratorPtr it=nodesIterator();
+  while(it->more())
+  {
+    it->next();
+    nbnodes++;
+  }
+  return nbnodes;
+}
 
-void SMDS_MeshElement::setShapeID( const int shapeID ) const
+///////////////////////////////////////////////////////////////////////////////
+///Return the number of edges owned by or linked with the current element
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_MeshElement::NbEdges() const
 {
-  const_cast<SMDS_ElementChunk*>( myHolder )->SetShapeID( this, shapeID );
+  int nbedges=0;
+  SMDS_ElemIteratorPtr it=edgesIterator();
+  while(it->more())
+  {
+    it->next();
+    nbedges++;
+  }
+  return nbedges;
 }
 
-//================================================================================
-/*!
- * \brief Return ID of a shape this element was generated on
- */
-//================================================================================
+///////////////////////////////////////////////////////////////////////////////
+///Return the number of faces owned by or linked with the current element
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_MeshElement::NbFaces() const
+{
+  int nbfaces=0;
+  SMDS_ElemIteratorPtr it=facesIterator();
+  while(it->more())
+  {
+    it->next();
+    nbfaces++;
+  }
+  return nbfaces;
+}
 
-int SMDS_MeshElement::GetShapeID() const
+///////////////////////////////////////////////////////////////////////////////
+///Create an iterator which iterate on elements linked with the current element.
+///@param type The of elements on which you want to iterate
+///@return A smart pointer to iterator, you are not to take care of freeing memory
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
+{
+  const SMDS_MeshElement * myElement;
+  bool myMore;
+public:
+  SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element):
+    myElement(element),myMore(true) {}
+
+  bool more()
+  {
+    return myMore;
+  }
+
+  const SMDS_MeshElement* next()
+  {
+    myMore=false;
+    return myElement;   
+  }     
+};
+
+SMDS_ElemIteratorPtr
+SMDS_MeshElement::elementsIterator(SMDSAbs_ElementType type) const
 {
-  return myHolder->GetShapeID( this );
+  /** @todo Check that iterator in the child classes return elements
+      in the same order for each different implementation (i.e: SMDS_VolumeOfNodes
+      and SMDS_VolumeOfFaces */
+  if(type==GetType())
+    return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this));
+  else
+  {
+    MESSAGE("Iterator not implemented");
+    return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
+  }
 }
 
-//================================================================================
-/*!
- * \brief Return VTK ID of this element
- */
-//================================================================================
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_NodeIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const
+{
+  return nodeIterator();
+}
 
-int SMDS_MeshElement::GetVtkID() const
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_NodeIteratorPtr SMDS_MeshElement::interlacedNodesIterator() const
 {
-  return myHolder->GetVtkID( this );
+  return nodeIterator();
 }
 
-//================================================================================
-/*!
- * \brief Mark this element
- */
-//================================================================================
+namespace
+{
+  //=======================================================================
+  //class : _MyNodeIteratorFromElemIterator
+  //=======================================================================
+  class _MyNodeIteratorFromElemIterator : public SMDS_NodeIterator
+  {
+    SMDS_ElemIteratorPtr myItr;
+  public:
+    _MyNodeIteratorFromElemIterator(SMDS_ElemIteratorPtr elemItr):myItr( elemItr ) {}
+    bool                 more() { return myItr->more(); }
+    const SMDS_MeshNode* next() { return static_cast< const SMDS_MeshNode*>( myItr->next() ); }
+  };
+  //=======================================================================
+  //class : _MyElemIteratorFromNodeIterator
+  //=======================================================================
+  class _MyElemIteratorFromNodeIterator : public SMDS_ElemIterator
+  {
+    SMDS_NodeIteratorPtr myItr;
+  public:
+    _MyElemIteratorFromNodeIterator(SMDS_NodeIteratorPtr nodeItr): myItr( nodeItr ) {}
+    bool more()                    { return myItr->more(); }
+    const SMDS_MeshElement* next() { return myItr->next(); }
+  };
+}
 
-void SMDS_MeshElement::setIsMarked( bool is ) const
+SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const
 {
-  const_cast<SMDS_ElementChunk*>( myHolder )->SetIsMarked( this, is );
+  return SMDS_ElemIteratorPtr
+    ( new _MyElemIteratorFromNodeIterator( interlacedNodesIterator() ));
 }
 
-//================================================================================
-/*!
- * \brief Check if this element is marked
- */
-//================================================================================
+SMDS_NodeIteratorPtr SMDS_MeshElement::nodeIterator() const
+{
+  return SMDS_NodeIteratorPtr
+    ( new _MyNodeIteratorFromElemIterator( nodesIterator() ));
+}
 
-bool SMDS_MeshElement::isMarked() const
+bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
 {
-  return myHolder->IsMarked( this );
+  if(e1.GetType()!=e2.GetType()) return false;
+  switch(e1.GetType())
+  {
+  case SMDSAbs_Node:
+    return static_cast<const SMDS_MeshNode &>(e1) <
+    static_cast<const SMDS_MeshNode &>(e2);
+
+  case SMDSAbs_Edge:
+    return static_cast<const SMDS_MeshEdge &>(e1) <
+    static_cast<const SMDS_MeshEdge &>(e2);
+
+  case SMDSAbs_Face:
+    return static_cast<const SMDS_MeshFace &>(e1) <
+    static_cast<const SMDS_MeshFace &>(e2);
+
+  case SMDSAbs_Volume:
+    return static_cast<const SMDS_MeshVolume &>(e1) <
+    static_cast<const SMDS_MeshVolume &>(e2);
+
+  default : MESSAGE("Internal Error");
+  }
+  return false;
 }
 
-//================================================================================
-/*!
- * \brief Store VTK ID
- */
-//================================================================================
+bool SMDS_MeshElement::IsValidIndex(const int ind) const
+{
+  return ( ind>-1 && ind<NbNodes() );
+}
 
-void SMDS_MeshElement::setVtkID( const int vtkID )
+const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const
 {
-  myHolder->SetVTKID( this, vtkID );
+  if ( ind >= 0 ) {
+    SMDS_ElemIteratorPtr it = nodesIterator();
+    for ( int i = 0; i < ind; ++i )
+      it->next();
+    if ( it->more() )
+      return static_cast<const SMDS_MeshNode*> (it->next());
+  }
+  return 0;
 }
 
-//================================================================================
-/*!
- * \brief Return the mesh this element belongs to
- */
-//================================================================================
+bool SMDS_MeshElement::IsQuadratic() const
+{
+  return false;
+}
 
-SMDS_Mesh* SMDS_MeshElement::GetMesh() const
+bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
 {
-  return const_cast<SMDS_ElementChunk*>( myHolder )->GetMesh();
+  return false;
 }
 
 //================================================================================
 /*!
- * \brief Return a SMDS_UnstructuredGrid
+ * \brief Return number of nodes excluding medium ones
  */
 //================================================================================
 
-SMDS_UnstructuredGrid* SMDS_MeshElement::getGrid() const
+int SMDS_MeshElement::NbCornerNodes() const
 {
-  return const_cast<SMDS_ElementChunk*>( myHolder )->GetMesh()->GetGrid();
+  return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes();
 }
 
 //================================================================================
 /*!
- * \brief Print self
+ * \brief Check if a node belongs to the element
+ * \param node - the node to check
+ * \retval int - node index within the element, -1 if not found
  */
 //================================================================================
 
-void SMDS_MeshElement::Print(ostream & OS) const
-{
-  OS << "dump of mesh element" << endl;
-}
-
-ostream & operator <<(ostream & OS, const SMDS_MeshElement * e)
+int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const
 {
-  e->Print(OS);
-  return OS;
+  SMDS_ElemIteratorPtr nIt = nodesIterator();
+  for ( int i = 0; nIt->more(); ++i )
+    if ( nIt->next() == node )
+      return i;
+  return -1;
 }