From 1838b710e0d9d5b3b09c6dcff57f255c321af16d Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 15 Dec 2010 10:52:08 +0000 Subject: [PATCH] 0020832: EDF 1359 SMESH : Automatic meshing of boundary layers 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 | 62 ++++++++++++++++++++++---------- src/SMESH/SMESH_MesherHelper.hxx | 9 +++-- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index c3e284a47..1694926ec 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -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 to 2 edges and select projection most close to - 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 { 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* 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; } diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index d904f95de..c854a30fd 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -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 */ -- 2.39.2