diff --git a/CurveAux.cpp b/CurveAux.cpp index 09000b6..9291c93 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -1670,11 +1670,9 @@ ApproxCurveWithBezier( const ICurve* pCrv , double dTol, const Vector3d& vtStart VCT3DVECTOR vPrevDer ; VCT3DVECTOR vNextDer ; ComputeAkimaTangents( false, vParam, vPnt, vPrevDer, vNextDer) ; - vPrevDer[0] = vtStart ; - vNextDer.back() = vtEnd ; if ( ! AreSameVectorExact(vtStart, V_NULL)) { - vPrevDer[1] = vtStart ; - vNextDer.end()[-2] = vtEnd ; + vNextDer[0] = vtStart ; + vPrevDer.back() = vtEnd ; } int nOverSampling = ssize( vPntOverSampling) ; diff --git a/Trimming.cpp b/Trimming.cpp index 588f1f8..f5fd22a 100644 --- a/Trimming.cpp +++ b/Trimming.cpp @@ -62,7 +62,7 @@ #define DEBUG_EDGES 0 #define DEBUG_SHAPE_STM 0 #define DEBUG_HOLES 0 -#define DEBUG_SMOOTH_CURVATURE 0 +#define DEBUG_SMOOTH_CURVATURE 1 #if DEBUG_BASIC_BORDERS || DEBUG_CHAIN_CURVES || DEBUG_ANG_APPROX || DEBUG_BEZIER_INTERP || \ DEBUG_FACE_SEARCH || DEBUG_FACE_SEARCH_TRIA_MODIF || DEBUG_BRK_POINTS || DEBUG_BRK_THICK || \ DEBUG_BRK || DEBUG_BORDERS_BY_NORMALS || DEBUG_SYNC_POINTS || DEBUG_SYNC_INTERPOLATION || \ @@ -83,8 +83,6 @@ using namespace std ; -bool RegolarizeBorders( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, double dTol) ; - // Vettori e Matrici di Curve Composite typedef vector COMPOVECTOR ; typedef vector COMPOMATRIX ; @@ -4293,6 +4291,10 @@ GetTrimmingRuledBezier( const CISURFPVECTOR& vSurf, const ICurve* pCrvEdge1, } } + //////debug + //RegolarizeBordersLocally(pCrvEdge1,pCrvEdge2, pSurfBz, 0.2) ; + //return nullptr ; + return ( IsNull( pSurfBz) || ! pSurfBz->IsValid() ? nullptr : Release( pSurfBz)) ; } @@ -4969,94 +4971,116 @@ typedef vector PNTINFOVECTOR ; //------------------------------------------------------------------------------ // Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim // Le curve vengono modificate entro una data tolleranza, in modo che -static bool -RegolarizeBorders( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, double dTol) +bool +RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol) { + #if DEBUG_SMOOTH_CURVATURE + VT.clear() ; + #endif -#if DEBUG_SMOOTH_CURVATURE - VT.push_back( pCrv1->Clone()) ; -#endif - // le due curve sono compo di bezier, e tutte le sottocurve sono dello stesso grado (3) - PNTINFOVECTOR vPntInfo ; - const ICurveComposite* pCC1 = GetCurveComposite( pCrv1) ; - for ( int i = 0 ; i < pCC1->GetCurveCount() ; ++i) { - const ICurveBezier* pSubCrv = GetCurveBezier( pCC1->GetCurve( i)) ; - int nDeg = pSubCrv->GetDegree() ; - for ( int j = i == 0 ? 0 : 1 ; j <= nDeg ; ++j) { - bool bOk = false ; - Point3d pt = pSubCrv->GetControlPoint( j, &bOk) ; - DistPointSurfBz dpsb( pt, *pSurfBz) ; - double dDist = 0 ; dpsb.GetDist( dDist) ; - Point3d ptMinDist ; dpsb.GetMinDistPoint( ptMinDist) ; - Vector3d vtN ; dpsb.GetNorm( vtN) ; - Vector3d vtPos = pt - ptMinDist ; - double dSide = vtPos * vtN ; - int nSide = 0 ; - if ( abs( dSide) > EPS_SMALL) { - if ( dSide > 0) - nSide = 1 ; - else - nSide = - 1 ; - } - vPntInfo.emplace_back( pt, i, j, dDist, vtN, nSide) ; + // prendo per buone le isocurve di inizio e fine tratto e devo identificare tra loro le isocurve che creano troppo twist e che sono da raddrizzare + int nUS1 = - 1, nUS2 = -1 ; + const Point3d& ptS1 = bpIsoStart.first ; + const Point3d& ptS2 = bpIsoEnd.first ; + int nDegU, nDegV, nSpanU, nSpanV ; + bool bRat, bTrimmed ; + pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ; + if ( nDegU != 3) + return false ; + // individuo quali isocurve sono state indicate come inizio e fine + for ( int i = 0 ; i < nDegU * nSpanU + 1 ; ++i) { + bool bOk = false ; + Point3d pt = pSurfBz->GetControlPoint( i, 0, &bOk) ; + if ( nUS1 == -1 && AreSamePointExact(pt, ptS1)) + nUS1 = i ; + else if ( AreSamePointExact( pt, ptS2)) { + nUS2 = i ; + break ; } } - // se trovo tre punti di fila che sono dallo stesso lato, opposto a quello degli altri punti attorno, allora cerco di spostarli lungo la - // normale alla superficie in modo da evitare cambi di concavità - int nCurrSide = vPntInfo[0].nSide ; - int c = 0 ; - CurveComposite CC ; - for ( int i = 0 ; i < ssize( vPntInfo) ; ++i) { - if ( nCurrSide == 0) - nCurrSide = vPntInfo[i].nSide ; - int nFirst = i ; - int nSecond = nFirst == ssize( vPntInfo) ? 0 : nFirst + 1 ; - int nThird = nSecond == ssize( vPntInfo) ? 0 : nSecond + 1 ; - int nFourth = nThird == ssize( vPntInfo) ? 0 : nThird + 1 ; - if ( i > 2 && vPntInfo[nFirst].nSide != nCurrSide && vPntInfo[nFirst].nSide != 0) { - // devo verificare anche che sia uguale ai due successivi - if ( ( vPntInfo[nFirst].nSide == vPntInfo[nSecond].nSide || vPntInfo[nSecond].nSide == 0) && - ( vPntInfo[nFirst].nSide == vPntInfo[nThird].nSide || vPntInfo[nThird].nSide == 0)) { - // se il successivo al terzetto è diverso ho un terzetto anomalo da aggiustare - // altrimenti ho un cambio naturale di concavità - if ( vPntInfo[nFirst].nSide != vPntInfo[nFourth].nSide) { - // modifico due curve - CurveComposite CCToApprox ; - int nCurrSub = nFirst / 3 ; - if ( nFirst % 3 == 0) - --nCurrSub ; - CCToApprox.AddCurve( pCC1->CopyParamRange( nCurrSub, nCurrSub + 2)) ; - Vector3d vtStart ; pCC1->GetStartDir( vtStart) ; - Vector3d vtEnd ; pCC1->GetEndDir( vtEnd) ; - PtrOwner pCrvApprox( ApproxCurveWithBezier( &CCToApprox, dTol, vtStart, vtEnd)) ; - if ( ! IsNull( pCrvApprox)) - CC.AddCurve( Release( pCrvApprox)) ; - else - return false ; + // scorro le isocurve a partire dallo start e dell'end della zona indicata + // controllo il twist rispetto alla isocurva precedente + int nMid = ( nUS2 + nUS1) / 2 ; + Point3d ptPrevS = ptS1 ; + Point3d ptPrevE = bpIsoStart.second ; + Vector3d vtIsoPrev = ptPrevE - ptPrevS ; vtIsoPrev.Normalize() ; + Point3d ptBez ; Vector3d vtNPrev ; + pSurfBz->GetPointNrmD1D2( nUS1, 0.5, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez, vtNPrev) ; + int nPoints = ( nUS2 - nUS1) * nDegU + 1 ; + PNTVECTOR vPnt0 ; vPnt0.reserve( nPoints) ; vPnt0.push_back( ptPrevS) ; + PNTVECTOR vPnt1 ; vPnt1.reserve( nPoints) ;vPnt1.push_back( ptPrevE) ; + // salvo il secondo punto di controllo della patch + bool bOk = false ; + Point3d ptSecond1Curr = pSurfBz->GetControlPoint( nUS1 + 1, 0, &bOk) ; + vPnt0.push_back( ptSecond1Curr) ; + Point3d ptSecond2Curr = pSurfBz->GetControlPoint( nUS1 + 1, 1, &bOk) ; + vPnt1.push_back( ptSecond2Curr) ; + // scorro le isocurve di separazione tra patch + for ( int i = nUS1 + 3 ; i < nUS2 ; i +=3) { /////////////////// scorro fino in fondo?? + // recupero precedente e successivo + Point3d ptThird1Curr = pSurfBz->GetControlPoint( i - 1, 0, &bOk) ; + Point3d ptThird2Curr = pSurfBz->GetControlPoint( i - 1, 1, &bOk) ; + Point3d ptSecond1Next = pSurfBz->GetControlPoint( i + 1, 0, &bOk) ; + Point3d ptSecond2Next = pSurfBz->GetControlPoint( i + 1, 1, &bOk) ; + // recupero corrente e verifico la torsione + Point3d ptCurrS = pSurfBz->GetControlPoint( i, 0, &bOk) ; + Point3d ptCurrE = pSurfBz->GetControlPoint( i, 1, &bOk) ; + Vector3d vtIsoCurr = ptCurrE - ptCurrS ; + double dDist = vtIsoCurr.Len() ; + vtIsoCurr.Normalize() ; + Vector3d vtDirPrev = vtIsoPrev ^ vtNPrev ; + Vector3d vtCurrInPlane = OrthoCompo( vtIsoCurr, vtDirPrev) ; + bool bDet = false ; + double dAng = 0 ; vtIsoPrev.GetRotation( vtCurrInPlane, vtDirPrev, dAng, bDet) ; + if ( abs( dAng) > 0) { + // se l'isocurva di separazione dalla patch successiva è torta rispetto alla precedente + // allora prendo il penultimo punto della curva corrente, l'ultimo e il secondo della prossima e li sposto lungo la normale della superficie + dDist *= dAng * DEGTORAD ; + ptThird1Curr += vtNPrev * dDist ; + ptCurrS += vtNPrev * dDist ; + ptSecond1Next += vtNPrev * dDist ; + ptThird2Curr -= vtNPrev * dDist ; + ptCurrE -= vtNPrev * dDist ; + ptSecond2Next -= vtNPrev * dDist ; + } + vPnt0.push_back( ptThird1Curr) ; + vPnt0.push_back( ptCurrS) ; + vPnt0.push_back( ptSecond1Next) ; - // scavalco i punti delle curve che ho appena modificato - i += 6 ; - } - c = 0 ; - nCurrSide = vPntInfo[i].nSide ; - } - else - ++c ; - } - else { - ++c ; - if ( i != 0 && i % 3 == 0) - CC.AddCurve( pCC1->GetCurve( i / 3 - 1)->Clone()) ; - } + vPnt1.push_back( ptThird2Curr) ; + vPnt1.push_back( ptCurrE) ; + vPnt1.push_back( ptSecond2Next) ; + + vtIsoPrev = ptCurrE - ptCurrS ; vtIsoPrev.Normalize() ; + vtNPrev = ( ptSecond1Next - ptCurrS) ^ vtIsoPrev ; vtNPrev.Normalize() ; } + PtrOwner pCC1( CreateCurveComposite()) ; + PtrOwner pCC2( CreateCurveComposite()) ; + for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) { + PtrOwner cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ; + cb1->SetControlPoint( 0, vPnt0[i]) ; + cb1->SetControlPoint( 1, vPnt0[i+1]) ; + cb1->SetControlPoint( 2, vPnt0[i+2]) ; + cb1->SetControlPoint( 3, vPnt0[i+3]) ; + pCC1->AddCurve( Release( cb1)) ; + + PtrOwner cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ; + cb2->SetControlPoint( 0, vPnt1[i]) ; + cb2->SetControlPoint( 1, vPnt1[i+1]) ; + cb2->SetControlPoint( 2, vPnt1[i+2]) ; + cb2->SetControlPoint( 3, vPnt1[i+3]) ; + pCC2->AddCurve( Release( cb2)) ; + } + + //PtrOwner pSB( CreateSurfBezier()) ; //pSB->CreateSmoothRuledByTwoCurves( pCrv1, pCrv2, 10) ; #if DEBUG_SMOOTH_CURVATURE - VT.push_back( CC.Clone()) ; - VT.push_back( pSurfBz->Clone()) ; - SaveGeoObj( VT, "D:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ; + VT.push_back( Release(pCC1)) ; + VT.push_back( Release(pCC2)) ; + SaveGeoObj( VT, "D:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ; #endif return true ;