declareAsNew();
}
+bool DataArrayDouble::isUniform(double val, double eps) const
+{
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component !");
+ int nbOfTuples=getNumberOfTuples();
+ const double *w=getConstPointer();
+ const double *end=w+nbOfTuples;
+ const double vmin=val-eps;
+ const double vmax=val+eps;
+ for(;w!=end;w++)
+ if(*w<vmin || *w>vmax)
+ return false;
+ return true;
+}
+
std::string DataArrayDouble::repr() const
{
std::ostringstream ret;
return ret;
}
+DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
+{
+ if(_mem.isNull())
+ throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
+ double *tab=_mem.fromNoInterlace(getNumberOfComponents());
+ DataArrayDouble *ret=DataArrayDouble::New();
+ ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+ return ret;
+}
+
+DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
+{
+ if(_mem.isNull())
+ throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
+ double *tab=_mem.toNoInterlace(getNumberOfComponents());
+ DataArrayDouble *ret=DataArrayDouble::New();
+ ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+ return ret;
+}
+
/*!
* This method does \b not change the number of tuples after this call.
* Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used.
return ret;
}
+DataArrayDouble *DataArrayDouble::fromPolarToCart() const
+{
+ int nbOfComp=getNumberOfComponents();
+ if(nbOfComp!=2)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
+ int nbOfTuple=getNumberOfTuples();
+ DataArrayDouble *ret=DataArrayDouble::New();
+ ret->alloc(nbOfTuple,2);
+ double *w=ret->getPointer();
+ const double *wIn=getConstPointer();
+ for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
+ {
+ w[0]=wIn[0]*cos(wIn[1]);
+ w[1]=wIn[0]*sin(wIn[1]);
+ }
+ return ret;
+}
+
+DataArrayDouble *DataArrayDouble::fromCylToCart() const
+{
+ int nbOfComp=getNumberOfComponents();
+ if(nbOfComp!=3)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
+ int nbOfTuple=getNumberOfTuples();
+ DataArrayDouble *ret=DataArrayDouble::New();
+ ret->alloc(getNumberOfTuples(),3);
+ double *w=ret->getPointer();
+ const double *wIn=getConstPointer();
+ for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
+ {
+ w[0]=wIn[0]*cos(wIn[1]);
+ w[1]=wIn[0]*sin(wIn[1]);
+ w[2]=wIn[2];
+ }
+ ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
+ return ret;
+}
+
+DataArrayDouble *DataArrayDouble::fromSpherToCart() const
+{
+ int nbOfComp=getNumberOfComponents();
+ if(nbOfComp!=3)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
+ int nbOfTuple=getNumberOfTuples();
+ DataArrayDouble *ret=DataArrayDouble::New();
+ ret->alloc(getNumberOfTuples(),3);
+ double *w=ret->getPointer();
+ const double *wIn=getConstPointer();
+ for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
+ {
+ w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
+ w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
+ w[2]=wIn[0]*cos(wIn[1]);
+ }
+ return ret;
+}
+
DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
{
int nbOfComp=getNumberOfComponents();
declareAsNew();
}
+DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
+{
+ if(_mem.isNull())
+ throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
+ int *tab=_mem.fromNoInterlace(getNumberOfComponents());
+ DataArrayInt *ret=DataArrayInt::New();
+ ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+ return ret;
+}
+
+DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
+{
+ if(_mem.isNull())
+ throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
+ int *tab=_mem.toNoInterlace(getNumberOfComponents());
+ DataArrayInt *ret=DataArrayInt::New();
+ ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+ return ret;
+}
+
void DataArrayInt::renumberInPlace(const int *old2New)
{
int nbTuples=getNumberOfTuples();
return true;
}
+bool DataArrayInt::isUniform(int val) const
+{
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component !");
+ int nbOfTuples=getNumberOfTuples();
+ const int *w=getConstPointer();
+ const int *end=w+nbOfTuples;
+ for(;w!=end;w++)
+ if(*w!=val)
+ return false;
+ return true;
+}
+
DataArrayDouble *DataArrayInt::convertToDblArr() const
{
DataArrayDouble *ret=DataArrayDouble::New();
computeTypes();
}
+/*!
+ * This method is the opposite of ParaMEDMEM::MEDCouplingUMesh::convertToPolyTypes method.
+ * The aim is to take all polygons or polyhedrons cell and to try to traduce them into classical cells.
+ *
+ */
+void MEDCouplingUMesh::unPolyze()
+{
+ checkFullyDefined();
+ if(getMeshDimension()<=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
+ int nbOfCells=getNumberOfCells();
+ if(nbOfCells<1)
+ return ;
+ int initMeshLgth=getMeshLength();
+ int *conn=_nodal_connec->getPointer();
+ int *index=_nodal_connec_index->getPointer();
+ int posOfCurCell=0;
+ int newPos=0;
+ int lgthOfCurCell;
+ for(int i=0;i<nbOfCells;i++)
+ {
+ lgthOfCurCell=index[i+1]-posOfCurCell;
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+ INTERP_KERNEL::NormalizedCellType newType;
+ int newLgth;
+ if(cm.isDynamic())
+ {
+ if(cm.getDimension()==2)
+ {
+ int *tmp=new int[lgthOfCurCell-1];
+ std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,tmp);
+ newType=tryToUnPoly2D(tmp,lgthOfCurCell-1,conn+newPos+1,newLgth);
+ delete [] tmp;
+ }
+ if(cm.getDimension()==3)
+ {
+ int nbOfFaces,lgthOfPolyhConn;
+ int *zipFullReprOfPolyh=getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn);
+ newType=tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth);
+ delete [] zipFullReprOfPolyh;
+ }
+ conn[newPos]=newType;
+ newPos+=newLgth+1;
+ posOfCurCell=index[i+1];
+ index[i+1]=newPos;
+ }
+ }
+ if(newPos!=initMeshLgth)
+ _nodal_connec->reAlloc(newPos);
+ computeTypes();
+}
+
/*!
* Array returned is the correspondance new to old.
* The maximum value stored in returned array is the number of nodes of 'this' minus 1 after call of this method.
else
throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !");
}
-
-
-
}
/*!
setConnectivity(newConn,newConnI,false);
}
+/*!
+ * This method converts all degenerated cells to simpler cells. For example a NORM_QUAD4 cell consituted from 2 same node id in its
+ * nodal connectivity will be transform to a NORM_TRI3 cell.
+ * This method works \b only \b on \b linear cells.
+ * This method works on nodes ids, that is to say a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes
+ * method could be usefull before calling this method in case of presence of several pair of nodes located on same position.
+ * This method throws an exception if 'this' is not fully defined (connectivity).
+ * This method throws an exception too if a "too" degenerated cell is detected. For example a NORM_TRI3 with 3 times the same node id.
+ */
+void MEDCouplingUMesh::convertDegeneratedCells() throw(INTERP_KERNEL::Exception)
+{
+ checkFullyDefined();
+ if(getMeshDimension()<=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
+ int nbOfCells=getNumberOfCells();
+ if(nbOfCells<1)
+ return ;
+ int initMeshLgth=getMeshLength();
+ int *conn=_nodal_connec->getPointer();
+ int *index=_nodal_connec_index->getPointer();
+ int posOfCurCell=0;
+ int newPos=0;
+ int lgthOfCurCell;
+ for(int i=0;i<nbOfCells;i++)
+ {
+ lgthOfCurCell=index[i+1]-posOfCurCell;
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+ int newLgth;
+ INTERP_KERNEL::NormalizedCellType newType=simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
+ conn+newPos+1,newLgth);
+ conn[newPos]=newType;
+ newPos=posOfCurCell+newLgth+1;
+ posOfCurCell=index[i+1];
+ index[i+1]=newPos;
+ }
+ if(newPos!=initMeshLgth)
+ _nodal_connec->reAlloc(newPos);
+ computeTypes();
+}
+
/*!
* This method checks that all or only polygons (depending 'polyOnly' parameter) 2D cells are correctly oriented relative to 'vec' vector.
* The 'vec' vector has to have a non nul norm.
else
throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
}
+
+
+/*!
+ * This method takes as input a cell with type 'type' and whose connectivity is defined by (conn,lgth)
+ * It retrieves the same cell with a potentially different type (in return) whose connectivity is defined by (retConn,retLgth)
+ * \b WARNING for optimization reason the arrays 'retConn' and 'conn' can overlapped !
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth,
+ int *retConn, int& retLgth) throw(INTERP_KERNEL::Exception)
+{
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+ std::set<int> c(conn,conn+lgth);
+ c.erase(-1);
+ bool isObviousNonDegeneratedCell=((int)c.size()==lgth);
+ if(cm.isQuadratic() || isObviousNonDegeneratedCell)
+ {//quadratic do nothing for the moment.
+ retLgth=lgth;
+ int *tmp=new int[lgth];//no direct std::copy ! overlapping of conn and retConn !
+ std::copy(conn,conn+lgth,tmp);
+ std::copy(tmp,tmp+lgth,retConn);
+ delete [] tmp;
+ return type;
+ }
+ if(cm.getDimension()==2)
+ {
+ int *tmp=new int[lgth];
+ tmp[0]=conn[0];
+ int newPos=1;
+ for(int i=1;i<lgth;i++)
+ if(std::find(tmp,tmp+newPos,conn[i])==tmp+newPos)
+ tmp[newPos++]=conn[i];
+ INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly2D(tmp,newPos,retConn,retLgth);
+ delete [] tmp;
+ return ret;
+ }
+ if(cm.getDimension()==3)
+ {
+ int nbOfFaces,lgthOfPolyhConn;
+ int *zipFullReprOfPolyh=getFullPolyh3DCell(type,conn,lgth,nbOfFaces,lgthOfPolyhConn);
+ INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,retConn,retLgth);
+ delete [] zipFullReprOfPolyh;
+ return ret;
+ }
+ throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyDegeneratedCell : works only with 2D and 3D cell !");
+}
+
+
+/*!
+ * This static method tries to unpolygonize a cell whose connectivity is given by 'conn' and 'lgth'.
+ * Contrary to ParaMEDMEM::MEDCouplingUMesh::simplifyDegeneratedCell method 'conn' and 'retConn' do not overlap.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPoly2D(const int *conn, int lgth, int *retConn, int& retLgth)
+{
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ switch(lgth)
+ {
+ case 3:
+ return INTERP_KERNEL::NORM_TRI3;
+ case 4:
+ return INTERP_KERNEL::NORM_QUAD4;
+ default:
+ return INTERP_KERNEL::NORM_POLYGON;
+ }
+}
+
+/*!
+ * This method takes as input a 3D linear cell and put its representation in returned array. Warning the returned array has to be deallocated.
+ * The length of the returned array is specified by out parameter
+ * The format of output array is the following :
+ * 1,2,3,-1,3,4,2,-1,3,4,1,-1,1,2,4,NORM_TRI3,NORM_TRI3,NORM_TRI3 (faces type at the end of classical polyhedron nodal description)
+ */
+int *MEDCouplingUMesh::getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth,
+ int& retNbOfFaces, int& retLgth)
+{
+ const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type);
+ unsigned nbOfFaces=cm.getNumberOfSons2(conn,lgth);
+ int *tmp=new int[nbOfFaces*(lgth+1)];
+ int *work=tmp;
+ std::vector<int> faces;
+ for(unsigned j=0;j<nbOfFaces;j++)
+ {
+ INTERP_KERNEL::NormalizedCellType type;
+ unsigned offset=cm.fillSonCellNodalConnectivity2(j,conn,lgth,work,type);
+ //
+ int *tmp2=new int[offset];
+ tmp2[0]=work[0];
+ int newPos=1;
+ for(unsigned k=1;k<offset;k++)
+ if(std::find(tmp2,tmp2+newPos,work[k])==tmp2+newPos)
+ tmp2[newPos++]=work[k];
+ if(newPos<3)
+ continue;
+ int tmp3;
+ faces.push_back(tryToUnPoly2D(tmp2,newPos,work,tmp3));
+ delete [] tmp2;
+ //
+ work+=newPos;
+ *work++=-1;
+ }
+ std::copy(faces.begin(),faces.end(),--work);
+ retNbOfFaces=faces.size();
+ retLgth=std::distance(tmp,work);
+ return tmp;
+}
+
+/*!
+ * This static method tries to unpolygonize a cell whose connectivity is given by 'conn' (format is the same as specified in
+ * method ParaMEDMEM::MEDCouplingUMesh::getFullPolyh3DCell ) and 'lgth'+'nbOfFaces'.
+ * Contrary to ParaMEDMEM::MEDCouplingUMesh::simplifyDegeneratedCell method 'conn' and 'retConn' do not overlap.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth)
+{
+ std::set<int> nodes(conn,conn+lgth);
+ nodes.erase(-1);
+ int nbOfNodes=nodes.size();
+ int magicNumber=100*nbOfNodes+nbOfFaces;
+ switch(magicNumber)
+ {
+ case 806:
+ return tryToUnPolyHex8(conn,nbOfFaces,lgth,retConn,retLgth);
+ case 506:
+ return tryToUnPolyPenta6(conn,nbOfFaces,lgth,retConn,retLgth);
+ case 505:
+ return tryToUnPolyPyra5(conn,nbOfFaces,lgth,retConn,retLgth);
+ case 404:
+ return tryToUnPolyTetra4(conn,nbOfFaces,lgth,retConn,retLgth);
+ default:
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ return INTERP_KERNEL::NORM_POLYHED;
+ }
+}
+
+bool MEDCouplingUMesh::orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace)
+{
+ std::vector<int> tmp2;
+ std::set<int> bases(baseFace,baseFace+lgthBaseFace);
+ std::set<int> sides(sideFace,sideFace+4);
+ std::set_intersection(bases.begin(),bases.end(),sides.begin(),sides.end(),std::back_insert_iterator< std::vector<int> >(tmp2));
+ if(tmp2.size()!=2)
+ return false;
+ std::vector< std::pair<int,int> > baseEdges(lgthBaseFace);
+ std::vector< std::pair<int,int> > oppEdges(lgthBaseFace);
+ std::vector< std::pair<int,int> > sideEdges(4);
+ for(int i=0;i<lgthBaseFace;i++)
+ {
+ baseEdges[i]=std::pair<int,int>(baseFace[i],baseFace[(i+1)%lgthBaseFace]);
+ oppEdges[i]=std::pair<int,int>(retConn[i],retConn[(i+1)%lgthBaseFace]);
+ }
+ for(int i=0;i<4;i++)
+ sideEdges[i]=std::pair<int,int>(sideFace[i],sideFace[(i+1)%4]);
+ std::vector< std::pair<int,int> > tmp;
+ std::set< std::pair<int,int> > baseEdgesS(baseEdges.begin(),baseEdges.end());
+ std::set< std::pair<int,int> > sideEdgesS(sideEdges.begin(),sideEdges.end());
+ std::set_intersection(baseEdgesS.begin(),baseEdgesS.end(),sideEdgesS.begin(),sideEdgesS.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(tmp));
+ if(tmp.empty())
+ {
+ //reverse sideFace
+ for(int i=0;i<4;i++)
+ {
+ std::pair<int,int> p=sideEdges[i];
+ std::pair<int,int> r(p.second,p.first);
+ sideEdges[i]=r;
+ }
+ //end reverse sideFace
+ std::set< std::pair<int,int> > baseEdgesS(baseEdges.begin(),baseEdges.end());
+ std::set< std::pair<int,int> > sideEdgesS(sideEdges.begin(),sideEdges.end());
+ std::set_intersection(baseEdgesS.begin(),baseEdgesS.end(),sideEdgesS.begin(),sideEdgesS.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(tmp));
+ if(tmp.empty())
+ return false;
+ }
+ if(tmp.size()!=1)
+ return false;
+ bool found=false;
+ std::pair<int,int> pInOpp;
+ for(int i=0;i<4 && !found;i++)
+ {//finding the pair(edge) in sideFace that do not include any node of tmp[0] edge
+ found=(tmp[0].first!=sideEdges[i].first && tmp[0].first!=sideEdges[i].second &&
+ tmp[0].second!=sideEdges[i].first && tmp[0].second!=sideEdges[i].second);
+ if(found)
+ {//found ! reverse it
+ pInOpp.first=sideEdges[i].second;
+ pInOpp.second=sideEdges[i].first;
+ }
+ }
+ if(!found)
+ return false;
+ int pos=std::distance(baseEdges.begin(),std::find(baseEdges.begin(),baseEdges.end(),tmp[0]));
+ std::vector< std::pair<int,int> >::iterator it=std::find(oppEdges.begin(),oppEdges.end(),pInOpp);
+ if(it==oppEdges.end())//the opposite edge of side face is not found opposite face ... maybe problem of orientation of polyhedron
+ return false;
+ int pos2=std::distance(oppEdges.begin(),it);
+ int offset=pos-pos2;
+ if(offset<0)
+ offset+=lgthBaseFace;
+ //this is the end copy the result
+ int *tmp3=new int[lgthBaseFace];
+ for(int i=0;i<lgthBaseFace;i++)
+ tmp3[(offset+i)%lgthBaseFace]=oppEdges[i].first;
+ std::copy(tmp3,tmp3+lgthBaseFace,retConn);
+ delete [] tmp3;
+ return true;
+}
+
+bool MEDCouplingUMesh::isWellOriented(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace)
+{
+ return true;
+}
+
+/*!
+ * This method is trying to permute the connectivity of 'oppFace' face so that the k_th node of 'baseFace' is associated to the
+ * k_th node in retConnOfOppFace. Excluded faces 'baseFace' and 'oppFace' all the other faces in 'conn' must be QUAD4 faces.
+ * If the arragement process succeeds true is returned and retConnOfOppFace is filled.
+ */
+bool MEDCouplingUMesh::tryToArrangeOppositeFace(const int *conn, int lgth, int lgthBaseFace, const int *baseFace, const int *oppFace, int nbOfFaces, int *retConnOfOppFace)
+{
+ retConnOfOppFace[0]=oppFace[0];
+ for(int j=1;j<lgthBaseFace;j++)
+ retConnOfOppFace[j]=oppFace[lgthBaseFace-j];
+ const int *curFace=conn;
+ int sideFace=0;
+ bool ret=true;
+ for(int i=0;i<nbOfFaces && ret;i++)
+ {
+ if(curFace!=baseFace && curFace!=oppFace)
+ {
+ if(sideFace==0)
+ ret=orientOppositeFace(baseFace,retConnOfOppFace,curFace,lgthBaseFace);
+ else
+ ret=isWellOriented(baseFace,retConnOfOppFace,curFace,lgthBaseFace);
+ sideFace++;
+ }
+ curFace=std::find(curFace,conn+lgth,-1);
+ curFace++;
+ }
+ return ret;
+}
+
+/*!
+ * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_HEXA8 is returned.
+ * This method is only callable if in 'conn' there is 8 nodes and 6 faces.
+ * If fails a POLYHED is returned.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth)
+{
+ if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to<int>(),(int)INTERP_KERNEL::NORM_QUAD4))==conn+lgth+nbOfFaces)
+ {//6 faces are QUAD4.
+ int oppositeFace=-1;
+ std::set<int> conn1(conn,conn+4);
+ for(int i=1;i<6 && oppositeFace<0;i++)
+ {
+ std::vector<int> tmp;
+ std::set<int> conn2(conn+5*i,conn+5*i+4);
+ std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ if(tmp.empty())
+ oppositeFace=i;
+ }
+ if(oppositeFace>=1)
+ {//oppositeFace of face#0 found.
+ int tmp2[4];
+ if(tryToArrangeOppositeFace(conn,lgth,4,conn,conn+5*oppositeFace,6,tmp2))
+ {
+ std::copy(conn,conn+4,retConn);
+ std::copy(tmp2,tmp2+4,retConn+4);
+ retLgth=8;
+ return INTERP_KERNEL::NORM_HEXA8;
+ }
+ }
+ }
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ return INTERP_KERNEL::NORM_POLYHED;
+}
+
+/*!
+ * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PENTA6 is returned.
+ * If fails a POLYHED is returned.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth)
+{
+ int nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3);
+ int nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4);
+ if(nbOfTriFace==2 && nbOfQuadFace==3)
+ {
+ int tri3_0=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3));
+ int tri3_1=std::distance(conn+lgth,std::find(conn+lgth+tri3_0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3));
+ const int *tri_0,*tri_1;
+ const int *w=conn;
+ for(int i=0;i<5;i++)
+ {
+ if(i==tri3_0)
+ tri_0=w;
+ if(i==tri3_1)
+ tri_1=w;
+ w=std::find(w,conn+lgth,-1);
+ w++;
+ }
+ std::vector<int> tmp;
+ std::set<int> conn1(tri_0,tri_0+3);
+ std::set<int> conn2(tri_1,tri_1+3);
+ std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ if(tmp.empty())
+ {
+ int tmp2[3];
+ if(tryToArrangeOppositeFace(conn,lgth,3,tri_0,tri_1,5,tmp2))
+ {
+ std::copy(conn,conn+4,retConn);
+ std::copy(tmp2,tmp2+3,retConn+3);
+ retLgth=6;
+ return INTERP_KERNEL::NORM_PENTA6;
+ }
+ }
+ }
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ return INTERP_KERNEL::NORM_POLYHED;
+}
+
+/*!
+ * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PYRA5 is returned.
+ * If fails a POLYHED is returned.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth)
+{
+ int nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3);
+ int nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4);
+ if(nbOfTriFace==4 && nbOfQuadFace==1)
+ {
+ int quad4_pos=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4));
+ const int *quad4=0;
+ const int *w=conn;
+ for(int i=0;i<5 && quad4==0;i++)
+ {
+ if(i==quad4_pos)
+ quad4=w;
+ w=std::find(w,conn+lgth,-1);
+ w++;
+ }
+ std::set<int> quad4S(quad4,quad4+4);
+ w=conn;
+ bool ok=true;
+ int point=-1;
+ for(int i=0;i<5 && ok;i++)
+ if(i!=quad4_pos)
+ {
+ std::vector<int> tmp;
+ std::set<int> conn2(w,w+3);
+ std::set_intersection(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ ok=tmp.size()==2;
+ tmp.clear();
+ std::set_difference(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ ok=ok && tmp.size()==1;
+ if(ok)
+ {
+ if(point>=0)
+ ok=point==tmp[0];
+ else
+ point=tmp[0];
+ }
+ w=std::find(w,conn+lgth,-1);
+ w++;
+ }
+ if(ok && point>=0)
+ {
+ std::copy(quad4,quad4+4,retConn);
+ retConn[4]=point;
+ retLgth=5;
+ return INTERP_KERNEL::NORM_PYRA5;
+ }
+ }
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ return INTERP_KERNEL::NORM_POLYHED;
+}
+
+/*!
+ * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_TETRA4 is returned.
+ * If fails a POLYHED is returned.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth)
+{
+ if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to<int>(),(int)INTERP_KERNEL::NORM_TRI3))==conn+lgth+nbOfFaces)
+ {
+ std::set<int> tribase(conn,conn+3);
+ int point=-1;
+ bool ok=true;
+ for(int i=1;i<4 && ok;i++)
+ {
+ std::vector<int> tmp;
+ std::set<int> conn2(conn+i*4,conn+4*i+3);
+ std::set_intersection(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ ok=tmp.size()==2;
+ tmp.clear();
+ std::set_difference(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector<int> >(tmp));
+ ok=ok && tmp.size()==1;
+ if(ok)
+ {
+ if(point>=0)
+ ok=point==tmp[0];
+ else
+ point=tmp[0];
+ }
+ }
+ if(ok && point>=0)
+ {
+ std::copy(conn,conn+3,retConn);
+ retConn[3]=point;
+ retLgth=4;
+ return INTERP_KERNEL::NORM_TETRA4;
+ }
+ }
+ retLgth=lgth;
+ std::copy(conn,conn+lgth,retConn);
+ return INTERP_KERNEL::NORM_POLYHED;
+}