Salome HOME
PR: merged from V5_1_4rc1
[modules/smesh.git] / src / SMESH / SMESH_Block.cxx
index 59d48a9786386d0c0642aacbb1bf9069e764dce6..b26cfbd9ab435f0510aa6221b2e492743a6ac912 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2003  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 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 
-// 
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//  Copyright (C) 2007-2010  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
+//
+//  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.
+//
+//  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
+//
 
 // File      : SMESH_Pattern.hxx
 // Created   : Mon Aug  2 10:30:00 2004
 // Author    : Edward AGAPOV (eap)
-
-using namespace std;
-
+//
 #include "SMESH_Block.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
@@ -36,6 +37,7 @@ using namespace std;
 #include <Extrema_ExtPC.hxx>
 #include <Extrema_POnCurv.hxx>
 #include <Geom2d_Curve.hxx>
+#include <ShapeAnalysis.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -495,7 +497,7 @@ Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
     return true;
   }
 #ifdef DEBUG_PARAM_COMPUTE
-  cout << "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() << endl;
+  MESSAGE ( "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() );
   myNbIterations++; // how many times call ShellPoint()
 #endif
   ShellPoint( params, P );
@@ -556,8 +558,7 @@ Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
 #endif
     }
 #ifdef DEBUG_PARAM_COMPUTE
-    cout << "F = " << theFxyz(1) <<
-      " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3)  << endl;
+    MESSAGE ( "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) );
     myNbIterations +=3; // how many times call ShellPoint()
 #endif
 
@@ -613,9 +614,9 @@ bool SMESH_Block::computeParameters(const gp_Pnt& thePoint,
   }
 #ifdef DEBUG_PARAM_COMPUTE
   mySumDist += distance();
-  cout << " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"<<endl
-       << " ------ DIST : " << distance() << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
-       << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist << endl;
+  MESSAGE ( " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"<<endl
+         << " ------ DIST : " << distance() << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
+         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
 #endif
 
   theParams = myParam;
@@ -741,7 +742,7 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
   }
 
 #ifdef DEBUG_PARAM_COMPUTE
-  cout << " #### POINT " <<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<" ####"<< endl;
+  MESSAGE ( " #### POINT " <<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<" ####" );
 #endif
 
   if ( myTolerance < 0 ) myTolerance = 1e-6;
@@ -766,8 +767,8 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
         return computeParameters( thePoint, theParams, solution );
     }
 #ifdef DEBUG_PARAM_COMPUTE
-    cout << "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )"<< endl;
-    cout << "DIST: " << sqrt( sqDist ) << endl;
+    MESSAGE ( "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )" );
+    MESSAGE ( "DIST: " << sqrt( sqDist ) );
 #endif
 
     if ( sqDist < sqDistance ) { // get better
@@ -813,9 +814,9 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
 #ifdef DEBUG_PARAM_COMPUTE
   myNbIterations += nbLoops*4; // how many times ShellPoint called
   mySumDist += sqrt( sqDistance );
-  cout << " ------ SOLUTION: ( "<<solution.X()<<" "<<solution.Y()<<" "<<solution.Z()<<" )"<<endl
-       << " ------ DIST : " << sqrt( sqDistance ) << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
-       << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist << endl;
+  MESSAGE ( " ------ SOLUTION: ( "<<solution.X()<<" "<<solution.Y()<<" "<<solution.Z()<<" )"<< std::endl
+         << " ------ DIST : " << sqrt( sqDistance ) << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << std::endl
+         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
 #endif
 
   theParams = solution;
@@ -952,23 +953,42 @@ int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord )
   return id + 1; // shape ids start at 1
 }
 
