diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index 94de273..328ebe0 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -25,10 +25,10 @@ using namespace std ; -#define SAVECRVORIG 0 -#define SAVEOFFDIR 0 -#define SAVECYL 0 -#define SAVEOFFSET 0 +#define SAVECRVORIG 1 +#define SAVEOFFDIR 1 +#define SAVECYL 1 +#define SAVEOFFSET 1 #if SAVECRVORIG || SAVEOFFDIR || SAVECYL || SAVEOFFSET #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkGeoVector3d.h" @@ -268,7 +268,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) if ( vtDirPrevOff.IsValid()) dProj = vtDirCurrOff * vtDirPrevOff ; // prima di inserirlo controllo che il tratto non torni indietro - if ( vFlag[nCurr] != ANG_STR || dProj > - 0.866) { + if ( vFlag[nCurr] != ANG_STR || dProj > - 0.966) { // aggiungo tratto ICurveLine* pCL = CreateBasicCurveLine() ; pCL->Set( ptPrev, ptP) ; diff --git a/ProjectCurveSurf.cpp b/ProjectCurveSurf.cpp index 94c0808..8d4a416 100644 --- a/ProjectCurveSurf.cpp +++ b/ProjectCurveSurf.cpp @@ -76,17 +76,30 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax) double dProjPrev = ( vPt5ax[i].ptP - vPt5ax[j].ptP) * vPt5ax[j].vtDir1 ; double dProjCurr = ( vPt5ax[j].ptP - vPt5ax[i].ptP) * vPt5ax[i].vtDir1 ; bool bConvex = ( abs( dProjCurr) > abs( dProjPrev) ? dProjCurr < 0 : dProjPrev < 0) ; + int nPrev = i - 1 ; + if ( i < ssize( vPt5ax) - 2 && ! AreSameVectorExact(vPt5ax[i - 1].vtDir1, vPt5ax[i - 1].vtDir2)) { + int z = nPrev - 1 ; + // se vtDir1 e vtDir2 sono diverse allora sono su uno spigolo + double dProjPrev2 = ( vPt5ax[z].ptP - vPt5ax[nPrev].ptP) * vPt5ax[nPrev].vtDir2 ; + double dProjCurr2 = ( vPt5ax[i].ptP - vPt5ax[nPrev].ptP) * vPt5ax[nPrev].vtDir1 ; + // se uno dei due è convesso allora considero convesso l'angolo + bConvex = dProjPrev2 < EPS_SMALL || dProjCurr2 < EPS_SMALL ; + } bool bValidIntersAfterJ = true ; bool bValidIntersBeforeI = true ; if ( i > 2) { // verifico che l'intersezione sia tra i e j e non prima di j int k = i - 2 ; bValidIntersAfterJ = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[j].ptP - vPt5ax[k].ptP) > 0 ; + bool bBetweenIAndJ = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[i].ptP - vPt5ax[j].ptP) > 0 ; + bValidIntersAfterJ = bValidIntersAfterJ && bBetweenIAndJ ; } if ( i < ssize( vPt5ax) - 1) { // verifico anche che l'intersezione non sia dopo i int h = i + 1 ; bValidIntersBeforeI = ( ptInt - vPt5ax[i].ptP) * ( vPt5ax[h].ptP - vPt5ax[i].ptP) < 0 ; + bool bBetweenIAndJ = ( ptInt - vPt5ax[i].ptP) * ( vPt5ax[i].ptP - vPt5ax[j].ptP) < 0 ; + bValidIntersBeforeI = bValidIntersBeforeI && bBetweenIAndJ ; } bool bValidInters = ( bValidIntersAfterJ && bValidIntersBeforeI) ; // se convesso, metto due punti con direzione appena prima e appena dopo @@ -487,10 +500,28 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, ptAlter = ptP + vtDirNext * 5 * EPS_SMALL ; Point5ax Pt5axRec ; if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) { - if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) { + // aggiorno solo la vtDir1, la vtDir2 la mantengo con la normale successiva allo spigolo + if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) vPt5ax.back().vtDir1 = Pt5axRec.vtDir1 ; - vPt5ax.back().vtDir2 = Pt5axRec.vtDir2 ; - } + } + } + else if ( ssize( vPt5ax) > 1 && vPt5ax.back().vtDir1 * vPt5ax.end()[-2].vtDir1 < COS_ANG_MAX_CORNER) { + // se la normale corrente è sufficientemente diversa dalla precedente e i tratti non erano allineati + // controllo se il punto precedente erano su uno spigolo, ricalcolando in un punto appena oltre + Point3d ptAlter = ptPrev + ( ptP - ptPrev) * 5 * EPS_SMALL ; + Point5ax Pt5axRec ; + if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) { + // aggiorno solo la vtDir1, la vtDir2 la mantengo con la normale successiva allo spigolo + if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) + vPt5ax.end()[-2].vtDir1 = Pt5axRec.vtDir1 ; + } + } + + if ( bLast && bClosed) { + // controllo se il punto finale è di spigolo + if ( vPt5ax.back().vtDir1 * vPt5ax.front().vtDir1 < COS_ANG_MAX_CORNER) { + vPt5ax.back().vtDir2 = vPt5ax.front().vtDir1 ; + vPt5ax.front().vtDir2 = vPt5ax.back().vtDir1 ; } } vtNormPrev = vPt5ax.back().vtDir1 ; @@ -1300,60 +1331,26 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, Pt5ax.ptP = ptP ; Pt5ax.dPar = dPar ; double dDecimal ; - int nCrv = int( modf( dPar, &dDecimal) == 0.0 ? dPar - 1 : dPar) ; + bool bJoint = modf( dPar, &dDecimal) == 0.0 ; + int nCrv = int( bJoint ? dPar - 1 : dPar) ; if ( nCrv < 0) nCrv = 0 ; int nTria ; pCC->GetCurveTempProp( nCrv, nTria, 0) ; Triangle3d trTria ; pSurf.GetTriangle( nTria, trTria) ; Pt5ax.vtDir1 = trTria.GetN() ; - Pt5ax.vtDir2 = Pt5ax.vtDir1 ; + if ( bJoint) { + int nTria2 ; pCC->GetCurveTempProp( int( dPar), nTria2, 0) ; + Triangle3d trTria2 ; pSurf.GetTriangle( nTria2, trTria2) ; + Pt5ax.vtDir2 = trTria2.GetN() ; + } + else + Pt5ax.vtDir2 = Pt5ax.vtDir1 ; Pt5ax.vtDirU = V_NULL ; Pt5ax.vtDirV = V_NULL ; Pt5ax.nFlag = P5AX_STD ; vPt5ax.emplace_back( Pt5ax) ; - /*if ( ProjectPointOnSurf( ptP, vpSurf, dPar, Pt5ax)) - vPt5ax.emplace_back( Pt5ax) ;*/ - - ///////////////////////////////////////////// questa parte non dovrebbe servire più visto che so già qual'è il triangolo giusto per guardare la normale - //// controllo che la normale trovata sia in linea con la precedente, se i due tratti erano abbastanza allineati - //bool bRecalc = false ; - //if ( bFirst) - // bRecalc = true ; - //if ( ssize( vPt5ax) > 2) { - // Point5ax& pt5Curr = vPt5ax.back() ; - // Point5ax& pt5Prev = vPt5ax.end()[-2] ; - // Point5ax& pt5PrevPrev = vPt5ax.end()[-3] ; - // Vector3d vtDirCurr = pt5Curr.ptP - pt5Prev.ptP ; vtDirCurr.Normalize() ; - // Vector3d vtDirPrev = pt5Prev.ptP - pt5PrevPrev.ptP ; vtDirPrev.Normalize() ; - // double dProjDir = vtDirCurr * vtDirPrev ; - // if ( dProjDir > COS_ANG_MAX_CORNER) { - // double dProjNorm = vPt5ax.back().vtDir1 * vtNormPrev ; - // if ( dProjNorm < COS_ANG_MAX_CORNER) - // bRecalc = true ; - // } - //} Vector3d vtDirNext = ptPNext - ptP ; vtDirNext.Normalize() ; - //// se sono arrivato ad uno spigolo tengo la normale appena prima dello spigolo - //if ( bRecalc) { - // Point3d ptAlter ; - // if ( ! bFirst) { - // Vector3d vtDirPrev = ptP - ptPrev ; vtDirPrev.Normalize() ; - // ptAlter = ptP - vtDirPrev * 5 * EPS_SMALL ; - // } - // else - // ptAlter = ptP + vtDirNext * 5 * EPS_SMALL ; - // Point5ax Pt5axRec ; - // if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) { - // if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) { - // vPt5ax.back().vtDir1 = Pt5axRec.vtDir1 ; - // vPt5ax.back().vtDir2 = Pt5axRec.vtDir2 ; - // } - // } - //} - //vtNormPrev = vPt5ax.back().vtDir1 ; - - // se richiesta la tangente anziché la normale allora modifico il vettore associato al punto Vector3d vtDir ; if ( ! bNormOrTang) { @@ -1369,9 +1366,16 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, vtDir = Media( vtDirNext, vtDirPrev) ; } vtDirPrev = vtDirNext ; + bool bEdge = ! AreSameVectorExact( vPt5ax.back().vtDir1, vPt5ax.back().vtDir2) ; Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ; vPt5ax.back().vtDir1 = vtTang ; - vPt5ax.back().vtDir2 = vtTang ; + if ( bEdge) { + Vector3d vtTang2 = vtDirNext ^ vPt5ax.back().vtDir2 ; + vtTang2.Normalize() ; + vPt5ax.back().vtDir2 = vtTang2 ; + } + else + vPt5ax.back().vtDir2 = vtTang ; } // passo al successivo ptPrev = ptP ;