From c53c5fda2d7ba3b31002f56cff5e64282ed986ab Mon Sep 17 00:00:00 2001 From: geay Date: Wed, 26 Feb 2014 10:18:48 +0100 Subject: [PATCH] MEDCouplingUMesh::buildSpreadZonesWithPoly manages now quadratic polygons --- src/MEDCoupling/MEDCouplingUMesh.cxx | 114 +++++++++++++----- src/MEDCoupling/MEDCouplingUMesh.hxx | 2 + src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 23 ++++ 3 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index f2776bb34..2d46d5cfa 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -8252,34 +8252,20 @@ void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, c } } -/*! - * This method makes the assumption spacedimension == meshdimension == 2. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const { - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr m=computeSkin(); - MEDCouplingAutoRefCountObjectPtr o2n=m->zipCoordsTraducer(); - int nbOfNodesExpected=m->getNumberOfNodes(); - if(m->getNumberOfCells()!=nbOfNodesExpected) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part or a quadratic 2D mesh !"); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(m->getNumberOfNodes()); - const int *n2oPtr=n2o->getConstPointer(); + int nbOfNodesExpected(skin->getNumberOfNodes()); + const int *n2oPtr(n2o->getConstPointer()); MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - m->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); - const int *nodalPtr=m->getNodalConnectivity()->getConstPointer(); - const int *nodalIPtr=m->getNodalConnectivityIndex()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1); - int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYGON; + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_POLYGON; if(nbOfNodesExpected<1) return ret.retn(); - int prevCell=0; - int prevNode=nodalPtr[nodalIPtr[0]+1]; + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); *work++=n2oPtr[prevNode]; for(int i=1;i shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); shar.erase(prevCell); @@ -8299,17 +8285,89 @@ DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const prevNode=curNode; } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 2 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !"); } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 1 !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !"); } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !"); } return ret.retn(); } +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const +{ + int nbOfNodesExpected(skin->getNumberOfNodes()); + int nbOfTurn(nbOfNodesExpected/2); + const int *n2oPtr(n2o->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_QPOLYG; + if(nbOfNodesExpected<1) + return ret.retn(); + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); + *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++; + for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); + conn.erase(prevNode); + if(conn.size()==1) + { + int curNode(*(conn.begin())); + *work=n2oPtr[curNode]; + std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); + shar.erase(prevCell); + if(shar.size()==1) + { + int curCell(*(shar.begin())); + work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]]; + prevCell=curCell; + prevNode=curNode; + work++; + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !"); + } + return ret.retn(); +} + +/*! + * This method makes the assumption spacedimension == meshdimension == 2. + * This method works only for linear cells. + * + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) + */ +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr skin(computeSkin()); + int oldNbOfNodes(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr o2n(skin->zipCoordsTraducer()); + int nbOfNodesExpected(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes)); + int nbCells(skin->getNumberOfCells()); + if(nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshLinear(skin,n2o); + else if(2*nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshQuadratic(skin,n2o); + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !"); +} + /*! * This method makes the assumption spacedimension == meshdimension == 3. * This method works only for linear cells. diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 2ddc06b40..df10fbb49 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -288,6 +288,8 @@ namespace ParaMEDMEM DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; + DataArrayInt *buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; + DataArrayInt *buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 0c2764cec..8435e49a5 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -14260,6 +14260,29 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertEqual(c.getSpaceDimension(),1) pass + def testSwig2BuildSpreadZonesWithPolyOnQPolyg1(self): + nx=6 + ny=6 + m=MEDCouplingCMesh() + arr1=DataArrayDouble(nx) ; arr1.iota() + arr2=DataArrayDouble(ny) ; arr2.iota() + m.setCoords(arr1,arr2) + m=m.buildUnstructured() + da=DataArrayInt.Range(nx-1,(nx-1)*(ny-1),nx) + m2=m[da] ; m2.simplexize(0) + dan=da.buildComplement(m.getNumberOfCells()) + m1=m[dan] + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + # + m.convertLinearCellsToQuadratic() + m1=m[::2] ; m2=m[1::2] ; m2.convertAllToPoly() + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + p=m.buildSpreadZonesWithPoly() + self.assertTrue(p.getNodalConnectivity().isEqual(DataArrayInt([32,1,0,6,12,18,24,30,31,32,33,34,35,29,23,17,11,5,4,3,2,36,37,94,62,72,83,84,86,89,99,92,93,82,71,60,51,49,46,43,40]))) + self.assertTrue(p.getNodalConnectivityIndex().isEqual(DataArrayInt([0,41]))) + self.assertTrue(p.getCoords().isEqual(DataArrayDouble([0.,0.,1.,0.,2.,0.,3.,0.,4.,0.,5.,0.,0.,1.,1.,1.,2.,1.,3.,1.,4.,1.,5.,1.,0.,2.,1.,2.,2.,2.,3.,2.,4.,2.,5.,2.,0.,3.,1.,3.,2.,3.,3.,3.,4.,3.,5.,3.,0.,4.,1.,4.,2.,4.,3.,4.,4.,4.,5.,4.,0.,5.,1.,5.,2.,5.,3.,5.,4.,5.,5.,5.,0.5,0.,0.,0.5,0.5,1.,1.,0.5,1.5,0.,1.5,1.,2.,0.5,2.5,0.,2.5,1.,3.,0.5,3.5,0.,3.5,1.,4.,0.5,4.5,0.,4.5,1.,5.,0.5,1.,1.5,1.5,2.,2.,1.5,2.5,2.,3.,1.5,3.5,2.,4.,1.5,4.5,2.,5.,1.5,0.5,2.,0.,2.5,0.5,3.,1.,2.5,2.,2.5,2.5,3.,3.,2.5,3.5,3.,4.,2.5,4.5,3.,5.,2.5,0.,3.5,0.5,4.,1.,3.5,1.5,3.,1.5,4.,2.,3.5,3.,3.5,3.5,4.,4.,3.5,4.5,4.,5.,3.5,0.,4.5,0.5,5.,1.,4.5,1.5,5.,2.,4.5,2.5,4.,2.5,5.,3.,4.5,4.,4.5,4.5,5.,5.,4.5,0.,1.5,0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,3.5,5.0],100,2),1e-13)) + pass + def setUp(self): pass pass -- 2.39.2