Salome HOME
Replace Descret by Discrete in variable and method names.
[modules/smesh.git] / src / StdMeshers / StdMeshers_ProjectionUtils.cxx
index dd7db409c47f480b2675b31e17ea54a296f3c426..bc497c74bd4268cdf820f921b0cc609e0bc9972f 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011  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
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  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.
+// 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.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
@@ -307,11 +307,7 @@ namespace {
     if ( gr1It.Value().ShapeType() == TopAbs_FACE )
     {
       // find a boundary edge of group1 to start from
-      TopoDS_Shape bndEdge;
-      TopExp_Explorer edgeExp1( theGroup1, TopAbs_EDGE );
-      for ( ; bndEdge.IsNull() && edgeExp1.More(); edgeExp1.Next())
-        if ( HERE::IsBoundaryEdge( TopoDS::Edge( edgeExp1.Current()), theGroup1, theMesh ))
-          bndEdge = edgeExp1.Current();
+      TopoDS_Shape bndEdge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theGroup1, theMesh );
       if ( bndEdge.IsNull() )
         return false;
 
@@ -375,11 +371,53 @@ namespace {
     return dist2d < tol2d;
   }
 
+  //================================================================================
+  /*!
+   * \brief Returns an EDGE suitable for search of initial vertex association
+   */
+  //================================================================================
+
+  TopoDS_Shape getOuterEdge( const TopoDS_Shape theShape1, SMESH_Mesh& mesh )
+  {
+    TopoDS_Shape edge;
+    if ( theShape1.ShapeType() == TopAbs_COMPOUND )
+    {
+      TopoDS_Iterator it( theShape1 );
+      if ( it.Value().ShapeType() == TopAbs_FACE ) // group of FACEs
+      {
+        // look for a boundary EDGE of a group
+        edge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theShape1, mesh );
+        if ( !edge.IsNull() )
+          return edge;
+      }
+    }
+    edge = theShape1;
+    TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;
+    if ( expF.More() ) {
+      for ( ; expF.More(); expF.Next() ) {
+        edge.Nullify();
+        TopoDS_Shape wire =
+          StdMeshers_ProjectionUtils::OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE );
+        for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
+          if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
+            edge = expE.Current();
+        if ( !edge.IsNull() )
+          break;
+      }
+    } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces
+      edge.Nullify();
+      for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
+        if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
+          edge = expE.Current();
+    }
+    return edge;
+  }
+
 } // namespace
 
 //=======================================================================
 /*!
- * \brief Looks for association of all subshapes of two shapes
+ * \brief Looks for association of all sub-shapes of two shapes
  * \param theShape1 - shape 1
  * \param theMesh1 - mesh built on shape 1
  * \param theShape2 - shape 2
@@ -448,7 +486,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 
   if ( partner ) // Same shape with different location
   {
-    // recursively associate all subshapes of theShape1 and theShape2
+    // recursively associate all sub-shapes of theShape1 and theShape2
     typedef list< pair< TopoDS_Shape, TopoDS_Shape > > TShapePairsList;
     TShapePairsList shapesQueue( 1, make_pair( theShape1, theShape2 ));
     TShapePairsList::iterator s1_s2 = shapesQueue.begin();
@@ -556,7 +594,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       if ( edge2.IsNull() )
         RETURN_BAD_RESULT("GetEdgeByVertices() failed");
 
-      // build map of edge to faces if shapes are not subshapes of main ones
+      // build map of edge to faces if shapes are not sub-shapes of main ones
       bool isSubOfMain = false;
       if ( SMESHDS_SubMesh * sm = theMesh1->GetMeshDS()->MeshElements( theShape1 ))
         isSubOfMain = !sm->IsComplexSubmesh();
@@ -619,7 +657,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 
       TopTools_MapOfShape boundEdges;
 
-      // association of face subshapes and neighbour faces
+      // association of face sub-shapes and neighbour faces
       list< pair < TopoDS_Face, TopoDS_Edge > > FE1, FE2;
       list< pair < TopoDS_Face, TopoDS_Edge > >::iterator fe1, fe2;
       FE1.push_back( make_pair( TopoDS::Face( F1 ), edge1 ));
@@ -1012,15 +1050,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       if ( AssocGroupsByPropagation( theShape1, theShape2, *theMesh1, theMap ))
         return true;
 
-      // find a boundary edge for theShape1
-      TopoDS_Edge E;
-      for(TopExp_Explorer exp(theShape1, TopAbs_EDGE); exp.More(); exp.Next() ) {
-        E = TopoDS::Edge( exp.Current() );
-        if ( IsBoundaryEdge( E, theShape1, *theMesh1 ))
-          break;
-        else
-          E.Nullify();
-      }
+      // find a boundary edge of theShape1
+      TopoDS_Edge E = GetBoundaryEdge( theShape1, *theMesh1 );
       if ( E.IsNull() )
         break; // try by vertex closeness
 
@@ -1078,8 +1109,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   default:;
   }
 
-  // Find association by closeness of vertices
-  // ------------------------------------------
+  // 4.b) Find association by closeness of vertices
+  // ----------------------------------------------
 
   TopTools_IndexedMapOfShape vMap1, vMap2;
   TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 );
@@ -1146,24 +1177,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   // Find 2 closest vertices
 
   // get 2 linked vertices of shape 1 not belonging to an inner wire of a face
-  TopoDS_Shape edge = theShape1;
-  TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;
-  if ( expF.More() ) {
-    for ( ; expF.More(); expF.Next() ) {
-      edge.Nullify();
-      TopoDS_Shape wire = OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE );
-      for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
-        if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
-          edge = expE.Current();
-      if ( !edge.IsNull() )
-        break;
-    }
-  } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces
-    edge.Nullify();
-    for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
-      if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
-        edge = expE.Current();
-  }
+  TopoDS_Shape edge = getOuterEdge( theShape1, *theMesh1 );
   if ( edge.IsNull() || edge.ShapeType() != TopAbs_EDGE )
     RETURN_BAD_RESULT("Edge not found");
 
@@ -1302,9 +1316,10 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
     gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 );
     gp_Vec2d v01f1Vec( v0f1UV, v1f1UV );
     gp_Vec2d v01f2Vec( v0f2UV, v1f2UV );
-    if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV && Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV )
+    if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV &&
+         Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV )
     {
-      if ( i_ok_wire_algo != 1 )
+      if ( !OK /*i_ok_wire_algo != 1*/ )
       {
         edges1.clear();
         edges2.clear();
@@ -1581,7 +1596,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*        aMesh,
     * \param mesh1 - mesh containing elements on the first face
     * \param face2 - the second face
     * \param mesh2 - mesh containing elements on the second face
-    * \param assocMap - map associating subshapes of the faces
+    * \param assocMap - map associating sub-shapes of the faces
     * \param node1To2Map - map containing found matching nodes
     * \retval bool - is a success
    */
@@ -1637,7 +1652,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
     TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2 ));
     if ( !helper1.IsSubShape( e1, face1 ))
       RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( e1 ) <<
