Salome HOME
0020832: EDF 1359 SMESH : Automatic meshing of boundary layers
authoreap <eap@opencascade.com>
Wed, 15 Dec 2010 10:52:08 +0000 (10:52 +0000)
committereap <eap@opencascade.com>
Wed, 15 Dec 2010 10:52:08 +0000 (10:52 +0000)
   1) make CheckNodeUV() and CheckNodeU() optionally return XYZ of node
      projection to shape
   2) prevent ancestors iterator from returning duplicates

src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx

index c3e284a472edc879973b951ad8bbbd957122afe1..1694926eccce73a0e05adf4f0f824f8d66caa59a 100644 (file)
@@ -291,7 +291,7 @@ bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode*      node,
 //=======================================================================
 
 TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node,
-                                                   SMESHDS_Mesh*        meshDS)
+                                                   const SMESHDS_Mesh*  meshDS)
 {
   int shapeID = node->GetPosition()->GetShapeId();
   if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() )
@@ -500,7 +500,8 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
                                      const SMDS_MeshNode* n,
                                      gp_XY&               uv,
                                      const double         tol,
-                                     const bool           force) const
+                                     const bool           force,
+                                     double               distXYZ[4]) const
 {
   int shapeID = n->GetPosition()->GetShapeId();
   if ( force || toCheckPosOnShape( shapeID ))
@@ -508,13 +509,18 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
     // check that uv is correct
     TopLoc_Location loc;
     Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
-    gp_Pnt nodePnt = XYZ( n );
+    gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0);
+    double dist = 0;
     if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
-    if ( Precision::IsInfinite( uv.X() ) ||
-         Precision::IsInfinite( uv.Y() ) ||
-         nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > tol )
+    bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ));
+    if ( infinit ||
+         (dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol )
     {
       setPosOnShapeValidity( shapeID, false );
+      if ( !infinit && distXYZ ) {
+        distXYZ[0] = dist;
+        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
+      }
       // uv incorrect, project the node to surface
       GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol );
       projector.Perform( nodePnt );
@@ -526,7 +532,13 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
       Quantity_Parameter U,V;
       projector.LowerDistanceParameters(U,V);
       uv.SetCoord( U,V );
-      if ( nodePnt.Distance( surface->Value( U, V )) > tol )
+      surfPnt = surface->Value( U, V );
+      dist = nodePnt.Distance( surfPnt );
+      if ( distXYZ ) {
+        distXYZ[0] = dist;
+        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
+      }
+      if ( dist > tol )
       {
         MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
         return false;
@@ -686,7 +698,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
                                     double&              u,
                                     const double         tol,
                                     const bool           force,
-                                    double*              distance) const
+                                    double               distXYZ[4]) const
 {
   int shapeID = n->GetPosition()->GetShapeId();
   if ( force || toCheckPosOnShape( shapeID ))
@@ -706,8 +718,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
     {
       gp_Pnt nodePnt = SMESH_MeshEditor::TNodeXYZ( n );
       if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
-      double dist = nodePnt.Distance( curve->Value( u ));
-      if ( distance ) *distance = dist;
+      gp_Pnt curvPnt = curve->Value( u );
+      double dist = nodePnt.Distance( curvPnt );
+      if ( distXYZ ) {
+        distXYZ[0] = dist;
+        distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+      }
       if ( dist > tol )
       {
         setPosOnShapeValidity( shapeID, false );
@@ -730,8 +746,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
         }
         Quantity_Parameter U = projector->LowerDistanceParameter();
         u = double( U );
-        dist = nodePnt.Distance( curve->Value( U ));
-        if ( distance ) *distance = dist;
+        curvPnt = curve->Value( u );
+        dist = nodePnt.Distance( curvPnt );
+        if ( distXYZ ) {
+          distXYZ[0] = dist;
+          distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+        }
         if ( dist > tol )
         {
           MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" );
@@ -935,7 +955,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_
   // To find position on edge and 3D position for n12,
   // project <middle> to 2 edges and select projection most close to <middle>
 
-  double u = 0, distMiddleProj = Precision::Infinite();
+  double u = 0, distMiddleProj = Precision::Infinite(), distXYZ[4];
   int iOkEdge = 0;
   TopoDS_Edge edges[2];
   for ( int is2nd = 0; is2nd < 2; ++is2nd )
@@ -949,11 +969,11 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_
     // project to get U of projection and distance from middle to projection
     TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape );
     double node2MiddleDist = middle.Distance( XYZ(n) );
-    double foundU = GetNodeU( edge, n ), foundDist = node2MiddleDist;
-    CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, &foundDist );
-    if ( foundDist < node2MiddleDist )
+    double foundU = GetNodeU( edge, n );
+    CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, distXYZ );
+    if ( distXYZ[0] < node2MiddleDist )
     {
-      distMiddleProj = foundDist;
+      distMiddleProj = distXYZ[0];
       u = foundU;
       iOkEdge = is2nd;
     }
