]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
OK test 0->12.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 16 Dec 2014 14:40:22 +0000 (15:40 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 18 Dec 2014 13:52:13 +0000 (14:52 +0100)
src/INTERP_KERNEL/CellModel.cxx
src/INTERP_KERNEL/CellModel.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 5a22ab1c409f83e1959165ea5d244775863a6f19..2bdfb826bb2a2c47f2edbec4f29c516605262778 100644 (file)
@@ -591,6 +591,52 @@ namespace INTERP_KERNEL
       throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !");   
   }
 
+  void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const
+  {
+    if(sz<1)
+      return ;
+    if(!isQuadratic())
+      {
+        std::vector<int> tmp(sz-1);
+        std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
+        std::copy(tmp.begin(),tmp.end(),nodalConn+1);
+      }
+    else
+      {
+        unsigned int sz2(sz/2);
+        std::vector<int> tmp0(sz2-1),tmp1(sz2);
+        std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin());
+        std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin());
+        std::copy(tmp0.begin(),tmp0.end(),nodalConn+1);
+        std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2);
+      }
+  }
+
+  void CellModel::changeOrientationOf1D(int *nodalConn, unsigned int sz) const
+  {
+    if(!isDynamic())
+      {
+        if(sz==2 || sz==3)
+          {
+            std::swap(nodalConn[0],nodalConn[1]);
+            return ;
+          }
+        else if(sz==4)
+          {
+            std::swap(nodalConn[0],nodalConn[1]);
+            std::swap(nodalConn[2],nodalConn[3]);
+          }
+        else
+          throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !");
+      }
+    else
+      {
+        std::vector<int> tmp(sz-1);
+        std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin());
+        std::copy(tmp.begin(),tmp.end(),nodalConn+1);
+      }
+  }
+
   //================================================================================
   /*!
    * \brief Return number of nodes in sonId-th son of a Dynamic() cell
index 32974d57cd6dba21b04b4413ed7fd531080802a3..ab49dcf9978eb1f344d204479d8f6fd9818a0c70 100644 (file)
@@ -72,6 +72,8 @@ namespace INTERP_KERNEL
     INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const;
     INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const;
     INTERPKERNEL_EXPORT unsigned fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const;
+    INTERPKERNEL_EXPORT void changeOrientationOf2D(int *nodalConn, unsigned int sz) const;
+    INTERPKERNEL_EXPORT void changeOrientationOf1D(int *nodalConn, unsigned int sz) const;
   private:
     bool _dyn;
     bool _quadratic;
index d3f460529a0a2edb09ea81fa3377fd89b5b2c3c6..eca5fe45ba03c15eeee989e1c947c9132c5f9483 100644 (file)
@@ -6345,7 +6345,7 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb
 }
 
 /*!
- * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
+ * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
  * i.e. a current value is used as in index to get a new value from \a indArrBg.
  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
  *         to \a this array.
@@ -6354,15 +6354,15 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb
  *  \throw If \a this->getNumberOfComponents() != 1
  *  \throw If any value of \a this can't be used as a valid index for 
  *         [\a indArrBg, \a indArrEnd).
+ *
+ *  \sa replaceOneValByInThis
  */
 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
-  int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
-  int nbOfTuples=getNumberOfTuples();
-  int *pt=getPointer();
+  int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
   for(int i=0;i<nbOfTuples;i++,pt++)
     {
       if(*pt>=0 && *pt<nbElemsIn)
@@ -6376,6 +6376,29 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd
   declareAsNew();
 }
 