-                        " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 ));
+                        " isn't a sub-shape of face " << meshDS1->ShapeToIndex( face1 ));
     // check that there are nodes on edges
     SMESHDS_SubMesh * eSM1 = meshDS1->MeshElements( e1 );
     SMESHDS_SubMesh * eSM2 = meshDS2->MeshElements( e2 );
@@ -1903,10 +1918,10 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
 
 //================================================================================
   /*!
-   * \brief Return any subshape of a face belonging to the outer wire
+   * \brief Return any sub-shape of a face belonging to the outer wire
     * \param face - the face
-    * \param type - type of subshape to return
-    * \retval TopoDS_Shape - the found subshape
+    * \param type - type of sub-shape to return
+    * \retval TopoDS_Shape - the found sub-shape
    */
 //================================================================================
 
@@ -1939,7 +1954,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
 
   SMESH_Mesh* mesh = sm->GetFather();
   SMESH_Gen* gen   = mesh->GetGen();
-  SMESH_Algo* algo = gen->GetAlgo( *mesh, sm->GetSubShape() );
+  SMESH_Algo* algo = sm->GetAlgo();
   if ( !algo )
   {
     if ( sm->GetSubShape().ShapeType() != TopAbs_COMPOUND )
@@ -2003,9 +2018,9 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
 
 //================================================================================
 /*!
- * \brief Count nb of subshapes
+ * \brief Count nb of sub-shapes
  * \param shape - the shape
- * \param type - the type of subshapes to count
+ * \param type - the type of sub-shapes to count
  * \retval int - the calculated number
  */
 //================================================================================
@@ -2029,33 +2044,35 @@ int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape&    shape,
 
 //================================================================================
 /*!
- * \brief Return true if edge is a boundary of edgeContainer
+ * \brief Return a boundary EDGE of edgeContainer
  */
 //================================================================================
 
-bool StdMeshers_ProjectionUtils::IsBoundaryEdge(const TopoDS_Edge&  edge,
-                                                const TopoDS_Shape& edgeContainer,
-                                                SMESH_Mesh&         mesh)
+TopoDS_Edge StdMeshers_ProjectionUtils::GetBoundaryEdge(const TopoDS_Shape& edgeContainer,
+                                                        const SMESH_Mesh&   mesh)
 {
   TopTools_IndexedMapOfShape facesOfEdgeContainer, facesNearEdge;
   TopExp::MapShapes( edgeContainer, TopAbs_FACE, facesOfEdgeContainer );
 
-  const TopTools_ListOfShape& EAncestors = mesh.GetAncestors(edge);
-  TopTools_ListIteratorOfListOfShape itea(EAncestors);
-  for(; itea.More(); itea.Next()) {
-    if( itea.Value().ShapeType() == TopAbs_FACE &&
-        facesOfEdgeContainer.Contains( itea.Value() ))
+  if ( !facesOfEdgeContainer.IsEmpty() ) 
+    for ( TopExp_Explorer exp(edgeContainer, TopAbs_EDGE); exp.More(); exp.Next() )
     {
-      facesNearEdge.Add( itea.Value() );
-      if ( facesNearEdge.Extent() > 1 )
-        return false;
+      const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+      facesNearEdge.Clear();
+      PShapeIteratorPtr faceIt = SMESH_MesherHelper::GetAncestors( edge, mesh, TopAbs_FACE );
+      while ( const TopoDS_Shape* face = faceIt->next() )
+        if ( facesOfEdgeContainer.Contains( *face ))
+          if ( facesNearEdge.Add( *face ) && facesNearEdge.Extent() > 1 )
+            break;
+      if ( facesNearEdge.Extent() == 1 )
+        return edge;
     }
-  }
-  return ( facesNearEdge.Extent() == 1 );
+
+  return TopoDS_Edge();
 }
 
 
-namespace {
+namespace { // Definition of event listeners
 
   SMESH_subMeshEventListener* GetSrcSubMeshListener();
 
@@ -2068,8 +2085,8 @@ namespace {
 
   struct HypModifWaiter: SMESH_subMeshEventListener
   {
-    HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh
-
+    HypModifWaiter():SMESH_subMeshEventListener(false,// won't be deleted by submesh
+                                                "StdMeshers_ProjectionUtils::HypModifWaiter") {}
     void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
                       EventListenerData*, const SMESH_Hypothesis*)
     {
@@ -2079,9 +2096,7 @@ namespace {
         // delete current source listener
         subMesh->DeleteEventListener( GetSrcSubMeshListener() );
         // let algo set a new one
-        SMESH_Gen* gen = subMesh->GetFather()->GetGen();
-        if ( SMESH_Algo* algo = gen->GetAlgo( *subMesh->GetFather(),
-                                              subMesh->GetSubShape() ))
+        if ( SMESH_Algo* algo = subMesh->GetAlgo() )
           algo->SetEventListener( subMesh );
       }
     }
@@ -2103,7 +2118,8 @@ namespace {
   //================================================================================
 
   SMESH_subMeshEventListener* GetSrcSubMeshListener() {
-    static SMESH_subMeshEventListener srcListener(0); // won't be deleted by submesh
+    static SMESH_subMeshEventListener srcListener(false, // won't be deleted by submesh
+                                                  "StdMeshers_ProjectionUtils::SrcSubMeshListener");
     return &srcListener;
   }
 }
@@ -2137,7 +2153,7 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh,
       if ( srcShapeSM->GetSubMeshDS() &&
            srcShapeSM->GetSubMeshDS()->IsComplexSubmesh() )
       {  // source shape is a group
-        TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into subshapes...
+        TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into sub-shapes...
                            subMesh->GetSubShape().ShapeType()); // ...of target shape type
         for (; it.More(); it.Next())
         {