From 0d4c6ea9f81cb751e37e3e834b8969a8171ecd88 Mon Sep 17 00:00:00 2001 From: ageay Date: Thu, 14 Jun 2012 13:53:31 +0000 Subject: [PATCH] Duplication of nodes. And modification of API of MEDCouplingPointSet::findBoundaryNodes --- src/MEDCoupling/MEDCouplingUMesh.cxx | 598 ++++++++++++++++++++++- src/MEDCoupling/MEDCouplingUMesh.hxx | 22 +- src/MEDCoupling/MEDCouplingUMeshDesc.cxx | 2 +- src/MEDCoupling/MEDCouplingUMeshDesc.hxx | 2 +- 4 files changed, 601 insertions(+), 23 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 45da23b45..49a14be09 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -571,13 +571,13 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *d * \b WARNING this method do the assumption that connectivity lies on the coordinates set. * For speed reasons no check of this will be done. This method calls MEDCouplingUMesh::buildDescendingConnectivity to compute the result. * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities are considered. - * The a cell with id 'cellId' its neighbors are neighbors[neighborsIdx[cellId]:neighborsIdx[cellId+1]]. + * The a cell with id 'cellId' its neighbors are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. * - * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIdx 2nd output - * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIdx. - * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output + * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx. + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. */ -void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const throw(INTERP_KERNEL::Exception) +void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); @@ -585,6 +585,30 @@ void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArr MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); meshDM1=0; + computeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx); +} + +/*! + * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm of MEDCouplingUMesh::computeNeighborsOfCells. + * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is typically the case to extract a set a neighbours, + * excluding a set of meshdim-1 cells in input descending connectivity. + * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx input params are the result of MEDCouplingUMesh::buildDescendingConnectivity. + * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities are considered. + * The a cell with id 'cellId' its neighbors are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. + * + * \param [in] desc descending connectivity array. + * \param [in] descIndx descending connectivity index array used to walk through \b desc. + * \param [in] revDesc reverse descending connectivity array. + * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc. + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output + * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx. + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. + */ +void MEDCouplingUMesh::computeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx, + DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const throw(INTERP_KERNEL::Exception) +{ + if(!desc || !descIndx || !revDesc || !revDescIndx) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfCellsAdv some input array is empty !"); const int *descPtr=desc->getConstPointer(); const int *descIPtr=descIndx->getConstPointer(); const int *revDescPtr=revDesc->getConstPointer(); @@ -610,7 +634,7 @@ void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArr out0->alloc((int)out0v.size(),1); std::copy(out0v.begin(),out0v.end(),out0->getPointer()); neighbors=out0; out0->incrRef(); - neighborsIdx=out1; out1->incrRef(); + neighborsIndx=out1; out1->incrRef(); } /// @cond INTERNAL @@ -1571,6 +1595,65 @@ 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. + * 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). + * 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) +{ + checkConnectivityFullyDefined(); + otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); + if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); + if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); + oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd); + if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCells=getNumberOfCells(); + bool easyAssign=true; + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer(); + const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); + for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++) + { + if(*it>=0 && *it cellIdsKept; @@ -1721,9 +1804,10 @@ DataArrayInt *MEDCouplingUMesh::findCellsIdsOnBoundary() const throw(INTERP_KERN } /*! - * This methods returns set of nodes lying on the boundary of this. + * This methods returns set of nodes in a newly allocated array that the caller has to deal with. + * The returned nodes ids are those lying on the boundary of \b this. */ -void MEDCouplingUMesh::findBoundaryNodes(std::vector& nodes) const +DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const { DataArrayInt *desc=DataArrayInt::New(); DataArrayInt *descIndx=DataArrayInt::New(); @@ -1747,10 +1831,12 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector& nodes) const for(std::vector::const_iterator iter=boundaryCells.begin();iter!=boundaryCells.end();iter++) for(int k=connIndx[*iter]+1;kdecrRef(); + // + DataArrayInt *retda=DataArrayInt::New(); + retda->alloc((int)ret.size(),1); + std::copy(ret.begin(),ret.end(),retda->getPointer()); + return retda; } MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception) @@ -1783,6 +1869,7 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes * * @param newNodeNumbers array specifying the new numbering. * @param newNbOfNodes the new number of nodes. + * */ void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) { @@ -1790,6 +1877,100 @@ void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNode 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. + * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords. + * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated. + * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate. + * + * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input + * parameter is altered during the call. + * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above. + * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. + * + * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons). + */ +void MEDCouplingUMesh::findNodesToDuplicate(MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, DataArrayInt *& cellIdsNeededToBeRenum) const throw(INTERP_KERNEL::Exception) +{ + checkFullyDefined(); + otherDimM1OnSameCoords.checkFullyDefined(); + if(getCoords()!=otherDimM1OnSameCoords.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !"); + if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !"); + MEDCouplingAutoRefCountObjectPtr nodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds(); + // + MEDCouplingAutoRefCountObjectPtr cellIds0=getCellIdsLyingOnNodes(nodeIds1->begin(),nodeIds1->end(),false); + MEDCouplingAutoRefCountObjectPtr m0Part=static_cast(buildPartOfMySelf(cellIds0->begin(),cellIds0->end(),true)); + MEDCouplingAutoRefCountObjectPtr boundary0=m0Part->findBoundaryNodes(); + MEDCouplingAutoRefCountObjectPtr boundary1=otherDimM1OnSameCoords.findBoundaryNodes(); + MEDCouplingAutoRefCountObjectPtr diff=boundary1->buildSubstraction(boundary0); + MEDCouplingAutoRefCountObjectPtr nodeIdsToDuplicateTmp=nodeIds1->buildSubstraction(diff);//ready to go to nodeIdsToDuplicate + MEDCouplingAutoRefCountObjectPtr m00t=m0Part->zipCoordsTraducer(); + MEDCouplingAutoRefCountObjectPtr nodeIdsToDuplicate2=nodeIdsToDuplicateTmp->deepCpy(); + nodeIdsToDuplicate2->transformWithIndArr(m00t->begin(),m00t->end()); + MEDCouplingAutoRefCountObjectPtr revNod00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr revNodI00=DataArrayInt::New(); + m0Part->getReverseNodalConnectivity(revNod00,revNodI00); + MEDCouplingAutoRefCountObjectPtr desc00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr descI00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr revDesc00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr revDescI00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr m01=m0Part->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00); + otherDimM1OnSameCoords.renumberNodesInConn(m00t->begin()); + otherDimM1OnSameCoords.setCoords(m0Part->getCoords()); + DataArrayInt *idsTmp=0; + bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,0,idsTmp); + MEDCouplingAutoRefCountObjectPtr ids(idsTmp); + if(!b) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !"); + MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00); + DataArrayInt *tmp0=0,*tmp1=0; + m0Part->computeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1); + MEDCouplingAutoRefCountObjectPtr neigh00(tmp0); + MEDCouplingAutoRefCountObjectPtr neighI00(tmp1); + std::set cellIdsImpacted0; + const int *revNod00Ptr=revNod00->getConstPointer(); + const int *revNodI00Ptr=revNodI00->getConstPointer(); + for(const int *elt=nodeIdsToDuplicate2->begin();elt!=nodeIdsToDuplicate2->end();elt++) + for(const int *elt2=revNod00Ptr+revNodI00Ptr[*elt];elt2!=revNod00Ptr+revNodI00Ptr[*elt+1];elt2++) + cellIdsImpacted0.insert(*elt2); + MEDCouplingAutoRefCountObjectPtr cellIdsImpacted0_arr=DataArrayInt::New(); cellIdsImpacted0_arr->alloc((int)cellIdsImpacted0.size(),1); + std::copy(cellIdsImpacted0.begin(),cellIdsImpacted0.end(),cellIdsImpacted0_arr->getPointer()); + MEDCouplingUMesh::ExtractFromIndexedArrays(cellIdsImpacted0_arr->begin(),cellIdsImpacted0_arr->end(),neigh00,neighI00,tmp0,tmp1); + MEDCouplingAutoRefCountObjectPtr cellIdsImpacted0_arr2=cellIdsImpacted0_arr->invertArrayN2O2O2N(cellIds0->getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr neigh000(tmp0); + MEDCouplingAutoRefCountObjectPtr neighI000(tmp1); + neigh000->transformWithIndArr(cellIdsImpacted0_arr2->begin(),cellIdsImpacted0_arr2->end()); + MEDCouplingAutoRefCountObjectPtr cellsToModifyConn0_torenum=MEDCouplingUMesh::ComputeSpreadZoneGradually(neigh000,neighI000); + cellsToModifyConn0_torenum->transformWithIndArr(cellIdsImpacted0_arr->begin(),cellIdsImpacted0_arr->end()); + cellsToModifyConn0_torenum->transformWithIndArr(cellIds0->begin(),cellIds0->end()); + // + cellIdsNeededToBeRenum=cellsToModifyConn0_torenum; cellsToModifyConn0_torenum->incrRef(); + nodeIdsToDuplicate=nodeIdsToDuplicateTmp; nodeIdsToDuplicateTmp->incrRef(); +} + +/*! + * 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 + * 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, + * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2... + * + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. + * + * \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 + */ +void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) throw(INTERP_KERNEL::Exception) +{ + int nbOfNodes=getNumberOfNodes(); + duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); + duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes); +} + /*! * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords. * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care ! @@ -1841,6 +2022,46 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex updateTime(); } +/*! + * 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 + * 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, + * node id nodeIdsToDuplicateBg[2] will have id offset+2... + * + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. + * As an another consequense after the call of this method \b this can be transiently non cohrent. + * + * \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). + */ +void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception) +{ + checkConnectivityFullyDefined(); + std::map m; + int val=offset; + for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++) + m[*work]=val; + int *conn=getNodalConnectivity()->getPointer(); + const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for(int i=0;i=0)//avoid polyhedron separator + { + std::map::iterator it=m.find(node); + if(it!=m.end()) + node=(*it).second; + } + } + updateTime(); +} + /*! * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) * @@ -1854,6 +2075,8 @@ void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Ex * 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 * 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() */ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { @@ -1865,10 +2088,10 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INT // const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); - DataArrayInt *newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents()); newConn->copyStringInfoFrom(*_nodal_connec); - DataArrayInt *newConnI=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents()); newConnI->copyStringInfoFrom(*_nodal_connec_index); // @@ -1886,9 +2109,6 @@ void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INT } // setConnectivity(newConn,newConnI); - // - newConn->decrRef(); - newConnI->decrRef(); if(check) delete [] const_cast(array); } @@ -3253,7 +3473,7 @@ DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() throw(INTERP_KERNEL::Exception for(int i=0;i MEDCouplingUMesh::splitByType() const return ret; } +/*! + * 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). + * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting + * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old + * are not used here to avoid the build of big permutation array. + * + * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than + * those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method. + * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype + * in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh. + * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This + * output array gives for each chunck of same type the corresponding mesh id in \b ms. + * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh + * is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method. + */ +MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, + DataArrayInt *&szOfCellGrpOfSameType, + DataArrayInt *&idInMsOfCellGrpOfSameType) throw(INTERP_KERNEL::Exception) +{ + std::vector ms2; + for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + { + (*it)->checkConnectivityFullyDefined(); + ms2.push_back(*it); + } + if(ms2.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !"); + const DataArrayDouble *refCoo=ms2[0]->getCoords(); + int meshDim=ms2[0]->getMeshDimension(); + std::vector m1ssm; + std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmAuto; + // + std::vector m1ssmSingle; + std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmSingleAuto; + int fake=0,rk=0; + std::vector ret1Data; + std::vector ret2Data; + for(std::vector::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++) + { + if(meshDim!=(*it)->getMeshDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !"); + if(refCoo!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !"); + std::vector sp=(*it)->splitByType(); + std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector >(m1ssm)); + std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector > >(m1ssmAuto)); + for(std::vector::const_iterator it2=sp.begin();it2!=sp.end();it2++) + { + MEDCouplingUMesh *singleCell=static_cast((*it2)->buildPartOfMySelf(&fake,&fake+1,true)); + m1ssmSingleAuto.push_back(singleCell); + m1ssmSingle.push_back(singleCell); + ret1Data.push_back((*it2)->getNumberOfCells()); ret2Data.push_back(rk); + } + } + MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc((int)m1ssmSingle.size(),1); std::copy(ret1Data.begin(),ret1Data.end(),ret1->getPointer()); + MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)m1ssmSingle.size(),1); std::copy(ret2Data.begin(),ret2Data.end(),ret2->getPointer()); + MEDCouplingAutoRefCountObjectPtr m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle); + MEDCouplingAutoRefCountObjectPtr renum=m1ssmSingle2->sortCellsInMEDFileFrmt(); + std::vector m1ssmfinal(m1ssm.size()); + for(std::size_t i=0;igetIJ(i,0)]=m1ssm[i]; + MEDCouplingAutoRefCountObjectPtr ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal); + szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer()); + idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer()); + ret0->incrRef(); + return ret0; +} + /*! * This method returns a newly created DataArrayInt instance. * This method retrieves cell ids in [begin,end) that have the type 'type'. @@ -6105,7 +6395,7 @@ void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair& nodalConnecOut) throw(INTERP_KERNEL::Exception) +bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector& nodalConnecOut) throw(INTERP_KERNEL::Exception) { std::size_t sz=std::distance(nodalConnBg,nodalConnEnd); if(sz>=4) @@ -6188,7 +6478,277 @@ bool MEDCouplingUMesh::BuildConvecEnvelopOf2DCellJarvis(const double *coords, co } } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvecEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); +} + +/*! + * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx. + * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression. + * + * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included) + * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded) + * \param [in,out] arr array in which the remove operation will be done. + * \param [in,out] arrIndx array in the remove operation will modify + * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1]) + * \return true if \b arr and \b arrIndx have been modified, false if not. + */ +bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval) throw(INTERP_KERNEL::Exception) +{ + if(!arrIndx || !arr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !"); + if(offsetForRemoval<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !"); + std::set s(idsToRemoveBg,idsToRemoveEnd); + int nbOfGrps=arrIndx->getNumberOfTuples()-1; + int *arrIPtr=arrIndx->getPointer(); + *arrIPtr++=0; + int previousArrI=0; + const int *arrPtr=arr->getConstPointer(); + std::vector arrOut; + for(int i=0;ioffsetForRemoval) + { + for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++) + { + if(s.find(*work)==s.end()) + arrOut.push_back(*work); + } + } + previousArrI=*arrIPtr; + *arrIPtr=(int)arrOut.size(); + } + if(arr->getNumberOfTuples()==(int)arrOut.size()) + return false; + arr->alloc((int)arrOut.size(),1); + std::copy(arrOut.begin(),arrOut.end(),arr->getPointer()); + return true; +} + +/*! + * 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 in [\b idsOfSelectBg , \b idsOfSelectEnd ) ). + * 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 + */ +void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); + std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + int maxSizeOfArr=arrIn->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); + arrIo->alloc((int)(sz+1),1); + const int *idsIt=idsOfSelectBg; + 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::ExtractFromIndexedArrays : 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=idsOfSelectBg; + 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::ExtractFromIndexedArrays : 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; + arrIndexOut=arrIo; + arro->incrRef(); + arrIo->incrRef(); +} + +/*! + * 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 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] srcArrIndex index array of \b srcArr + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx + */ +void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception) +{ + if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !"); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + std::vector v(nbOfTuples,true); + int offset=0; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) + { + if(*it>=0 && *italloc(nbOfTuples+1,1); + arro->alloc(arrIn->getNumberOfTuples()+offset,1); + const int *arrInPtr=arrIn->getConstPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; + int *arroPtr=arro->getPointer(); + for(int ii=0;iiincrRef(); + arrIndexOut=arrIo; arrIo->incrRef(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn. + * + * \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,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] srcArrIndex index array of \b srcArr + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays + */ +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) +{ + if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int *arrInOutPtr=arrInOut->getPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) + { + if(*it>=0 && *itgetNumberOfTuples()-1. + * + * \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 + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. + */ +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + if(nbOfTuples<=0) + { + DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1); + return ret; + } + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); + arro->alloc(nbOfTuples,1); + arro->fillWithValue(-1); + int *arroPtr=arro->getPointer(); + std::set s; s.insert(0); + while(!s.empty()) + { + std::set s2; + for(std::set::const_iterator it=s.begin();it!=s.end();it++) + { + for(const int *work=arrInPtr+arrIndxPtr[*it];work!=arrInPtr+arrIndxPtr[*it+1];work++) + { + if(*work>=0 && arroPtr[*work]<0) + { + arroPtr[*work]=1; + s2.insert(*work); + } + } + } + s=s2; + } + return arro->getIdsEqual(1); } /*! diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 1db439bcc..d827083c9 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -108,21 +108,27 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void computeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, + DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT void setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; + MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; MEDCOUPLING_EXPORT DataArrayInt *findCellsIdsOnBoundary() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); MEDCOUPLING_EXPORT void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); + MEDCOUPLING_EXPORT void findNodesToDuplicate(MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, DataArrayInt *& cellIdsNeededToBeRenum) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getCellsInBoundingBox(const double *bbox, double eps, std::vector& elems) const; MEDCOUPLING_EXPORT void getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems); @@ -175,6 +181,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); MEDCOUPLING_EXPORT std::vector splitByType() const; + MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, + DataArrayInt *&szOfCellGrpOfSameType, + DataArrayInt *&idInMsOfCellGrpOfSameType) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; @@ -195,7 +204,16 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static bool BuildConvecEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector& nodalConnecOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector& nodalConnecOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception); private: MEDCouplingUMesh(); MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 893b547ca..e71ddee8d 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -397,7 +397,7 @@ DataArrayInt *MEDCouplingUMeshDesc::simplexize(int policy) throw(INTERP_KERNEL:: throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::simplexize : Not implemented yet !"); } -void MEDCouplingUMeshDesc::findBoundaryNodes(std::vector& nodes) const +DataArrayInt *MEDCouplingUMeshDesc::findBoundaryNodes() const { throw INTERP_KERNEL::Exception("Not implemented yet !"); } diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index 9f04b39ec..b8ca0c7a6 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -73,7 +73,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; + MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception); -- 2.39.2