From ce194b1f488313bca84e426a1725ccd2c0d83ce4 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 18 Jan 2016 12:14:36 +0100 Subject: [PATCH] MEDCouplingUMesh.tessellate2D - only one entry point now. --- .../doxygen/fakesources/MEDCouplingUMesh.C | 1 - src/MEDCoupling/MEDCouplingUMesh.cxx | 265 ++++++++++-------- src/MEDCoupling/MEDCouplingUMesh.hxx | 3 +- .../Test/MEDCouplingBasicsTest5.cxx | 2 +- .../MEDCouplingBasicsTest3.py | 2 +- src/MEDCoupling_Swig/MEDCouplingCommon.i | 1 - 6 files changed, 155 insertions(+), 119 deletions(-) diff --git a/doc/user/doxygen/fakesources/MEDCouplingUMesh.C b/doc/user/doxygen/fakesources/MEDCouplingUMesh.C index 443b632c7..e99a55189 100644 --- a/doc/user/doxygen/fakesources/MEDCouplingUMesh.C +++ b/doc/user/doxygen/fakesources/MEDCouplingUMesh.C @@ -178,7 +178,6 @@ MEDCouplingUMesh::isFullyQuadratic() const; MEDCouplingUMesh::isPresenceOfQuadratic() const; MEDCouplingUMesh::simplexize(int policy); MEDCouplingUMesh::tessellate2D(double eps); -MEDCouplingUMesh::tessellate2DCurve(double eps); ///@ /*! \name Others... */ diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index b852a63b3..7ba64d25a 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -5192,6 +5192,46 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType return ret.retn(); } +/*! + * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, + * so that the number of cells remains the same. Quadratic faces are converted to + * polygons. This method works only for 2D meshes in + * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, + * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of + * a polylinized edge constituting the input polygon. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 2. + */ +void MEDCouplingUMesh::tessellate2D(double eps) +{ + int meshDim(getMeshDimension()),spaceDim(getSpaceDimension()); + if(spaceDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D : works only with space dimension equal to 2 !"); + switch(meshDim) + { + case 1: + return tessellate2DCurveInternal(eps); + case 2: + return tessellate2DInternal(eps); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D : mesh dimension must be in [1,2] !"); + } +} +/*! + * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of + * a sub-divided edge. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 1. + * \throw If \a this->getSpaceDimension() != 2. + */ + #if 0 /*! * This method only works if \a this has spaceDimension equal to 2 and meshDimension also equal to 2. @@ -5473,120 +5513,6 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *& return ret.retn(); } -/*! - * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, - * so that the number of cells remains the same. Quadratic faces are converted to - * polygons. This method works only for 2D meshes in - * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, - * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of - * a polylinized edge constituting the input polygon. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2D(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); - revDesc1=0; revDescIndx1=0; - mDesc->tessellate2DCurve(eps); - subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer()); - setCoords(mDesc->getCoords()); -} - -/*! - * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of - * a sub-divided edge. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 1. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2DCurve(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=1 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10; - int nbCells=getNumberOfCells(); - int nbNodes=getNumberOfNodes(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coords=_coords->getConstPointer(); - std::vector addCoo; - std::vector newConn;//no direct DataArrayInt because interface with Geometric2D - MEDCouplingAutoRefCountObjectPtr newConnI(DataArrayInt::New()); - newConnI->alloc(nbCells+1,1); - int *newConnIPtr=newConnI->getPointer(); - *newConnIPtr=0; - int tmp1[3]; - INTERP_KERNEL::Node *tmp2[3]; - std::set types; - for(int i=0;itesselate(tmp1,nbNodes,epsa,newConn,addCoo); - types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]); - delete eac; - newConnIPtr[1]=(int)newConn.size(); - } - else - { - types.insert(INTERP_KERNEL::NORM_SEG2); - newConn.push_back(INTERP_KERNEL::NORM_SEG2); - newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - else - { - types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); - newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed - return ; - _types=types; - DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index); - MEDCouplingAutoRefCountObjectPtr newConnArr=DataArrayInt::New(); - newConnArr->alloc((int)newConn.size(),1); - std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer()); - DataArrayInt::SetArrayIn(newConnArr,_nodal_connec); - MEDCouplingAutoRefCountObjectPtr newCoords=DataArrayDouble::New(); - newCoords->alloc(nbNodes+((int)addCoo.size())/2,2); - double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer()); - std::copy(addCoo.begin(),addCoo.end(),work); - DataArrayDouble::SetArrayIn(newCoords,_coords); - updateTime(); -} - /*! * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D). * In addition, returns an array mapping new cells to old ones.
@@ -5872,6 +5798,117 @@ DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() return ret.retn(); } +/*! + * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, + * so that the number of cells remains the same. Quadratic faces are converted to + * polygons. This method works only for 2D meshes in + * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, + * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of + * a polylinized edge constituting the input polygon. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 2. + */ +void MEDCouplingUMesh::tessellate2DInternal(double eps) +{ + checkFullyDefined(); + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!"); + double epsa=fabs(eps); + if(epsa::min()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DInternal : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); + MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr mDesc(buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1)); + revDesc1=0; revDescIndx1=0; + mDesc->tessellate2D(eps); + subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer()); + setCoords(mDesc->getCoords()); +} + +/*! + * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of + * a sub-divided edge. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 1. + * \throw If \a this->getSpaceDimension() != 2. + */ +void MEDCouplingUMesh::tessellate2DCurveInternal(double eps) +{ + checkFullyDefined(); + if(getMeshDimension()!=1 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurveInternal works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!"); + double epsa=fabs(eps); + if(epsa::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::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10; + int nbCells=getNumberOfCells(); + int nbNodes=getNumberOfNodes(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coords=_coords->getConstPointer(); + std::vector addCoo; + std::vector newConn;//no direct DataArrayInt because interface with Geometric2D + MEDCouplingAutoRefCountObjectPtr newConnI(DataArrayInt::New()); + newConnI->alloc(nbCells+1,1); + int *newConnIPtr=newConnI->getPointer(); + *newConnIPtr=0; + int tmp1[3]; + INTERP_KERNEL::Node *tmp2[3]; + std::set types; + for(int i=0;itesselate(tmp1,nbNodes,epsa,newConn,addCoo); + types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]); + delete eac; + newConnIPtr[1]=(int)newConn.size(); + } + else + { + types.insert(INTERP_KERNEL::NORM_SEG2); + newConn.push_back(INTERP_KERNEL::NORM_SEG2); + newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3); + newConnIPtr[1]=newConnIPtr[0]+3; + } + } + else + { + types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]); + newConnIPtr[1]=newConnIPtr[0]+3; + } + } + if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed + return ; + _types=types; + DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index); + MEDCouplingAutoRefCountObjectPtr newConnArr=DataArrayInt::New(); + newConnArr->alloc((int)newConn.size(),1); + std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer()); + DataArrayInt::SetArrayIn(newConnArr,_nodal_connec); + MEDCouplingAutoRefCountObjectPtr newCoords=DataArrayDouble::New(); + newCoords->alloc(nbNodes+((int)addCoo.size())/2,2); + double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer()); + std::copy(addCoo.begin(),addCoo.end(),work); + DataArrayDouble::SetArrayIn(newCoords,_coords); + updateTime(); +} + /*! * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown. * This method completly ignore coordinates. diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 5e81aff3a..d1e94f506 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -181,7 +181,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear(); MEDCOUPLING_EXPORT DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0); MEDCOUPLING_EXPORT void tessellate2D(double eps); - MEDCOUPLING_EXPORT void tessellate2DCurve(double eps); MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const; MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); MEDCOUPLING_EXPORT bool areOnlySimplexCells() const; @@ -287,6 +286,8 @@ namespace ParaMEDMEM DataArrayInt *simplexizePol1(); DataArrayInt *simplexizePlanarFace5(); DataArrayInt *simplexizePlanarFace6(); + void tessellate2DInternal(double eps); + void tessellate2DCurveInternal(double eps); void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx index 2c855155e..cc222a024 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -102,7 +102,7 @@ void MEDCouplingBasicsTest5::testUMeshTessellate2DCurve1() myCoords->decrRef(); MEDCouplingUMesh *m2 = static_cast(m1->deepCpy()); - m2->tessellate2DCurve(0.1); + m2->tessellate2D(0.1); CPPUNIT_ASSERT_NO_THROW(m2->checkCoherency1(0.0)); // eps param not used m1->decrRef(); m2->decrRef(); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py index 30cbabe01..4e015d958 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py @@ -2505,7 +2505,7 @@ class MEDCouplingBasicsTest3(unittest.TestCase): m1.setCoords(myCoords) m2 = m1.deepCpy() - m2.tessellate2DCurve(0.1) + m2.tessellate2D(0.1) # If the following raises, the test will fail automatically: m2.checkCoherency1(0.0) # eps param not used diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 6a6f64d0e..41372aaec 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -1792,7 +1792,6 @@ namespace ParaMEDMEM MEDCouplingFieldDouble *buildDirectionVectorField() const throw(INTERP_KERNEL::Exception); bool isContiguous1D() const throw(INTERP_KERNEL::Exception); void tessellate2D(double eps) throw(INTERP_KERNEL::Exception); - void tessellate2DCurve(double eps) throw(INTERP_KERNEL::Exception); void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0) throw(INTERP_KERNEL::Exception); void convertDegeneratedCells() throw(INTERP_KERNEL::Exception); -- 2.30.2