]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
BuildPart on range of cell ids.
authorageay <ageay>
Tue, 3 Jul 2012 11:01:44 +0000 (11:01 +0000)
committerageay <ageay>
Tue, 3 Jul 2012 11:01:44 +0000 (11:01 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i

index 5f0967631cbbe70a756f15bca740500a0b86d462..0e7fac3d4ed8290fb37c675deba46ee3d580cd35 100644 (file)
@@ -369,6 +369,39 @@ int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, con
     return 0;
 }
 
+int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
+{
+  if(step!=0)
+    {
+      if(step>0)
+        {
+          if(begin<=value && end<value)
+            {
+              if((value-begin)%step==0)
+                return (value-begin)/step;
+              else
+                return -1;
+            }
+          else
+            return -1;
+        }
+      else
+        {
+          if(begin>=value && end>value)
+            {
+              if((begin-value)%(-step)==0)
+                return (begin-value)/(-step);
+              else
+                return -1;
+            }
+          else
+            return -1;
+        }
+    }
+  else
+    return -1;
+}
+
 DataArrayDouble *DataArrayDouble::New()
 {
   return new DataArrayDouble;
index 13a93f9bb0aa7d882659f58d14202ef4f34ed586..a7c1b4e044d6b795754e57f25c32ede19089f36d 100644 (file)
@@ -114,6 +114,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception);
   protected:
index df09cacb7163b234805af987a60dfe7db1ffef46..18b200ec6b69f596ae89a022dba58ee7c6063fc2 100644 (file)
@@ -94,6 +94,7 @@ namespace ParaMEDMEM
     MEDCouplingMesh *buildPart(const int *start, const int *end) const;
     MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const;
     virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const = 0;
+    virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) = 0;
     virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
     virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0;
     virtual DataArrayInt *findBoundaryNodes() const = 0;
index a8b16f9ecbd798b20cb86c4de55c0b38bb7548ee..8f8de1c6fd67f9261185db3e16dc4338aaece722 100644 (file)
@@ -1634,7 +1634,36 @@ void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& ot
 }
 
 /*!
- * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [begin,end).
+ * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords).
+ * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input
+ * cellIds is not given explicitely but by a range python like.
+ * 
+ * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
+ * \return a newly allocated
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=-1)
+    {
+      MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords2(start,end,step);
+      if(!keepCoords)
+        ret->zipCoords();
+      return ret;
+    }
+  else
+    {
+      int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh ");
+      if(newNbOfCells!=1)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
+      if(start!=0)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
+      incrRef();
+      return const_cast<MEDCouplingUMesh *>(this);
+    }
+}
+
+/*!
+ * build a sub part of \b this. This sub part is defined by the cell ids contained in the array in [begin,end).
  * @param begin begin of array containing the cell ids to keep.
  * @param end end of array of cell ids to keep. \b WARNING end param is \b not included ! Idem STL standard definitions.
  * @param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
@@ -1708,7 +1737,10 @@ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsE
         }
     }
   if(easyAssign)
-    MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
+    {
+      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
+      computeTypes();
+    }
   else
     {
       DataArrayInt *arrOut=0,*arrIOut=0;
@@ -1718,6 +1750,57 @@ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsE
     }
 }
 
+void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  otherOnSameCoordsThanThis.checkConnectivityFullyDefined();
+  if(getCoords()!=otherOnSameCoordsThanThis.getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !");
+  if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension();
+      oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : ");
+  if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" <<  nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCells=getNumberOfCells();
+  bool easyAssign=true;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer();
+  const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
+  int it=start;
+  for(int i=0;i<nbOfCellsToModify && easyAssign;i++,it+=step,connIOther++)
+    {
+      if(it>=0 && it<nbOfCells)
+        {
+          easyAssign=(connIOther[1]-connIOther[0])==(connI[it+1]-connI[it]);
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : On pos #" << i << " id is equal to " << it << " which is not in [0," << nbOfCells << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(easyAssign)
+    {
+      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
+      computeTypes();
+    }
+  else
+    {
+      DataArrayInt *arrOut=0,*arrIOut=0;
+      MEDCouplingUMesh::SetPartOfIndexedArrays2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index,
+                                               arrOut,arrIOut);
+      setConnectivity(arrOut,arrIOut,true);
+    }
+}                      
+
 DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
 {
   std::vector<int> cellIdsKept;
@@ -2724,7 +2807,63 @@ void MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, con
 }
 
 /*!
- * This is the low algorithm of buildPartOfMySelf. 
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2.
+ * CellIds are given using range specified by a start an end and step.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
+{
+  checkFullyDefined();
+  int ncell=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+  ret->_mesh_dim=_mesh_dim;
+  ret->setCoords(_coords);
+  int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : ");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1);
+  int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0;
+  int work=start;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      if(work>=0 && work<ncell)
+        {
+          newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work];
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1);
+  int *newConnPtr=newConn->getPointer();
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  work=start;
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]);
+      newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr);
+    }
+  ret->setConnectivity(newConn,newConnI,false);
+  ret->_types=types;
+  ret->copyTinyInfoFrom(this);
+  std::string name(getName());
+  std::size_t sz=strlen(PART_OF_NAME);
+  if(name.length()>=sz)
+    name=name.substr(0,sz);
+  if(name!=PART_OF_NAME)
+    {
+      std::ostringstream stream; stream << PART_OF_NAME << getName();
+      ret->setName(stream.str().c_str());
+    }
+  else
+    ret->setName(getName());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf.
  * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
  * The return newly allocated mesh will share the same coordinates as 'this'.
  */
