Salome HOME
Regression of SALOME_TESTS/Grids/smesh/imps_09/K2
[modules/smesh.git] / src / StdMeshers / StdMeshers_ProjectionUtils.cxx
index 3e9f5c46239fdb906be4b9f9540f0f43699fce2c..ae6f38419e465580eafdaad0461a7a1eaa107224 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -438,8 +438,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
                                                          TShapeShapeMap &    theMap)
 {
   // Structure of this long function is following
-  // 1) Group->group projection: theShape1 is a group member,
-  //    theShape2 is a group. We find a group theShape1 is in and recall self.
+  // 1) Group -> Group projection: theShape1 is a group member,
+  //    theShape2 is another group. We find a group theShape1 is in and recall self.
   // 2) Accosiate same shapes with different location (partners).
   // 3) If vertex association is given, perform accosiation according to shape type:
   //       switch ( ShapeType ) {
@@ -622,7 +622,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       TopTools_ListIteratorOfListOfShape ancestIt1( edgeToFace1.FindFromKey( edge1 ));
       for ( ; F1.IsNull() && ancestIt1.More(); ancestIt1.Next() )
         if ( ancestIt1.Value().ShapeType() == TopAbs_FACE )
-          F1 = ancestIt1.Value().Oriented( TopAbs_FORWARD );
+          F1 = ancestIt1.Value().Oriented //( TopAbs_FORWARD );
+            ( SMESH_MesherHelper::GetSubShapeOri( theShape1, ancestIt1.Value() ));
       if ( F1.IsNull() )
         RETURN_BAD_RESULT(" Face1 not found");
 
@@ -630,7 +631,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       TopTools_ListIteratorOfListOfShape ancestIt2( edgeToFace2.FindFromKey( edge2 ));
       for ( int i = 0; FF2[1].IsNull() && ancestIt2.More(); ancestIt2.Next() )
         if ( ancestIt2.Value().ShapeType() == TopAbs_FACE )
-          FF2[ i++ ] = ancestIt2.Value().Oriented( TopAbs_FORWARD );
+          FF2[ i++ ] = ancestIt2.Value().Oriented // ( TopAbs_FORWARD );
+            ( SMESH_MesherHelper::GetSubShapeOri( theShape2, ancestIt2.Value() ));
 
       // get oriented edge1 and edge2 from F1 and FF2[0]
       for ( exp.Init( F1, TopAbs_EDGE ); exp.More(); exp.Next() )
@@ -1330,9 +1332,15 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
           CONT_BAD_RESULT("GetOrderedEdges() failed");
       }
     }
-    edgeIt = --edges2.end();
     if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
       reverse = !reverse;
