if(_mesh2D!=0)
_mesh2D->incrRef();
computeExtrusion(mesh3D);
+ setName(mesh3D->getName());
}
-catch(INTERP_KERNEL::Exception&)
+catch(INTERP_KERNEL::Exception& e)
{
+ if(_mesh2D)
+ _mesh2D->decrRef();
+ if(_mesh1D)
+ _mesh1D->decrRef();
+ if(_mesh3D_ids)
+ _mesh3D_ids->decrRef();
+ throw e;
}
MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1)
INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const
{
+ const int *ids=_mesh3D_ids->getConstPointer();
+ int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
+ const int *where=std::find(ids,ids+nbOf3DCells,cellId);
+ if(where==ids+nbOf3DCells)
+ throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !");
int nbOfCells2D=_mesh2D->getNumberOfCells();
- int locId=cellId%nbOfCells2D;
+ int locId=std::distance(ids,where)%nbOfCells2D;
INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId);
return INTERP_KERNEL::CellModel::getCellModel(tmp).getExtrudedType();
}
}
}
+MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const
+{
+ MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMeshFromThis(_mesh1D,0);
+ const int *renum=_mesh3D_ids->getConstPointer();
+ int nbOf3DCells=_mesh3D_ids->getNumberOfTuples();
+ ret->renumberCells(renum,renum+nbOf3DCells,false);
+ ret->setName(getName());
+ return ret;
+}
+
MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
{
- //not implemented yet
- return 0;
+ std::string name="MeasureOfMesh_";
+ name+=getName();
+ MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true);
+ MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true);
+ const double *ret2DPtr=ret2D->getArray()->getConstPointer();
+ const double *ret1DPtr=ret1D->getArray()->getConstPointer();
+ int nbOf2DCells=_mesh2D->getNumberOfCells();
+ int nbOf1DCells=_mesh1D->getNumberOfCells();
+ int nbOf3DCells=nbOf2DCells*nbOf1DCells;
+ const int *renum=_mesh3D_ids->getConstPointer();
+ MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+ ret->setMesh(this);
+ DataArrayDouble *da=DataArrayDouble::New();
+ da->alloc(nbOf3DCells,1);
+ double *retPtr=da->getPointer();
+ for(int i=0;i<nbOf1DCells;i++)
+ for(int j=0;j<nbOf2DCells;j++)
+ retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i];
+ ret->setArray(da);
+ da->decrRef();
+ ret->setName(name.c_str());
+ ret2D->decrRef();
+ ret1D->decrRef();
+ return ret;
}
-MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) const
+MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const
{
//not implemented yet
return 0;
MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
{
- //not implemented yet
- throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField not implemented yet !");
+ throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !");
}
int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const
MEDCouplingUMesh *getMesh2D() const { return _mesh2D; }
MEDCouplingUMesh *getMesh1D() const { return _mesh1D; }
DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; }
+ MEDCouplingUMesh *build3DUnstructuredMesh() const;
MEDCouplingFieldDouble *getMeasureField(bool) const;
MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const;
MEDCouplingFieldDouble *buildOrthogonalField() const;
private:
MEDCouplingUMesh *_mesh2D;
MEDCouplingUMesh *_mesh1D;
+ //! New to old 3D cell Ids Array
DataArrayInt *_mesh3D_ids;
int _cell_2D_id;
};
const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_";
+double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14;
+
MEDCouplingUMesh *MEDCouplingUMesh::New()
{
return new MEDCouplingUMesh;
{
ipt=connec_index[iel];
type=(INTERP_KERNEL::NormalizedCellType)connec[ipt];
- area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space);
+ area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space,isAbs);
}
if(isAbs)
for(int iel=0;iel<nbelem;iel++)
return ret;
}
+/*!
+ * 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.
+ * If not 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+ if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+ throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !");
+ int nbOfCells=getNumberOfCells();
+ const int *conn=_nodal_connec->getConstPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coordsPtr=_coords->getConstPointer();
+ for(int i=0;i<nbOfCells;i++)
+ {
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+ if(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
+ {
+ if(!isPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+ cells.push_back(i);
+ }
+ }
+}
+
+/*!
+ * This method orient correctly (if needed) 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.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception)
+{
+ if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+ throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
+ int nbOfCells=getNumberOfCells();
+ int *conn=_nodal_connec->getPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coordsPtr=_coords->getConstPointer();
+ bool isModified=false;
+ for(int i=0;i<nbOfCells;i++)
+ {
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+ if(!polyOnly || type==INTERP_KERNEL::NORM_POLYGON)
+ if(!isPolygonWellOriented(vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+ {
+ isModified=true;
+ std::vector<int> tmp(connI[i+1]-connI[i]-2);
+ std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
+ std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
+ }
+ }
+ if(isModified)
+ _nodal_connec->declareAsNew();
+ updateTime();
+}
+
+/*!
+ * This method checks that all polyhedrons cells have correctly oriented faces.
+ * If not, 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3
+ */
+void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+ if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+ throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !");
+ int nbOfCells=getNumberOfCells();
+ const int *conn=_nodal_connec->getConstPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coordsPtr=_coords->getConstPointer();
+ for(int i=0;i<nbOfCells;i++)
+ {
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+ if(type==INTERP_KERNEL::NORM_POLYHED)
+ {
+ if(!isPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+ cells.push_back(i);
+ }
+ }
+}
+
+/*!
+ * This method tries to orient correctly polhedrons cells.
+ * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails.
+ */
+void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception)
+{
+ if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+ throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons on it : must be meshDim==3 and spaceDim==3 !");
+ int nbOfCells=getNumberOfCells();
+ int *conn=_nodal_connec->getPointer();
+ const int *connI=_nodal_connec_index->getConstPointer();
+ const double *coordsPtr=_coords->getConstPointer();
+ bool isModified=false;
+ for(int i=0;i<nbOfCells;i++)
+ {
+ INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+ if(type==INTERP_KERNEL::NORM_POLYHED)
+ if(!isPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+ {
+ tryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+ isModified=true;
+ }
+ }
+ if(isModified)
+ _nodal_connec->declareAsNew();
+ updateTime();
+}
+
/*!
* This method aggregate the bbox of each cell and put it into bbox parameter.
* @param bbox out parameter of size 2*spacedim*nbOfcells.
std::back_insert_iterator< std::vector<int> > ii(ret);
std::copy(connBg+1,connEnd,ii);
*ii++=-1;
- std::transform(connBg+1,connEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
+ std::reverse_iterator<const int *> rConnBg(connEnd);
+ std::reverse_iterator<const int *> rConnEnd(connBg+1);
+ std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
int nbOfRadFaces=std::distance(connBg+1,connEnd);
for(int i=0;i<nbOfRadFaces;i++)
{
*ii++=-1;
- int conn[4]={connBg[i+1],connBg[(i+1)%nbOfRadFaces+1],connBg[(i+1)%nbOfRadFaces+1]+deltaz,connBg[i+1]+deltaz};
+ int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz};
std::copy(conn,conn+4,ii);
}
break;
throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !");
}
}
+
+/*!
+ * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords)
+{
+ double v[3]={0.,0.,0.};
+ int sz=std::distance(begin,end);
+ for(int i=0;i<sz;i++)
+ {
+ v[0]+=coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]+2]-coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]+1];
+ v[1]+=coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]]-coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+2];
+ v[2]+=coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+1]-coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]];
+ }
+ return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]<0.;
+}
+
+/*!
+ * The polyhedron is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::isPolyhedronWellOriented(const int *begin, const int *end, const double *coords)
+{
+ std::vector<std::pair<int,int> > edges;
+ int nbOfFaces=std::count(begin,end,-1)+1;
+ const int *bgFace=begin;
+ for(int i=0;i<nbOfFaces;i++)
+ {
+ const int *endFace=std::find(bgFace+1,end,-1);
+ int nbOfEdgesInFace=std::distance(bgFace,endFace);
+ for(int j=0;j<nbOfEdgesInFace;j++)
+ {
+ std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+ if(std::find(edges.begin(),edges.end(),p1)!=edges.end())
+ return false;
+ edges.push_back(p1);
+ }
+ bgFace=endFace+1;
+ }
+ return INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION;
+}
+
+/*!
+ * This method tries to obtain a well oriented polyhedron.
+ * If the algorithm fails, an exception will be thrown.
+ */
+void MEDCouplingUMesh::tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception)
+{
+ std::vector<std::pair<int,int> > edges;
+ int nbOfFaces=std::count(begin,end,-1)+1;
+ int *bgFace=begin;
+ std::vector<bool> isPerm(nbOfFaces);
+ for(int i=0;i<nbOfFaces;i++)
+ {
+ int *endFace=std::find(bgFace+1,end,-1);
+ int nbOfEdgesInFace=std::distance(bgFace,endFace);
+ for(int l=0;l<nbOfEdgesInFace;l++)
+ {
+ std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]);
+ edges.push_back(p1);
+ }
+ int *bgFace2=endFace+1;
+ for(int k=i+1;k<nbOfFaces;k++)
+ {
+ int *endFace2=std::find(bgFace2+1,end,-1);
+ int nbOfEdgesInFace2=std::distance(bgFace2,endFace2);
+ for(int j=0;j<nbOfEdgesInFace2;j++)
+ {
+ std::pair<int,int> p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]);
+ if(std::find(edges.begin(),edges.end(),p2)!=edges.end())
+ {
+ if(isPerm[k])
+ throw INTERP_KERNEL::Exception("Fail to repare polyhedron ! Polyedron looks bad !");
+ std::vector<int> tmp(nbOfEdgesInFace2-1);
+ std::copy(bgFace2+1,endFace2,tmp.rbegin());
+ std::copy(tmp.begin(),tmp.end(),bgFace2+1);
+ isPerm[k]=true;
+ continue;
+ }
+ }
+ bgFace2=endFace2+1;
+ }
+ bgFace=endFace+1;
+ }
+ if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
+ {//not lucky ! The first face was not correctly oriented : reorient all faces...
+ bgFace=begin;
+ for(int i=0;i<nbOfFaces;i++)
+ {
+ int *endFace=std::find(bgFace+1,end,-1);
+ int nbOfEdgesInFace=std::distance(bgFace,endFace);
+ std::vector<int> tmp(nbOfEdgesInFace-1);
+ std::copy(bgFace+1,endFace,tmp.rbegin());
+ std::copy(tmp.begin(),tmp.end(),bgFace+1);
+ bgFace=endFace+1;
+ }
+ }
+}
MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy);
MEDCOUPLING_EXPORT bool isFullyQuadratic() const;
MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const;
+ MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const throw(INTERP_KERNEL::Exception);
+ MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception);
+ MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const throw(INTERP_KERNEL::Exception);
+ MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception);
//utilities for MED File RW
MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const;
MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes();
MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2);
MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes);
MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr);
+ MEDCOUPLING_EXPORT static bool isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords);
+ MEDCOUPLING_EXPORT static bool isPolyhedronWellOriented(const int *begin, const int *end, const double *coords);
+ MEDCOUPLING_EXPORT static void tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception);
private:
MEDCouplingUMesh();
MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy);
std::set<INTERP_KERNEL::NormalizedCellType> _types;
private:
static const char PART_OF_NAME[];
+ public:
+ static double EPS_FOR_POLYH_ORIENTATION;
};
}
CPPUNIT_TEST( testExtrudedMesh1 );
CPPUNIT_TEST( testExtrudedMesh2 );
CPPUNIT_TEST( testExtrudedMesh3 );
+ CPPUNIT_TEST( testExtrudedMesh4 );
CPPUNIT_TEST( testFindCommonNodes );
CPPUNIT_TEST( testCheckButterflyCells );
CPPUNIT_TEST( testMergeMesh1 );
//MEDCouplingBasicsTest2.cxx
CPPUNIT_TEST( testGaussPointField1 );
CPPUNIT_TEST( testGaussPointNEField1 );
+ CPPUNIT_TEST( testCellOrientation1 );
+ CPPUNIT_TEST( testCellOrientation2 );
//MEDCouplingBasicsTestInterp.cxx
CPPUNIT_TEST( test2DInterpP0P0_1 );
CPPUNIT_TEST( test2DInterpP0P0PL_1 );
void testExtrudedMesh1();
void testExtrudedMesh2();
void testExtrudedMesh3();
+ void testExtrudedMesh4();
void testFindCommonNodes();
void testCheckButterflyCells();
void testMergeMesh1();
//MEDCouplingBasicsTest2.cxx
void testGaussPointField1();
void testGaussPointNEField1();
+ void testCellOrientation1();
+ void testCellOrientation2();
//MEDCouplingBasicsTestInterp.cxx
void test2DInterpP0P0_1();
void test2DInterpP0P0PL_1();
m1->decrRef();
}
+/*!
+ * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method, but also, MEDCouplingExtrudedMesh following methods :
+ * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh.
+ */
+void MEDCouplingBasicsTest::testExtrudedMesh4()
+{
+ MEDCouplingUMesh *m1=build2DTargetMesh_1();
+ std::vector<int> cells(2); cells[0]=2; cells[1]=4;
+ m1->convertToPolyTypes(cells);
+ m1->changeSpaceDimension(3);
+ MEDCouplingUMesh *m2=buildCU1DMesh_U();
+ m2->changeSpaceDimension(3);
+ double center[3]={0.,0.,0.};
+ double vector[3]={0.,1.,0.};
+ m2->rotate(center,vector,-M_PI/2.);
+ MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0);
+ const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4};
+ const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12};
+ m3->renumberCells(expected1,expected1+15,false);
+ MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0);
+ CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0));
+ CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1));
+ CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2));
+ CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7));
+ MEDCouplingFieldDouble *f=m4->getMeasureField(true);
+ DataArrayDouble *arr=f->getArray();
+ CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples());
+ CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents());
+ const double *arrPtr=arr->getConstPointer();
+ const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625};
+ for(int i=0;i<15;i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16);
+ f->decrRef();
+ MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh();
+ CPPUNIT_ASSERT(m5->isEqual(m3,1e-12));
+ f=m5->getMeasureField(true);
+ arr=f->getArray();
+ arrPtr=arr->getConstPointer();
+ for(int i=0;i<15;i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16);
+ f->decrRef();
+ m5->decrRef();
+ //
+ m4->decrRef();
+ m3->decrRef();
+ m2->decrRef();
+ m1->decrRef();
+}
+
void MEDCouplingBasicsTest::testFindCommonNodes()
{
DataArrayInt *comm,*commI;
f->decrRef();
m->decrRef();
}
+
+void MEDCouplingBasicsTest::testCellOrientation1()
+{
+ MEDCouplingUMesh *m=build2DTargetMesh_1();
+ double vec[3]={0.,0.,1.};
+ std::vector<int> res1;
+ CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception);
+ m->changeSpaceDimension(3);
+ res1.clear();
+ m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+ CPPUNIT_ASSERT(res1.empty());
+ vec[2]=-1;
+ m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+ CPPUNIT_ASSERT_EQUAL(5,(int)res1.size());
+ res1.clear();
+ //
+ vec[2]=1.;
+ // connectivity inversion
+ int *conn=m->getNodalConnectivity()->getPointer();
+ int tmp=conn[11];
+ conn[11]=conn[12];
+ conn[12]=tmp;
+ m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+ CPPUNIT_ASSERT_EQUAL(1,(int)res1.size());
+ CPPUNIT_ASSERT_EQUAL(2,res1[0]);
+ res1.clear();
+ m->orientCorrectly2DCells(vec,false);
+ m->are2DCellsNotCorrectlyOriented(vec,false,res1);
+ CPPUNIT_ASSERT(res1.empty());
+ MEDCouplingUMesh *m2=build2DTargetMesh_1();
+ m2->changeSpaceDimension(3);
+ CPPUNIT_ASSERT(m->isEqual(m2,1e-12));
+ m2->decrRef();
+ //
+ m->decrRef();
+}
+
+void MEDCouplingBasicsTest::testCellOrientation2()
+{
+ MEDCouplingUMesh *m1=0;
+ MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1);
+ m1->decrRef();
+ std::vector<int> res1;
+ m2->arePolyhedronsNotCorrectlyOriented(res1);
+ CPPUNIT_ASSERT_EQUAL(6,(int)res1.size());
+ m2->orientCorrectlyPolyhedrons();
+ res1.clear();
+ m2->arePolyhedronsNotCorrectlyOriented(res1);
+ CPPUNIT_ASSERT(res1.empty());
+ m2->checkCoherency();
+ CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells());
+ int cellIds[3]={0,6,12};
+ std::vector<int> cellIds2(cellIds,cellIds+3);
+ m2->convertToPolyTypes(cellIds2);
+ m2->orientCorrectlyPolyhedrons();
+ res1.clear();
+ m2->arePolyhedronsNotCorrectlyOriented(res1);
+ CPPUNIT_ASSERT(res1.empty());
+ MEDCouplingFieldDouble *f2=m2->getMeasureField(false);
+ const double *f2Ptr=f2->getArray()->getConstPointer();
+ //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation
+ MEDCouplingUMesh *m3=build2DTargetMesh_1();
+ double vec[3]={0.,0.,-1.};//<- important for the test
+ m3->changeSpaceDimension(3);
+ const int ids1[5]={0,1,2,3,4};
+ std::vector<int> ids2(ids1,ids1+5);
+ m3->convertToPolyTypes(ids2);
+ m3->orientCorrectly2DCells(vec,false);
+ MEDCouplingUMesh *m4=buildCU1DMesh_U();
+ m4->changeSpaceDimension(3);
+ double center[3]={0.,0.,0.};
+ double vector[3]={0.,1.,0.};
+ m4->rotate(center,vector,-M_PI/2.);
+ MEDCouplingUMesh *m5=m3->buildExtrudedMeshFromThis(m4,0);
+ res1.clear();
+ m5->arePolyhedronsNotCorrectlyOriented(res1);
+ CPPUNIT_ASSERT_EQUAL(15,(int)res1.size());
+ m5->orientCorrectlyPolyhedrons();
+ res1.clear();
+ m5->arePolyhedronsNotCorrectlyOriented(res1);
+ CPPUNIT_ASSERT(res1.empty());
+ m5->decrRef();
+ m3->decrRef();
+ m4->decrRef();
+ //
+ f2->decrRef();
+ m2->decrRef();
+}
self.assertEqual(expected1,m3DIds);
pass
+ def testExtrudedMesh4(self):
+ m1=MEDCouplingDataForTest.build2DTargetMesh_1();
+ cells=[2,4];
+ m1.convertToPolyTypes(cells);
+ m1.changeSpaceDimension(3);
+ m2=MEDCouplingDataForTest.buildCU1DMesh_U();
+ m2.changeSpaceDimension(3);
+ center=[0.,0.,0.]
+ vector=[0.,1.,0.]
+ m2.rotate(center,vector,-pi/2.);
+ m3=m1.buildExtrudedMeshFromThis(m2,0);
+ expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4]
+ rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12]
+ m3.renumberCells(expected1,False);
+ m4=MEDCouplingExtrudedMesh.New(m3,m1,0);
+ self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0));
+ self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1));
+ self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2));
+ self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7));
+ f=m4.getMeasureField(True);
+ arr=f.getArray();
+ self.assertEqual(15,arr.getNumberOfTuples());
+ self.assertEqual(1,arr.getNumberOfComponents());
+ arrPtr=arr.getValues();
+ expected2=[0.075,0.0375,0.0375,0.075,0.075,
+ 0.1125,0.05625,0.05625,0.1125,0.1125,
+ 0.0625,0.03125,0.03125,0.0625,0.0625]
+ for i in xrange(15):
+ self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16);
+ pass
+ m5=m4.build3DUnstructuredMesh();
+ self.assertTrue(m5.isEqual(m3,1e-12));
+ f=m5.getMeasureField(True);
+ arr=f.getArray();
+ arrPtr=arr.getValues();
+ for i in xrange(15):
+ self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],1e-16);
+ pass
+ pass
+
def testFindCommonNodes(self):
targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1();
comm,commI=targetMesh.findCommonNodes(1e-10);
self.assertAlmostEqual(18.,f.getIJK(1,1,1),14);
pass
+ def testCellOrientation1(self):
+ m=MEDCouplingDataForTest.build2DTargetMesh_1();
+ vec=[0.,0.,1.]
+ self.assertRaises(Exception,m.are2DCellsNotCorrectlyOriented,vec,False);
+ m.changeSpaceDimension(3);
+ res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+ self.assertTrue(len(res1)==0);
+ vec[2]=-1.;
+ res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+ self.assertEqual(5,len(res1));
+ #
+ vec[2]=1.;
+ # connectivity inversion
+ conn=m.getNodalConnectivity().getValues();
+ tmp=conn[11];
+ conn[11]=conn[12];
+ conn[12]=tmp;
+ m.getNodalConnectivity().setValues(conn,len(conn),1)
+ res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+ self.assertEqual(1,len(res1));
+ self.assertEqual(2,res1[0]);
+ m.orientCorrectly2DCells(vec,False);
+ res1=m.are2DCellsNotCorrectlyOriented(vec,False);
+ self.assertTrue(len(res1)==0);
+ m2=MEDCouplingDataForTest.build2DTargetMesh_1();
+ m2.changeSpaceDimension(3);
+ self.assertTrue(m.isEqual(m2,1e-12));
+ pass
+
+ def testCellOrientation2(self):
+ m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1();
+ res1=m2.arePolyhedronsNotCorrectlyOriented();
+ self.assertEqual(6,len(res1));
+ m2.orientCorrectlyPolyhedrons();
+ res1=m2.arePolyhedronsNotCorrectlyOriented();
+ self.assertTrue(len(res1)==0);
+ m2.checkCoherency();
+ self.assertEqual(18,m2.getNumberOfCells());
+ cellIds2=[0,6,12]
+ m2.convertToPolyTypes(cellIds2);
+ m2.orientCorrectlyPolyhedrons();
+ res1=m2.arePolyhedronsNotCorrectlyOriented();
+ self.assertTrue(len(res1)==0);
+ f2=m2.getMeasureField(False);
+ f2Ptr=f2.getArray().getValues();
+ #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation
+ m3=MEDCouplingDataForTest.build2DTargetMesh_1();
+ vec=[0.,0.,-1.]
+ m3.changeSpaceDimension(3);
+ ids2=[0,1,2,3,4]
+ m3.convertToPolyTypes(ids2);
+ m3.orientCorrectly2DCells(vec,False);
+ m4=MEDCouplingDataForTest.buildCU1DMesh_U();
+ m4.changeSpaceDimension(3);
+ center=[0.,0.,0.]
+ vector=[0.,1.,0.]
+ m4.rotate(center,vector,-pi/2.);
+ m5=m3.buildExtrudedMeshFromThis(m4,0);
+ res1=m5.arePolyhedronsNotCorrectlyOriented();
+ self.assertEqual(15,len(res1));
+ m5.orientCorrectlyPolyhedrons();
+ res1=m5.arePolyhedronsNotCorrectlyOriented();
+ self.assertTrue(len(res1)==0);
+ pass
+
def setUp(self):
pass
pass
%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes;
%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType;
%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New;
+%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh;
%newobject ParaMEDMEM::MEDCouplingCMesh::New;
%feature("unref") DataArrayDouble "$this->decrRef();"
%feature("unref") MEDCouplingPointSet "$this->decrRef();"
DataArrayInt *zipConnectivityTraducer(int compType);
void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const;
+ void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception);
%extend {
int getCellContainingPoint(PyObject *p, double eps) const
{
PyList_SetItem(ret,1,ret1);
return ret;
}
+
+ PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception)
+ {
+ std::vector<int> cells;
+ int sz;
+ double *v=convertPyToNewDblArr2(vec,&sz);
+ try
+ {
+ self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete [] v;
+ throw e;
+ }
+ delete [] v;
+ return convertIntArrToPyList2(cells);
+ }
+
+ void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception)
+ {
+ int sz;
+ double *v=convertPyToNewDblArr2(vec,&sz);
+ try
+ {
+ self->orientCorrectly2DCells(v,polyOnly);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete [] v;
+ throw e;
+ }
+ delete [] v;
+ }
+
+ PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception)
+ {
+ std::vector<int> cells;
+ self->arePolyhedronsNotCorrectlyOriented(cells);
+ return convertIntArrToPyList2(cells);
+ }
}
void convertToPolyTypes(const std::vector<int>& cellIdsToConvert);
MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy);
{
public:
static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception);
+ MEDCouplingUMesh *build3DUnstructuredMesh() const;
%extend {
PyObject *getMesh2D() const
{