Salome HOME
[bos #24169] [CEA 24168] Error in AffectedElemGroupsInRegion
[modules/smesh.git] / src / SMDS / SMDS_ElementFactory.hxx
index b25b635c8af09718731fc1d08cfece7a4f9d1c2c..dcc00a307c1b71d705e2c1a6895e7543f9603baf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -40,6 +40,8 @@
 
 #include <vtkType.h>
 
+#include <smIdType.hxx>
+
 class SMDS_ElementChunk;
 class SMDS_Mesh;
 class SMDS_MeshCell;
@@ -67,8 +69,8 @@ protected:
   TChunkVector             myChunks;           // array of chunks of elements
   TChunkPtrSet             myChunksWithUnused; // sorted chunks having unused elements
   std::vector< vtkIdType > myVtkIDs;           // myVtkIDs[ smdsID-1 ] == vtkID
-  std::vector< int >       mySmdsIDs;          // mySmdsIDs[ vtkID ] == smdsID - 1
-  int                      myNbUsedElements;   // counter of elements
+  std::vector< smIdType >  mySmdsIDs;          // mySmdsIDs[ vtkID ] == smdsID - 1
+  smIdType                 myNbUsedElements;   // counter of elements
 
   friend class SMDS_ElementChunk;
 
@@ -78,25 +80,25 @@ public:
   virtual ~SMDS_ElementFactory();
 
   //! Return minimal ID of a non-used element
-  int GetFreeID();
+  smIdType GetFreeID();
 
   //! Return maximal ID of an used element
-  int GetMaxID();
+  smIdType GetMaxID();
 
   //! Return minimal ID of an used element
-  int GetMinID();
+  smIdType GetMinID();
 
   //! Return an element by ID. NULL if the element with the given ID is already used
-  SMDS_MeshElement* NewElement( const int id );
+  SMDS_MeshElement* NewElement( const smIdType id );
 
   //! Return a SMDS_MeshCell by ID. NULL if the cell with the given ID is already used
-  SMDS_MeshCell* NewCell( const int id ) { return static_cast<SMDS_MeshCell*>( NewElement( id )); }
+  SMDS_MeshCell* NewCell( const smIdType id ) { return static_cast<SMDS_MeshCell*>( NewElement( id )); }
 
   //! Return an used element by ID. NULL if the element with the given ID is not yet used
-  const SMDS_MeshElement* FindElement( const int id ) const;
+  const SMDS_MeshElement* FindElement( const smIdType id ) const;
 
   //! Return a number of used elements
-  int NbUsedElements() const { return myNbUsedElements; }
+  smIdType NbUsedElements() const { return myNbUsedElements; }
 
   //! Return an iterator on all element filtered using a given filter.
   //  nbElemsToReturn is used to optimize by stopping the iteration as soon as
@@ -108,21 +110,25 @@ public:
   //! Return an iterator on all element assigned to a given shape.
   //  nbElemsToReturn is used to optimize by stopping the iteration as soon as
   //  all elements assigned to the shape encountered.
+  //  sm1stElem is used to quickly find the first chunk holding elements of the shape;
+  //  it must have smallest ID between elements on the shape
   template< class ElemIterator >
-  boost::shared_ptr< ElemIterator > GetShapeIterator( int shapeID, size_t nbElemsToReturn );
+  boost::shared_ptr< ElemIterator > GetShapeIterator( int                     shapeID,
+                                                      size_t                  nbElemsToReturn,
+                                                      const SMDS_MeshElement* sm1stElem );
 
   //! Mark the element as non-used
   void Free( const SMDS_MeshElement* );
 
   //! Return an SMDS ID by a Vtk one
-  int FromVtkToSmds( vtkIdType vtkID );
+  smIdType FromVtkToSmds( vtkIdType vtkID );
 
   //! De-allocate all elements
   virtual void Clear();
 
   //! Remove unused elements located not at the end of the last chunk.
   //  Minimize allocated memory
-  virtual void Compact(std::vector<int>& idCellsOldToNew);
+  virtual void Compact(std::vector<smIdType>& idCellsOldToNew);
 
   //! Return true if Compact() will change IDs of elements
   virtual bool CompactChangePointers();
@@ -145,10 +151,10 @@ public:
   ~SMDS_NodeFactory();
 
   //! Return a SMDS_MeshNode by ID. NULL if the node with the given ID is already used
-  SMDS_MeshNode* NewNode( int id ) { return (SMDS_MeshNode*) NewElement(id); }
+  SMDS_MeshNode* NewNode( smIdType id ) { return (SMDS_MeshNode*) NewElement(id); }
 
   //! Return an used node by ID. NULL if the node with the given ID is not yet used
-  const SMDS_MeshNode* FindNode( int id ) { return (const SMDS_MeshNode*) FindElement(id); }
+  const SMDS_MeshNode* FindNode( smIdType id ) { return (const SMDS_MeshNode*) FindElement(id); }
 
   //! Set a total number of sub-shapes in the main shape
   void SetNbShapes( size_t nbShapes );
@@ -164,7 +170,7 @@ public:
 
   //! Remove unused nodes located not at the end of the last chunk.
   //  Minimize allocated memory
-  virtual void Compact(std::vector<int>& idNodesOldToNew);
+  virtual void Compact(std::vector<smIdType>& idNodesOldToNew);
 
   //! Return true if Compact() will change IDs of node
   virtual bool CompactChangePointers();
@@ -227,13 +233,13 @@ struct _RangeSet
    * \brief Return ranges of indices (from,to) of elements having a given value
    */
   bool GetIndices( const attr_t theValue, TIndexRanges & theIndices,
-                   const attr_t* theMinValue = 0, const attr_t* theMaxValue = 0) const
+                   const attr_t* /*theMinValue*/ = 0, const attr_t* /*theMaxValue*/ = 0) const
   {
     bool isFound = false;
 
-    if ( sizeof( attr_t ) == sizeof( int ) && theMinValue )
-      if ( theValue < *theMinValue || theValue > *theMaxValue )
-        return isFound;
+    // if ( sizeof( attr_t ) == sizeof( int ) && theMinValue )
+    //   if ( theValue < *theMinValue || theValue > *theMaxValue )
+    //     return isFound;
 
     for ( set_iterator it = mySet.begin(); it < mySet.end(); ++it )
     {
@@ -266,9 +272,14 @@ struct _RangeSet
    */
   attr_t SetValue( int theIndex, attr_t theValue )
   {
-    set_iterator rNext = mySet.upper_bound( theIndex );
+    set_iterator rNext = mySet.end(); // case of adding elements
     set_iterator     r = rNext - 1;
-    int          rSize = Size( r ); // range size
+    if ( r->my1st > theIndex )
+    {
+      rNext = mySet.upper_bound( theIndex );
+      r     = rNext - 1;
+    }
+    int         rSize = Size( r ); // range size
     attr_t      rValue = r->myValue;
     if ( rValue == theValue )
       return rValue; // it happens while compacting
@@ -347,7 +358,9 @@ typedef _Range< bool > _UsedRange;    // range of used elements
 typedef _RangeSet< _ShapeIDRange > TSubIDRangeSet;
 typedef _RangeSet< _UsedRange >    TUsedRangeSet;
 typedef boost::dynamic_bitset<>    TBitSet;
-typedef float                       TParam;
+//typedef float                       TParam;
+typedef double                     TParam;
+//typedef std::unordered_set<int>    TSubIDSet;
 
 //------------------------------------------------------------------------------------
 /*!
@@ -359,17 +372,18 @@ class SMDS_ElementChunk
 {
   SMDS_ElementFactory* myFactory;     // holder of this chunk
   SMDS_MeshElement*    myElements;    // array of elements
-  int                  my1stID;       // ID of myElements[0]
+  smIdType             my1stID;       // ID of myElements[0]
   TBitSet              myMarkedSet;   // mark some elements
   TUsedRangeSet        myUsedRanges;  // ranges of used/unused elements
   TSubIDRangeSet       mySubIDRanges; // ranges of elements on the same sub-shape
-  int                  myMinSubID;    // min sub-shape ID
-  int                  myMaxSubID;    // max sub-shape ID
+  //TSubIDSet*           mySubIDSet;    // set of sub-shape IDs
+  // int                  myMinSubID;    // min sub-shape ID
+  // int                  myMaxSubID;    // max sub-shape ID
   std::vector<TParam>  myPositions;   // UV parameters on shape: 2*param_t per an element
 
 public:
 
-  SMDS_ElementChunk( SMDS_ElementFactory* factory = 0, int id0 = 0 );
+  SMDS_ElementChunk( SMDS_ElementFactory* factory = 0, smIdType id0 = 0 );
   ~SMDS_ElementChunk();
 
   //! Return an element by an index [0,ChunkSize()]
@@ -379,7 +393,7 @@ public:
   const SMDS_MeshElement* Element(int index) const { return & myElements[index]; }
 
   //! Return ID of the first non-used element
-  int  GetUnusedID() const;
+  smIdType  GetUnusedID() const;
 
   //! Mark an element as used
   void UseElement( const int index );
@@ -391,10 +405,10 @@ public:
   static bool IsUsed( const _UsedRange& r ) { return r.myValue; }
 
   //! Return index of an element in the chunk
-  int Index( const SMDS_MeshElement* e ) const { return e - myElements; }
+  int Index( const SMDS_MeshElement* e ) const { return (int)( e - myElements ); }
 
   //! Return ID of the 1st element in the chunk
-  int Get1stID() const { return my1stID; }
+  smIdType Get1stID() const { return my1stID; }
 
   //! Return pointer to on-shape-parameters of a node
   TParam* GetPositionPtr( const SMDS_MeshElement* node, bool allocate=false );
@@ -405,8 +419,8 @@ public:
   { min = false; max = true; return myUsedRanges; }
 
   //! Return ranges of elements assigned to sub-shapes and min/max of sub-shape IDs
-  const TSubIDRangeSet& GetSubIDRangesMinMax( int& min, int& max ) const
-  { min = myMinSubID; max = myMaxSubID; return mySubIDRanges; }
+  const TSubIDRangeSet& GetSubIDRangesMinMax( int& /*min*/, int& /*max*/ ) const
+  { /*min = myMinSubID; max = myMaxSubID;*/ return mySubIDRanges; }
 
   //! Minimize allocated memory
   void Compact();
@@ -417,9 +431,9 @@ public:
 
   // Methods called by SMDS_MeshElement
 
-  int  GetID( const SMDS_MeshElement* e ) const;
+  smIdType  GetID( const SMDS_MeshElement* e ) const;
 
-  int  GetVtkID( const SMDS_MeshElement* e ) const;
+  vtkIdType  GetVtkID( const SMDS_MeshElement* e ) const;
   void SetVTKID( const SMDS_MeshElement* e, const vtkIdType id );
 
   int  GetShapeID( const SMDS_MeshElement* e ) const;
@@ -463,11 +477,12 @@ struct _ChunkIterator : public ELEM_ITERATOR
                   get_rangeset_fun          theGetRangeSetFun,
                   attr_type                 theAttrValue,
                   SMDS_MeshElement::Filter* theFilter,
-                  size_t                    theNbElemsToReturn = -1):
+                  size_t                    theNbElemsToReturn = -1,
+                  int                       theChunkIndex = 0):
     myElement( 0 ),
     myRangeIndex( 0 ),
     myChunks( theChunks ),
