+
+ typedef std::vector< SMDS_MeshGroup* > TGroupVec;
+
+ //================================================================================
+ /*!
+ * \brief Fill theFaceID2Groups map for a given face
+ * \param [in] theFace - the face
+ * \param [in] theGroupsToUpdate - list of groups to treat
+ * \param [out] theFaceID2Groups - the map to fill in
+ * \param [out] theWorkGroups - a working buffer of groups
+ */
+ //================================================================================
+
+ void findGroups( const SMDS_MeshElement * theFace,
+ TGroupVec & theGroupsToUpdate,
+ NCollection_DataMap< int, TGroupVec > & theFaceID2Groups,
+ TGroupVec & theWorkGroups )
+ {
+ theWorkGroups.clear();
+ for ( size_t i = 0; i < theGroupsToUpdate.size(); ++i )
+ if ( theGroupsToUpdate[i]->Contains( theFace ))
+ theWorkGroups.push_back( theGroupsToUpdate[i] );
+
+ if ( !theWorkGroups.empty() )
+ theFaceID2Groups.Bind( theFace->GetID(), theWorkGroups );
+ }
+
+ //================================================================================
+ /*!
+ * \brief Check distance between a point and an edge defined by a couple of nodes
+ */
+ //================================================================================
+
+ bool isOnEdge( const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const gp_Pnt& p,
+ const double tol )
+ {
+ SMDS_LinearEdge edge( n1, n2 );
+ return ( SMESH_MeshAlgos::GetDistance( &edge, p ) < tol );
+ }
+
+ //================================================================================
+ /*!
+ * \return Index of intersection point detected on a triangle cut by planes
+ * \param [in] i - index of a cut triangle side
+ * \param [in] n1 - 1st point of a cut triangle side
+ * \param [in] n2 - 2nd point of a cut triangle side
+ * \param [in] face - a not cut triangle
+ * \param [in] intPoint - the intersection point
+ * \param [in] faceNodes - nodes of not cut triangle
+ * \param [in] tol - tolerance
+ */
+ //================================================================================
+
+ int edgeIndex( const int i,
+ const SMESH_NodeXYZ& n1,
+ const SMESH_NodeXYZ& n2,
+ const SMDS_MeshElement* face,
+ const IntPoint& intPoint,
+ const std::vector< const SMDS_MeshNode* >& faceNodes,
+ const double tol )
+ {
+ if ( n1.Node() && n2.Node() )
+ return face->GetNodeIndex( n1.Node() );
+
+ // project intPoint to sides of face
+ for ( size_t i = 1; i < faceNodes.size(); ++i )
+ if ( isOnEdge( faceNodes[ i-1 ], faceNodes[ i ], intPoint.myNode, tol ))
+ return i - 1;
+
+ return -(i+1);
+ }
+
+ //================================================================================
+ /*!
+ * \brief Find a neighboring segment and its next node
+ * \param [in] curSegment - a current segment
+ * \param [in,out] curNode - a current node to update
+ * \param [in] segmentsOfNode - map of segments of nodes
+ * \return Segment* - the found segment
+ */
+ //================================================================================
+
+ Segment* nextSegment( const Segment* curSegment,
+ const SMDS_MeshNode* & curNode,
+ const TSegmentsOfNode& segmentsOfNode )
+ {
+ Segment* neighborSeg = 0;
+ const NodeData& noData = segmentsOfNode( curNode );
+ for ( size_t iS = 0; iS < noData.mySegments.size() && !neighborSeg; ++iS )
+ if ( noData.mySegments[ iS ] != curSegment )
+ neighborSeg = noData.mySegments[ iS ];
+
+ if ( neighborSeg )
+ {
+ int iN = ( neighborSeg->Node(0) == curNode );
+ curNode = neighborSeg->Node( iN );
+ }
+ return neighborSeg;
+ }
+
+ //================================================================================
+ /*!
+ * \brief Tries to find a segment to which a given point is too close
+ * \param [in] p - the point
+ * \param [in] minDist - minimal allowed distance from segment
+ * \param [in] curSegment - start segment
+ * \param [in] curNode - start node
+ * \param [in] segmentsOfNode - map of segments of nodes
+ * \return bool - true if a too close segment found
+ */
+ //================================================================================
+
+ const Segment* findTooCloseSegment( const IntPoint& p,
+ const double minDist,
+ const double /*tol*/,
+ const Segment* curSegment,
+ const SMDS_MeshNode* curNode,
+ const TSegmentsOfNode& segmentsOfNode )
+ {
+ double prevDist = Precision::Infinite();
+ while ( curSegment )
+ {
+ double dist = SMESH_MeshAlgos::GetDistance( curSegment->myEdge, p.myNode );
+ if ( dist < minDist )
+ {
+ // check if dist is less than distance of curSegment to its cuts
+ // double minCutDist = prevDist;
+ // bool coincide = false;
+ // for ( size_t iC = 0; iC < curSegment->myCuts.size(); ++iC )
+ // {
+ // if (( coincide = ( curSegment->myCuts[iC].SquareDistance( p.myNode ) < tol * tol )))
+ // break;
+ // for ( size_t iP = 0; iP < 2; ++iP )
+ // {
+ // double cutDist = SMESH_MeshAlgos::GetDistance( curSegment->myEdge,
+ // curSegment->myCuts[iC][iP].myNode );
+ // minCutDist = std::min( minCutDist, cutDist );
+ // }
+ // }
+ // if ( !coincide && minCutDist > dist )
+ return curSegment;
+ }
+ if ( dist > prevDist )
+ break;
+ prevDist = dist;
+ curSegment = nextSegment( curSegment, curNode, segmentsOfNode );
+ }
+ return 0;
+ }