#include "InterpKernelMeshQuality.hxx"
#include "InterpKernelCellSimplify.hxx"
#include "InterpKernelGeo2DEdgeArcCircle.hxx"
-#include "MEDCouplingAutoRefCountObjectPtr.hxx"
#include "InterpKernelAutoPtr.hxx"
#include "InterpKernelGeo2DNode.hxx"
#include "InterpKernelGeo2DEdgeLin.hxx"
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<MEDCouplingUMesh> ret=clone(false);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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)
setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true);
}
-std::size_t MEDCouplingUMesh::getHeapMemorySize() const
+std::size_t MEDCouplingUMesh::getHeapMemorySizeWithoutChildren() const
+{
+ std::size_t ret(MEDCouplingPointSet::getHeapMemorySizeWithoutChildren());
+ return ret;
+}
+
+std::vector<const BigMemoryObject *> MEDCouplingUMesh::getDirectChildren() const
{
- std::size_t ret=0;
+ std::vector<const BigMemoryObject *> ret(MEDCouplingPointSet::getDirectChildren());
if(_nodal_connec)
- ret+=_nodal_connec->getHeapMemorySize();
+ ret.push_back(_nodal_connec);
if(_nodal_connec_index)
- ret+=_nodal_connec_index->getHeapMemorySize();
- return MEDCouplingPointSet::getHeapMemorySize()+ret;
+ ret.push_back(_nodal_connec_index);
+ return ret;
}
void MEDCouplingUMesh::updateTime() const
* 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)
{
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<DataArrayInt> 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<nbOfCells;i++,retPtr++)
+ {
+ std::set<int> 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.
}
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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;
}
}
}
- 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".<br>
- * \ref py_mcumesh_mergeNodes "Here is a Python example".
- */
-DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
-{
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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".<br>
- * \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)
int mdim=getMeshDimension();
if(mdim<0)
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !");
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),mdim);
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
bool needToCpyCT=true;
if(!_nodal_connec)
*/
MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
{
- checkFullyDefined();
+ checkConnectivityFullyDefined();
int ncell=getNumberOfCells();
MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
ret->_mesh_dim=_mesh_dim;
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(nbOfPts,1);
const int *nc=_nodal_connec->begin(),*ncI=_nodal_connec_index->begin(); const double *coords=_coords->begin();
double *ret0Ptr=ret0->getPointer(); int *ret1Ptr=ret1->getPointer(); const double *ptsPtr=pts->begin();
- std::vector<double> bbox;
- getBoundingBoxForBBTree(bbox);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree());
+ const double *bbox(bboxArr->begin());
switch(spaceDim)
{
case 3:
{
- BBTreeDst<3> myTree(&bbox[0],0,0,nbCells);
+ BBTreeDst<3> myTree(bbox,0,0,nbCells);
for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=3)
{
double x=std::numeric_limits<double>::max();
}
case 2:
{
- BBTreeDst<2> myTree(&bbox[0],0,0,nbCells);
+ BBTreeDst<2> myTree(bbox,0,0,nbCells);
for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=2)
{
double x=std::numeric_limits<double>::max();
* faster.
* \param [in] pos - array of coordinates of the ball central point.
* \param [in] eps - ball radius.
- * \param [in,out] elts - vector returning ids of the found cells. It is cleared
+ * \param [out] elts - vector returning ids of the found cells. It is cleared
* before inserting ids.
* \throw If the coordinates array is not set.
* \throw If \a this->getMeshDimension() != \a this->getSpaceDimension().
*/
void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
{
- std::vector<int> eltsIndex;
- getCellsContainingPoints(pos,1,eps,elts,eltsIndex);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsUg,eltsIndexUg;
+ getCellsContainingPoints(pos,1,eps,eltsUg,eltsIndexUg);
+ elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end());
}
/// @cond INTERNAL
template<int SPACEDIM>
void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
- double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const
+ double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
{
- std::vector<double> bbox;
- eltsIndex.resize(nbOfPoints+1);
- eltsIndex[0]=0;
- elts.clear();
- getBoundingBoxForBBTree(bbox);
+ elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
+ int *eltsIndexPtr(eltsIndex->getPointer());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree());
+ const double *bbox(bboxArr->begin());
int nbOfCells=getNumberOfCells();
const int *conn=_nodal_connec->getConstPointer();
const int *connI=_nodal_connec_index->getConstPointer();
BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
for(int i=0;i<nbOfPoints;i++)
{
- eltsIndex[i+1]=eltsIndex[i];
+ eltsIndexPtr[i+1]=eltsIndexPtr[i];
for(int j=0;j<SPACEDIM;j++)
{
bb[2*j]=pos[SPACEDIM*i+j];
(INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]],
coords,conn+connI[*iter]+1,sz,eps))
{
- eltsIndex[i+1]++;
- elts.push_back(*iter);
+ eltsIndexPtr[i+1]++;
+ elts->pushBackSilent(*iter);
}
}
}
* this->getSpaceDimension() * \a nbOfPoints
* \param [in] nbOfPoints - number of points to locate within \a this mesh.
* \param [in] eps - radius of balls (i.e. the precision).
- * \param [in,out] elts - vector returning ids of found cells.
- * \param [in,out] eltsIndex - an array, of length \a nbOfPoints + 1,
+ * \param [out] elts - vector returning ids of found cells.
+ * \param [out] eltsIndex - an array, of length \a nbOfPoints + 1,
* dividing cell ids in \a elts into groups each referring to one
* point. Its every element (except the last one) is an index pointing to the
* first id of a group of cells. For example cells in contact with the *i*-th
* \ref py_mcumesh_getCellsContainingPoints "Here is a Python example".
*/
void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps,
- std::vector<int>& elts, std::vector<int>& eltsIndex) const
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
{
int spaceDim=getSpaceDimension();
int mDim=getMeshDimension();
* 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)
{
/*!
* This method aggregate the bbox of each cell and put it into bbox parameter.
- * \param bbox out parameter of size 2*spacedim*nbOfcells.
+ *
+ * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components.
+ *
+ * \throw If \a this is not fully set (coordinates and connectivity).
+ * \throw If a cell in \a this has no valid nodeId.
*/
-void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector<double>& bbox) const
+DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree() const
{
- int spaceDim=getSpaceDimension();
- int nbOfCells=getNumberOfCells();
- bbox.resize(2*nbOfCells*spaceDim);
+ checkFullyDefined();
+ int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim);
+ double *bbox(ret->getPointer());
for(int i=0;i<nbOfCells*spaceDim;i++)
{
bbox[2*i]=std::numeric_limits<double>::max();
bbox[2*i+1]=-std::numeric_limits<double>::max();
}
- const double *coordsPtr=_coords->getConstPointer();
- const int *conn=_nodal_connec->getConstPointer();
- const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coordsPtr(_coords->getConstPointer());
+ const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer());
for(int i=0;i<nbOfCells;i++)
{
int offset=connI[i]+1;
- int nbOfNodesForCell=connI[i+1]-offset;
+ int nbOfNodesForCell(connI[i+1]-offset),kk(0);
for(int j=0;j<nbOfNodesForCell;j++)
{
int nodeId=conn[offset+j];
- if(nodeId>=0)
- for(int k=0;k<spaceDim;k++)
- {
- bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
- bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
- }
+ if(nodeId>=0 && nodeId<nbOfNodes)
+ {
+ for(int k=0;k<spaceDim;k++)
+ {
+ bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
+ bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
+ }
+ kk++;
+ }
+ }
+ if(kk==0)
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
+ return ret.retn();
}
/// @cond INTERNAL
* 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<int> MEDCouplingUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
const int *work=connI;
int nbOfCells=getNumberOfCells();
std::size_t n=getAllTypes().size();
- std::vector<int> ret(3*n,0); //ret[3*k+2]==0 because it has no sense here
+ std::vector<int> ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here
std::set<INTERP_KERNEL::NormalizedCellType> types;
for(std::size_t i=0;work!=connI+nbOfCells;i++)
{
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !");
std::vector<INTERP_KERNEL::NormalizedCellType> types;
int nb=0;
+ bool isNoPflUsed=true;
for(std::size_t i=0;i<n;i++)
if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)code[3*i])==types.end())
{
nb+=code[3*i+1];
if(_types.find((INTERP_KERNEL::NormalizedCellType)code[3*i])==_types.end())
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : expected geo types not in this !");
+ isNoPflUsed=isNoPflUsed && (code[3*i+2]==-1);
}
if(types.size()!=n)
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code contains duplication of types in unstructured mesh !");
- if(idsPerType.empty())
+ if(isNoPflUsed)
{
if(!checkConsecutiveCellTypesAndOrder(&types[0],&types[0]+types.size()))
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : non contiguous type !");
if(types.size()==_types.size())
return 0;
}
- DataArrayInt *ret=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
ret->alloc(nb,1);
int *retPtr=ret->getPointer();
const int *connI=_nodal_connec_index->getConstPointer();
{
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;k<pos2;k++)
- *retPtr++=(int)k+offset;
- i=j;
- }
+ for(int k=0;k<nbOfCellsOfCurType;k++)
+ *retPtr++=k+offset;
else
{
- retPtr=std::transform(idsPerType[code[3*kk+2]]->getConstPointer(),idsPerType[code[3*kk+2]]->getConstPointer()+idsPerType[code[3*kk+2]]->getNbOfElems(),
- retPtr,std::bind2nd(std::plus<int>(),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<nbOfCellsOfCurType)
+ *retPtr=(*k)+offset;
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : the section " << kk << " points to the profile #" << idInIdsPerType;
+ oss << ", and this profile contains a value " << *k << " should be in [0," << nbOfCellsOfCurType << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ }
+ else
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of a profile with nb of compo != 1 !");
+ }
+ else
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of null profile !");
+ }
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : at section " << kk << " of code it points to the array #" << idInIdsPerType;
+ oss << " should be in [0," << idsPerType.size() << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
}
+ i=j;
}
- return ret;
+ return ret.retn();
}
/*!
*/
std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const
{
- checkFullyDefined();
+ checkConnectivityFullyDefined();
const int *conn=_nodal_connec->getConstPointer();
const int *connI=_nodal_connec_index->getConstPointer();
int nbOfCells=getNumberOfCells();
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<MEDCoupling1GTUMesh> ret=MEDCoupling1GTUMesh::New(getName(),typ);
+ MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> ret=MEDCoupling1GTUMesh::New(getName().c_str(),typ);
ret->setCoords(getCoords());
MEDCoupling1SGTUMesh *retC=dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh*)ret);
if(retC)
{
- int nbCells=getNumberOfCells();
- int nbNodesPerCell=retC->getNumberOfNodesPerCell();
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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;i<nbCells;i++,connI++)
- {
- if(conn[connI[0]]==typi && connI[1]-connI[0]==nbNodesPerCell)
- outPtr=std::copy(conn+connI[0]+1,conn+connI[1],outPtr);
- else
- {
- std::ostringstream oss; oss << "MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : there something wrong in cell #" << i << " ! The type of cell is not those expected, or the length of nodal connectivity is not those expected (" << nbNodesPerCell-1 << ") !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- }
- retC->setNodalConnectivity(connOut);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=convertNodalConnectivityToStaticGeoTypeMesh();
+ retC->setNodalConnectivity(c);
}
else
- throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : not implemented yet for non static geometric type !");
+ {
+ MEDCoupling1DGTUMesh *retD=dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh*)ret);
+ if(!retD)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !");
+ DataArrayInt *c=0,*ci=0;
+ convertNodalConnectivityToDynamicGeoTypeMesh(c,ci);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<DataArrayInt> 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;i<nbCells;i++,connI++)
+ {
+ if(conn[connI[0]]==typi && connI[1]-connI[0]==nbNodesPerCell)
+ outPtr=std::copy(conn+connI[0]+1,conn+connI[1],outPtr);
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : there something wrong in cell #" << i << " ! The type of cell is not those expected, or the length of nodal connectivity is not those expected (" << nbNodesPerCell-1 << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ return connOut.retn();
+}
+
+void MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const throw(INTERP_KERNEL::Exception)
+{
+ static const char msg0[]="MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : nodal connectivity in this are invalid ! Call checkCoherency2 !";
+ checkConnectivityFullyDefined();
+ if(_types.size()!=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : current mesh does not contain exactly one geometric type !");
+ int nbCells=getNumberOfCells(),lgth=_nodal_connec->getNumberOfTuples();
+ if(lgth<nbCells)
+ throw INTERP_KERNEL::Exception(msg0);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<nbCells;i++,cip++,incip++)
+ {
+ int strt(incip[0]+1),stop(incip[1]);//+1 to skip geo type
+ int delta(stop-strt);
+ if(delta>=1)
+ {
+ if((strt>=0 && strt<lgth) && (stop>=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).
tmp->alloc(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();
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
}
-void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const throw(INTERP_KERNEL::Exception)
{
int nbOfCells=getNumberOfCells();
if(nbOfCells<=0)
ofs << " </CellData>\n";
ofs << " <Points>\n";
if(getSpaceDimension()==3)
- _coords->writeVTK(ofs,8,"Points");
+ _coords->writeVTK(ofs,8,"Points",byteData);
else
{
MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.);
- coo->writeVTK(ofs,8,"Points");
+ coo->writeVTK(ofs,8,"Points",byteData);
}
ofs << " </Points>\n";
ofs << " <Cells>\n";
}
}
types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE);
- types->writeVTK(ofs,8,"UInt8","types");
- offsets->writeVTK(ofs,8,"Int32","offsets");
+ types->writeVTK(ofs,8,"UInt8","types",byteData);
+ offsets->writeVTK(ofs,8,"Int32","offsets",byteData);
if(szFaceOffsets!=0)
{//presence of Polyhedra
connectivity->reAlloc(szConn);
- faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets");
+ faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets",byteData);
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1);
w1=faces->getPointer();
for(int i=0;i<nbOfCells;i++)
w6=w5+1;
}
}
- faces->writeVTK(ofs,8,"Int32","faces");
+ faces->writeVTK(ofs,8,"Int32","faces",byteData);
}
- connectivity->writeVTK(ofs,8,"Int32","connectivity");
+ connectivity->writeVTK(ofs,8,"Int32","connectivity",byteData);
ofs << " </Cells>\n";
ofs << " </Piece>\n";
ofs << " </" << getVTKDataSetType() << ">\n";
std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2)
{
static const int SPACEDIM=2;
- std::vector<double> bbox1,bbox2;
const double *coo1=m1->getCoords()->getConstPointer();
const int *conn1=m1->getNodalConnectivity()->getConstPointer();
const int *connI1=m1->getNodalConnectivityIndex()->getConstPointer();
const int *connI2=m2->getNodalConnectivityIndex()->getConstPointer();
int offset2=offset1+m2->getNumberOfNodes();
int offset3=offset2+((int)addCoords.size())/2;
- m1->getBoundingBoxForBBTree(bbox1);
- m2->getBoundingBoxForBBTree(bbox2);
- BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2->getNumberOfCells(),eps);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree());
+ const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
+ BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2->getNumberOfCells(),eps);
int ncell1=m1->getNumberOfCells();
crI.push_back(0);
for(int i=0;i<ncell1;i++)
{
std::vector<int> candidates2;
- myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+ myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
std::map<INTERP_KERNEL::Node *,int> mapp;
std::map<int,INTERP_KERNEL::Node *> mappRev;
INTERP_KERNEL::QuadraticPolygon pol1;
MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc);
const int *c1=m1Desc->getNodalConnectivity()->getConstPointer();
const int *ci1=m1Desc->getNodalConnectivityIndex()->getConstPointer();
- std::vector<double> bbox1,bbox2;
- m1Desc->getBoundingBoxForBBTree(bbox1);
- m2Desc->getBoundingBoxForBBTree(bbox2);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree());
+ const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin());
int ncell1=m1Desc->getNumberOfCells();
int ncell2=m2Desc->getNumberOfCells();
intersectEdge1.resize(ncell1);
colinear2.resize(ncell2);
subDiv2.resize(ncell2);
- BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2Desc->getNumberOfCells(),-eps);
+ BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps);
std::vector<int> candidates1(1);
int offset1=m1->getNumberOfNodes();
int offset2=offset1+m2->getNumberOfNodes();
for(int i=0;i<ncell1;i++)
{
std::vector<int> candidates2;
- myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+ myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2);
if(!candidates2.empty())
{
std::map<INTERP_KERNEL::Node *,int> map1,map2;
* \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<DataArrayInt> arro=DataArrayInt::New();
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
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<DataArrayInt> arro=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
+ arrIo->alloc((int)(sz+1),1);
+ int idsIt=idsOfSelectStart;
+ int *work=arrIo->getPointer();
+ *work++=0;
+ int lgth=0;
+ for(int i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
+ {
+ if(idsIt>=0 && idsIt<nbOfGrps)
+ lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
+ else
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(lgth>=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(int i=0;i<sz;i++,idsIt+=idsOfSelectStep)
+ {
+ if(arrIndxPtr[idsIt]>=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
std::vector<DataArrayInt *> partition=partitionBySpreadZone();
std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partitionAuto; partitionAuto.reserve(partition.size());
std::copy(partition.begin(),partition.end(),std::back_insert_iterator<std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > >(partitionAuto));
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),mdim);
ret->setCoords(getCoords());
ret->allocateCells((int)partition.size());
//
*/
std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception)
{
- //#if 0
int nbOfCellsCur=getNumberOfCells();
std::vector<DataArrayInt *> ret;
if(nbOfCellsCur<=0)
for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::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<DataArrayInt> neighAuto(neigh),neighIAuto(neighI);
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::New(); ids->alloc(nbOfCellsCur,1); ids->iota();
- std::vector<DataArrayInt *> ret;
- std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret2;
- while(nbOfCellsCur>0)
- {
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=MEDCouplingUMesh::ComputeSpreadZoneGradually(neighAuto,neighIAuto);
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3=tmp->buildComplement(nbOfCellsCur);
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<DataArrayInt> renum=tmp3->invertArrayN2O2O2N(nbOfCellsCur+tmp->getNumberOfTuples());
- neighAuto->transformWithIndArr(renum->begin(),renum->end());
- }
- }
- for(std::vector<DataArrayInt *>::const_iterator it=ret.begin();it!=ret.end();it++)
- (*it)->incrRef();
- return ret;
-#endif
}
/*!
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<MEDCoupling1SGTUMesh> ret0(MEDCoupling1SGTUMesh::New(getName().c_str(),INTERP_KERNEL::NORM_TETRA4));
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfCells,1);
+ int *retPt(ret->getPointer());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn(DataArrayInt::New()); newConn->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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<nbOfCells;i++,oldci++,retPt++)
+ {
+ std::vector<int> a; std::vector<double> 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<int>::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;j<nbOfTet;j++,aa+=4)
+ newConn->insertAtTheEnd(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)
{