+      edgeIt = --edges2.end();
+      // move a degenerated edge from back to front
+      // http://www.salome-platform.org/forum/forum_11/173031193
+      if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt ))) {
+        edges2.splice( edges2.begin(), edges2, edgeIt );
+        edgeIt = --edges2.end();
+      }
       // check if the second vertex belongs to the first or last edge in the wire
       if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) {
         bool KO = true; // belongs to none
@@ -1420,7 +1428,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
               // move edge2Beg to place before edge2End
               edges2.splice( edge2End, edges2, edge2Beg++ );
 
-            if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
+            if ( edge2Beg != edges2.end() &&
+                 sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
             {
               if ( iW1 == 0 ) OK = true; // OK is for the first wire
               // reverse edges2 if needed
@@ -1604,79 +1613,87 @@ TopoDS_Vertex StdMeshers_ProjectionUtils::GetNextVertex(const TopoDS_Edge&   edg
 /*
  * Return a propagation edge
  *  \param aMesh - mesh
- *  \param theEdge - edge to find by propagation
+ *  \param anEdge - edge to find by propagation
  *  \param fromEdge - start edge for propagation
+ *  \param chain - return, if !NULL, a propagation chain passed till
+ *         anEdge; if anEdge.IsNull() then a full propagation chain is returned;
+ *         fromEdge is the 1st in the chain
  *  \retval pair<int,TopoDS_Edge> - propagation step and found edge
  */
 //================================================================================
 
 pair<int,TopoDS_Edge>
-StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*        aMesh,
-                                                const TopoDS_Edge& theEdge,
-                                                const TopoDS_Edge& fromEdge)
+StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*                 aMesh,
+                                                const TopoDS_Edge&          anEdge,
+                                                const TopoDS_Edge&          fromEdge,
+                                                TopTools_IndexedMapOfShape* chain)
 {
-  TopTools_IndexedMapOfShape aChain;
+  TopTools_IndexedMapOfShape locChain;
+  TopTools_IndexedMapOfShape& aChain = chain ? *chain : locChain;
   int step = 0;
 
+  //TopTools_IndexedMapOfShape checkedWires;
+  BRepTools_WireExplorer aWE;
+  TopoDS_Shape fourEdges[4];
+
   // List of edges, added to chain on the previous cycle pass
   TopTools_ListOfShape listPrevEdges;
-  listPrevEdges.Append(fromEdge);
+  listPrevEdges.Append( fromEdge );
+  aChain.Add( fromEdge );
 
   // Collect all edges pass by pass
-  while (listPrevEdges.Extent() > 0) {
+  while (listPrevEdges.Extent() > 0)
+  {
     step++;
     // List of edges, added to chain on this cycle pass
     TopTools_ListOfShape listCurEdges;
 
     // Find the next portion of edges
     TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
-    for (; itE.More(); itE.Next()) {
-      TopoDS_Shape anE = itE.Value();
+    for (; itE.More(); itE.Next())
+    {
+      const TopoDS_Shape& anE = itE.Value();
 
       // Iterate on faces, having edge <anE>
       TopTools_ListIteratorOfListOfShape itA (aMesh->GetAncestors(anE));
-      for (; itA.More(); itA.Next()) {
-        TopoDS_Shape aW = itA.Value();
+      for (; itA.More(); itA.Next())
+      {
+        const TopoDS_Shape& aW = itA.Value();
 
         // There are objects of different type among the ancestors of edge
-        if (aW.ShapeType() == TopAbs_WIRE) {
-          TopoDS_Shape anOppE;
-
-          BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
-          Standard_Integer nb = 1, found = 0;
-          TopTools_Array1OfShape anEdges (1,4);
-          for (; aWE.More(); aWE.Next(), nb++) {
-            if (nb > 4) {
-              found = 0;
+        if ( aW.ShapeType() == TopAbs_WIRE /*&& checkedWires.Add( aW )*/)
+        {
+          Standard_Integer nb = 0, found = -1;
+          for ( aWE.Init( TopoDS::Wire( aW )); aWE.More(); aWE.Next() ) {
+            if (nb+1 > 4) {
+              found = -1;
               break;
             }
-            anEdges(nb) = aWE.Current();
-            if (anEdges(nb).IsSame(anE)) found = nb;
+            fourEdges[ nb ] = aWE.Current();
+            if ( aWE.Current().IsSame( anE )) found = nb;
+            nb++;
           }
-
-          if (nb == 5 && found > 0) {
+          if (nb == 4 && found >= 0) {
             // Quadrangle face found, get an opposite edge
-            Standard_Integer opp = found + 2;
-            if (opp > 4) opp -= 4;
-            anOppE = anEdges(opp);
+            TopoDS_Shape& anOppE = fourEdges[( found + 2 ) % 4 ];
 
             // add anOppE to aChain if ...
-            if (!aChain.Contains(anOppE)) { // ... anOppE is not in aChain
+            int prevChainSize = aChain.Extent();
+            if ( aChain.Add(anOppE) > prevChainSize ) { // ... anOppE is not in aChain
               // Add found edge to the chain oriented so that to
               // have it co-directed with a forward MainEdge
               TopAbs_Orientation ori = anE.Orientation();
-              if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
+              if ( anOppE.Orientation() == fourEdges[found].Orientation() )
                 ori = TopAbs::Reverse( ori );
               anOppE.Orientation( ori );
-              if ( anOppE.IsSame( theEdge ))
+              if ( anOppE.IsSame( anEdge ))
                 return make_pair( step, TopoDS::Edge( anOppE ));
-              aChain.Add(anOppE);
               listCurEdges.Append(anOppE);
             }
-          } // if (nb == 5 && found > 0)
+          } // if (nb == 4 && found >= 0)
         } // if (aF.ShapeType() == TopAbs_WIRE)
-      } // for (; itF.More(); itF.Next())
-    } // for (; itE.More(); itE.Next())
+      } // loop on ancestors of anE
+    } // loop on listPrevEdges
 
     listPrevEdges = listCurEdges;
   } // while (listPrevEdges.Extent() > 0)
@@ -2100,7 +2117,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
 
   string algoType = algo->GetName();
   if ( algoType.substr(0, 11) != "Projection_")
-    return gen->Compute( *mesh, shape );
+    return gen->Compute( *mesh, shape, /*shapeOnly=*/true );
 
   // try to compute source mesh
 
@@ -2132,7 +2149,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
     }
   }
   if ( srcShape.IsNull() ) // no projection source defined
-    return gen->Compute( *mesh, shape );
+    return gen->Compute( *mesh, shape, /*shapeOnly=*/true );
 
   if ( srcShape.IsSame( shape ))
     RETURN_BAD_RESULT("Projection from self");
@@ -2141,7 +2158,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
     srcMesh = mesh;
 
   if ( MakeComputed( srcMesh->GetSubMesh( srcShape ), iterationNb + 1 ) &&
-       gen->Compute( *mesh, shape ))
+       gen->Compute( *mesh, shape, /*shapeOnly=*/true ))
     return sm->IsMeshComputed();
 
   return false;