@@ -2919,10 +2939,14 @@ struct TAncestorsIterator : public SMDS_Iterator<const TopoDS_Shape*>
 {
   TopTools_ListIteratorOfListOfShape _ancIter;
   TopAbs_ShapeEnum                   _type;
+  TopTools_MapOfShape                _encountered;
   TAncestorsIterator( const TopTools_ListOfShape& ancestors, TopAbs_ShapeEnum type)
     : _ancIter( ancestors ), _type( type )
   {
-    if ( _ancIter.More() && _ancIter.Value().ShapeType() != _type ) next();
+    if ( _ancIter.More() ) {
+      if ( _ancIter.Value().ShapeType() != _type ) next();
+      else _encountered.Add( _ancIter.Value() );
+    }
   }
   virtual bool more()
   {
@@ -2933,7 +2957,7 @@ struct TAncestorsIterator : public SMDS_Iterator<const TopoDS_Shape*>
     const TopoDS_Shape* s = _ancIter.More() ? & _ancIter.Value() : 0;
     if ( _ancIter.More() )
       for ( _ancIter.Next();  _ancIter.More(); _ancIter.Next())
-        if ( _ancIter.Value().ShapeType() == _type )
+        if ( _ancIter.Value().ShapeType() == _type && _encountered.Add( _ancIter.Value() ))
           break;
     return s;
   }
index d904f95ded3491c0ec6ef67954b8cadf812ed355..c854a30fde511578c8e20ffff8da182b0ffc0869 100644 (file)
@@ -104,7 +104,7 @@ public:
    * \retval TopoDS_Shape - found support shape
    */
   static TopoDS_Shape GetSubShapeByNode(const SMDS_MeshNode* node,
-                                        SMESHDS_Mesh*        meshDS);
+                                        const SMESHDS_Mesh*  meshDS);
 
   /*!
    * \brief Return a valid node index, fixing the given one if necessary
@@ -301,16 +301,19 @@ public:
   /*!
    * \brief Check and fix node UV on a face
    *  \param force - check even if checks of other nodes on this face passed OK
+   *  \param distXYZ - returns result distance and point coordinates
    *  \retval bool - false if UV is bad and could not be fixed
    */
   bool CheckNodeUV(const TopoDS_Face&   F,
                    const SMDS_MeshNode* n,
                    gp_XY&               uv,
                    const double         tol,
-                   const bool           force=false) const;
+                   const bool           force=false,
+                   double               distXYZ[4]=0) const;
   /*!
    * \brief Check and fix node U on an edge
    *  \param force - check even if checks of other nodes on this edge passed OK
+   *  \param distXYZ - returns result distance and point coordinates
    *  \retval bool - false if U is bad and could not be fixed
    */
   bool CheckNodeU(const TopoDS_Edge&   E,
@@ -318,7 +321,7 @@ public:
                   double&              u,
                   const double         tol,
                   const bool           force=false,
-                  double*              distance=0) const;
+                  double               distXYZ[4]=0) const;
   /*!
    * \brief Return middle UV taking in account surface period
    */