X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHUtils%2FSMESH_MeshAlgos.cxx;h=dbadd82505154cbcbbae5e0fca2c686f205a9697;hp=a897decd65c3ec05780c8b345736a69277861033;hb=4bbb63cfb97fb344eb1b0b1f12eaa89359097900;hpb=5482b99d07dd144fd5be299e722f39a81de3b5be diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index a897decd6..dbadd8250 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -60,7 +60,8 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher /*! * \brief Constructor */ - SMESH_NodeSearcherImpl( const SMDS_Mesh* theMesh ) + SMESH_NodeSearcherImpl( const SMDS_Mesh* theMesh = 0, + SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr() ) { myMesh = ( SMDS_Mesh* ) theMesh; @@ -70,6 +71,14 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher while ( nIt->more() ) nodes.insert( nodes.end(), nIt->next() ); } + else if ( theElemIt ) + { + while ( theElemIt->more() ) + { + const SMDS_MeshElement* e = theElemIt->next(); + nodes.insert( e->begin_nodes(), e->end_nodes() ); + } + } myOctreeNode = new SMESH_OctreeNode(nodes) ; // get max size of a leaf box @@ -575,7 +584,7 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& lin { GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )), SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); - anExtCC.Init( lineCurve, edge); + anExtCC.Init( lineCurve, edge.Value() ); if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol) { Quantity_Parameter pl, pe; @@ -714,8 +723,12 @@ FindElementsByPoint(const gp_Pnt& point, if ( type == SMDSAbs_Node || type == SMDSAbs_0DElement || type == SMDSAbs_Ball) { if ( !_nodeSearcher ) - _nodeSearcher = new SMESH_NodeSearcherImpl( _mesh ); - + { + if ( _meshPartIt ) + _nodeSearcher = new SMESH_NodeSearcherImpl( 0, _meshPartIt ); + else + _nodeSearcher = new SMESH_NodeSearcherImpl( _mesh ); + } std::vector< const SMDS_MeshNode* > foundNodes; _nodeSearcher->FindNearPoint( point, tolerance, foundNodes ); @@ -893,8 +906,9 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) } else if ( ! intersection.IsParallel() && intersection.NbPoints() > 0 ) { + double tol = 1e-4 * Sqrt( fNorm.Modulus() ); gp_Pnt intersectionPoint = intersection.Point(1); - if ( !SMESH_MeshAlgos::IsOut( *face, intersectionPoint, tolerance )) + if ( !SMESH_MeshAlgos::IsOut( *face, intersectionPoint, tol )) u2inters.insert(make_pair( intersection.ParamOnConic(1), TInters( *face, fNorm ))); } } @@ -973,16 +987,19 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) // skip tangent intersections int nbTgt = 0; - const SMDS_MeshElement* prevFace = u_int1->second._face; - while ( ok && u_int2->second._coincides ) + if ( u_int2 != u2inters.end() ) { - if ( SMESH_MeshAlgos::GetCommonNodes(prevFace , u_int2->second._face).empty() ) - ok = false; - else + const SMDS_MeshElement* prevFace = u_int1->second._face; + while ( ok && u_int2->second._coincides ) { - nbTgt++; - u_int2++; - ok = ( u_int2 != u2inters.end() ); + if ( SMESH_MeshAlgos::GetCommonNodes(prevFace , u_int2->second._face).empty() ) + ok = false; + else + { + nbTgt++; + u_int2++; + ok = ( u_int2 != u2inters.end() ); + } } } if ( !ok ) break; @@ -1120,14 +1137,11 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin // get ordered nodes - vector< SMESH_TNodeXYZ > xyz; + vector< SMESH_TNodeXYZ > xyz; xyz.reserve( element->NbNodes()+1 ); SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator(); - while ( nodeIt->more() ) - { - SMESH_TNodeXYZ node = nodeIt->next(); - xyz.push_back( node ); - } + for ( int i = 0; nodeIt->more(); ++i ) + xyz.push_back( SMESH_TNodeXYZ( nodeIt->next() )); int i, nbNodes = (int) xyz.size(); // central node of biquadratic is missing @@ -1158,8 +1172,23 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin // check if the point lays on face plane gp_Vec n2p( xyz[0], point ); - if ( fabs( n2p * faceNorm ) > tol ) - return true; // not on face plane + double dot = n2p * faceNorm; + if ( Abs( dot ) > tol ) // not on face plane + { + bool isOut = true; + if ( nbNodes > 3 ) // maybe the face is not planar + { + double elemThick = 0; + for ( i = 1; i < nbNodes; ++i ) + { + gp_Vec n2n( xyz[0], xyz[i] ); + elemThick = Max( elemThick, Abs( n2n * faceNorm )); + } + isOut = Abs( dot ) > elemThick + tol; + } + if ( isOut ) + return isOut; + } // check if point is out of face boundary: // define it by closest transition of a ray point->infinity through face boundary @@ -1171,7 +1200,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin normSize = plnNorm.Magnitude(); if ( normSize <= tol ) return false; // point coincides with the first node plnNorm /= normSize; - // for each node of the face, compute its signed distance to the plane + // for each node of the face, compute its signed distance to the cutting plane vector dist( nbNodes + 1); for ( i = 0; i < nbNodes; ++i ) { @@ -1181,12 +1210,12 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin dist.back() = dist.front(); // find the closest intersection int iClosest = -1; - double rClosest, distClosest = 1e100;; + double rClosest = 0, distClosest = 1e100; gp_Pnt pClosest; for ( i = 0; i < nbNodes; ++i ) { double r; - if ( fabs( dist[i]) < tol ) + if ( fabs( dist[i] ) < tol ) r = 0.; else if ( fabs( dist[i+1]) < tol ) r = 1.; @@ -1195,17 +1224,14 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin else continue; // no intersection gp_Pnt pInt = xyz[i] * (1.-r) + xyz[i+1] * r; - gp_Vec p2int ( point, pInt); - if ( p2int * ray > -tol ) // right half-space + gp_Vec p2int( point, pInt); + double intDist = p2int.SquareMagnitude(); + if ( intDist < distClosest ) { - double intDist = p2int.SquareMagnitude(); - if ( intDist < distClosest ) - { - iClosest = i; - rClosest = r; - pClosest = pInt; - distClosest = intDist; - } + iClosest = i; + rClosest = r; + pClosest = pInt; + distClosest = intDist; } } if ( iClosest < 0 ) @@ -1229,6 +1255,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin bool covexCorner = ( edgeNorm * edgeAdjacent * (rClosest==1. ? 1. : -1.)) < 0; return covexCorner ? (out || out2) : (out && out2); } + if ( element->GetType() == SMDSAbs_Edge ) // -------------------------------------------------- { // point is out of edge if it is NOT ON any straight part of edge @@ -1256,10 +1283,11 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin } return true; } + // Node or 0D element ------------------------------------------------------------------------- { gp_Vec n2p ( xyz[0], point ); - return n2p.SquareMagnitude() <= tol * tol; + return n2p.SquareMagnitude() > tol * tol; } return true; } @@ -1695,6 +1723,17 @@ SMESH_NodeSearcher* SMESH_MeshAlgos::GetNodeSearcher(SMDS_Mesh& mesh) return new SMESH_NodeSearcherImpl( &mesh ); } +//======================================================================= +/*! + * \brief Return SMESH_NodeSearcher + */ +//======================================================================= + +SMESH_NodeSearcher* SMESH_MeshAlgos::GetNodeSearcher(SMDS_ElemIteratorPtr elemIt) +{ + return new SMESH_NodeSearcherImpl( 0, elemIt ); +} + //======================================================================= /*! * \brief Return SMESH_ElementSearcher