diff --git a/IntersLineSurfTm.cpp b/IntersLineSurfTm.cpp index 5a0aa42..b6dfd54 100644 --- a/IntersLineSurfTm.cpp +++ b/IntersLineSurfTm.cpp @@ -52,6 +52,8 @@ OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo) []( const IntLinStmInfo& a, const IntLinStmInfo& b) { double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ; double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ; + if ( abs( dUa - dUb) < EPS_SMALL) + return ( a.dCosDN < b.dCosDN) ; return ( dUa < dUb) ; }) ; } diff --git a/ProjectCurveSurfTm.cpp b/ProjectCurveSurfTm.cpp index 053cf10..1bc3167 100644 --- a/ProjectCurveSurfTm.cpp +++ b/ProjectCurveSurfTm.cpp @@ -22,6 +22,10 @@ using namespace std ; +//---------------------------------------------------------------------------- +// Angolo limite tra normale al triangolo e direzione di proiezione 89° +const double COS_ANG_LIM = 0.0175 ; + //---------------------------------------------------------------------------- static bool PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol) @@ -89,9 +93,9 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec // controllo le tolleranze dLinTol = max( dLinTol, LIN_TOL_MIN) ; dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ; - // approssimo la curva con una polilinea entro la metà della tolleranza + // approssimo la curva con una polilinea alla massima risoluzione PolyLine PL ; - if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ; if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN)) @@ -112,12 +116,17 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec Point3d ptP ; bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ; while ( bFound) { + // intersezione retta di proiezione con superficie Point3d ptL = GetToLoc( ptP, frRefLine) ; ILSIVECTOR vIntRes ; intPLSTM.GetInters( ptL, 1, vIntRes, false) ; - if ( ! vIntRes.empty()) { + // cerco la prima intersezione valida a partire dall'ultima (è la più alta) + int nI = int( vIntRes.size()) - 1 ; + while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM) + --nI ; + // se trovata + if ( nI >= 0) { // calcolo il punto - int nI = int( vIntRes.size()) - 1 ; Point3d ptInt ; if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ptInt = vIntRes[nI].ptI2 ; @@ -187,9 +196,13 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGe vtLine /= dLineLen ; ILSIVECTOR vIntRes ; if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) { - if ( vIntRes.size() > 0) { + // cerco la prima intersezione valida a partire dall'ultima (è la più alta) + int nI = int( vIntRes.size()) - 1 ; + while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM) + --nI ; + // se trovata + if ( nI >= 0) { // calcolo il punto - int nI = int( vIntRes.size()) - 1 ; Point3d ptInt ; if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ptInt = vIntRes[nI].ptI2 ; @@ -235,9 +248,9 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu dLinTol = max( dLinTol, LIN_TOL_MIN) ; dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ; - // approssimo la curva con una polilinea entro la metà della tolleranza + // approssimo la curva con una polilinea alla massima risoluzione PolyLine PL ; - if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) return false ; const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ; if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN)) @@ -264,9 +277,13 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu vtLine /= dLineLen ; ILSIVECTOR vIntRes ; if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) { - if ( vIntRes.size() > 0) { + // cerco la prima intersezione valida a partire dall'ultima (è la più alta) + int nI = int( vIntRes.size()) - 1 ; + while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM) + --nI ; + // se trovata + if ( nI >= 0) { // calcolo il punto - int nI = int( vIntRes.size()) - 1 ; Point3d ptInt ; if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ptInt = vIntRes[nI].ptI2 ; @@ -342,9 +359,13 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu vtLine /= dLineLen ; ILSIVECTOR vIntRes ; if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) { - if ( vIntRes.size() > 0) { + // cerco la prima intersezione valida a partire dall'ultima (è la più alta) + int nI = int( vIntRes.size()) - 1 ; + while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM) + --nI ; + // se trovata + if ( nI >= 0) { // calcolo il punto - int nI = int( vIntRes.size()) - 1 ; Point3d ptInt ; if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ptInt = vIntRes[nI].ptI2 ;