+ // ----------------------------------------------------------
+ // If a plane fully cuts off edges of one side of a segment,
+ // it also may cut edges of adjacent segments
+ // ----------------------------------------------------------
+
+ for ( TSegmentIterator segIt( segmentPool ); segIt.more(); ) // loop on all segments
+ {
+ Segment* segment = const_cast< Segment* >( segIt.next() );
+ if ( segment->NbFreeEnds( tol ) >= 4 )
+ continue;
+
+ for ( int iE = 0; iE < 2; ++iE ) // loop on 2 segment ends
+ {
+ const SMDS_MeshNode* n1 = segment->Node( iE );
+ const SMDS_MeshNode* n2 = segment->Node( 1 - iE );
+ planeNormal[0] = segmentsOfNode( n1 ).Plane( segment );
+
+ bool isNeighborCut;
+ Segment* neighborSeg = segment;
+ do // check segments connected to the segment via n2
+ {
+ neighborSeg = nextSegment( neighborSeg, n2, segmentsOfNode );
+ if ( !neighborSeg )
+ break;
+
+ isNeighborCut = false;
+ for ( size_t iC = 0; iC < neighborSeg->myCuts.size(); ++iC ) // check cut edges
+ {
+ IntPoint* intPnt = &( neighborSeg->myCuts[iC].myIntPnt1 );
+ isOut( intPnt[0].myNode, planeNormal, intPnt[0].myIsOutPln, 1 );
+ isOut( intPnt[1].myNode, planeNormal, intPnt[1].myIsOutPln, 1 );
+ const Segment * closeSeg[2] = { 0, 0 };
+ if ( intPnt[0].myIsOutPln[0] )
+ closeSeg[0] = findTooCloseSegment( intPnt[0], 0.5 * theWidth - tol, tol,
+ segment, n1, segmentsOfNode );
+ if ( intPnt[1].myIsOutPln[0] )
+ closeSeg[1] = findTooCloseSegment( intPnt[1], 0.5 * theWidth - tol, tol,
+ segment, n1, segmentsOfNode );
+ int nbCut = bool( closeSeg[0] ) + bool( closeSeg[1] );
+ if ( nbCut == 0 )
+ continue;
+ isNeighborCut = true;
+ if ( nbCut == 2 ) // remove a cut
+ {
+ if ( iC < neighborSeg->myCuts.size() - 1 )
+ neighborSeg->myCuts[iC] = neighborSeg->myCuts.back();
+ neighborSeg->myCuts.pop_back();
+ }
+ else // shorten cuts of 1) neighborSeg and 2) closeSeg
+ {
+ // 1)
+ int iP = bool( closeSeg[1] );
+ gp_Lin segLine( closeSeg[iP]->Ax1() );
+ gp_Ax3 cylAxis( segLine.Location(), segLine.Direction() );
+ gp_Cylinder cyl( cylAxis, 0.5 * theWidth );
+ intPoints.clear();
+ if ( intersectEdge( cyl, intPnt[iP].myNode, intPnt[1-iP].myNode, tol, intPoints ) &&
+ intPoints[0].SquareDistance( intPnt[iP] ) > tol * tol )
+ intPnt[iP].myNode = intPoints[0].myNode;
+
+ // 2)
+ double minCutDist = theWidth;
+ gp_XYZ projection, closestProj;
+ int iCut;
+ for ( size_t iC = 0; iC < closeSeg[iP]->myCuts.size(); ++iC )
+ {
+ double cutDist = closeSeg[iP]->myCuts[iC].SquareDistance( intPnt[iP].myNode,
+ projection );
+ if ( cutDist < minCutDist )
+ {
+ closestProj = projection;
+ minCutDist = cutDist;
+ iCut = iC;
+ }
+ if ( minCutDist < tol * tol )
+ break;
+ }
+ double d1 = SMESH_MeshAlgos::GetDistance( neighborSeg->myEdge,
+ closeSeg[iP]->myCuts[iCut][0].myNode );
+ double d2 = SMESH_MeshAlgos::GetDistance( neighborSeg->myEdge,
+ closeSeg[iP]->myCuts[iCut][1].myNode );
+ int iP2 = ( d2 < d1 );
+ IntPoint& ip = const_cast< IntPoint& >( closeSeg[iP]->myCuts[iCut][iP2] );
+ ip = intPnt[iP];
+ }
+ // update myFreeEnds
+ neighborSeg->myFreeEnds.clear();
+ neighborSeg->NbFreeEnds( tol );
+ }
+ }
+ while ( isNeighborCut );
+ }
+ }
+
+ // -----------------------
+ // Cut faces by cut edges
+ // -----------------------
+
+ for ( TSegmentIterator segIt( segmentPool ); segIt.more(); ) // loop on all segments
+ {
+ Segment* segment = const_cast< Segment* >( segIt.next() );
+ for ( size_t iC = 0; iC < segment->myCuts.size(); ++iC )
+ {
+ Cut & cut = segment->myCuts[ iC ];
+ computeNormal( cut.myFace, faceNormals );
+ meshIntersector.Cut( cut.myFace,
+ cut.myIntPnt1.myNode, cut.myIntPnt1.myEdgeIndex,
+ cut.myIntPnt2.myNode, cut.myIntPnt2.myEdgeIndex );
+
+ Edge e = { cut.myIntPnt1.myNode.Node(), cut.myIntPnt2.myNode.Node(), 0 };
+ bndEdges.push_back( e );
+
+ findGroups( cut.myFace, theGroupsToUpdate, faceID2Groups, groupVec );
+ }
+ }
+
+ // -----------------------------------------