Salome HOME
Merge from V5_1_main branch 24/11/2010
[modules/smesh.git] / src / SMESH / SMESH_Algo.cxx
index c44010450c5b0899dc64014bd857081ffe27aa86..3a6a4efd97dad1f5624cdbb07a530c909c59b2b1 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  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
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Algo.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #include "SMESH_Algo.hxx"
 #include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
@@ -61,6 +61,7 @@
 #include "utilities.h"
 
 #include <algorithm>
+#include <limits>
 
 using namespace std;
 
@@ -76,7 +77,7 @@ SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen)
   gen->_mapAlgo[hypId] = this;
 
   _onlyUnaryInput = _requireDescretBoundary = _requireShape = true;
-  _quadraticMesh = false;
+  _quadraticMesh = _supportSubmeshes = false;
   _error = COMPERR_OK;
 }
 
@@ -175,6 +176,37 @@ double SMESH_Algo::EdgeLength(const TopoDS_Edge & E)
   return length;
 }
 
+//================================================================================
+/*!
+ * \brief Calculate normal of a mesh face
+ */
+//================================================================================
+
+bool SMESH_Algo::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized)
+{
+  if ( !F || F->GetType() != SMDSAbs_Face )
+    return false;
+
+  normal.SetCoord(0,0,0);
+  int nbNodes = F->IsQuadratic() ? F->NbNodes()/2 : F->NbNodes();
+  for ( int i = 0; i < nbNodes-2; ++i )
+  {
+    gp_XYZ p[3];
+    for ( int n = 0; n < 3; ++n )
+    {
+      const SMDS_MeshNode* node = F->GetNode( i + n );
+      p[n].SetCoord( node->X(), node->Y(), node->Z() );
+    }
+    normal += ( p[2] - p[1] ) ^ ( p[0] - p[1] );
+  }
+  double size2 = normal.SquareModulus();
+  bool ok = ( size2 > numeric_limits<double>::min() * numeric_limits<double>::min());
+  if ( normalized && ok )
+    normal /= sqrt( size2 );
+
+  return ok;
+}
+
 //================================================================================
 /*!
  * \brief Find out elements orientation on a geometrical face
@@ -321,7 +353,7 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
   if ( !eSubMesh || !eSubMesh->GetElements()->more() )
     return false; // edge is not meshed
 
-  int nbEdgeNodes = 0;
+  //int nbEdgeNodes = 0;
   set < double > paramSet;
   if ( eSubMesh )
   {
@@ -457,9 +489,14 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
  */
 //================================================================================
 
-GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1,
-                                     const TopoDS_Edge & E2)
+GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1,
+                                     TopoDS_Edge E2)
 {
+  //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges
+  if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL
+      E1.Orientation( TopAbs_FORWARD );
+  if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL
+      E2.Orientation( TopAbs_FORWARD );
   TopoDS_Vertex V = TopExp::LastVertex (E1, true);
   if ( !V.IsSame( TopExp::FirstVertex(E2, true )))
     if ( !TopExp::CommonVertex( E1, E2, V ))
@@ -500,6 +537,21 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
   return 0;
 }
 
+//=======================================================================
+//function : GetCommonNodes
+//purpose  : Return nodes common to two elements
+//=======================================================================
+
+vector< const SMDS_MeshNode*> SMESH_Algo::GetCommonNodes(const SMDS_MeshElement* e1,
+                                                         const SMDS_MeshElement* e2)
+{
+  vector< const SMDS_MeshNode*> common;
+  for ( int i = 0 ; i < e1->NbNodes(); ++i )
+    if ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 )
+      common.push_back( e1->GetNode( i ));
+  return common;
+}
+
 //================================================================================
 /*!
  * \brief Sets event listener to submeshes if necessary