+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+ if(type==INTERP_KERNEL::NORM_SEG2)
+ {
+ types.insert(INTERP_KERNEL::NORM_SEG3);
+ newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3);
+ newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3);
+ newConn->pushBackSilent(offset++);
+ lastVal+=4;
+ newConnI->pushBackSilent(lastVal);
+ ret->pushBackSilent(i);
+ }
+ else
+ {
+ types.insert(type);
+ lastVal+=(icPtr[1]-icPtr[0]);
+ newConnI->pushBackSilent(lastVal);
+ newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+ }
+ }
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+ coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn();
+ return ret.retn();
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+ //
+ const int *descPtr(desc->begin()),*descIPtr(descI->begin());
+ DataArrayInt *conn1D=0,*conn1DI=0;
+ std::set<INTERP_KERNEL::NormalizedCellType> types1D;
+ DataArrayDouble *coordsTmp=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+ const int *c1DPtr=conn1D->begin();
+ const int *c1DIPtr=conn1DI->begin();
+ int nbOfCells=getNumberOfCells();
+ const int *cPtr=_nodal_connec->getConstPointer();
+ const int *icPtr=_nodal_connec_index->getConstPointer();
+ int lastVal=0;
+ for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
+ {
+ INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+ if(!cm.isQuadratic())
+ {
+ INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType();
+ types.insert(typ2); newConn->pushBackSilent(typ2);
+ newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+ for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+ newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+ lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]);
+ newConnI->pushBackSilent(lastVal);
+ ret->pushBackSilent(i);
+ }
+ else
+ {
+ types.insert(typ);
+ lastVal+=(icPtr[1]-icPtr[0]);
+ newConnI->pushBackSilent(lastVal);
+ newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+ }
+ }
+ conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn();
+ return ret.retn();
+}
+
+/*!
+ * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ */
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+ return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+ //
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
+ //
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner();
+ const int *descPtr(desc->begin()),*descIPtr(descI->begin());
+ DataArrayInt *conn1D=0,*conn1DI=0;
+ std::set<INTERP_KERNEL::NormalizedCellType> types1D;
+ DataArrayDouble *coordsTmp=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+ const int *c1DPtr=conn1D->begin();
+ const int *c1DIPtr=conn1DI->begin();
+ int nbOfCells=getNumberOfCells();
+ const int *cPtr=_nodal_connec->getConstPointer();
+ const int *icPtr=_nodal_connec_index->getConstPointer();
+ int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
+ for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++)
+ {
+ INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+ if(!cm.isQuadratic())
+ {
+ INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
+ types.insert(typ2); newConn->pushBackSilent(typ2);
+ newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+ for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+ newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+ newConn->pushBackSilent(offset+ret->getNumberOfTuples());
+ lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1;
+ newConnI->pushBackSilent(lastVal);
+ ret->pushBackSilent(i);
+ }
+ else
+ {
+ types.insert(typ);
+ lastVal+=(icPtr[1]-icPtr[0]);
+ newConnI->pushBackSilent(lastVal);
+ newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+ }
+ }
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+ coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn();
+ return ret.retn();
+}
+
+/*!
+ * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method.
+ * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells.
+ * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic.
+ */
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0;
+ return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types);
+}
+
+DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const
+{
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2D=buildDescendingConnectivityGen<MinusOneSonsGeneratorBiQuadratic>(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New());
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0;
+ //
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1);
+ //
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner();
+ const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin());
+ DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0;
+ std::set<INTERP_KERNEL::NormalizedCellType> types1D,types2D;
+ DataArrayDouble *coordsTmp=0,*coordsTmp2=0;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmp2Safe(coordsTmp2);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn2DSafe(conn2D),conn2DISafe(conn2DI);
+ const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin();
+ int nbOfCells=getNumberOfCells();
+ const int *cPtr=_nodal_connec->getConstPointer();
+ const int *icPtr=_nodal_connec_index->getConstPointer();
+ int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples();
+ for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++,desc2IPtr++)
+ {
+ INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr];
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+ if(!cm.isQuadratic())
+ {
+ INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2();
+ if(typ2==INTERP_KERNEL::NORM_ERROR)
+ {
+ std::ostringstream oss; oss << "MEDCouplingUMesh::convertLinearCellsToQuadratic3D1 : On cell #" << i << " the linear cell type does not support advanced quadratization !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ types.insert(typ2); newConn->pushBackSilent(typ2);
+ newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]);
+ for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++)
+ newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]);
+ for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++)
+ {
+ int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1];
+ int tmpPos=newConn->getNumberOfTuples();
+ newConn->pushBackSilent(nodeId2);
+ ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos);
+ }
+ newConn->pushBackSilent(offset+ret->getNumberOfTuples());
+ lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1;
+ newConnI->pushBackSilent(lastVal);
+ ret->pushBackSilent(i);
+ }
+ else
+ {
+ types.insert(typ);
+ lastVal+=(icPtr[1]-icPtr[0]);
+ newConnI->pushBackSilent(lastVal);
+ newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]);
+ }
+ }
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffRet2D=ret2D->getDifferentValues();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples());
+ coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end());
+ std::vector<const DataArrayDouble *> v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp;
+ int *c=newConn->getPointer();
+ const int *cI(newConnI->begin());
+ for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++)
+ c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset;
+ offset=coordsTmp2Safe->getNumberOfTuples();
+ for(const int *elt=ret->begin();elt!=ret->end();elt++)
+ c[cI[(*elt)+1]-1]+=offset;
+ coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn();
+ return ret.retn();
+}
+
+/*!
+ * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces,
+ * so that the number of cells remains the same. Quadratic faces are converted to
+ * polygons. This method works only for 2D meshes in
+ * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8,
+ * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged.
+ * \warning This method can lead to a huge amount of nodes if \a eps is very low.
+ * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of
+ * a polylinized edge constituting the input polygon.
+ * \throw If the coordinates array is not set.
+ * \throw If the nodal connectivity of cells is not defined.
+ * \throw If \a this->getMeshDimension() != 2.
+ * \throw If \a this->getSpaceDimension() != 2.
+ */
+void MEDCouplingUMesh::tessellate2D(double eps)
+{
+ checkFullyDefined();
+ if(getMeshDimension()!=2 || getSpaceDimension()!=2)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!");
+ double epsa=fabs(eps);
+ if(epsa<std::numeric_limits<double>::min())
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
+ revDesc1=0; revDescIndx1=0;
+ mDesc->tessellate2DCurve(eps);
+ subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer());
+ setCoords(mDesc->getCoords());
+}
+
+/*!
+ * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges.
+ * \warning This method can lead to a huge amount of nodes if \a eps is very low.
+ * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of
+ * a sub-divided edge.
+ * \throw If the coordinates array is not set.
+ * \throw If the nodal connectivity of cells is not defined.
+ * \throw If \a this->getMeshDimension() != 1.
+ * \throw If \a this->getSpaceDimension() != 2.
+ */
+void MEDCouplingUMesh::tessellate2DCurve(double eps)
+{
+ checkFullyDefined();
+ if(getMeshDimension()!=1 || getSpaceDimension()!=2)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!");
+ double epsa=fabs(eps);
+ if(epsa<std::numeric_limits<double>::min())
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+ INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10;
+ int nbCells=getNumberOfCells();
+ int nbNodes=getNumberOfNodes();
+ const int *conn=_nodal_connec->getConstPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coords=_coords->getConstPointer();
+ std::vector<double> addCoo;
+ std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI(DataArrayInt::New());
+ newConnI->alloc(nbCells+1,1);
+ int *newConnIPtr=newConnI->getPointer();
+ *newConnIPtr=0;
+ int tmp1[3];
+ INTERP_KERNEL::Node *tmp2[3];
+ std::set<INTERP_KERNEL::NormalizedCellType> types;
+ for(int i=0;i<nbCells;i++,newConnIPtr++)
+ {
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+ if(cm.isQuadratic())
+ {//assert(connI[i+1]-connI[i]-1==3)