-    myChunkIndex( -1 ),
+    myChunkIndex( theChunkIndex-1 ),
     myGetRangeSetFun( theGetRangeSetFun ),
     myValue( theAttrValue ),
     myFilter( theFilter ),
@@ -546,14 +561,18 @@ SMDS_ElementFactory::GetIterator( SMDS_MeshElement::Filter* filter,
 
 template< class ElemIterator >
 boost::shared_ptr< ElemIterator >
-SMDS_ElementFactory::GetShapeIterator( int shapeID, size_t nbElemsToReturn )
+SMDS_ElementFactory::GetShapeIterator( int                     shapeID,
+                                       size_t                  nbElemsToReturn,
+                                       const SMDS_MeshElement* sm1stElem )
 {
+  smIdType iChunk = sm1stElem ? (( sm1stElem->GetID() - 1 ) / ChunkSize()) : 0;
   typedef _ChunkIterator< ElemIterator, TSubIDRangeSet > TChuckIterator;
   return boost::make_shared< TChuckIterator >( myChunks,
                                                & SMDS_ElementChunk::GetSubIDRangesMinMax,
                                                /*shapeID=*/shapeID,
                                                new SMDS_MeshElement::NonNullFilter(),
-                                               nbElemsToReturn );
+                                               nbElemsToReturn,
+                                               iChunk );
 }
 
 #endif