X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingUMesh.cxx;h=fca3d1aa2a65063a3c2487722807e5616d3fde70;hb=b79f750df5fc807078f4efbf89d88587a88f7548;hp=754a7d7978e44f147cf983398cfdeadc4c1488aa;hpb=4ba7ca14b51a481efc60d025ccd0571c8e88af77;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 754a7d797..fca3d1aa2 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -89,6 +89,22 @@ 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) @@ -1375,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) { @@ -1395,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. @@ -1769,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; @@ -1813,63 +1860,13 @@ 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) -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes(ret->begin(),newNbOfNodes); - return ret.retn(); -} - - -/*! - * 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; -} - MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const { if(!other) @@ -2833,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) @@ -3163,7 +3160,7 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, i */ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const { - checkFullyDefined(); + checkConnectivityFullyDefined(); int ncell=getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); ret->_mesh_dim=_mesh_dim; @@ -6242,7 +6239,7 @@ namespace ParaMEDMEMImpl * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how * \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]==0 because it has no sense here. + * 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) @@ -6253,7 +6250,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++) { @@ -6705,7 +6702,7 @@ DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() */ std::vector MEDCouplingUMesh::splitByType() const { - checkFullyDefined(); + checkConnectivityFullyDefined(); const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -6743,36 +6740,93 @@ MEDCoupling1GTUMesh *MEDCouplingUMesh::convertIntoSingleGeoTypeMesh() const thro 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(); - int typi=(int)typ; - MEDCouplingAutoRefCountObjectPtr ret=MEDCoupling1GTUMesh::New(getName(),typ); + MEDCouplingAutoRefCountObjectPtr ret=MEDCoupling1GTUMesh::New(getName().c_str(),typ); ret->setCoords(getCoords()); MEDCoupling1SGTUMesh *retC=dynamic_cast((MEDCoupling1GTUMesh*)ret); if(retC) { - int nbCells=getNumberOfCells(); - int nbNodesPerCell=retC->getNumberOfNodesPerCell(); - 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;isetNodalConnectivity(connOut); + MEDCouplingAutoRefCountObjectPtr c=convertNodalConnectivityToStaticGeoTypeMesh(); + retC->setNodalConnectivity(c); } else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : not implemented yet for non static geometric type !"); + { + 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). @@ -7385,7 +7439,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(); @@ -8684,16 +8738,22 @@ bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, cons * \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::ExtractFromIndexedArrays2 */ 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 !"); + arrIn->checkAllocated(); 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(); @@ -8738,6 +8798,78 @@ 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 @@ -9074,7 +9206,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()); //