Salome HOME
Attempt of Management of profiles in spliter
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh_internal.cxx
index d955503df85cf7aee44e1fdff610f5a187f7b90e..37640b535fdcf95e0e52809e6874bb19207f5e96 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -348,7 +348,7 @@ void MEDCouplingUMesh::tessellate2DCurveInternal(double eps)
   double epsa=fabs(eps);
   if(epsa<std::numeric_limits<double>::min())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
-  INTERP_KERNEL::QuadraticPlanarArcDetectionPrecision arcPrec(1.e-10);  // RAII
+  INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1.e-10);  // RAII
   int nbCells=getNumberOfCells();
   int nbNodes=getNumberOfNodes();
   const int *conn=_nodal_connec->begin();
@@ -898,9 +898,9 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin
       connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork);
     }
   MCAuto<DataArrayInt> connRetArr=DataArrayInt::New();
-  connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1);
+  connRetArr->useArray(connRet,true,DeallocType::C_DEALLOC,connIndexRet[nbOfElemsRet],1);
   MCAuto<DataArrayInt> connIndexRetArr=DataArrayInt::New();
-  connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1);
+  connIndexRetArr->useArray(connIndexRet,true,DeallocType::C_DEALLOC,(int)nbOfElemsRet+1,1);
   ret->setConnectivity(connRetArr,connIndexRetArr,false);
   ret->_types=types;
   ret->copyTinyInfoFrom(this);
@@ -972,7 +972,7 @@ int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNE
 
 
 /*!
- * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * Implements \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
  * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
  * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
  */
@@ -1060,7 +1060,7 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDC
 }
 
 /*!
- * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * Implements \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
  * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
  * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
  */
@@ -1124,7 +1124,7 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&
 }
 
 /*!
- * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * Implements \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
  * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
  * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
  */
@@ -1754,3 +1754,84 @@ void MEDCouplingUMesh::ComputeAllTypesInternal(std::set<INTERP_KERNEL::Normalize
           types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
     }
 }
+
+/*!
+ * This method expects that \a this a quadratic 1D, 2D or 3D mesh.
+ * This method will 'attract' middle points of seg3 (deduced from this by explosion if needed) of cells connected to nodes specified in [\a nodeIdsBg, \a nodeIdsEnd )
+ * For those selected mid points, their coordinates will be modified by applying a dilation between node in input [\a nodeIdsBg, \a nodeIdsEnd ) and the corresponding mid points using \a ratio input value.
+ * So this method is non const because coordinates are modified.
+ * If there is a couple of 2 points in [\a nodeIdsBg, \a nodeIdsEnd ) that are boundaries of a seg3, the corresponding mid point will remain untouched.
+ *
+ * \param [in] ratio - ratio of dilation
+ * \param [in] nodeIdsBg - start (included) of input node list
+ * \param [in] nodeIdsEnd - end (excluded) of input node list
+ * \throw if there is a point in [\a nodeIdsBg, \a nodeIdsEnd ) that is a mid point of a seg3
+ * \warning in case of throw the coordinates may be partially modified before the exception arises
+ */
+void MEDCouplingUMesh::attractSeg3MidPtsAroundNodes(double ratio, const int *nodeIdsBg, const int *nodeIdsEnd)
+{
+  checkFullyDefined();
+  int mdim(getMeshDimension());
+  if(mdim==2 || mdim==3)
+    {
+      MCAuto<MEDCouplingUMesh> edges;
+      {
+        MCAuto<DataArrayInt> a,b,c,d;
+        edges=this->explodeIntoEdges(a,b,c,d);
+      }
+      return edges->attractSeg3MidPtsAroundNodesUnderground(ratio,nodeIdsBg,nodeIdsEnd);
+    }
+  if(mdim==1)
+    return attractSeg3MidPtsAroundNodesUnderground(ratio,nodeIdsBg,nodeIdsEnd);
+  throw INTERP_KERNEL::Exception("MEDCouplingUMesh::attractSeg3MidPtsAroundNodes : not managed dimension ! Should be in [1,2,3] !");
+}
+
+/*!
+ * \a this is expected to have meshdim==1.
+ */
+void MEDCouplingUMesh::attractSeg3MidPtsAroundNodesUnderground(double ratio, const int *nodeIdsBg, const int *nodeIdsEnd)
+{
+  int spaceDim(getSpaceDimension());
+  double *coords(getCoords()->getPointer());
+  auto nbNodes(getNumberOfNodes());
+  auto nbCells(getNumberOfCells());
+  std::vector<bool> fastFinder(nbNodes,false);
+  for(auto work=nodeIdsBg;work!=nodeIdsEnd;work++)
+    if(*work>=0 && *work<nbNodes)
+      fastFinder[*work]=true;
+  MCAuto<DataArrayInt> cellsIds(getCellIdsLyingOnNodes(nodeIdsBg,nodeIdsEnd,false));
+  const int *nc(_nodal_connec->begin()),*nci(_nodal_connec_index->begin());
+  for(auto cellId=0;cellId<nbCells;cellId++,nci++)
+    {
+      const int *isSelected(std::find_if(nc+nci[0]+1,nc+nci[1],[&fastFinder](int v) { return fastFinder[v]; }));
+      if(isSelected!=nc+nci[1])
+        {
+          if((INTERP_KERNEL::NormalizedCellType)nc[nci[0]]==INTERP_KERNEL::NORM_SEG3 && nci[1]-nci[0]==4)
+            {
+              bool aa(fastFinder[nc[*nci+1]]),bb(fastFinder[nc[*nci+2]]),cc(fastFinder[nc[*nci+3]]);
+              if(!cc)
+                {
+                  if(aa^bb)
+                    {
+                      auto ptToMove(nc[*nci+3]);
+                      auto attractor(aa?nc[*nci+1]:nc[*nci+2]),endPt(aa?nc[*nci+2]:nc[*nci+1]);
+                      std::transform(coords+spaceDim*attractor,coords+spaceDim*(attractor+1),coords+spaceDim*endPt,
+                                     coords+spaceDim*ptToMove,[ratio](const double& stPt, const double& endPt) { return stPt+ratio*(endPt-stPt); });
+                    }
+                  else
+                    continue;//both 2 boundary nodes of current seg3 are un nodeIds input list -> skip it.
+                }
+              else
+                {
+                  std::ostringstream oss; oss << "MEDCouplingUMesh::attractSeg3MidPtsAroundNodes : cell #" << cellId << " has a mid point " << nc[*nci+3] << " ! This node is in input list !";
+                  throw INTERP_KERNEL::Exception(oss.str());
+                }
+            }
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::attractSeg3MidPtsAroundNodes : cell #" << cellId << " sharing one of the input nodes list its geo type is NOT SEG3 !";
+              throw INTERP_KERNEL::Exception(oss.str());
+            }
+        }
+    }
+}