+/*!
+ * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy.
+ *
+ * \param [in] valToBeReplaced - the value in \a this to be replaced.
+ * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
+ *
+ * \sa DataArrayInt::transformWithIndArr
+ */
+void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  if(valToBeReplaced==replacedBy)
+    return ;
+  int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    {
+      if(*pt==valToBeReplaced)
+        *pt=replacedBy;
+    }
+}
+
 /*!
  * Computes distribution of values of \a this one-dimensional array between given value
  * ranges (casts). This method is typically useful for entity number spliting by types,
@@ -9422,7 +9445,7 @@ void DataArrayInt::applyModulus(int val)
  * \param [in] vmax end of range. This value is \b not included in range (excluded).
  * \return a newly allocated data array that the caller should deal with.
  *
- * \sa DataArrayInt::getIdsNotInRange
+ * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative
  */
 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
 {
@@ -9447,7 +9470,7 @@ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
  * \param [in] vmax end of range. This value is included in range (included).
  * \return a newly allocated data array that the caller should deal with.
  * 
- * \sa DataArrayInt::getIdsInRange
+ * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative
  */
 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
 {
@@ -9463,6 +9486,26 @@ DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
   return ret.retn();
 }
 
+/*!
+ * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
+ *
+ * \return a newly allocated data array that the caller should deal with.
+ * \sa DataArrayInt::getIdsInRange
+ */
+DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !");
+  const int *cptr(getConstPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  int nbOfTuples(getNumberOfTuples());
+  for(int i=0;i<nbOfTuples;i++,cptr++)
+    if(*cptr<0)
+      ret->pushBackSilent(i);
+  return ret.retn();
+}
+
 /*!
  * This method works only on data array with one component.
  * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown.
index 8c25de2fb6e94cf3c859a79924322ff7aab17c0a..a5b1a3101dff3bdbc6461a6078534de1c82f8c5e 100644 (file)
@@ -476,6 +476,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const;
     MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd);
+    MEDCOUPLING_EXPORT void replaceOneValByInThis(int valToBeReplaced, int replacedBy);
     MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const;
     MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd,
                                               DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const;
@@ -568,6 +569,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void applyRPow(int val);
     MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const;
     MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(int vmin, int vmax) const;
+    MEDCOUPLING_EXPORT DataArrayInt *getIdsStrictlyNegative() const;
     MEDCOUPLING_EXPORT bool checkAllIdsInRange(int vmin, int vmax) const;
     MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2);
     MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector<const DataArrayInt *>& arr);
index 367ec010d09c895c1611d5c8b92450ee30fee3e2..8cbb5ab4ab5298a1c0917bffe115404e0c058eb1 100644 (file)
@@ -5978,40 +5978,28 @@ void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool po
  *  \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br>
  *  \ref  py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example".
  *  \endif
+ *
+ *  \sa changeOrientationOfCells
  */
 void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
 {
   if(getMeshDimension()!=2 || getSpaceDimension()!=3)
     throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
-  int nbOfCells=getNumberOfCells();
-  int *conn=_nodal_connec->getPointer();
-  const int *connI=_nodal_connec_index->getConstPointer();
-  const double *coordsPtr=_coords->getConstPointer();
-  bool isModified=false;
+  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
+  const int *connI(_nodal_connec_index->getConstPointer());
+  const double *coordsPtr(_coords->getConstPointer());
+  bool isModified(false);
   for(int i=0;i<nbOfCells;i++)
     {
-      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
       if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
         {
-          bool isQuadratic(INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic());
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+          bool isQuadratic(cm.isQuadratic());
           if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
             {
               isModified=true;
-              if(!isQuadratic)
-                {
-                  std::vector<int> tmp(connI[i+1]-connI[i]-2);
-                  std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
-                  std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
-                }
-              else
-                {
-                  int sz(((int)(connI[i+1]-connI[i]-1))/2);
-                  std::vector<int> tmp0(sz-1),tmp1(sz);
-                  std::copy(conn+connI[i]+2,conn+connI[i]+1+sz,tmp0.rbegin());
-                  std::copy(conn+connI[i]+1+sz,conn+connI[i+1],tmp1.rbegin());
-                  std::copy(tmp0.begin(),tmp0.end(),conn+connI[i]+2);
-                  std::copy(tmp1.begin(),tmp1.end(),conn+connI[i]+1+sz);
-                }
+              cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
             }
         }
     }
@@ -6020,6 +6008,38 @@ void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly)
   updateTime();
 }
 
