Salome HOME
22316: EDF 2719 SMESH: Split hexas into prisms
authoreap <eap@opencascade.com>
Mon, 20 Jan 2014 10:35:19 +0000 (10:35 +0000)
committereap <eap@opencascade.com>
Mon, 20 Jan 2014 10:35:19 +0000 (10:35 +0000)
+  double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point );
+  double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point );
+  double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point );

src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESHUtils/SMESH_MeshAlgos.hxx

index 2ecd29a9044f5b483c2645a8b13e7be1a4b700cf..24481ca468f26ff6d6af5f5a947ef7482a6686d1 100644 (file)
 
 #include "SMESH_MeshAlgos.hxx"
 
+#include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_LinearEdge.hxx"
-#include "SMDS_VolumeTool.hxx"
 #include "SMDS_Mesh.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
 #include "SMESH_OctreeNode.hxx"
 
 #include <GC_MakeSegment.hxx>
@@ -743,7 +745,7 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt&       point,
 {
   const SMDS_MeshElement* closestElem = 0;
 
-  if ( type == SMDSAbs_Face )
+  if ( type == SMDSAbs_Face || type == SMDSAbs_Volume )
   {
     if ( !_ebbTree || _elementType != type )
     {
@@ -773,8 +775,7 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt&       point,
     TIDSortedElemSet::iterator elem = suspectElems.begin();
     for ( ; elem != suspectElems.end(); ++elem )
     {
-      double dist = SMESH_MeshAlgos::GetDistance( dynamic_cast<const SMDS_MeshFace*>(*elem),
-                                                   point );
+      double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
       if ( dist < minDist + 1e-10)
       {
         minDist = dist;
@@ -1290,6 +1291,31 @@ namespace
   }
 }
 
+//=======================================================================
+/*!
+ * \brief Return minimal distance from a point to an element
+ *
+ * Currently we ignore non-planarity and 2nd order of face
+ */
+//=======================================================================
+
+double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
+                                     const gp_Pnt&           point )
+{
+  switch ( elem->GetType() )
+  {
+  case SMDSAbs_Volume:
+    return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point);
+  case SMDSAbs_Face:
+    return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point);
+  case SMDSAbs_Edge:
+    return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point);
+  case SMDSAbs_Node:
+    return point.Distance( SMESH_TNodeXYZ( elem ));
+  }
+  return -1;
+}
+
 //=======================================================================
 /*!
  * \brief Return minimal distance from a point to a face
@@ -1386,6 +1412,68 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
   return badDistance;
 }
 
+//=======================================================================
+/*!
+ * \brief Return minimal distance from a point to an edge
+ */
+//=======================================================================
+
+double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point )
+{
+  throw SALOME_Exception(LOCALIZED("not implemented so far"));
+}
+
+//=======================================================================
+/*!
+ * \brief Return minimal distance from a point to a volume
+ *
+ * Currently we ignore non-planarity and 2nd order
+ */
+//=======================================================================
+
+double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point )
+{
+  SMDS_VolumeTool vTool( volume );
+  vTool.SetExternalNormal();
+  const int iQ = volume->IsQuadratic() ? 2 : 1;
+
+  double n[3], bc[3];
+  double minDist = 1e100, dist;
+  for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
+  {
+    // skip a facet with normal not "looking at" the point
+    if ( !vTool.GetFaceNormal( iF, n[0], n[1], n[2] ) ||
+         !vTool.GetFaceBaryCenter( iF, bc[0], bc[1], bc[2] ))
+      continue;
+    gp_XYZ bcp = point.XYZ() - gp_XYZ( bc[0], bc[1], bc[2] );
+    if ( gp_XYZ( n[0], n[1], n[2] ) * bcp < 1e-6 )
+      continue;
+
+    // find distance to a facet
+    const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iF );
+    switch ( vTool.NbFaceNodes( iF ) / iQ ) {
+    case 3:
+    {
+      SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
+      dist = GetDistance( &tmpFace, point );
+      break;
+    }
+    case 4:
+    {
+      SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
+      dist = GetDistance( &tmpFace, point );
+      break;
+    }
+    default:
+      vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
+      SMDS_PolygonalFaceOfNodes tmpFace( nvec );
+      dist = GetDistance( &tmpFace, point );
+    }
+    minDist = Min( minDist, dist );
+  }
+  return minDist;
+}
+
 //================================================================================
 /*!
  * \brief Returns barycentric coordinates of a point within a triangle.
index dc4d8fcb451831dd2c82253c6ab910e16183352f..df65d1f83585b3bbd01040a2a1389b2e6033466e 100644 (file)
@@ -100,9 +100,18 @@ namespace SMESH_MeshAlgos
   SMESHUtils_EXPORT
   bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
 
+  SMESHUtils_EXPORT
+  double GetDistance( const SMDS_MeshElement* elem, const gp_Pnt& point );
+
+  SMESHUtils_EXPORT
+  double GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point );
+
   SMESHUtils_EXPORT
   double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point );
 
+  SMESHUtils_EXPORT
+  double GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point );
+
   SMESHUtils_EXPORT
   void GetBarycentricCoords( const gp_XY& point,
                              const gp_XY& t0, const gp_XY& t1, const gp_XY& t2,