]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Debugging orientCorrectlyPoly. More general implementation
authorageay <ageay>
Fri, 25 Jan 2013 11:30:50 +0000 (11:30 +0000)
committerageay <ageay>
Fri, 25 Jan 2013 11:30:50 +0000 (11:30 +0000)
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py

index 465419372253d959e3febc2c6aa7288beca54bc4..327c593c8b47b8eec83ae1e6be8f9c64b5f2406c 100644 (file)
@@ -4767,8 +4767,18 @@ void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Excepti
     {
       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);
+        {
+          try
+            {
+              if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+                TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+            }
+          catch(INTERP_KERNEL::Exception& e)
+            {
+              std::ostringstream oss; oss << "Something wrong in polyhedron #" << i << " : " << e.what();
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
     }
   updateTime();
 }
@@ -6500,42 +6510,63 @@ void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, c
  */
 void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception)
 {
-  std::vector<std::pair<int,int> > edges;
+  std::list< std::pair<int,int> > edgesOK,edgesFinished;
   std::size_t nbOfFaces=std::count(begin,end,-1)+1;
-  int *bgFace=begin;
-  std::vector<bool> isPerm(nbOfFaces);
-  for(std::size_t i=0;i<nbOfFaces;i++)
+  std::vector<bool> isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented
+  isPerm[0]=true;
+  int *bgFace=begin,*endFace=std::find(begin+1,end,-1);
+  std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
+  for(std::size_t l=0;l<nbOfEdgesInFace;l++) { std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); }
+  //
+  while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end())
     {
-      int *endFace=std::find(bgFace+1,end,-1);
-      std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
-      for(std::size_t 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(std::size_t k=i+1;k<nbOfFaces;k++)
+      bgFace=begin;
+      std::size_t smthChanged=0;
+      for(std::size_t i=0;i<nbOfFaces;i++)
         {
-          int *endFace2=std::find(bgFace2+1,end,-1);
-          std::size_t nbOfEdgesInFace2=std::distance(bgFace2,endFace2);
-          for(std::size_t j=0;j<nbOfEdgesInFace2;j++)
+          endFace=std::find(bgFace+1,end,-1);
+          nbOfEdgesInFace=std::distance(bgFace,endFace);
+          if(!isPerm[i])
             {
-              std::pair<int,int> p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]);
-              if(std::find(edges.begin(),edges.end(),p2)!=edges.end())
+              bool b;
+              for(std::size_t j=0;j<nbOfEdgesInFace;j++)
                 {
-                  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;
+                  std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+                  std::pair<int,int> p2(p1.second,p1.first);
+                  bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end();
+                  bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end();
+                  if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; }
+                }
+              if(isPerm[i])
+                { 
+                  if(!b)
+                    std::reverse(bgFace+1,endFace);
+                  for(std::size_t j=0;j<nbOfEdgesInFace;j++)
+                    {
+                      std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+                      std::pair<int,int> p2(p1.second,p1.first);
+                      if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end())
+                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+                      if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end())
+                        { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+                      std::list< std::pair<int,int> >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2);
+                      if(it!=edgesOK.end())
+                        {
+                          edgesOK.erase(it);
+                          edgesFinished.push_back(p1);
+                        }
+                      else
+                        edgesOK.push_back(p1);
+                    }
                 }
             }
-          bgFace2=endFace2+1;
+          bgFace=endFace+1;
         }
-      bgFace=endFace+1;
+      if(smthChanged==0)
+        { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); }
     }
+  if(!edgesOK.empty())
+    { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); }
   if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
     {//not lucky ! The first face was not correctly oriented : reorient all faces...
       bgFace=begin;
index 34444816a2d4c1e1bc0ac0de39c7f7198d04d8da..cdae0a4cb67ac4756cce3e3d9c99c55fa0cb3f43 100644 (file)
@@ -10818,6 +10818,28 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             pass
         pass
 
+    def testSwigCellOrientation1(self):
+        coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3)
+        conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]]
+        for i in xrange(256):
+            mesh=MEDCouplingUMesh("FluidMesh_1",3);
+            mesh.allocateCells(0)
+            conn2=[elt[:] for elt in conn]
+            code=bin(i)[2:] ; code='0'*(8-len(code))+code
+            for face,rev in zip(conn2,code):
+                if bool(int(rev)):
+                    face.reverse()
+                    pass
+                pass
+            conn3=[elt+[-1] for elt in conn2]
+            conn3=sum(conn3,[])[:-1]
+            mesh.insertNextCell(NORM_POLYHED,conn3)
+            mesh.setCoords(coords)
+            mesh.orientCorrectlyPolyhedrons()
+            self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12))
+            pass
+        pass
+
     def setUp(self):
         pass
     pass