+/*!
+ * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted.
+ *
+ * \sa orientCorrectly2DCells
+ */
+void MEDCouplingUMesh::changeOrientationOfCells()
+{
+  int mdim(getMeshDimension());
+  if(mdim!=2 && mdim!=1)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !");
+  int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer());
+  const int *connI(_nodal_connec_index->getConstPointer());
+  if(mdim==2)
+    {//2D
+      for(int i=0;i<nbOfCells;i++)
+        {
+          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+          cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
+        }
+    }
+  else
+    {//1D
+      for(int i=0;i<nbOfCells;i++)
+        {
+          INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+          const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+          cm.changeOrientationOf1D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1));
+        }
+    }
+}
+
 /*!
  * Finds incorrectly oriented polyhedral cells, i.e. polyhedrons having correctly
  * oriented facets. The normal vector of the facet should point out of the cell.
@@ -9405,6 +9425,76 @@ MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCo
   return BuildMesh2DCutInternal(eps,splitMesh1D,allEdges,allEdgesPtr,offset,idsLeftRight);
 }
 
+bool AreEdgeEqual(const double *coo2D, const INTERP_KERNEL::CellModel& typ1, const int *conn1, const INTERP_KERNEL::CellModel& typ2, const int *conn2, double eps)
+{
+  if(!typ1.isQuadratic() && !typ2.isQuadratic())
+    {//easy case comparison not
+      return conn1[0]==conn2[0] && conn1[1]==conn2[1];
+    }
+  else if(typ1.isQuadratic() && typ2.isQuadratic())
+    {
+      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
+      if(!status0)
+        return false;
+      if(conn1[2]==conn2[2])
+        return true;
+      const double *a(coo2D+2*conn1[2]),*b(coo2D+2*conn2[2]);
+      double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
+      return dist<eps;
+    }
+  else
+    {//only one is quadratic
+      bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]);
+      if(!status0)
+        return false;
+      if(typ1.isQuadratic())
+        {
+          const double *a(coo2D+2*conn1[2]),*bb(coo2D+2*conn2[0]),*be(coo2D+2*conn2[1]);
+          double b[2]; b[0]=(be[0]+bb[0])/2.; b[1]=(be[1]+bb[1])/2.;
+          double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])));
+          return dist<eps;
+        }
+    }
+}
+
+/*!
+ * This method returns among the cellIds [ \a candidatesIn2DBg , \a candidatesIn2DEnd ) in \a mesh2DSplit those exactly sharing \a cellIdInMesh1DSplitRelative in \a mesh1DSplit.
+ * \a mesh2DSplit and \a mesh1DSplit are expected to share the coordinates array.
+ *
+ * \param [in] cellIdInMesh1DSplitRelative is in Fortran mode using sign to specify direction.
+ */
+int FindRightCandidateAmong(const MEDCouplingUMesh *mesh2DSplit, const int *candidatesIn2DBg, const int *candidatesIn2DEnd, const MEDCouplingUMesh *mesh1DSplit, int cellIdInMesh1DSplitRelative, double eps)
+{
+  if(candidatesIn2DEnd==candidatesIn2DBg)
+    throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 1 !");
+  const double *coo(mesh2DSplit->getCoords()->begin());
+  if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1)
+    return *candidatesIn2DBg;
+  int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur1D(static_cast<MEDCouplingUMesh *>(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true)));
+  if(cellIdInMesh1DSplitRelative<0)
+    cur1D->changeOrientationOfCells();
+  const int *c1D(cur1D->getNodalConnectivity()->begin());
+  const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0]));
+  for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur2D(static_cast<MEDCouplingUMesh *>(mesh2DSplit->buildPartOfMySelf(it,it+1,true)));
+      const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin());
+      const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]]));
+      unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1));
+      INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[1]-ci[0]]);
+      for(unsigned it2=0;it2<sz;it2++)
+        {
+          INTERP_KERNEL::NormalizedCellType typeOfSon;
+          cm.fillSonCellNodalConnectivity2(it2,c+ci[0]+1,ci[1]-ci[0]-1,tmpPtr,typeOfSon);
+          const INTERP_KERNEL::CellModel &curCM(INTERP_KERNEL::CellModel::GetCellModel(typeOfSon));
+          if(AreEdgeEqual(coo,ref1DType,c1D+1,curCM,tmpPtr,eps))
+            return *it;
+        }
+    }
+  throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 2 ! Unable to find the edge among split cell !");
+}
+
 /// @endcond
 
 /*!
@@ -9474,7 +9564,7 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D,
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(DataArrayInt::New()); ret2->alloc(0,1);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1,
       idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear));
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(-1); ret3->rearrange(2);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits<int>::max()); ret3->rearrange(2);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells()));
   // deal with cells in mesh2D that are not cut but only some of their edges are
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCpy());
@@ -9522,7 +9612,7 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D,
       int offset(ret2->getNumberOfTuples());
       ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end());
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1);
-      partOfRet3->fillWithValue(-1); partOfRet3->rearrange(2);
+      partOfRet3->fillWithValue(std::numeric_limits<int>::max()); partOfRet3->rearrange(2);
       int kk(0),*ret3ptr(partOfRet3->getPointer());
       for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++)
         {
@@ -9538,7 +9628,12 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D,
                     ret3ptr[2*kk+1]=tmp+offset;
                 }
               else
-                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine : internal error 1 !");
+                {//the current edge is shared by a 2D cell that will be split just after
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk]=-(*it2+1);
+                  if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1])
+                    ret3ptr[2*kk+1]=-(*it2+1);
+                }
             }
         }
       ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true);
@@ -9563,9 +9658,21 @@ void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D,
     tmp[i]=outMesh2DSplit[i];
   //
   ret1->getCoords()->setInfoOnComponents(compNames);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp));
+  // To finish - filter ret3 - std::numeric_limits<int>::max() -> -1 - negate values must be resolved.
+  ret3->rearrange(1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> edgesToDealWith(ret3->getIdsStrictlyNegative());
+  for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++)
+    {
+      int old2DCellId(-ret3->getIJ(*it,0)-1);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates(ret2->getIdsEqual(old2DCellId));
+      ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3
+    }
+  ret3->replaceOneValByInThis(std::numeric_limits<int>::max(),-1);
+  ret3->rearrange(2);
   //
   splitMesh1D=ret1.retn();
-  splitMesh2D=MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp);
+  splitMesh2D=ret2D.retn();
   cellIdInMesh2D=ret2.retn();
   cellIdInMesh1D=ret3.retn();
 }
index e1b2c93d742da6149c3d72066243b5af65ebf97f..202f0f33481847d61247a0faa029929bf32c20bc 100644 (file)
@@ -185,6 +185,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void convertDegeneratedCells();
     MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const;
     MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly);
+    MEDCOUPLING_EXPORT void changeOrientationOfCells();
     MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const;
     MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons();
     MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const;
index bda97d201e4005506c1ef9fbf9ef2fb86ec64bde..1305e7675523cbba120606a6ebf6e78a172aa550 100644 (file)
@@ -25,7 +25,7 @@ from datetime import datetime
 from MEDCouplingDataForTest import MEDCouplingDataForTest
 import rlcompleter,readline # this line has to be here, to ensure a usability of MEDCoupling/MEDLoader. B4 removing it please notify to anthony.geay@cea.fr
 
-class MEDCouplingBasicsTest:
+class MEDCouplingBasicsTest(unittest.TestCase):
     def testArray2(self):
         arr=DataArrayDouble.New()
         arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4)
@@ -15882,7 +15882,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer())
         self.assertEqual([0, 0], c.getValues())
         self.assertEqual([-1, -1, 0, 1, -1, -1], d.getValues())
-#class MEDCouplingBasicsTest(unittest.TestCase):
+
     def testSwig2Intersect2DMeshWith1DLine11(self):
         """ Quad line re-entering a square cell """
         eps = 1.0e-8
@@ -15908,8 +15908,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertTrue(DataArrayInt([0,0,0]).isEqual(c))
         self.assertTrue(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(0,1),(-1,-1)]).isEqual(d))
         pass
-    
-class MEDCouplingBasicsTest2:
+
     def testSwig2Intersect2DMeshWith1DLine12(self):
         """ Two squares one in the other intersected by an horizontal line """
         eps = 1.0e-8
@@ -15924,27 +15923,21 @@ class MEDCouplingBasicsTest2:
         m_line = MEDCouplingUMesh.New("seg", 1)  
         m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2))
         m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2))
-#         m_line.writeVTK("/tmp/m1d_12.vtu")
-#         m.writeVTK("/tmp/m2d_12.vtu")
-        
+        m_line2 = m_line.deepCpy()
+        m2 = m.deepCpy()
         a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps)
-#         a.writeVTK("/tmp/m2d_fine_12.vtu")
-#         b.writeVTK("/tmp/m1d_fine_12.vtu")
-        
-        self.assertEqual([], a.getNodalConnectivity().getValues())
-        self.assertEqual([], a.getNodalConnectivityIndex().getValues())
-        self.assertEqual([], b.getNodalConnectivity().getValues())
-        self.assertEqual([], b.getNodalConnectivityIndex().getValues())
-        self.assertTrue(a.getCoords()[:8].isEqual(m.getCoords(),1e-12))
-        self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12))
-        coo_tgt = DataArrayDouble([])
-        self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt, 1.0e-12))
         self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer())
-        self.assertEqual([], c.getValues())
-        self.assertEqual([], d.getValues())
+        self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-0.5,-0.5),(-0.5,0.5),(0.5,0.5),(0.5,-0.5),(-0.25,-0.25),(-0.25,0.25),(0.25,0.25),(0.25,-0.25),(-1.0,0.25),(1.0,0.25),(-0.5,0.25),(0.5,0.25)]),1e-12))
+        self.assertEqual([5,4,5,6,7,5,1,5,10,5,4,0,10,5,5,5,1,2,11,6,5,3,0,4,7,6,11],a.getNodalConnectivity().getValues())
+        self.assertEqual([0,5,9,14,20,27],a.getNodalConnectivityIndex().getValues())
+        self.assertEqual([1,8,10,1,10,5,1,5,6,1,6,11,1,11,9],b.getNodalConnectivity().getValues())
+        self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues())
+        self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2])))
+        self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)])))
         pass
 
-    def testSwig2Intersect2DMeshWith1DLine13(self):
+#class MEDCouplingBasicsTest(unittest.TestCase):
+    def tessSwig2Intersect2DMeshWith1DLine13(self):
         """ A square (side length) in a circle intersected by a simple horizontal line """
         import math
         eps = 1.0e-8
@@ -15961,37 +15954,37 @@ class MEDCouplingBasicsTest2:
         m.checkCoherency()
         coords2 = [-2.0, 1.0, 2.0, 1.0]
         connec2, cI2 = [NORM_SEG2, 0, 1], [0,3]
-        m_line = MEDCouplingUMesh.New("seg", 1)  
+        m_line = MEDCouplingUMesh("seg", 1)  
         m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2))
         m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2))
-        m_line2 = m_line.deepCpy()
-        m2 = m.deepCpy()
-        m_line2.tessellate2DCurve(0.1)
-        m2.tessellate2D(0.05)
-        m_line2.writeVTK("/tmp/m1d_13.vtu")
-        m2.writeVTK("/tmp/m2d_13.vtu")
+        m_line2 = m_line.deepCpy()
+        m2 = m.deepCpy()
+        m_line2.tessellate2DCurve(0.1)
+        m2.tessellate2D(0.05)
+        m_line2.writeVTK("/tmp/m1d_13.vtu")
+        m2.writeVTK("/tmp/m2d_13.vtu")
         
         a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps)
 #         a.mergeNodes(1.0e-8)
-        a.tessellate2D(0.1)
-        b.tessellate2DCurve(0.1)
-        a.writeVTK("/tmp/m2d_fine_13.vtu")
-        b.writeVTK("/tmp/m1d_fine_13.vtu")
+        a.tessellate2D(0.1)
+        b.tessellate2DCurve(0.1)
+        a.writeVTK("/tmp/m2d_fine_13.vtu")
+        b.writeVTK("/tmp/m1d_fine_13.vtu")
         
-        self.assertEqual([], a.getNodalConnectivity().getValues())
-        self.assertEqual([], a.getNodalConnectivityIndex().getValues())
-        self.assertEqual([], b.getNodalConnectivity().getValues())
-        self.assertEqual([], b.getNodalConnectivityIndex().getValues())
-        self.assertTrue(a.getCoords()[:8].isEqual(m.getCoords(),1e-12))
-        self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12))
-        coo_tgt = DataArrayDouble([])
-        self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt, 1.0e-12))
-        self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer())
-        self.assertEqual([], c.getValues())
-        self.assertEqual([], d.getValues())
-        pass
-
-    def testSwig2Intersect2DMeshWith1DLine14(self):
+#        self.assertEqual([], a.getNodalConnectivity().getValues())
+#        self.assertEqual([], a.getNodalConnectivityIndex().getValues())
+#        self.assertEqual([], b.getNodalConnectivity().getValues())
+#        self.assertEqual([], b.getNodalConnectivityIndex().getValues())
+#        self.assertTrue(a.getCoords()[:8].isEqual(m.getCoords(),1e-12))
+#        self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12))
+#        coo_tgt = DataArrayDouble([])
+#        self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt, 1.0e-12))
+#        self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer())
+#        self.assertEqual([], c.getValues())
+#        self.assertEqual([], d.getValues())
+        pass
+
+    def tessSwig2Intersect2DMeshWith1DLine14(self):
         """ A circle in a circle intersected by a simple horizontal line, not tangent to the circles """
         eps = 1.0e-8
         m = MEDCouplingUMesh("boxcircle", 2)
index b78056bfb231b87ddf145d4a5f946c0b1dcee346..3866bfe1b405c2d86062db448ebe905b323a58a4 100644 (file)
@@ -1687,6 +1687,7 @@ namespace ParaMEDMEM
     DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception);
+    void changeOrientationOfCells() throw(INTERP_KERNEL::Exception);
     int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
index 911cb7a39a666c74833891b9b993b26057ba5b3a..a71654beed325b2db20486ae9a599b8cef2e2283 100644 (file)
@@ -73,6 +73,7 @@
 %newobject ParaMEDMEM::DataArrayInt::computeAbs;
 %newobject ParaMEDMEM::DataArrayInt::getIdsInRange;
 %newobject ParaMEDMEM::DataArrayInt::getIdsNotInRange;
+%newObject ParaMEDMEM::DataArrayInt::getIdsStrictlyNegative;
 %newobject ParaMEDMEM::DataArrayInt::Aggregate;
 %newobject ParaMEDMEM::DataArrayInt::AggregateIndexes;
 %newobject ParaMEDMEM::DataArrayInt::Meld;
@@ -2507,6 +2508,7 @@ namespace ParaMEDMEM
     void fillWithZero() throw(INTERP_KERNEL::Exception);
     void fillWithValue(int val) throw(INTERP_KERNEL::Exception);
     void iota(int init=0) throw(INTERP_KERNEL::Exception);
+    void replaceOneValByInThis(int valToBeReplaced, int replacedBy) throw(INTERP_KERNEL::Exception);
     std::string repr() const throw(INTERP_KERNEL::Exception);
     std::string reprZip() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const throw(INTERP_KERNEL::Exception);
@@ -2568,6 +2570,7 @@ namespace ParaMEDMEM
     void applyRPow(int val) throw(INTERP_KERNEL::Exception);
     DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *getIdsNotInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception);
+    DataArrayInt *getIdsStrictlyNegative() const throw(INTERP_KERNEL::Exception);
     bool checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception);
     static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) throw(INTERP_KERNEL::Exception);
     static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception);