Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/medcoupling
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
index b19c250b7601d6f513a291f02bfec95cc6ff463c..8a0293fd01c6bf82a4aa1a5d5358020414a45aa8 100644 (file)
@@ -404,7 +404,7 @@ MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator()
 
 /*!
  * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated.
- * If \a this is not so that that cells are grouped by geo types this method will throw an exception.
+ * If \a this is not so that the cells are grouped by geo types, this method will throw an exception.
  * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method.
  * Useful for python users.
  */
@@ -1706,7 +1706,7 @@ int MEDCouplingUMesh::AreCellsEqualPolicy7(const int *conn, const int *connI, in
  * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned.
  * \param [out] commonCellsArr common cells ids (\ref numbering-indirect)
  * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect)
- * \return the correspondance array old to new in a newly allocated array.
+ * \return the correspondence array old to new in a newly allocated array.
  * 
  */
 void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const
@@ -4629,8 +4629,9 @@ bool MEDCouplingUMesh::areOnlySimplexCells() const
 /*!
  * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler
  * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in
- * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method
- * does \b not perform geometrical checks and checks only nodal connectivity of cells,
+ * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell.
+ * Quadratic cells in 2D are also handled. In those cells edges where start=end=midpoint are removed.
+ * This method does \b not perform geometrical checks and checks only nodal connectivity of cells,
  * so it can be useful to call mergeNodes() before calling this method.
  *  \throw If \a this->getMeshDimension() <= 1.
  *  \throw If the coordinates array is not set.
@@ -4667,6 +4668,62 @@ void MEDCouplingUMesh::convertDegeneratedCells()
   computeTypes();
 }
 
+/*!
+ * Same as MEDCouplingUMesh::convertDegeneratedCells() plus deletion of the flat cells.
+ * A cell is flat in the following cases:
+ *   - for a linear cell, all points in the connectivity are equal
+ *   - for a quadratic cell, either the above, or a quadratic polygon with two (linear) points and two
+ *   identical quadratic points
+ * \return a new instance of DataArrayInt holding ids of removed cells. The caller is to delete
+ *      this array using decrRef() as it is no more needed.
+ */
+DataArrayInt *MEDCouplingUMesh::convertDegeneratedCellsAndRemoveFlatOnes()
+{
+  checkFullyDefined();
+  if(getMeshDimension()<=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
+  int nbOfCells=getNumberOfCells();
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  if(nbOfCells<1)
+    return ret;
+  int initMeshLgth=getNodalConnectivityArrayLen();
+  int *conn=_nodal_connec->getPointer();
+  int *index=_nodal_connec_index->getPointer();
+  int posOfCurCell=0;
+  int newPos=0;
+  int lgthOfCurCell, nbDelCells(0);
+  for(int i=0;i<nbOfCells;i++)
+    {
+      lgthOfCurCell=index[i+1]-posOfCurCell;
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+      int newLgth;
+      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
+                                                                                                     conn+newPos+1,newLgth);
+      // Shall we delete the cell if it is completely degenerated:
+      bool delCell=INTERP_KERNEL::CellSimplify::isFlatCell(conn, newPos, newLgth, newType);
+      if (delCell)
+        {
+          nbDelCells++;
+          ret->pushBackSilent(i);
+        }
+      else   //if the cell is to be deleted, simply stay at the same place
+        {
+          conn[newPos]=newType;
+          newPos+=newLgth+1;
+        }
+      posOfCurCell=index[i+1];
+      index[i+1-nbDelCells]=newPos;
+    }
+  if(newPos!=initMeshLgth)
+    _nodal_connec->reAlloc(newPos);
+  const int nCellDel=ret->getNumberOfTuples();
+  if (nCellDel)
+    _nodal_connec_index->reAlloc(nbOfCells-nCellDel+1);
+  computeTypes();
+  return ret.retn();
+}
+
+
 /*!
  * Finds incorrectly oriented cells of this 2D mesh in 3D space.
  * A cell is considered to be oriented correctly if an angle between its
@@ -5681,7 +5738,7 @@ DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<
  *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
  * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
  */
-void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const
+void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType, bool smartPflKiller) const
 {
   if(!profile)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !");
@@ -5723,7 +5780,7 @@ void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vec
       code[3*i]=(int)types[castId];
       code[3*i+1]=tmp3->getNumberOfTuples();
       MCAuto<DataArrayInt> tmp4=rankInsideCast->selectByTupleId(tmp3->begin(),tmp3->begin()+tmp3->getNumberOfTuples());
-      if(!tmp4->isIota(typeRangeVals[castId+1]-typeRangeVals[castId]))
+      if(!smartPflKiller || !tmp4->isIota(typeRangeVals[castId+1]-typeRangeVals[castId]))
         {
           tmp4->copyStringInfoFrom(*profile);
           idsPerType2.push_back(tmp4);
@@ -5928,7 +5985,7 @@ DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::Norma
 /*!
  * This method behaves exactly as MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec but the order is those defined in MED file spec.
  *
- * \return a new object containing the old to new correspondance.
+ * \return a new object containing the old to new correspondence.
  *
  * \sa MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec, MEDCouplingUMesh::sortCellsInMEDFileFrmt.
  */
@@ -5938,7 +5995,7 @@ DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const
 }
 
 /*!
- * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this.
+ * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specified by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this.
  * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells.
  * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs.
  * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same.
@@ -5957,7 +6014,7 @@ DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INT
  * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as
  * MEDCouplingUMesh::sortCellsInMEDFileFrmt.
  *
- * \return the array giving the correspondance old to new.
+ * \return the array giving the correspondence old to new.
  */
 DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes()
 {
@@ -6898,7 +6955,7 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<ME
 
 
 /*!
- * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [ \a begin , \a end ).
+ * This static operates only for coords in 3D. The polygon is specified by its connectivity nodes in [ \a begin , \a end ).
  */
 bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords)
 {
@@ -6942,7 +6999,7 @@ bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec
 }
 
 /*!
- * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ).
+ * The polyhedron is specified by its connectivity nodes in [ \a begin , \a end ).
  */
 bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords)
 {