From: Anthony Geay Date: Wed, 10 Aug 2016 15:12:12 +0000 (+0200) Subject: new functionality MEDCouplingUMesh.explodeMeshIntoMicroEdges X-Git-Tag: V8_1_0b1~2^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c6793ce3738701fff515da97187fecb4bd018afb;p=tools%2Fmedcoupling.git new functionality MEDCouplingUMesh.explodeMeshIntoMicroEdges --- diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx index bd676e424..9632fb1ce 100644 --- a/src/INTERP_KERNEL/CellModel.cxx +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -452,6 +452,28 @@ namespace INTERP_KERNEL return (lgth-std::count(conn,conn+lgth,-1))/2; } + /*! + * \sa fillMicroEdgeNodalConnectivity + */ + unsigned CellModel::getNumberOfMicroEdges() const + { + unsigned mul(isQuadratic()?2:1); + if(!isDynamic()) + { + switch(getDimension()) + { + case 2: + return mul*getNumberOfSons(); + case 3: + return mul*_nb_of_little_sons; + default: + throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : only 2D and 3D cells support this !"); + } + } + else + throw INTERP_KERNEL::Exception("CellModel::getNumberOfMacroEdges : not supported by dynamic type !"); + } + NormalizedCellType CellModel::getCorrespondingPolyType() const { switch(getDimension()) @@ -592,6 +614,50 @@ namespace INTERP_KERNEL throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !"); } + /*! + * \sa getNumberOfMicroEdges + */ + unsigned CellModel::fillMicroEdgeNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn, NormalizedCellType& typeOfSon) const + { + if(isQuadratic()) + { + int edgeId(sonId/2),subEdgeId(sonId%2); + typeOfSon=NORM_SEG2; + const unsigned *sonConn(0); + switch(getDimension()) + { + case 2: + { + sonConn=_sons_con[edgeId]; + break; + } + case 3: + { + sonConn=_little_sons_con[edgeId]; + break; + } + default: + throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this !"); + } + const unsigned tmp[3]={sonConn[0],sonConn[2],sonConn[1]}; + sonNodalConn[0]=nodalConn[tmp[subEdgeId]]; + sonNodalConn[1]=nodalConn[tmp[subEdgeId+1]]; + return 2; + } + else + { + switch(getDimension()) + { + case 2: + return fillSonCellNodalConnectivity2(sonId,nodalConn,0,sonNodalConn,typeOfSon); + case 3: + return fillSonEdgesNodalConnectivity3D(sonId,nodalConn,0,sonNodalConn,typeOfSon); + default: + throw INTERP_KERNEL::Exception("CellModel::fillMicroEdgeNodalConnectivity : only 2D and 3D cells support this #2 !"); + } + } + } + void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const { if(sz<1) diff --git a/src/INTERP_KERNEL/CellModel.hxx b/src/INTERP_KERNEL/CellModel.hxx index 59cfb6e4d..9da0f7d22 100644 --- a/src/INTERP_KERNEL/CellModel.hxx +++ b/src/INTERP_KERNEL/CellModel.hxx @@ -60,6 +60,7 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT unsigned getNumberOfSons() const { return _nb_of_sons; } INTERPKERNEL_EXPORT unsigned getNumberOfSons2(const int *conn, int lgth) const; INTERPKERNEL_EXPORT unsigned getNumberOfEdgesIn3D(const int *conn, int lgth) const; + INTERPKERNEL_EXPORT unsigned getNumberOfMicroEdges() const; INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; } INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const; INTERPKERNEL_EXPORT NormalizedCellType getExtrudedType() const { return _extruded_type; } @@ -74,6 +75,7 @@ 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 unsigned fillMicroEdgeNodalConnectivity(int sonId, const int *nodalConn, 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; INTERPKERNEL_EXPORT DiameterCalculator *buildInstanceOfDiameterCalulator(int spaceDim) const; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index e41149f6b..f7f960cec 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -674,6 +674,28 @@ private: const INTERP_KERNEL::CellModel& _cm; }; +class MicroEdgesGenerator2D +{ +public: + MicroEdgesGenerator2D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } + unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); } + unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); } + static const int DELTA=1; +private: + const INTERP_KERNEL::CellModel& _cm; +}; + +class MicroEdgesGenerator3D +{ +public: + MicroEdgesGenerator3D(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } + unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfMicroEdges(); } + unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillMicroEdgeNodalConnectivity(sonId,nodalConn,sonNodalConn,typeOfSon); } + static const int DELTA=2; +private: + const INTERP_KERNEL::CellModel& _cm; +}; + /// @endcond /*! @@ -740,6 +762,26 @@ MEDCouplingUMesh *MEDCouplingUMesh::explode3DMeshTo1D(DataArrayInt *desc, DataAr return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); } +/*! + * This method computes the micro edges constituting each cell in \a this. Micro edge is an edge for non quadratic cells. Micro edge is an half edge for quadratic cells. + * This method works for both meshes with mesh dimenstion equal to 2 or 3. Dynamical cells are not supported (polygons, polyhedrons...) + * + * \sa explode3DMeshTo1D, buildDescendingConnectiviy + */ +MEDCouplingUMesh *MEDCouplingUMesh::explodeMeshIntoMicroEdges(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const +{ + checkFullyDefined(); + switch(getMeshDimension()) + { + case 2: + return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); + case 3: + return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::explodeMeshIntoMicroEdges : Only 2D and 3D supported !"); + } +} + /*! * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a * this->getMeshDimension(), that bound cells of \a this mesh. In diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index e43203028..68093553c 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -123,6 +123,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *explodeMeshIntoMicroEdges(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py index 5722fee79..534079086 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py @@ -4307,7 +4307,32 @@ class MEDCouplingBasicsTest5(unittest.TestCase): m.setNodalConnectivity(DataArrayInt([]),DataArrayInt([0])) m=m.buildUnstructured() pass - + + def testExplodeMeshIntoMicroEdges1(self): + """ test for new functionality MEDCouplingUMesh.explodeMeshIntoMicroEdges""" + m=MEDCouplingUMesh("mesh",2) + coo=DataArrayDouble([2,0,10,0,12,0,0,3,4,5,10,5,12,7,3,2.5,7,2.5,6,0,10,2.5,11,2.5,11,0,7,5],14,2) + m.setCoords(coo) + m.allocateCells() + # here a mix of quadratic, linear cells. Non conform but conform considering micro edges + m.insertNextCell(NORM_TRI6,[0,4,1,7,8,9]) + m.insertNextCell(NORM_TRI6,[1,5,2,10,11,12]) + m.insertNextCell(NORM_TRI6,[5,1,4,10,8,13]) + m.insertNextCell(NORM_TRI3,[3,4,7]) + m.insertNextCell(NORM_TRI3,[3,7,0]) + m.insertNextCell(NORM_TRI3,[6,2,11]) + m.insertNextCell(NORM_TRI3,[6,11,5]) + m.insertNextCell(NORM_TRI3,[6,5,13]) + m.insertNextCell(NORM_TRI3,[6,13,4]) + edges,d,di,rd,rdi=m.explodeMeshIntoMicroEdges() # <- new method + self.assertTrue(MEDCoupling1SGTUMesh(edges).getNodalConnectivity().isEqual(DataArrayInt([0,7,7,4,4,8,8,1,1,9,9,0,1,10,10,5,5,11,11,2,2,12,12,1,4,13,13,5,3,4,7,3,0,3,6,2,11,6,5,6,13,6,4,6]))) + self.assertEqual(edges.getCoords().getHiddenCppPointer(),coo.getHiddenCppPointer()) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,7,6,3,2,12,13,14,1,15,15,0,16,17,9,18,18,8,19,19,13,20,20,12,21]))) + self.assertTrue(di.isEqual(DataArrayInt([0,6,12,18,21,24,27,30,33,36]))) + self.assertTrue(rd.isEqual(DataArrayInt([0,4,0,3,0,2,0,2,0,0,1,2,1,2,1,6,1,5,1,1,2,8,2,7,3,3,4,4,5,5,6,6,7,7,8,8]))) + self.assertTrue(rdi.isEqual(DataArrayInt([0,2,4,6,8,9,10,12,14,16,18,19,20,22,24,25,27,28,29,31,33,35,36]))) + pass + pass if __name__ == '__main__': diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index eaaa5eb64..bcd478112 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -279,6 +279,7 @@ using namespace INTERP_KERNEL; %newobject MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity; %newobject MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity2; %newobject MEDCoupling::MEDCouplingUMesh::explode3DMeshTo1D; +%newobject MEDCoupling::MEDCouplingUMesh::explodeMeshIntoMicroEdges; %newobject MEDCoupling::MEDCouplingUMesh::buildExtrudedMesh; %newobject MEDCoupling::MEDCouplingUMesh::buildSpreadZonesWithPoly; %newobject MEDCoupling::MEDCouplingUMesh::MergeUMeshes; @@ -1788,6 +1789,7 @@ namespace MEDCoupling MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *explodeMeshIntoMicroEdges(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception); bool isPresenceOfQuadratic() const throw(INTERP_KERNEL::Exception); bool isFullyQuadratic() const throw(INTERP_KERNEL::Exception); @@ -2540,6 +2542,22 @@ namespace MEDCoupling return ret; } + PyObject *explodeMeshIntoMicroEdges() const throw(INTERP_KERNEL::Exception) + { + MCAuto d0=DataArrayInt::New(); + MCAuto d1=DataArrayInt::New(); + MCAuto d2=DataArrayInt::New(); + MCAuto d3=DataArrayInt::New(); + MEDCouplingUMesh *m=self->explodeMeshIntoMicroEdges(d0,d1,d2,d3); + PyObject *ret=PyTuple_New(5); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_MEDCoupling__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_MEDCoupling__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + PyObject *buildDescendingConnectivity() const throw(INTERP_KERNEL::Exception) { MCAuto d0=DataArrayInt::New();