-//=======================================================================
-//function : GetOrderedEdges
-//purpose  : return nb wires and a list of oredered edges
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Return number of wires and a list of oredered edges.
+ *  \param theFace - the face to process
+ *  \param theFirstVertex - the vertex of the outer wire to set first in the returned
+ *         list ( theFirstVertex may be NULL )
+ *  \param theEdges - all ordered edges of theFace (outer edges goes first).
+ *  \param theNbVertexInWires - nb of vertices (== nb of edges) in each wire
+ *  \param theShapeAnalysisAlgo - if true, ShapeAnalysis::OuterWire() is used to find
+ *         the outer wire else BRepTools::OuterWire() is used.
+ *  \retval int - nb of wires
+ * 
+ * Always try to set a seam edge first.
+ * BRepTools::OuterWire() fails e.g. in the case of issue 0020184,
+ * ShapeAnalysis::OuterWire() fails in the case of issue 0020452
+ */
+//================================================================================
 
 int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
                                   TopoDS_Vertex        theFirstVertex,
                                   list< TopoDS_Edge >& theEdges,
-                                  list< int >  &       theNbVertexInWires)
+                                  list< int >  &       theNbVertexInWires,
+                                  const bool           theShapeAnalysisAlgo)
 {
   // put wires in a list, so that an outer wire comes first
   list<TopoDS_Wire> aWireList;
-  TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace );
-  aWireList.push_back( anOuterWire );
+  TopoDS_Wire anOuterWire =
+    theShapeAnalysisAlgo ? ShapeAnalysis::OuterWire( theFace ) : BRepTools::OuterWire( theFace );
   for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() )
-    if ( !anOuterWire.IsSame( wIt.Value() ))
-      aWireList.push_back( TopoDS::Wire( wIt.Value() ));
+    if ( wIt.Value().ShapeType() == TopAbs_WIRE ) // it can be internal vertex!
+    {
+      if ( !anOuterWire.IsSame( wIt.Value() ))
+        aWireList.push_back( TopoDS::Wire( wIt.Value() ));
+      else
+        aWireList.push_front( TopoDS::Wire( wIt.Value() ));
+    }
 
   // loop on edges of wires
   theNbVertexInWires.clear();
@@ -980,9 +1000,15 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
     for ( iE = 0; wExp.More(); wExp.Next(), iE++ )
     {
       TopoDS_Edge edge = wExp.Current();
-      edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
+      // commented for issue 0020557, other related ones: 0020526, PAL19080
+      // edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
       theEdges.push_back( edge );
     }
+    if ( iE == 0 ) // wExp returns nothing if e.g. the wire contains one internal edge
+    { // Issue 0020676
+      for ( TopoDS_Iterator e( *wlIt ); e.More(); e.Next(), ++iE )
+        theEdges.push_back( TopoDS::Edge( e.Value() ));
+    }
     theNbVertexInWires.push_back( iE );
     iE = 0;
     if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire
@@ -1024,10 +1050,10 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
           if ( iE++ > theNbVertexInWires.back() ) {
 #ifdef _DEBUG_
             gp_Pnt p = BRep_Tool::Pnt( theFirstVertex );
-            cout << " : Warning : vertex "<< theFirstVertex.TShape().operator->()
-                 << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" 
-                 << " not found in outer wire of face "<< theFace.TShape().operator->()
-                 << " with vertices: " <<  endl;
+            MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->()
+                   << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" 
+                   << " not found in outer wire of face "<< theFace.TShape().operator->()
+                   << " with vertices: " );
             wExp.Init( *wlIt, theFace );
             for ( int i = 0; wExp.More(); wExp.Next(), i++ )
             {
@@ -1035,8 +1061,8 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
               edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
               TopoDS_Vertex v = TopExp::FirstVertex( edge, true );
               gp_Pnt p = BRep_Tool::Pnt( v );
-              cout << i << " " << v.TShape().operator->() << " "
-                   << p.X() << " " << p.Y() << " " << p.Z() << " " << endl;
+              MESSAGE_ADD ( i << " " << v.TShape().operator->() << " "
+                            << p.X() << " " << p.Y() << " " << p.Z() << " " << std::endl );
             }
 #endif
             break; // break infinite loop