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())
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)
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; }
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;
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
/*!
return buildDescendingConnectivityGen<MinusTwoSonsGenerator>(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<MicroEdgesGenerator2D>(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer);
+ case 3:
+ return buildDescendingConnectivityGen<MicroEdgesGenerator2D>(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
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);
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__':
%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;
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);
return ret;
}
+ PyObject *explodeMeshIntoMicroEdges() const throw(INTERP_KERNEL::Exception)
+ {
+ MCAuto<DataArrayInt> d0=DataArrayInt::New();
+ MCAuto<DataArrayInt> d1=DataArrayInt::New();
+ MCAuto<DataArrayInt> d2=DataArrayInt::New();
+ MCAuto<DataArrayInt> 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<DataArrayInt> d0=DataArrayInt::New();