From: ageay Date: Tue, 3 Aug 2010 08:29:48 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: V5_1_main_FINAL~69 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=eee52a533ea7ac2d93fe393dceeef8a02c253d18;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 928edc0c3..bfa591c18 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -67,9 +67,17 @@ try:_mesh2D(mesh2D),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id( 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) @@ -148,8 +156,13 @@ bool MEDCouplingExtrudedMesh::isEqual(const MEDCouplingMesh *other, double prec) 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(); } @@ -236,13 +249,45 @@ void MEDCouplingExtrudedMesh::updateTime() } } +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;isetArray(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; @@ -250,8 +295,7 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) con 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 diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 559831fbc..566b23616 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -55,6 +55,7 @@ namespace ParaMEDMEM 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; @@ -92,6 +93,7 @@ namespace ParaMEDMEM private: MEDCouplingUMesh *_mesh2D; MEDCouplingUMesh *_mesh1D; + //! New to old 3D cell Ids Array DataArrayInt *_mesh3D_ids; int _cell_2D_id; }; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 7c046c06c..e0bcf76ca 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -36,6 +36,8 @@ using namespace ParaMEDMEM; const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_"; +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; + MEDCouplingUMesh *MEDCouplingUMesh::New() { return new MEDCouplingUMesh; @@ -1271,7 +1273,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const { ipt=connec_index[iel]; type=(INTERP_KERNEL::NormalizedCellType)connec[ipt]; - area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space); + area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space,isAbs); } if(isAbs) for(int iel=0;iel& 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;igetPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + bool isModified=false; + for(int i=0;i 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& 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;igetPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + bool isModified=false; + for(int i=0;ideclareAsNew(); + updateTime(); +} + /*! * This method aggregate the bbox of each cell and put it into bbox parameter. * @param bbox out parameter of size 2*spacedim*nbOfcells. @@ -2186,12 +2296,14 @@ void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd, std::back_insert_iterator< std::vector > ii(ret); std::copy(connBg+1,connEnd,ii); *ii++=-1; - std::transform(connBg+1,connEnd,ii,std::bind2nd(std::plus(),deltaz)); + std::reverse_iterator rConnBg(connEnd); + std::reverse_iterator rConnEnd(connBg+1); + std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus(),deltaz)); int nbOfRadFaces=std::distance(connBg+1,connEnd); for(int i=0;i > edges; + int nbOfFaces=std::count(begin,end,-1)+1; + const int *bgFace=begin; + for(int i=0;i 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(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 > edges; + int nbOfFaces=std::count(begin,end,-1)+1; + int *bgFace=begin; + std::vector isPerm(nbOfFaces); + for(int i=0;i p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); + edges.push_back(p1); + } + int *bgFace2=endFace+1; + for(int k=i+1;k 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 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(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 tmp(nbOfEdgesInFace-1); + std::copy(bgFace+1,endFace,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),bgFace+1); + bgFace=endFace+1; + } + } +} diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 04d4bb691..1ae0fdc74 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -93,6 +93,10 @@ namespace ParaMEDMEM 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& 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& 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(); @@ -105,6 +109,9 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector& meshes); MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& 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); @@ -131,6 +138,8 @@ namespace ParaMEDMEM std::set _types; private: static const char PART_OF_NAME[]; + public: + static double EPS_FOR_POLYH_ORIENTATION; }; } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index ce8d1b8c4..7fb1d01fe 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -57,6 +57,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testExtrudedMesh1 ); CPPUNIT_TEST( testExtrudedMesh2 ); CPPUNIT_TEST( testExtrudedMesh3 ); + CPPUNIT_TEST( testExtrudedMesh4 ); CPPUNIT_TEST( testFindCommonNodes ); CPPUNIT_TEST( testCheckButterflyCells ); CPPUNIT_TEST( testMergeMesh1 ); @@ -88,6 +89,8 @@ namespace ParaMEDMEM //MEDCouplingBasicsTest2.cxx CPPUNIT_TEST( testGaussPointField1 ); CPPUNIT_TEST( testGaussPointNEField1 ); + CPPUNIT_TEST( testCellOrientation1 ); + CPPUNIT_TEST( testCellOrientation2 ); //MEDCouplingBasicsTestInterp.cxx CPPUNIT_TEST( test2DInterpP0P0_1 ); CPPUNIT_TEST( test2DInterpP0P0PL_1 ); @@ -173,6 +176,7 @@ namespace ParaMEDMEM void testExtrudedMesh1(); void testExtrudedMesh2(); void testExtrudedMesh3(); + void testExtrudedMesh4(); void testFindCommonNodes(); void testCheckButterflyCells(); void testMergeMesh1(); @@ -204,6 +208,8 @@ namespace ParaMEDMEM //MEDCouplingBasicsTest2.cxx void testGaussPointField1(); void testGaussPointNEField1(); + void testCellOrientation1(); + void testCellOrientation2(); //MEDCouplingBasicsTestInterp.cxx void test2DInterpP0P0_1(); void test2DInterpP0P0PL_1(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index 09e9401e7..ef2f42354 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -1103,6 +1103,55 @@ void MEDCouplingBasicsTest::testExtrudedMesh3() 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 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; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index 81d9eee56..b3f96a287 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -142,3 +142,91 @@ void MEDCouplingBasicsTest::testGaussPointNEField1() f->decrRef(); m->decrRef(); } + +void MEDCouplingBasicsTest::testCellOrientation1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + double vec[3]={0.,0.,1.}; + std::vector 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 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 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 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(); +} diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index dc4568624..9a06753e0 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -726,6 +726,46 @@ class MEDCouplingBasicsTest(unittest.TestCase): 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); @@ -1767,6 +1807,71 @@ class MEDCouplingBasicsTest(unittest.TestCase): 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 diff --git a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i index 8bba623ac..42397071b 100644 --- a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i +++ b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i @@ -90,6 +90,7 @@ using namespace INTERP_KERNEL; %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();" @@ -369,6 +370,7 @@ namespace ParaMEDMEM 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 { @@ -499,6 +501,47 @@ namespace ParaMEDMEM PyList_SetItem(ret,1,ret1); return ret; } + + PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception) + { + std::vector 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 cells; + self->arePolyhedronsNotCorrectlyOriented(cells); + return convertIntArrToPyList2(cells); + } } void convertToPolyTypes(const std::vector& cellIdsToConvert); MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy); @@ -509,6 +552,7 @@ namespace ParaMEDMEM { public: static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *build3DUnstructuredMesh() const; %extend { PyObject *getMesh2D() const {