Salome HOME
Merge remote-tracking branch 'origin/abn/bug_fixes' into V8_5_BR
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingSkyLineArray.cxx
index ffb964e1fa8237f273fdfdff3fa49a9a7f52678a..e07b195c8f8da33e92b89f2e27ee7099ce298af4 100644 (file)
 #include "MEDCouplingSkyLineArray.hxx"
 
 #include <sstream>
+#include <deque>
+#include <set>
 
 using namespace MEDCoupling;
 
 MEDCouplingSkyLineArray::MEDCouplingSkyLineArray():
-  _index( DataArrayInt::New() ), _values( DataArrayInt::New() ), _super_index( DataArrayInt::New() )
+  _super_index( DataArrayInt::New() ), _index( DataArrayInt::New() ), _values( DataArrayInt::New() )
 {
 }
 
@@ -76,9 +78,9 @@ MEDCouplingSkyLineArray * MEDCouplingSkyLineArray::BuildFromPolyhedronConn( cons
 
   const int * cP(c->begin()), * cIP(cI->begin());
   int prev = -1;
-  if (c->getNbOfElems() != *(cI->end()-1))
+  if ((int)c->getNbOfElems() != *(cI->end()-1))
     throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::BuildFromDynamicConn: misformatted connectivity (wrong nb of tuples)!");
-  for (int i=0; i < cI->getNbOfElems(); i++)
+  for (std::size_t i=0; i < cI->getNbOfElems(); i++)
     {
       int j = cIP[i];
       if (cIP[i] < prev)
@@ -95,7 +97,7 @@ MEDCouplingSkyLineArray * MEDCouplingSkyLineArray::BuildFromPolyhedronConn( cons
   superIdx.push_back(0);
   idx.push_back(0);
   vals.resize(c->getNbOfElems()); // too much because of the type and the -1, but still better than push_back().
-  for (int i=0; i < cI->getNbOfElems()-1; i++)
+  for (std::size_t i=0; i < cI->getNbOfElems()-1; i++)
     {
       int start = cIP[i]+1, end = cIP[i+1];
       int * work = vals.data() + cnt;
@@ -145,7 +147,7 @@ void MEDCouplingSkyLineArray::convertToPolyhedronConn( MCAuto<DataArrayInt>& c,
   c->alloc(sz, 1);
   int * cVecP(c->getPointer());
 
-  for (int i=0; i < _super_index->getNbOfElems()-1; i++)
+  for ( std::size_t i=0; i < _super_index->getNbOfElems()-1; i++)
      {
        cIVecP[i]= cnt;
        int endId = siP[i+1];
@@ -197,18 +199,18 @@ void MEDCouplingSkyLineArray::set3( DataArrayInt* superIndex, DataArrayInt* inde
 
 DataArrayInt* MEDCouplingSkyLineArray::getSuperIndexArray() const
 {
-  return ((MEDCouplingSkyLineArray*)this)->_super_index;
+  return const_cast<MEDCouplingSkyLineArray*>(this)->_super_index;
 }
 
 
 DataArrayInt* MEDCouplingSkyLineArray::getIndexArray() const
 {
-  return ((MEDCouplingSkyLineArray*)this)->_index;
+  return const_cast<MEDCouplingSkyLineArray*>(this)->_index;
 }
 
 DataArrayInt* MEDCouplingSkyLineArray::getValuesArray() const
 {
-  return ((MEDCouplingSkyLineArray*)this)->_values;
+  return const_cast<MEDCouplingSkyLineArray*>(this)->_values;
 }
 
 void MEDCouplingSkyLineArray::checkSuperIndex(const std::string& func) const
@@ -223,7 +225,7 @@ void MEDCouplingSkyLineArray::checkSuperIndex(const std::string& func) const
 
 void MEDCouplingSkyLineArray::validSuperIndex(const std::string& func, int superIndex) const
 {
-  if(superIndex < 0 || superIndex >= _super_index->getNbOfElems())
+  if(superIndex < 0 || superIndex >= (int)_super_index->getNbOfElems())
     {
       std::ostringstream oss;
       oss << "MEDCouplingSkyLineArray::" << func <<  ": invalid super index!";
@@ -233,7 +235,7 @@ void MEDCouplingSkyLineArray::validSuperIndex(const std::string& func, int super
 
 void MEDCouplingSkyLineArray::validIndex(const std::string& func, int idx) const
 {
-  if(idx < 0 || idx >= _index->getNbOfElems())
+  if(idx < 0 || idx >= (int)_index->getNbOfElems())
     {
       std::ostringstream oss;
       oss << "MEDCouplingSkyLineArray::" << func <<  ": invalid index!";
@@ -245,7 +247,7 @@ void MEDCouplingSkyLineArray::validSuperIndexAndIndex(const std::string& func, i
 {
   validSuperIndex(func, superIndex);
   int idx = _super_index->begin()[superIndex] + index;
-  if(idx < 0 || idx >= _index->getNbOfElems())
+  if(idx < 0 || idx >= (int)_index->getNbOfElems())
     {
       std::ostringstream oss;
       oss << "MEDCouplingSkyLineArray::" << func <<  ": invalid index!";
@@ -315,7 +317,7 @@ std::string MEDCouplingSkyLineArray::simpleRepr() const
  */
 void MEDCouplingSkyLineArray::getSimplePackSafe(const int absolutePackId, std::vector<int> & pack) const
 {
-  if(absolutePackId < 0 || absolutePackId >= _index->getNbOfElems())
+  if(absolutePackId < 0 || absolutePackId >= (int)_index->getNbOfElems())
     throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::getPackSafe: invalid index!");
   const int * iP(_index->begin()), *vP(_values->begin());
   int sz = iP[absolutePackId+1]-iP[absolutePackId];
@@ -328,7 +330,7 @@ void MEDCouplingSkyLineArray::getSimplePackSafe(const int absolutePackId, std::v
  */
 const int * MEDCouplingSkyLineArray::getSimplePackSafePtr(const int absolutePackId, int & packSize) const
 {
-  if(absolutePackId < 0 || absolutePackId >= _index->getNbOfElems())
+  if(absolutePackId < 0 || absolutePackId >= (int)_index->getNbOfElems())
     throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::getPackSafe: invalid index!");
   const int * iP(_index->begin()), *vP(_values->begin());
   packSize = iP[absolutePackId+1]-iP[absolutePackId];
@@ -384,8 +386,6 @@ void MEDCouplingSkyLineArray::findPackIds(const std::vector<int> & superPackIndi
  */
 void MEDCouplingSkyLineArray::deletePack(const int superIdx, const int idx)
 {
-  using namespace std;
-
   checkSuperIndex("deletePack");
   validSuperIndexAndIndex("deletePack", superIdx, idx);
 
@@ -393,21 +393,143 @@ void MEDCouplingSkyLineArray::deletePack(const int superIdx, const int idx)
   int * siP(_super_index->getPointer()), *iP(_index->getPointer());
   const int start = iP[siP[superIdx]+idx], end = iP[siP[superIdx]+idx+1];
   // _values
-  copy(vP+end, vP+_values->getNbOfElems(), vP+start);
+  std::copy(vP+end, vP+_values->getNbOfElems(), vP+start);
   _values->reAlloc(_values->getNbOfElems() - (end-start));
 
   // _index
   int nt = _index->getNbOfElems();
-  copy(iP+siP[superIdx]+idx+1, iP+nt, iP+siP[superIdx]+idx);
+  std::copy(iP+siP[superIdx]+idx+1, iP+nt, iP+siP[superIdx]+idx);
   _index->reAlloc(nt-1); iP = _index->getPointer();  // better not forget this ...
   for(int ii = siP[superIdx]+idx; ii < nt-1; ii++)
     iP[ii] -= (end-start);
 
   // _super_index
-  for(int ii = superIdx+1; ii < _super_index->getNbOfElems(); ii++)
+  for(int ii = superIdx+1; ii < (int)_super_index->getNbOfElems(); ii++)
     (siP[ii])--;
 }
 
+void MEDCouplingSkyLineArray::deleteSimplePack(const int idx)
+{
+  validIndex("deleteSimplePack", idx);
+  
+  int* iP(_index->getPointer());
+  const int start(iP[idx]), end(iP[idx+1]);
+
+  // _values
+  int initValSz( _values->getNbOfElems() );
+  int deltaSz( start-end );  // should be negative
+  int *vP(_values->getPointer());
+  if (deltaSz < 0)
+    {
+      std::copy(vP+end, vP+initValSz, vP+start);
+      _values->reAlloc(initValSz+deltaSz);
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::deleteSimplePack");
+  // _index
+  int nt(_index->getNbOfElems());
+  std::copy(iP+idx+1, iP+nt, iP+idx);
+  for(int ii = idx; ii < nt-1; ii++)
+    iP[ii] += deltaSz;
+  _index->reAlloc(nt-1);
+}
+
+void MEDCouplingSkyLineArray::replaceSimplePacks(const DataArrayInt* idx, const std::vector<const DataArrayInt*>& packs)
+{    
+  if (idx->empty())
+    return;
+    
+  for (const int * id = idx->begin(); id != idx->end(); id++)
+    validIndex("deleteSimplePacks", *id);
+    
+  if (idx->getNbOfElems() != packs.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::deleteSimplePacks: size of list of pack is incorrect");
+    
+  // copy _index, _values into a deque<set<int>>
+  std::deque< std::set<int> > valuesByIdx;
+  int* vP(_values->getPointer());
+  int* iP(_index->getPointer());
+  std::size_t nt ( _index->getNbOfElems() );
+  for (int ii = 0; ii < nt-1; ii++)
+    valuesByIdx.push_back(std::set<int>(vP+iP[ii], vP+iP[ii+1]));
+    
+  // modify the deque<set<int>> according to idx and packs
+  int ii(0);
+  for (const int *id = idx->begin(); id != idx->end(); id++)
+    {
+      valuesByIdx[*id] = std::set<int>(packs[ii]->begin(), packs[ii]->end());
+      ii++;
+    }
+  // copy back the deque<set<int>> into _index, _values
+  int valSz(0);
+  *iP = 0;
+  for (std::deque< std::set<int> >::const_iterator values=valuesByIdx.begin();values!=valuesByIdx.end();values++)
+    {
+      valSz += (*values).size();
+      *(++iP) = valSz;
+    }
+  _values->reAlloc(valSz);
+  iP = _index->getPointer();
+  vP = _values->getPointer();
+  for (auto values : valuesByIdx)
+    {
+      std::copy(values.begin(), values.end(), vP+(*iP));
+      iP++;
+    }
+}
+
+void MEDCouplingSkyLineArray::deleteSimplePacks(const DataArrayInt* idx)
+{    
+  for (auto id = idx->begin(); id != idx->end(); id++)
+    validIndex("deleteSimplePacks", *id);
+  
+  std::set<int> packsToDelete(idx->begin(), idx->end());
+    
+  // _values
+  int* iP(_index->getPointer());
+  int initValSz = _values->getNbOfElems();
+  int *vP(_values->getPointer());
+  int end_prec(0),start_prec(0);
+  for(std::set<int>::const_iterator ii=packsToDelete.begin();ii!=packsToDelete.end();ii++)
+    {
+      int start = iP[*ii];
+      if (end_prec != 0)
+        std::copy(vP+end_prec, vP+start, vP+start_prec);
+      start_prec += start-end_prec;
+      end_prec = iP[*ii+1];
+    }
+  if (end_prec != 0)
+    std::copy(vP+end_prec, vP+initValSz, vP+start_prec);
+  _values->reAlloc(initValSz-(end_prec-start_prec));
+    
+  // _index
+  int nt = _index->getNbOfElems();
+  int offset = 0;
+  end_prec = 0;
+  start_prec = 0;
+  int deleted = 0;
+  for(std::set<int>::const_iterator ii=packsToDelete.begin();ii!=packsToDelete.end();ii++)
+    {
+      if (end_prec != 0)
+        {
+          std::copy(iP+end_prec, iP+*ii, iP+start_prec);
+          for (int i=start_prec; i<*ii; i++)
+            iP[i] -= offset;
+        }
+      offset += iP[*ii+1] - iP[*ii];
+      start_prec = *ii-deleted;
+      end_prec = *ii+1;
+      deleted += 1;
+    }
+  if (end_prec != 0)
+    {
+      std::copy(iP+end_prec, iP+nt, iP+start_prec);
+      for (int i=start_prec; i<nt; i++)
+        iP[i] -= offset;
+    }
+  _index->reAlloc(nt-deleted);
+}
+
 /**!
  * Insert a new pack in super-pack at index 'superIdx'. The pack is inserted at the end of the pack list of the chosen super-pack.
  */
@@ -438,7 +560,7 @@ void MEDCouplingSkyLineArray::pushBackPack(const int superIdx, const int * packB
     iP[ii] += sz;
 
   // _super_index
-  for(int ii = superIdx+1; ii < _super_index->getNbOfElems(); ii++)
+  for(int ii = superIdx+1; ii < (int)_super_index->getNbOfElems(); ii++)
     (siP[ii])++;
 }
 
@@ -448,12 +570,10 @@ void MEDCouplingSkyLineArray::pushBackPack(const int superIdx, const int * packB
  */
 void MEDCouplingSkyLineArray::replaceSimplePack(const int idx, const int * packBg, const int * packEnd)
 {
-  using namespace std;
-
   validIndex("replaceSimplePack", idx);
 
   int * iP(_index->getPointer());
-  int newSz = distance(packBg, packEnd);
+  int newSz = std::distance(packBg, packEnd);
   const int start = iP[idx], end = iP[idx+1];
 
   // _values
@@ -464,16 +584,16 @@ void MEDCouplingSkyLineArray::replaceSimplePack(const int idx, const int * packB
       if (deltaSz > 0)
         _values->reAlloc(initValSz+deltaSz);
       int *vP(_values->getPointer());
-      copy(vP+end, vP+initValSz, vP+end+deltaSz);
+      std::copy(vP+end, vP+initValSz, vP+end+deltaSz);
       if (deltaSz < 0)
         _values->reAlloc(initValSz+deltaSz);
     }
 
   // copy new pack
-  copy(packBg, packEnd, _values->getPointer()+start);
+  std::copy(packBg, packEnd, _values->getPointer()+start);
 
   // _index
-  for(int ii = idx+1; ii < _index->getNbOfElems(); ii++)
+  for(int ii = idx+1; ii < (int)_index->getNbOfElems(); ii++)
     iP[ii] += deltaSz;
 }
 
@@ -481,15 +601,13 @@ void MEDCouplingSkyLineArray::replaceSimplePack(const int idx, const int * packB
  * Replace pack with super index 'superIdx' and index 'idx' with the provided new pack.
  * Function can be used only for 3-level SkyLine.
  */
-void MEDCouplingSkyLineArray::replacePack(const int superIdx, const int idx, const int * packBg, const int * packEnd)
+void MEDCouplingSkyLineArray::replacePack(const int superIdx, const int idx, const int *packBg, const int *packEnd)
 {
-  using namespace std;
-
   checkSuperIndex("replacePack");
   validSuperIndexAndIndex("replacePack", superIdx, idx);
 
   int * siP(_super_index->getPointer()), *iP(_index->getPointer());
-  int newSz = distance(packBg, packEnd);
+  int newSz = std::distance(packBg, packEnd);
   const int start = iP[siP[superIdx]+idx], end = iP[siP[superIdx]+idx+1];
 
   // _values
@@ -500,15 +618,15 @@ void MEDCouplingSkyLineArray::replacePack(const int superIdx, const int idx, con
       if (deltaSz > 0)
         _values->reAlloc(initValSz+deltaSz);
       int *vP(_values->getPointer());
-      copy(vP+end, vP+initValSz, vP+end+deltaSz);
+      std::copy(vP+end, vP+initValSz, vP+end+deltaSz);
       if (deltaSz < 0)
         _values->reAlloc(initValSz+deltaSz);
     }
 
   // copy new pack
-  copy(packBg, packEnd, _values->getPointer()+start);
+  std::copy(packBg, packEnd, _values->getPointer()+start);
 
   // _index
-  for(int ii = siP[superIdx]+idx+1; ii < _index->getNbOfElems(); ii++)
+  for(int ii = siP[superIdx]+idx+1; ii < (int)_index->getNbOfElems(); ii++)
     iP[ii] += deltaSz;
 }