From 7d0c614b5a6f6721a09b2c59ef00b84f602a83a8 Mon Sep 17 00:00:00 2001 From: ageay Date: Fri, 15 Jun 2012 08:43:17 +0000 Subject: [PATCH] Implementation of MEDCouplingUMesh::partitionBySpreadZone --- src/MEDCoupling/MEDCouplingUMesh.cxx | 60 +++++++++++++++++++++++++++- src/MEDCoupling/MEDCouplingUMesh.hxx | 3 +- src/MEDCoupling_Swig/MEDCoupling.i | 12 ++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 992c2aa0d..0e7a57a25 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -6746,10 +6746,66 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *a } /*! - * Given a 2D mesh conn by (conn2D,connI2D) it returns a single polygon + * \b this is expected to be a mesh fully defined whose spaceDim==meshDim. + * It returns a new allocated mesh having the same mesh dimension and lying on same coordinates. + * The returned mesh contains as poly cells as number of contiguous zone (regarding connectivity). + * A spread contiguous zone is built using poly cells (polyhedra in 3D, polygons in 2D and polyline in 1D). + * The sum of measure field of returned mesh is equal to the sum of measure field of this. + * + * \return a newly allocated mesh lying on the same coords than \b this with same meshdimension than \b this. */ -void MEDCouplingUMesh::BuildUnionOf2DMesh(const std::vector& conn2D, const std::vector& connI2D, std::vector& polyUnion) +MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception) { + checkFullyDefined(); + int mdim=getMeshDimension(); + int nbCells=getNumberOfCells(); + std::vector partition=partitionBySpreadZone(); + std::vector< MEDCouplingAutoRefCountObjectPtr > partitionAuto; partitionAuto.reserve(partition.size()); + std::copy(partition.begin(),partition.end(),std::back_insert_iterator > >(partitionAuto)); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); + ret->setCoords(getCoords()); + ret->allocateCells((int)partition.size()); + // + throw INTERP_KERNEL::Exception("Implementation not finished yet !"); + // + ret->finishInsertingCells(); + ret->incrRef(); return ret; +} + +/*! + * This method partitions \b this into contiguous zone. + * This method only needs a well defined connectivity. Coordinates are not considered here. + * This method returns a vector of \b newly allocated arrays that the caller has to deal with. + */ +std::vector MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception) +{ + int nbOfCellsCur=getNumberOfCells(); + DataArrayInt *neigh=0,*neighI=0; + computeNeighborsOfCells(neigh,neighI); + MEDCouplingAutoRefCountObjectPtr neighAuto(neigh),neighIAuto(neighI); + MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(nbOfCellsCur,1); ids->iota(); + std::vector ret; + std::vector< MEDCouplingAutoRefCountObjectPtr > ret2; + while(nbOfCellsCur>0) + { + MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::ComputeSpreadZoneGradually(neighAuto,neighIAuto); + MEDCouplingAutoRefCountObjectPtr tmp3=tmp->buildComplement(nbOfCellsCur); + MEDCouplingAutoRefCountObjectPtr tmp2=ids->selectByTupleId(tmp->begin(),tmp->end()); + ret2.push_back(tmp2); ret.push_back(tmp2); + nbOfCellsCur=tmp3->getNumberOfTuples(); + if(nbOfCellsCur>0) + { + ids=ids->selectByTupleId(tmp3->begin(),tmp3->end()); + MEDCouplingUMesh::ExtractFromIndexedArrays(tmp3->begin(),tmp3->end(),neighAuto,neighIAuto,neigh,neighI); + neighAuto=neigh; + neighIAuto=neighI; + MEDCouplingAutoRefCountObjectPtr renum=tmp3->invertArrayN2O2O2N(nbOfCellsCur+tmp->getNumberOfTuples()); + neighAuto->transformWithIndArr(renum->begin(),renum->end()); + } + } + for(std::vector::const_iterator it=ret.begin();it!=ret.end();it++) + (*it)->incrRef(); + return ret; } MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index dd2453769..7d5223e65 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -98,6 +98,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void convertAllToPoly(); MEDCOUPLING_EXPORT void convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void unPolyze(); + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::vector partitionBySpreadZone() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); @@ -256,7 +258,6 @@ namespace ParaMEDMEM const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector >& intesctEdges2, const std::vector& addCoords, std::vector& addCoordsQuadratic, std::vector& cr, std::vector& crI, std::vector& cNb1, std::vector& cNb2); - static void BuildUnionOf2DMesh(const std::vector& conn2D, const std::vector& connI2D, std::vector& polyUnion); static void AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, const int *nodal3DCurve, const int *nodalIndx3DCurve, const int *desc, const int *descIndx, std::vector< std::pair >& cut3DSurf) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i index a017be40e..69b26c452 100644 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ b/src/MEDCoupling_Swig/MEDCoupling.i @@ -252,6 +252,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; %newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2; %newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildSpreadZonesWithPoly; %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes; %newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords; %newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; @@ -1323,6 +1324,16 @@ namespace ParaMEDMEM return ret; } + PyObject *partitionBySpreadZone() const throw(INTERP_KERNEL::Exception) + { + std::vector retCpp=self->partitionBySpreadZone(); + int sz=retCpp.size(); + PyObject *ret=PyList_New(sz); + for(int i=0;i