@@ -5702,7 +5841,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<c
   for(std::size_t ii=0;ii<meshes.size();ii++)
     if(!meshes[ii])
       {
-        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshesOnSameCoords : item #" << ii << " in input array of size "<< meshes.size() << " is empty !";;
+        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshesOnSameCoords : item #" << ii << " in input array of size "<< meshes.size() << " is empty !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   const DataArrayDouble *coords=meshes.front()->getCoords();
@@ -7016,7 +7155,7 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const in
         }
       else
         {
-          std::size_t pos=(int)std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
+          std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
           arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
           *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
         }
@@ -7056,13 +7195,13 @@ void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, c
             std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
           else
             {
-              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
+              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
               throw INTERP_KERNEL::Exception(oss.str().c_str());
             }
         }
       else
         {
-          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
@@ -7116,6 +7255,118 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *a
   return arro->getIdsEqual(1);
 }
 
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [\b idsOfSelectBg, \b idsOfSelectEnd) and for
+ * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
+ * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays.
+ *
+ * \param [in] start begin of set of ids of the input extraction (included)
+ * \param [in] end end of set of ids of the input extraction (excluded)
+ * \param [in] step step of the set of ids in range mode.
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * \param [out] arrOut the resulting array
+ * \param [out] arrIndexOut the index array of the resulting array \b arrOut
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+                                               const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
+                                               DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception)
+{
+  if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  int offset=0;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : ");
+  int it=start;
+  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
+    {
+      if(it>=0 && it<nbOfTuples)
+        offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  arrIo->alloc(nbOfTuples+1,1);
+  arro->alloc(arrIn->getNumberOfTuples()+offset,1);
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
+  int *arroPtr=arro->getPointer();
+  for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
+    {
+      int pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
+      if(pos<0)
+        {
+          arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
+        }
+      else
+        {
+          arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
+        }
+    }
+  arrOut=arro; arro->incrRef();
+  arrIndexOut=arrIo; arrIo->incrRef();
+}
+
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn.
+ *
+ * \param [in] start begin of set of ids of the input extraction (included)
+ * \param [in] end end of set of ids of the input extraction (excluded)
+ * \param [in] step step of the set of ids in range mode.
+ * \param [in,out] arrInOut arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArrays2 MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
+                                                      const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception)
+{
+  if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : presence of null pointer in input parameter !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  int *arrInOutPtr=arrInOut->getPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : ");
+  int it=start;
+  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
+    {
+      if(it>=0 && it<nbOfTuples)
+        {
+          if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
+            std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+}
+
 /*!
  * \b this is expected to be a mesh fully defined whose spaceDim==meshDim.
  * It returns a new allocated mesh having the same mesh dimension and lying on same coordinates.
index f771a40204a48546f5dc63fbd11659c190deaa0d..209e5fa3df70797626ee8ff297751ad1cfbbcd0c 100644 (file)
@@ -119,8 +119,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const;
+    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT void setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
@@ -221,8 +223,13 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
                                                           const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
                                                           DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+    MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
                                                                  const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+                                                           const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
+                                                           DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
+                                                                  const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception);
   private:
     MEDCouplingUMesh();
@@ -246,6 +253,7 @@ namespace ParaMEDMEM
     void findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const;
     bool areCellsEqualInPool(const std::vector<int>& candidates, int compType, std::vector<int>& result) const;
     MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const;
+    MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const;
     template<int SPACEDIM>
     void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
                                      double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const;
index e71ddee8df0b014af6798b927d25891d15ad7a68..4807d075b0a438d183e5052e62c0f9286e040e69 100644 (file)
@@ -374,6 +374,12 @@ void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet
   throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
 
+MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Not implemented yet !");
+  return 0;
+}
+
 MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const
 {
   throw INTERP_KERNEL::Exception("Not implemented yet !");
index b8ca0c7a69bc28867e13d61f0951241bc47fc08a..27216c8f348c7eb7766acd405327112c78e83ba6 100644 (file)
@@ -69,6 +69,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes);
     MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=0) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
     MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const;
index f5cb3df6be8a125a81504ba2ddad948d389d0470..53378fe9343f96004746257abfbc535373d145ce 100644 (file)
@@ -1326,3 +1326,49 @@ void MEDCouplingBasicsTest5::testComputeTupleIdsToSelectFromCellIds1()
   sel->decrRef();
   res->decrRef();
 }
+
+void MEDCouplingBasicsTest5::testComputeSkin1()
+{
+  const double input1[5]={2.,3.4,5.6,7.7,8.0};
+  const double input2[6]={2.,3.4,5.6,7.7,9.0,14.2};
+  DataArrayDouble *arrX=DataArrayDouble::New(); arrX->alloc(5,1); std::copy(input1,input1+5,arrX->getPointer());
+  DataArrayDouble *arrY=DataArrayDouble::New(); arrY->alloc(6,1); std::copy(input2,input2+6,arrY->getPointer());
+  MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New() ; cmesh->setCoordsAt(0,arrX) ; cmesh->setCoordsAt(1,arrY);
+  MEDCouplingUMesh *umesh=cmesh->buildUnstructured();
+  cmesh->decrRef(); arrX->decrRef(); arrY->decrRef();
+  //
+  MEDCouplingUMesh *skin=umesh->computeSkin();
+  CPPUNIT_ASSERT_EQUAL(18,skin->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(1,skin->getMeshDimension());
+  CPPUNIT_ASSERT(skin->getCoords()==umesh->getCoords());
+  const int expected1[19]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54};
+  const int expected2[54]={1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24};
+  CPPUNIT_ASSERT_EQUAL(19,skin->getNodalConnectivityIndex()->getNbOfElems());
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+19,skin->getNodalConnectivityIndex()->getConstPointer()));
+  CPPUNIT_ASSERT_EQUAL(54,skin->getNodalConnectivity()->getNbOfElems());
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+54,skin->getNodalConnectivity()->getConstPointer()));
+  DataArrayInt *ids=skin->computeFetchedNodeIds();
+  const int expected3[18]={0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29};
+  CPPUNIT_ASSERT_EQUAL(18,ids->getNbOfElems());
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+18,ids->getConstPointer()));
+  MEDCouplingUMesh *part=dynamic_cast<MEDCouplingUMesh *>(umesh->buildFacePartOfMySelfNode(ids->begin(),ids->end(),true));
+  part->setName(skin->getName());
+  CPPUNIT_ASSERT(part->isEqual(skin,1e-12));
+  MEDCouplingUMesh *part2=dynamic_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf2(1,18,2,true));
+  DataArrayInt *ids2=DataArrayInt::Range(0,18,2);
+  part->setPartOfMySelf(ids2->begin(),ids2->end(),*part2);
+  ids2->decrRef();
+  CPPUNIT_ASSERT(!part->isEqual(skin,1e-12));
+  DataArrayInt *trad=part->zipConnectivityTraducer(0);
+  CPPUNIT_ASSERT_EQUAL(9,part->getNumberOfCells());
+  const int expected4[18]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8};
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+18,trad->getConstPointer()));
+  CPPUNIT_ASSERT_EQUAL(18,trad->getNbOfElems());
+  trad->decrRef();
+  part->decrRef();
+  part2->decrRef();
+  //
+  ids->decrRef();
+  umesh->decrRef();
+  skin->decrRef();
+}
index 67b7b7c93b989eccfe1701c92cfb07c30a5d7aaf..d8798baa3d417b91e2dec26427adcd19c15a92c6 100644 (file)
@@ -60,6 +60,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testGiveCellsWithType1 );
     CPPUNIT_TEST( testBuildSlice3D2 );
     CPPUNIT_TEST( testComputeTupleIdsToSelectFromCellIds1 );
+    CPPUNIT_TEST( testComputeSkin1 );
     CPPUNIT_TEST_SUITE_END();
   public:
     void testUMeshTessellate2D1();
@@ -87,6 +88,7 @@ namespace ParaMEDMEM
     void testGiveCellsWithType1();
     void testBuildSlice3D2();
     void testComputeTupleIdsToSelectFromCellIds1();
+    void testComputeSkin1();
   };
 }
 
index 1ee7ed1b1d2e7a4a2cdf62ea231c2652b5cf44e3..5c33f07010f373857446e82e2952264b646fb041 100644 (file)
@@ -9832,7 +9832,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
     
     def testPartitionBySpreadZone1(self):
         m=MEDCouplingDataForTest.build2DTargetMesh_1();
-        m4=MEDCouplingUMesh.MergeUMeshes([m,m[2:],m[0:2]]);
+        m4=MEDCouplingUMesh.MergeUMeshes([m,m[-3:],m[0:2]]);
         m4.renumberCells([5,2,9,6,4,7,0,1,3,8]);
         #
         v2=m4.partitionBySpreadZone();
@@ -10020,6 +10020,30 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertTrue(arr2.isEqual(f2.getArray(),1e-12))
         pass
 
+    def testComputeSkin1(self):
+        arrX=DataArrayDouble([2.,3.4,5.6,7.7,8.0]) ; arrY=DataArrayDouble([2.,3.4,5.6,7.7,9.0,14.2])
+        cmesh=MEDCouplingCMesh() ; cmesh.setCoordsAt(0,arrX) ; cmesh.setCoordsAt(1,arrY)
+        umesh=cmesh.buildUnstructured()
+        #
+        skin=umesh.computeSkin()
+        self.assertEqual(18,skin.getNumberOfCells())
+        self.assertEqual(1,skin.getMeshDimension())
+        self.assertTrue(skin.getCoords().getHiddenCppPointer()==umesh.getCoords().getHiddenCppPointer())
+        self.assertEqual([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],skin.getNodalConnectivityIndex().getValues())
+        self.assertEqual([1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24],skin.getNodalConnectivity().getValues())
+        ids=skin.computeFetchedNodeIds()
+        self.assertEqual([0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29],ids.getValues())
+        part=umesh.buildFacePartOfMySelfNode(ids,True)
+        part.setName(skin.getName());
+        self.assertTrue(part.isEqual(skin,1e-12))
+        part2=part[1::2]
+        part[::2]=part2
+        self.assertTrue(not part.isEqual(skin,1e-12))
+        trad=part.zipConnectivityTraducer(0)
+        self.assertEqual(9,part.getNumberOfCells())
+        self.assertEqual([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8],trad.getValues())
+        pass
+
     def setUp(self):
         pass
     pass
index 857e7ad88737382de93b62b1f420e2903b83bc82..8d57723cc8beaee2b38930268dbc1c524ffc5c78 100644 (file)
@@ -244,6 +244,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes;
 %newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh;
 %newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray;
+%newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2;
 %newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType;
 %newobject ParaMEDMEM::MEDCouplingUMesh::New;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity;
@@ -791,6 +792,7 @@ namespace ParaMEDMEM
       void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception);
       void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception);
       void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
+      virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception);
       virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception);
       static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception);
       static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception);
@@ -1237,6 +1239,7 @@ namespace ParaMEDMEM
     MEDCouplingUMeshCellByTypeEntry *cellsByType() throw(INTERP_KERNEL::Exception);
     void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true) throw(INTERP_KERNEL::Exception);
     INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception);
+    void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception);
     int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception);
     int getMeshLength() const throw(INTERP_KERNEL::Exception);
     void computeTypes() throw(INTERP_KERNEL::Exception);
@@ -1338,8 +1341,7 @@ namespace ParaMEDMEM
             }
           case 3:
             {
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::Range(slic.first,slic.second.first,slic.second.second);
-              return self->buildPartOfMySelf(d0->begin(),d0->end(),true);
+              return self->buildPartOfMySelf2(slic.first,slic.second.first,slic.second.second,true);
             }
           case 4:
             {
@@ -1352,6 +1354,64 @@ namespace ParaMEDMEM
             throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !");
           }
       }
+      
+      void setPartOfMySelf(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception)
+      {
+        int sw;
+        int singleVal;
+        std::vector<int> multiVal;
+        std::pair<int, std::pair<int,int> > slic;
+        ParaMEDMEM::DataArrayInt *daIntTyypp=0;
+        int nbc=self->getNumberOfCells();
+        convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp);
+        switch(sw)
+          {
+          case 1:
+            {
+              if(singleVal>=nbc)
+                {
+                  std::ostringstream oss;
+                  oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+              if(singleVal>=0)
+                {
+                  self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis);
+                  break;
+                }
+              else
+                {
+                  if(nbc+singleVal>0)
+                    {
+                      int tmp=nbc+singleVal;
+                      self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis);
+                      break;
+                    }
+                  else
+                    {
+                      std::ostringstream oss;
+                      oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !";
+                      throw INTERP_KERNEL::Exception(oss.str().c_str());
+                    }
+                }
+            }
+          case 2:
+            {
+              self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis);
+              break;
+            }
+          case 4:
+            {
+              if(!daIntTyypp)
+                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : null instance has been given in input !");
+              daIntTyypp->checkAllocated();
+              self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis);
+              break;
+            }
+          default:
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !");
+          }
+      }
 
       void __setitem__(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception)
       {
@@ -1400,8 +1460,7 @@ namespace ParaMEDMEM
             }
           case 3:
             {
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::Range(slic.first,slic.second.first,slic.second.second);
-              self->setPartOfMySelf(d0->begin(),d0->end(),otherOnSameCoordsThanThis);
+              self->setPartOfMySelf2(slic.first,slic.second.first,slic.second.second,otherOnSameCoordsThanThis);
               break;
             }
           case 4:
@@ -1413,7 +1472,7 @@ namespace ParaMEDMEM
               break;
             }
           default:
-            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !");
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int, slice, DataArrayInt instance !");
           }
       }