X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingUMesh.cxx;h=d594c82ab143ee3afe9f3fe8cdb16bf1dce804e0;hb=5f64369e27eb852fd111d1ccdd17a9d583fe8473;hp=6772aafafcf5162e8f05a55618b3d2b72e35dc4e;hpb=de8da643a7f441fb2154818cde04b7b24ca76bb4;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 6772aafaf..d594c82ab 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -19,6 +19,7 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingUMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" #include "MEDCouplingMemArray.txx" #include "MEDCouplingFieldDouble.hxx" #include "CellModel.hxx" @@ -88,6 +89,33 @@ MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const return new MEDCouplingUMesh(*this,recDeepCpy); } +/*! + * This method behaves mostly like MEDCouplingUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. + * The coordinates are shared between \a this and the returned instance. + * + * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) + * \sa MEDCouplingUMesh::deepCpy + */ +MEDCouplingPointSet *MEDCouplingUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + MEDCouplingAutoRefCountObjectPtr ret=clone(false); + MEDCouplingAutoRefCountObjectPtr c(getNodalConnectivity()->deepCpy()),ci(getNodalConnectivityIndex()->deepCpy()); + ret->setConnectivity(c,ci); + return ret.retn(); +} + +void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !"); + MEDCouplingUMesh *otherC2=const_cast(otherC);//sorry :( + setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true); +} + std::size_t MEDCouplingUMesh::getHeapMemorySize() const { std::size_t ret=0; @@ -150,6 +178,9 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !"); if(_nodal_connec_index) { if(_nodal_connec_index->getNumberOfComponents()!=1) @@ -157,6 +188,9 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) if(_nodal_connec_index->getInfoOnComponent(0)!="") throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !"); } /*! @@ -268,14 +302,19 @@ void MEDCouplingUMesh::setMeshDimension(int meshDim) } /*! - * Allocates memory to store given number of cells. - * \param [in] nbOfCells - number of cell \a this mesh will contain. + * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, + * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. + * If a nodal connectivity previouly existed before the call of this method, it will be reset. + * + * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. * * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
* \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". */ void MEDCouplingUMesh::allocateCells(int nbOfCells) { + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !"); if(_nodal_connec_index) { _nodal_connec_index->decrRef(); @@ -359,7 +398,7 @@ MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator() /*! * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated. - * If 'this' is not so that that cells are grouped by geo types this method will throw an exception. + * If \a this is not so that that cells are grouped by geo types this method will throw an exception. * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method. * Useful for python users. */ @@ -372,7 +411,8 @@ MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() throw(INTERP_KE /*! * Returns a set of all cell types available in \a this mesh. - * \return std::set - the set of cell types. + * \return std::set - the set of cell types. + * \warning this method does not throw any exception even if \a this is not defined. */ std::set MEDCouplingUMesh::getAllGeoTypes() const { @@ -380,7 +420,7 @@ std::set MEDCouplingUMesh::getAllGeoTypes() c } /*! - * This method is a method that compares 'this' and 'other'. + * This method is a method that compares \a this and \a other. * This method compares \b all attributes, even names and component names. */ bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception) @@ -474,108 +514,6 @@ bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other return true; } -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are - * considered equivalent if (1) \a this mesh contains the same nodes as the \a other - * mesh (with a specified precision) and (2) \a this mesh contains the same cells as - * the \a other mesh (with use of a specified cell comparison technique). The mapping - * from \a other to \a this for nodes and cells is returned via out parameters. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - the precision used to compare nodes of the two meshes. - * \param [out] cellCor - a cell permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \param [out] nodeCor - a node permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - */ -void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) -{ - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !"); - MEDCouplingMesh::checkFastEquivalWith(other,prec); - if(_types!=otherC->_types) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !"); - MEDCouplingAutoRefCountObjectPtr m=MergeUMeshes(this,otherC); - bool areNodesMerged; - int newNbOfNodes; - int oldNbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); - //mergeNodes - if(!areNodesMerged) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); - const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),oldNbOfNodes-1)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !"); - m->renumberNodes(da->getConstPointer(),newNbOfNodes); - // - MEDCouplingAutoRefCountObjectPtr nodeCor2=da->substr(oldNbOfNodes); - da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); - - // - da=m->zipConnectivityTraducer(cellCompPol); - int nbCells=getNumberOfCells(); - int maxId=-1; - if(nbCells!=0) - maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+nbCells); - pt=std::find_if(da->getConstPointer()+nbCells,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(nbCells,da->getNbOfElems(),1); - nodeCor=nodeCor2->isIdentity()?0:nodeCor2.retn(); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - -/*! - * Checks if \a this and \a other meshes are geometrically equivalent, else an - * exception is thrown. The meshes are considered equivalent if (1) they share one - * node coordinates array and (2) they contain the same cells (with use of a specified - * cell comparison technique). The mapping from cells of the \a other to ones of \a this - * is returned via an out parameter. - * \param [in] other - the mesh to compare with. - * \param [in] cellCompPol - id [0-2] of cell comparison method. See the meaning of - * each method in description of MEDCouplingUMesh::zipConnectivityTraducer(). - * \param [in] prec - a not used parameter. - * \param [out] cellCor - the permutation array in "Old to New" mode. The caller is - * to delete this array using decrRef() as it is no more needed. - * \throw If the two meshes do not match. - * - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - */ -void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) -{ - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Two meshes are not not unstructured !"); - MEDCouplingMesh::checkFastEquivalWith(other,prec); - if(_types!=otherC->_types) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Types are not equal !"); - if(_coords!=otherC->_coords) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - MEDCouplingAutoRefCountObjectPtr m=MergeUMeshesOnSameCoords(ms); - MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); - const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); - } - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - /*! * Checks if \a this and \a other meshes are geometrically equivalent with high * probability, else an exception is thrown. The meshes are considered equivalent if @@ -588,19 +526,10 @@ void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *ot */ void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { - const MEDCouplingUMesh *otherC=dynamic_cast(other); + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCouplingUMesh *otherC=dynamic_cast(other); if(!otherC) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not not unstructured !"); - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - bool status=true; - status&=areCellsFrom2MeshEqual(otherC,0,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); - if(!status) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); } /*! @@ -1357,7 +1286,7 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except * The returned node ids are sortes ascendingly. This method is closed to MEDCouplingUMesh::getNodeIdsInUse except * the format of returned DataArrayInt instance. * - * @return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. + * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. * \sa MEDCouplingUMesh::getNodeIdsInUse */ DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception) @@ -1462,6 +1391,7 @@ DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const thro * So for pohyhedrons some nodes can be counted several times in the returned result. * * \return a newly allocated array + * \sa MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell */ DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) { @@ -1482,6 +1412,36 @@ DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const throw(INTERP_KER return ret.retn(); } +/*! + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, + * will be counted only once here whereas it will be counted several times in MEDCouplingUMesh::computeNbOfNodesPerCell method. + * + * \return DataArrayInt * - new object to be deallocated by the caller. + * \sa MEDCouplingUMesh::computeNbOfNodesPerCell + */ +DataArrayInt *MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i s(conn+connI[i]+1,conn+connI[i+1]); + if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED) + *retPtr=(int)s.size(); + else + { + s.erase(-1); + *retPtr=(int)s.size(); + } + } + return ret.retn(); +} + /*! * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. @@ -1521,15 +1481,12 @@ DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const throw(INTERP_KER */ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Exception) { - int newNbOfNodes=-1; - DataArrayInt *traducer=getNodeIdsInUse(newNbOfNodes); - renumberNodes(traducer->getConstPointer(),newNbOfNodes); - return traducer; + return MEDCouplingPointSet::zipCoordsTraducer(); } /*! * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. - * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. */ int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) { @@ -1550,7 +1507,7 @@ int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1 } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0. */ int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) { @@ -1560,7 +1517,7 @@ int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1. */ int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) { @@ -1593,7 +1550,7 @@ int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2. */ int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) { @@ -1624,7 +1581,7 @@ int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell } /*! - * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 7. + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7. */ int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) { @@ -1685,39 +1642,11 @@ int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell return 0; } - -/*! - * This method compares 2 cells coming from two unstructured meshes : 'this' and 'other'. - * This method compares 2 cells having the same id 'cellId' in 'this' and 'other'. - */ -bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const -{ - if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) - return false; - std::vector c1,c2; - getNodeIdsOfCell(cellId,c1); - other->getNodeIdsOfCell(cellId,c2); - std::size_t sz=c1.size(); - if(sz!=c2.size()) - return false; - for(std::size_t i=0;i n1,n2; - getCoordinatesOfNode(c1[0],n1); - other->getCoordinatesOfNode(c2[0],n2); - std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus()); - std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun(fabs)); - if(*std::max_element(n1.begin(),n1.end())>prec) - return false; - } - return true; -} - /*! * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned * and result remains unchanged. - * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. * If in 'candidates' pool -1 value is considered as an empty value. * WARNING this method returns only ONE set of result ! */ @@ -1765,7 +1694,6 @@ bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, i */ void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception) { - checkConnectivityFullyDefined(); MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); getReverseNodalConnectivity(revNodal,revNodalI); FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); @@ -1852,49 +1780,6 @@ void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const D commonCellsIArr=commonCellsI.retn(); } -/*! - * Removes duplicates of cells from \a this mesh and returns an array mapping between - * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no - * equal cells found. - * \warning Cells of the result mesh are \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] compType - specifies a cell comparison technique. Meaning of its - * valid values [0,1,2] is as follows. - * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal - * connectivity and type. This is the strongest policy. - * - 1 : "permuted same orientation". Two cells are considered equal \c iff they - * are based on same nodes and have the same type and orientation. - * - 2 : "nodal". Two cells are considered equal \c iff they - * are based on same nodes and have the same type. This is the weakest - * policy, it can be used by users not sensitive to cell orientation. - * \param [in] startCellId - specifies the cell id at which search for equal cells - * starts. By default it is 0, which means that all cells in \a this will be - * scanned. - * \return DataArrayInt - a new instance of DataArrayInt, of length \a - * this->getNumberOfCells() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception) -{ - DataArrayInt *commonCells=0,*commonCellsI=0; - findCommonCells(compType,startCellId,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - int newNbOfCells=-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), - commonCellsI->end(),newNbOfCells); - MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); - MEDCouplingAutoRefCountObjectPtr self=static_cast(buildPartOfMySelf(ret2->begin(),ret2->end(),true)); - setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true); - return ret.retn(); -} - /*! * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger @@ -1931,7 +1816,7 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com } MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); arr=o2n->substr(nbOfCells); - arr->setName(other->getName()); + arr->setName(other->getName().c_str()); int tmp; if(other->getNumberOfCells()==0) return true; @@ -1939,13 +1824,13 @@ bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int com } /*! - * This method makes the assumption that 'this' and 'other' share the same coords. If not an exception will be thrown ! + * This method makes the assumption that \a this and \a other share the same coords. If not an exception will be thrown ! * This method tries to determine if \b other is fully included in \b this. * The main difference is that this method is not expected to throw exception. * This method has two outputs : * - * @param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'. - * @return If 'other' is fully included in 'this 'true is returned. If not false is returned. + * \param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'. + * \return If \a other is fully included in 'this 'true is returned. If not false is returned. */ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception) { @@ -1975,108 +1860,24 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr } } } - arr2->setName(other->getName()); + arr2->setName(other->getName().c_str()); if(arr2->presenceOfValue(0)) return false; arr=arr2.retn(); return true; } -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes(ret->getConstPointer(),newNbOfNodes); - return ret; -} - - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location - * of merged nodes is changed to be at their barycenter. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref MEDCouplingArrayRenumbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes2(ret->getConstPointer(),newNbOfNodes); - return ret; -} - -/*! - * Substitutes node coordinates array of \a this mesh with that of \a other mesh - * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two - * meshes match with a specified precision, else an exception is thrown and \a this - * remains unchanged. In case of success the nodal connectivity of \a this mesh - * is permuted according to new order of nodes. - * Contrary to tryToShareSameCoords() this method makes a deeper analysis of - * coordinates (and so more expensive) than simple equality. - * \param [in] other - the other mesh whose node coordinates array will be used by - * \a this mesh in case of their equality. - * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). - * \throw If the coordinates array of \a this is not set. - * \throw If the coordinates array of \a other is not set. - * \throw If the coordinates of \a this and \a other do not match. - */ -void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { - const DataArrayDouble *coords=other.getCoords(); - if(!coords) - throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !"); - if(!_coords) - throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); - int otherNbOfNodes=other.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr newCoords=MergeNodesArray(&other,this); - _coords->incrRef(); - MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; - setCoords(newCoords); - bool areNodesMerged; - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes); - if(!areNodesMerged) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !"); - } - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes); - const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); - } - setCoords(oldCoords); - renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); - setCoords(coords); + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !"); + std::vector ms(2); + ms[0]=this; + ms[1]=otherC; + return MergeUMeshesOnSameCoords(ms); } /*! @@ -2093,12 +1894,7 @@ void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& ot MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception) { if(getMeshDimension()!=-1) - { - MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords2(start,end,step); - if(!keepCoords) - ret->zipCoords(); - return ret; - } + return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords); else { int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); @@ -2135,12 +1931,7 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, in MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const { if(getMeshDimension()!=-1) - { - MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(begin,end); - if(!keepCoords) - ret->zipCoords(); - return ret; - } + return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords); else { if(end-begin!=1) @@ -2155,13 +1946,13 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const /*! * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here. * - * This method allows to partially modify some cells in \b this (whose list is specified by [\b cellIdsBg, \b cellIdsEnd) ) with cells coming in \b otherOnSameCoordsThanThis. - * Size of [\b cellIdsBg, \b cellIdsEnd) ) must be equal to the number of cells of otherOnSameCoordsThanThis. + * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis. + * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis. * The number of cells of \b this will remain the same with this method. * * \param [in] begin begin of cell ids (included) of cells in this to assign * \param [in] end end of cell ids (excluded) of cells in this to assign - * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd). + * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ). * Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same */ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) @@ -2264,36 +2055,14 @@ void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDC } /*! - * Finds cells whose all nodes are in a given array of node ids. - * \param [in] partBg - the array of node ids. - * \param [in] partEnd - a pointer to a (last+1)-th element of \a partBg. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * cells. The caller is to delete this array using decrRef() as it is no - * more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a partBg is not valid. - * - * \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept); - cellIdsKept->setName(getName()); - return cellIdsKept; -} - -/*! - * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. - * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not. - * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept. + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. + * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept. * * \param [in] begin input start of array of node ids. * \param [in] end input end of array of node ids. - * \param [in] fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in. + * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in. * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. */ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const @@ -2325,60 +2094,6 @@ void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int cellIdsKeptArr=cellIdsKept.retn(); } -/*! - * Finds cells whose all or some nodes are in a given array of node ids. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are returned only, else cells whose any node is in the - * array \a begin are returned. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a begin is not valid. - * - * \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example". - */ -DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - cellIdsKept->setName(getName()); - return cellIdsKept; -} - -/*! - Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to - copy are selected basing on specified node ids and the value of \a fullyIn - parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the - array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its - node is in the array of node ids. The created mesh shares the node coordinates array - with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are copied, else cells whose any node is in the - * array \a begin are copied. - * \return MEDCouplingPointSet * - new instance of MEDCouplingUMesh. The caller is - * to delete this mesh using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any node id in \a begin is not valid. - * - * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); - return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); -} - /*! * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a * this->getMeshDimension(), that bound some cells of \a this mesh. @@ -2449,7 +2164,7 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const /*! * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary. * A cell is detected to be on boundary if it contains one or more than one face having only one father. - * This method makes the assumption that 'this' is fully defined (coords,connectivity). If not an exception will be thrown. + * This method makes the assumption that \a this is fully defined (coords,connectivity). If not an exception will be thrown. */ DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception) { @@ -2588,50 +2303,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNE return const_cast(this); } -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - */ -void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) -{ - MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. In contrast to renumberNodes(), location - * of merged nodes (whose new ids coincide) is changed to be at their barycenter. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref MEDCouplingArrayRenumbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is - * actually one more than the maximal id in \a newNodeNumbers. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - */ -void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) -{ - MEDCouplingPointSet::renumberNodes2(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); -} - /*! * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. @@ -2692,7 +2363,7 @@ void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1On /*! * This method operates a modification of the connectivity and coords in \b this. - * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1, @@ -2747,7 +2418,7 @@ void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care ! * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method". * - * @param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this. + * \param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this. */ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception) { @@ -2771,7 +2442,7 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex /*! * This method operates a modification of the connectivity in \b this. * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method. - * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1, @@ -2782,7 +2453,7 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex * * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - * \param [in] offset the offset applied to all node ids in connectivity that are in [nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd). + * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). */ void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception) { @@ -2809,17 +2480,17 @@ void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, con } /*! - * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) + * This method renumbers cells of \a this using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) * * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. * After the call of this method the number of cells remains the same as before. * - * If 'check' equals true the method will check that any elements in [old2NewBg;old2NewEnd) is unique ; if not - * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [old2NewBg;old2NewEnd) is not expected to + * If 'check' equals true the method will check that any elements in [ \a old2NewBg; \a old2NewEnd ) is unique ; if not + * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to * be strictly in [0;this->getNumberOfCells()). * - * If 'check' equals false the method will not check the content of [old2NewBg;old2NewEnd). - * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [old2NewBg;old2NewEnd) should be unique and + * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ). + * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and * should be contained in[0;this->getNumberOfCells()). * * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells() @@ -2997,6 +2668,7 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co /*! * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. + * This method does not throw exception if geometric type \a type is not in \a this. * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. * The coordinates array is not considered here. * @@ -3025,7 +2697,7 @@ DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellT } /*! - * Returns nb of cells having the geometric type 'type'. + * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. */ int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const { @@ -3144,13 +2816,13 @@ std::string MEDCouplingUMesh::reprConnectivityOfThis() const } /*! - * This method builds a newly allocated instance (with the same name than 'this') that the caller has the responsability to deal with. + * This method builds a newly allocated instance (with the same name than \a this) that the caller has the responsability to deal with. * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates) * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with * some algos). * - * This method expects that 'this' has a mesh dimension set and higher or equal to 0. If not an exception will be thrown. - * This method analyzes the 3 arrays of 'this'. For each the following behaviour is done : if the array is null a newly one is created + * This method expects that \a this has a mesh dimension set and higher or equal to 0. If not an exception will be thrown. + * This method analyzes the 3 arrays of \a this. For each the following behaviour is done : if the array is null a newly one is created * with number of tuples set to 0, if not the array is taken as this in the returned instance. */ MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception) @@ -3158,7 +2830,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const int mdim=getMeshDimension(); if(mdim<0) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName().c_str(),mdim); MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; bool needToCpyCT=true; if(!_nodal_connec) @@ -3265,7 +2937,7 @@ void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connInd } /*! - * Copy constructor. If 'deepCpy' is false 'this' is a shallow copy of other. + * Copy constructor. If 'deepCpy' is false \a this is a shallow copy of other. * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied. */ MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim), @@ -3386,7 +3058,7 @@ bool MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const /*! * Second step of serialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ void MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const { @@ -3417,7 +3089,7 @@ void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const /*! * Second and final unserialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) { @@ -3441,7 +3113,7 @@ void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, con * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. * CellIds are given using range specified by a start an end and step. */ -MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const { checkFullyDefined(); int ncell=getNumberOfCells(); @@ -3483,12 +3155,12 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int /*! * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. - * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). - * The return newly allocated mesh will share the same coordinates as 'this'. + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). + * The return newly allocated mesh will share the same coordinates as \a this. */ -MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const { - checkFullyDefined(); + checkConnectivityFullyDefined(); int ncell=getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); ret->_mesh_dim=_mesh_dim; @@ -4057,7 +3729,7 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co } /*! - * This method checks that 'this' is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1. + * This method checks that \a this is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1. * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too. * No consideration of coordinate is done by this method. * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m) @@ -4085,10 +3757,10 @@ bool MEDCouplingUMesh::isContiguous1D() const throw(INTERP_KERNEL::Exception) /*! * This method is only callable on mesh with meshdim == 1 containing only SEG2 and spaceDim==3. * This method projects this on the 3D line defined by (pt,v). This methods first checks that all SEG2 are along v vector. - * @param pt reference point of the line - * @param v normalized director vector of the line - * @param eps max precision before throwing an exception - * @param res output of size this->getNumberOfCells + * \param pt reference point of the line + * \param v normalized director vector of the line + * \param eps max precision before throwing an exception + * \param res output of size this->getNumberOfCells */ void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const { @@ -4633,7 +4305,7 @@ void MEDCouplingUMesh::checkButterflyCells(std::vector& cells, double eps) * Only connectivity of some cells could be modified if those cells were not representing a convex envelop. If a cell already equals its convex envelop (regardless orientation) * its connectivity will remain unchanged. If the computation leads to a modification of nodal connectivity of a cell its geometric type will be modified to INTERP_KERNEL::NORM_POLYGON. * - * @return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned. + * \return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned. */ DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() throw(INTERP_KERNEL::Exception) { @@ -4668,12 +4340,12 @@ DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() throw(INTERP_KERNEL::Exception } /*! - * This method is \b NOT const because it can modify 'this'. - * 'this' is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. - * @param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. - * @param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), + * This method is \b NOT const because it can modify \a this. + * \a this is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. + * \param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. + * \param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), * \b 1 for translation and rotation around point of 'mesh1D'. - * @return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than 'this'. + * \return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than \a this. */ MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) { @@ -4722,13 +4394,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *me /*! * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3). * If it is not the case an exception will be thrown. - * This method is non const because the coordinate of 'this' can be appended with some new points issued from + * This method is non const because the coordinate of \a this can be appended with some new points issued from * intersection of plane defined by ('origin','vec'). * This method has one in/out parameter : 'cut3DCurve'. * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()') - * if cut3DCurve[i]==-2, it means that for cell #i in 'this' nothing has been detected previously. + * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously. * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec'). - * This method will throw an exception if 'this' contains a non linear segment. + * This method will throw an exception if \a this contains a non linear segment. */ void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve) throw(INTERP_KERNEL::Exception) { @@ -4788,8 +4460,8 @@ void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double /*! * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method. - * @param mesh1D is the input 1D mesh used for translation computation. - * @return newCoords new coords filled by this method. + * \param mesh1D is the input 1D mesh used for translation computation. + * \return newCoords new coords filled by this method. */ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const { @@ -4834,8 +4506,8 @@ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCoupli /*! * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * @return newCoords new coords filled by this method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. */ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception) { @@ -4848,8 +4520,8 @@ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const /*! * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * @return newCoords new coords filled by this method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. */ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception) { @@ -4892,8 +4564,8 @@ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(con /*! * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * @return newCoords new coords filled by this method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. */ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception) { @@ -4961,7 +4633,7 @@ DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(con * This method is private because not easy to use for end user. This method is const contrary to * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain * the coords sorted slice by slice. - * @param isQuad specifies presence of quadratic cells. + * \param isQuad specifies presence of quadratic cells. */ MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const { @@ -5567,6 +5239,7 @@ void MEDCouplingUMesh::tessellate2DCurve(double eps) throw(INTERP_KERNEL::Except * and \a this->getMeshDimension() != 3. * \throw If \a policy is not one of the four discussed above. * \throw If the nodal connectivity of cells is not defined. + * \sa MEDCouplingUMesh::tetrahedrize */ DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception) { @@ -5828,12 +5501,12 @@ DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exc } /*! - * This private method is used to subdivide edges of a mesh with meshdim==2. If 'this' has no a meshdim equal to 2 an exception will be thrown. + * 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. - * @param nodeSubdived is the nodal connectivity of subdivision of edges - * @param nodeIndxSubdived is the nodal connectivity index of subdivision of edges - * @param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 - * @param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 + * \param nodeSubdived is the nodal connectivity of subdivision of edges + * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges + * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 + * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 */ void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) throw(INTERP_KERNEL::Exception) { @@ -6219,9 +5892,9 @@ DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() throw(INTERP_ /*! * This method has a sense for meshes with spaceDim==3 and meshDim==2. * If it is not the case an exception will be thrown. - * This method is fast because the first cell of 'this' is used to compute the plane. - * @param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. - * @param pos output of size at least 3 used to store a point owned of searched plane. + * This method is fast because the first cell of \a this is used to compute the plane. + * \param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. + * \param pos output of size at least 3 used to store a point owned of searched plane. */ void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception) { @@ -6503,7 +6176,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERN /*! * This method aggregate the bbox of each cell and put it into bbox parameter. - * @param bbox out parameter of size 2*spacedim*nbOfcells. + * \param bbox out parameter of size 2*spacedim*nbOfcells. */ void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector& bbox) const { @@ -6563,11 +6236,11 @@ namespace ParaMEDMEMImpl /// @endcond /*! - * This method expects that 'this' is sorted by types. If not an exception will be thrown. + * This method expects that \a this is sorted by types. If not an exception will be thrown. * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how - * 'this' is composed in cell types. - * The returned array is of size 3*n where n is the number of different types present in 'this'. - * For every k in [0,n] ret[3*k+2]==0 because it has no sense here. + * \a this is composed in cell types. + * The returned array is of size 3*n where n is the number of different types present in \a this. + * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. * This parameter is kept only for compatibility with other methode listed above. */ std::vector MEDCouplingUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) @@ -6578,7 +6251,7 @@ std::vector MEDCouplingUMesh::getDistributionOfTypes() const throw(INTERP_K const int *work=connI; int nbOfCells=getNumberOfCells(); std::size_t n=getAllTypes().size(); - std::vector ret(3*n,0); //ret[3*k+2]==0 because it has no sense here + std::vector ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here std::set types; for(std::size_t i=0;work!=connI+nbOfCells;i++) { @@ -6599,20 +6272,20 @@ std::vector MEDCouplingUMesh::getDistributionOfTypes() const throw(INTERP_K } /*! - * This method is used to check that this has contiguous cell type in same order than described in 'code'. + * This method is used to check that this has contiguous cell type in same order than described in \a code. * only for types cell, type node is not managed. - * Format of 'code' is the following. 'code' should be of size 3*n and non empty. If not an exception is thrown. + * Format of \a code is the following. \a code should be of size 3*n and non empty. If not an exception is thrown. * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k. * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array. - * If 2 or more same geometric type is in 'code' and exception is thrown too. + * If 2 or more same geometric type is in \a code and exception is thrown too. * * This method firstly checks * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown. * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match, * an exception is thrown too. * - * If all geometric types in 'code' are exactly those in 'this' null pointer is returned. - * If it exists a geometric type in 'this' \b not in 'code' \b no exception is thrown + * If all geometric types in \a code are exactly those in \a this null pointer is returned. + * If it exists a geometric type in \a this \b not in \a code \b no exception is thrown * and a DataArrayInt instance is returned that the user has the responsability to deallocate. */ DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) @@ -6625,6 +6298,7 @@ DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector< throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !"); std::vector types; int nb=0; + bool isNoPflUsed=true; for(std::size_t i=0;i ret=DataArrayInt::New(); ret->alloc(nb,1); int *retPtr=ret->getPointer(); const int *connI=_nodal_connec_index->getConstPointer(); @@ -6654,38 +6329,69 @@ DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector< { i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it))); int offset=(int)std::distance(connI,i); + const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); + int nbOfCellsOfCurType=(int)std::distance(i,j); if(code[3*kk+2]==-1) - { - const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); - std::size_t pos2=std::distance(i,j); - for(std::size_t k=0;kgetConstPointer(),idsPerType[code[3*kk+2]]->getConstPointer()+idsPerType[code[3*kk+2]]->getNbOfElems(), - retPtr,std::bind2nd(std::plus(),offset)); + int idInIdsPerType=code[3*kk+2]; + if(idInIdsPerType>=0 && idInIdsPerType<(int)idsPerType.size()) + { + const DataArrayInt *zePfl=idsPerType[idInIdsPerType]; + if(zePfl) + { + zePfl->checkAllocated(); + if(zePfl->getNumberOfComponents()==1) + { + for(const int *k=zePfl->begin();k!=zePfl->end();k++,retPtr++) + { + if(*k>=0 && *k& code, std::vector& idsInPflPerType, std::vector& idsPerType) const throw(INTERP_KERNEL::Exception) { + if(!profile) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !"); if(profile->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !"); checkConnectivityFullyDefined(); @@ -6755,7 +6461,7 @@ void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vec /*! * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon. - * This method make the assumption that 'this' and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does. + * This method make the assumption that \a this and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does. * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1' * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered. */ @@ -6847,7 +6553,7 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const throw(INT /*! * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check - * that the order is specified in array defined by [orderBg,orderEnd). + * that the order is specified in array defined by [ \a orderBg , \a orderEnd ). * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. */ @@ -6939,7 +6645,7 @@ DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const throw(INTERP_K } /*! - * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [orderBg,orderEnd) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in 'this'. + * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. @@ -6953,12 +6659,12 @@ DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INT } /*! - * This method reorganize the cells of 'this' so that the cells with same geometric types are put together. + * This method reorganize the cells of \a this so that the cells with same geometric types are put together. * The number of cells remains unchanged after the call of this method. * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as * MEDCouplingUMesh::sortCellsInMEDFileFrmt. * - * @return the array giving the correspondance old to new. + * \return the array giving the correspondance old to new. */ DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() { @@ -6991,13 +6697,13 @@ DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() } /*! - * This method splits 'this' into as mush as untructured meshes that consecutive set of same type cells. + * This method splits \a this into as mush as untructured meshes that consecutive set of same type cells. * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. * This method makes asumption that connectivity is correctly set before calling. */ std::vector MEDCouplingUMesh::splitByType() const { - checkFullyDefined(); + checkConnectivityFullyDefined(); const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -7019,6 +6725,109 @@ std::vector MEDCouplingUMesh::splitByType() const return ret; } +/*! + * This method performs the opposite operation than those in MEDCoupling1SGTUMesh::buildUnstructured. + * If \a this is a single geometric type unstructured mesh, it will be converted into a more compact data structure, + * MEDCoupling1GTUMesh instance. The returned instance will aggregate the same DataArrayDouble instance of coordinates than \a this. + * + * \return a newly allocated instance, that the caller must manage. + * \throw If \a this contains more than one geometric type. + * \throw If the nodal connectivity of \a this is not fully defined. + * \throw If the internal data is not coherent. + */ +MEDCoupling1GTUMesh *MEDCouplingUMesh::convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); + MEDCouplingAutoRefCountObjectPtr ret=MEDCoupling1GTUMesh::New(getName().c_str(),typ); + ret->setCoords(getCoords()); + MEDCoupling1SGTUMesh *retC=dynamic_cast((MEDCoupling1GTUMesh*)ret); + if(retC) + { + MEDCouplingAutoRefCountObjectPtr c=convertNodalConnectivityToStaticGeoTypeMesh(); + retC->setNodalConnectivity(c); + } + else + { + MEDCoupling1DGTUMesh *retD=dynamic_cast((MEDCoupling1GTUMesh*)ret); + if(!retD) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !"); + DataArrayInt *c=0,*ci=0; + convertNodalConnectivityToDynamicGeoTypeMesh(c,ci); + MEDCouplingAutoRefCountObjectPtr cs(c),cis(ci); + retD->setNodalConnectivity(cs,cis); + } + return ret.retn(); +} + +DataArrayInt *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh() const throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + if(cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : this contains a single geo type (" << cm.getRepr() << ") but "; + oss << "this type is dynamic ! Only static geometric type is possible for that type ! call convertNodalConnectivityToDynamicGeoTypeMesh instead !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbCells=getNumberOfCells(); + int typi=(int)typ; + int nbNodesPerCell=(int)cm.getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1); + int *outPtr=connOut->getPointer(); + const int *conn=_nodal_connec->begin(); + const int *connI=_nodal_connec_index->begin(); + nbNodesPerCell++; + for(int i=0;igetNumberOfTuples(); + if(lgth c(DataArrayInt::New()),ci(DataArrayInt::New()); + c->alloc(lgth-nbCells,1); ci->alloc(nbCells+1,1); + int *cp(c->getPointer()),*cip(ci->getPointer()); + const int *incp(_nodal_connec->begin()),*incip(_nodal_connec_index->begin()); + cip[0]=0; + for(int i=0;i=1) + { + if((strt>=0 && strt=0 && stop<=lgth)) + cp=std::copy(incp+strt,incp+stop,cp); + else + throw INTERP_KERNEL::Exception(msg0); + } + else + throw INTERP_KERNEL::Exception(msg0); + cip[1]=cip[0]+delta; + } + nodalConn=c.retn(); nodalConnIndex=ci.retn(); +} + /*! * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions. * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt). @@ -7088,7 +6897,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(cons /*! * This method returns a newly created DataArrayInt instance. - * This method retrieves cell ids in [begin,end) that have the type 'type'. + * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type. */ DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception) { @@ -7177,7 +6986,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::Normalized /*! * This method returns a vector of size 'this->getNumberOfCells()'. - * This method retrieves for each cell in 'this' if it is linear (false) or quadratic(true). + * This method retrieves for each cell in \a this if it is linear (false) or quadratic(true). */ std::vector MEDCouplingUMesh::getQuadraticStatus() const throw(INTERP_KERNEL::Exception) { @@ -7195,7 +7004,7 @@ std::vector MEDCouplingUMesh::getQuadraticStatus() const throw(INTERP_KERN } /*! - * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'. + * Returns a newly created mesh (with ref count ==1) that contains merge of \a this and \a other. */ MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const { @@ -7631,7 +7440,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vectoralloc(curNbOfCells,1); std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer()); offset+=curNbOfCells; - tmp->setName(meshes[i]->getName()); + tmp->setName(meshes[i]->getName().c_str()); corr[i]=tmp; } return ret.retn(); @@ -7745,9 +7554,9 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector& ret) @@ -7828,7 +7637,7 @@ void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, } /*! - * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [begin,end). + * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [ \a begin , \a end ). */ bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords) { @@ -7846,7 +7655,7 @@ bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec } /*! - * The polyhedron is specfied by its connectivity nodes in [begin,end). + * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ). */ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords) { @@ -7870,7 +7679,7 @@ bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end } /*! - * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [begin,end). + * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [ \a begin , \a end ). */ bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords) { @@ -7922,7 +7731,7 @@ bool MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, con } /*! - * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [\b begin, \b end) + * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [ \b begin , \b end ) * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to * a 2D space. * @@ -8015,7 +7824,7 @@ void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble /*! * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going - * through origin. The plane is defined by its nodal connectivity [\b begin, \b end). + * through origin. The plane is defined by its nodal connectivity [ \b begin, \b end ). * * \param [in] eps below that value the dot product of 2 vectors is considered as colinears * \param [in] coords coordinates expected to have 3 components. @@ -8565,9 +8374,9 @@ void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, c * - a mesh 'm2' with meshDim==1 and a SpaceDim==2 * - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids in randomly sorted. * The aim of this method is to sort the splitting nodes, if any, and to put in 'intersectEdge' output paramter based on edges of mesh 'm2' - * @param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. Only present for its coords in case of 'subDiv' shares some nodes of 'm1' - * @param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. - * @param addCoo input parameter with additionnal nodes linked to intersection of the 2 meshes. + * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. Only present for its coords in case of 'subDiv' shares some nodes of 'm1' + * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. + * \param addCoo input parameter with additionnal nodes linked to intersection of the 2 meshes. */ void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector& addCoo, const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge) throw(INTERP_KERNEL::Exception) { @@ -8621,15 +8430,15 @@ void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MED * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells * with a plane. The result will be put in 'cut3DSuf' out parameter. - * @param cut3DCurve input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially. - * @param nodesOnPlane, returns all the nodes that are on the plane. - * @param nodal3DSurf is the nodal connectivity of 3D surf mesh. - * @param nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh. - * @param nodal3DCurve is the nodal connectivity of 3D curve mesh. - * @param nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh. - * @param desc is the descending connectivity 3DSurf->3DCurve - * @param descIndx is the descending connectivity index 3DSurf->3DCurve - * @param cut3DSuf input/output param. + * \param [in] cut3DCurve input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially. + * \param [out] nodesOnPlane, returns all the nodes that are on the plane. + * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh. + * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh. + * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh. + * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh. + * \param [in] desc is the descending connectivity 3DSurf->3DCurve + * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve + * \param [out] cut3DSuf input/output param. */ void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3DCurve, std::vector& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, const int *nodal3DCurve, const int *nodalIndx3DCurve, @@ -8694,13 +8503,13 @@ void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector& cut3D } /*! - * 'this' is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. + * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters. - * @param cut3DSurf input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve). - * @param desc is the descending connectivity 3D->3DSurf - * @param descIndx is the descending connectivity index 3D->3DSurf + * \param cut3DSurf input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve). + * \param desc is the descending connectivity 3D->3DSurf + * \param descIndx is the descending connectivity index 3D->3DSurf */ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, const int *desc, const int *descIndx, @@ -8781,10 +8590,10 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::paircheckAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !"); std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); const int *arrInPtr=arrIn->getConstPointer(); const int *arrIndxPtr=arrIndxIn->getConstPointer(); int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); int maxSizeOfArr=arrIn->getNumberOfTuples(); MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); @@ -8984,17 +8799,89 @@ void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const arrIndexOut=arrIo.retn(); } +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ). + * The selection of extraction is done standardly in new2old format. + * This method returns indexed arrays using 2 arrays (arrOut,arrIndexOut). + * + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays + */ +void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !"); + arrIn->checkAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !"); + int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice "); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); + int maxSizeOfArr=arrIn->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); + arrIo->alloc((int)(sz+1),1); + int idsIt=idsOfSelectStart; + int *work=arrIo->getPointer(); + *work++=0; + int lgth=0; + for(std::size_t i=0;i=0 && idsIt=work[-1]) + *work=lgth; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt; + oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arro->alloc(lgth,1); + work=arro->getPointer(); + idsIt=idsOfSelectStart; + for(std::size_t i=0;i=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr) + work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx["; + oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + /*! * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [\b idsOfSelectBg, \b idsOfSelectEnd) and for - * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for + * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. * * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) * \param [in] arrIn arr origin array from which the extraction will be done. * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd ) * \param [in] srcArrIndex index array of \b srcArr * \param [out] arrOut the resulting array * \param [out] arrIndexOut the index array of the resulting array \b arrOut @@ -9060,7 +8947,7 @@ void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const in * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) * \param [in,out] arrInOut arr origin array from which the extraction will be done. * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd ) * \param [in] srcArrIndex index array of \b srcArr * * \sa MEDCouplingUMesh::SetPartOfIndexedArrays @@ -9190,7 +9077,7 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vecto /*! * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [\b idsOfSelectBg, \b idsOfSelectEnd) and for + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. * @@ -9320,7 +9207,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER 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); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName().c_str(),mdim); ret->setCoords(getCoords()); ret->allocateCells((int)partition.size()); // @@ -9354,7 +9241,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER */ std::vector MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception) { - //#if 0 int nbOfCellsCur=getNumberOfCells(); std::vector ret; if(nbOfCellsCur<=0) @@ -9374,36 +9260,6 @@ std::vector MEDCouplingUMesh::partitionBySpreadZone() const thro for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=ret2.begin();it!=ret2.end();it++) ret.push_back((*it).retn()); return ret; - //#endif -#if 0 - 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; -#endif } /*! @@ -9430,6 +9286,78 @@ DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vec return ret.retn(); } +/*! + * This method expects that \a this a 3D mesh (spaceDim=3 and meshDim=3) with all coordinates and connectivities set. + * All cells in \a this are expected to be linear 3D cells. + * This method will split **all** 3D cells in \a this into INTERP_KERNEL::NORM_TETRA4 cells and put them in the returned mesh. + * It leads to an increase to number of cells. + * This method contrary to MEDCouplingUMesh::simplexize can append coordinates in \a this to perform its work. + * The \a nbOfAdditionalPoints returned value informs about it. If > 0, the coordinates array in returned mesh will have \a nbOfAdditionalPoints + * more tuples (nodes) than in \a this. Anyway, all the nodes in \a this (with the same order) will be in the returned mesh. + * + * \param [in] policy - the policy of splitting that must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48). The policy will be used only for INTERP_KERNEL::NORM_HEXA8 cells. + * For all other cells, the splitting policy will be ignored. + * \param [out] nbOfAdditionalPoints - number of nodes added to \c this->_coords. If > 0 a new coordinates object will be constructed result of the aggregation of the old one and the new points added. + * \param [out] n2oCells - A new instance of DataArrayInt holding, for each new cell, + * an id of old cell producing it. The caller is to delete this array using + * decrRef() as it is no more needed. + * \return MEDCoupling1SGTUMesh * - the mesh containing only INTERP_KERNEL::NORM_TETRA4 cells. + * + * \throw If \a this is not a 3D mesh (spaceDim==3 and meshDim==3). + * \throw If \a this is not fully constituted with linear 3D cells. + * \sa MEDCouplingUMesh::simplexize + */ +MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const throw(INTERP_KERNEL::Exception) +{ + INTERP_KERNEL::SplittingPolicy pol((INTERP_KERNEL::SplittingPolicy)policy); + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tetrahedrize : only available for mesh with meshdim == 3 and spacedim == 3 !"); + int nbOfCells(getNumberOfCells()),nbNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr ret0(MEDCoupling1SGTUMesh::New(getName().c_str(),INTERP_KERNEL::NORM_TETRA4)); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfCells,1); + int *retPt(ret->getPointer()); + MEDCouplingAutoRefCountObjectPtr newConn(DataArrayInt::New()); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr addPts(DataArrayDouble::New()); addPts->alloc(0,1); + const int *oldc(_nodal_connec->begin()); + const int *oldci(_nodal_connec_index->begin()); + const double *coords(_coords->begin()); + for(int i=0;i a; std::vector b; + INTERP_KERNEL::SplitIntoTetras(pol,(INTERP_KERNEL::NormalizedCellType)oldc[oldci[0]],oldc+oldci[0]+1,oldc+oldci[1],coords,a,b); + std::size_t nbOfTet(a.size()/4); *retPt=(int)nbOfTet; + const int *aa(&a[0]); + if(!b.empty()) + { + for(std::vector::iterator it=a.begin();it!=a.end();it++) + if(*it<0) + *it=(-(*(it))-1+nbNodes); + addPts->insertAtTheEnd(b.begin(),b.end()); + nbNodes+=(int)b.size()/3; + } + for(std::size_t j=0;jinsertAtTheEnd(aa,aa+4); + } + if(!addPts->empty()) + { + addPts->rearrange(3); + nbOfAdditionalPoints=addPts->getNumberOfTuples(); + addPts=DataArrayDouble::Aggregate(getCoords(),addPts); + ret0->setCoords(addPts); + } + else + { + nbOfAdditionalPoints=0; + ret0->setCoords(getCoords()); + } + ret0->setNodalConnectivity(newConn); + // + ret->computeOffsets2(); + n2oCells=ret->buildExplicitArrOfSliceOnScaledArr(0,nbOfCells,1); + return ret0.retn(); +} + MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), _own_cell(true),_cell_id(-1),_nb_cell(0) {