diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index 6cd46ac..94de273 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -83,35 +83,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) return false ; } - // identifico le zone circostanti un angolo interno - for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) { - if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) { - // scorro indietro e avanti flaggando i tratti da controllare - int nPrev = i - 1 ; - if ( nPrev < 0) - nPrev = ssize( vPnt5Ax) - 1; - int nNext = i + 1 ; - if ( nNext >= ssize( vPnt5Ax)) - nNext = 0 ; - double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) ; - double dDistAngConc = dOffDist * tan( dAng / 2) ; - int c = nPrev ; - while ( c > 0 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) { - vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ; - --c ; - } - vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ; - // scorro in avanti - c = nNext ; - while ( c < ssize( vPnt5Ax) && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) { - vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ; - ++c ; - } - vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ; - i = c ; - } - } - PtrOwner pCrv( CreateBasicCurveComposite()) ; if ( ! pCrv->FromPolyLine( PL)) return false ; @@ -158,6 +129,47 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) bool bClosed = pCrv->IsClosed() ; + // identifico le zone circostanti un angolo interno + for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) { + if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) { + // scorro indietro e avanti flaggando i tratti da controllare + int nPrev = i - 1 ; + if ( nPrev < 0) + nPrev = ssize( vPnt5Ax) - 1; + int nNext = i + 1 ; + if ( nNext >= ssize( vPnt5Ax)) + nNext = 0 ; + double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) * RADTODEG ; + double dDistAngConc = dOffDist * tan( ( dAng / 2) * DEGTORAD) ; + int c = nPrev ; + while ( Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) { + vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ; + --c ; + if ( c < 0) { + if ( bClosed) + c = ssize( vPnt5Ax) - 1 ; + else + break ; + } + } + vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ; + // scorro in avanti + c = nNext ; + while ( c < ssize( vPnt5Ax) - 1 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) { + vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ; + ++c ; + if ( c == ssize( vPnt5Ax) - 1) { + if ( bClosed) + c = 0 ; + else + break ; + } + } + vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ; + i = c ; + } + } + for ( int i = 1 ; i < ssize( vFlag) - 1 ; ++i) { if ( vFlag[i-1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC && vFlag[i+1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC && @@ -218,10 +230,10 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) vtTang.Normalize() ; Vector3d vtCorr = vtOffDir ; double dCorrK = 1 ; - if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) { - double dHalfAlfa = acos( vtTang * vtTangPrev) ; - dCorrK = 1 / sin( 90 - dHalfAlfa) ; - } + //if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) { + // double dHalfAlfa = acos( vtTang * vtTangPrev) * RADTODEG ; + // dCorrK = 1 / sin( ( 90 - dHalfAlfa) * DEGTORAD) ; + //} Point3d ptP ; if ( pCrvCurr != nullptr) @@ -250,30 +262,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) if ( ! vtAng.IsSmall() && vtAng.Normalize()) bPlanarConcCvex = abs( vtAng * vOffDir[nCurr]) < COS_ANG_MAX_PLANAR ; - //// se punto di angolo interno di fianco, elimino eventuali movimenti precedenti invertiti - //if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX == 3) { - // local nLastId = EgtGetLastInGroup( nClPathId) - // while nLastId do - // local vtMlast = ptP - EgtEP( nLastId, GDB_ID.ROOT) ; vtMlast:normalize() - // if vtMlast * vtGpre < 0.5 then - // ptPpre = EgtSP( nLastId, GDB_ID.ROOT) - // EgtErase( nLastId) - // else - // break - // end - // nLastId = EgtGetLastInGroup( nClPathId) - // end - //} - - //// se appena dopo angolo interno di fianco, verifico se da aggiungere - //bool bToAdd = true - //if ( nFlpre == 3 and abs( dSideAng) > GEO.EPS_ANG_SMALL) { - // local vtMove = ptP - ptPpre ; vtMove:normalize() - // if vtMove * vtTang < 0.5 then - // bToAdd = false - // end - //} - if ( ! bCheckingClosure) { Vector3d vtDirCurrOff = ptP - ptPrev ; vtDirCurrOff.Normalize() ; double dProj = 1 ; @@ -376,21 +364,8 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) return true ; - // raccordi - // angoli interni - - // angoli esterni - - // auto intersezioni - - //// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi - - //// ottavo passo : concateno i percorsi risultanti (senza cambiare verso) - - //// nono passo : se con smusso o estensione, sostituisco i fillet con questi - //// ordino le curve in ordine decrescente di lunghezza //if ( m_CrvLst.size() > 1) { // for ( auto pCrv : m_CrvLst) { @@ -467,18 +442,11 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v const double dLinTol = 10 * EPS_SMALL ; for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { int nFlag = vOffsetCrvs[i].nFlag ; - if ( nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC || nFlag == OffsetCurve3d::AngType::ANG_BEFORE_CONC) { + // considero tutt le zone concave + if ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) { // scorro i prossimi finchè trovo la fine della zona concava - INTVECTOR vLines ; - while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) { - vLines.push_back( i) ; - ++i ; - if ( i < ssize( vOffsetCrvs)) - nFlag = vOffsetCrvs[i].nFlag ; - else - nFlag = OffsetCurve3d::AngType::ANG_STR ; - } // controllo se devo considerare anche tratti prima dello start + INTVECTOR vLines ; if ( i == 0) { INTVECTOR vLinesAdd ; int c = ssize( vOffsetCrvs) - 1 ; @@ -489,9 +457,24 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v if ( c > 0) nFlag = vOffsetCrvs[c].nFlag ; } - vLinesAdd.insert( vLinesAdd.end(), vLines.begin(), vLines.end()) ; - swap( vLinesAdd, vLines) ; + // inserisco il vettore al contrario, in modo che sia in ordine crescente + vLines.insert( vLines.end(), vLinesAdd.rbegin(), vLinesAdd.rend()) ; } + bool bDone = false ; + nFlag = vOffsetCrvs[i].nFlag ; + while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) { + vLines.push_back( i) ; + ++i ; + if ( i < ssize( vOffsetCrvs)) + nFlag = vOffsetCrvs[i].nFlag ; + else { + bDone = true ; + break ; + } + } + // se sto ricominciando, esco dal for ( il tratto finale è già stato considerato insieme al tratto iniziale) + if ( bDone) + break ; CYLVECT vCyl ; // creo un cilindro della dimensione del raggio for ( int j = 0 ; j < ssize( vLines) ; ++j) { @@ -501,7 +484,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v Point3d ptStart, ptEnd ; pSubCrv->GetStartPoint( ptStart) ; pSubCrv->GetEndPoint( ptEnd) ; - ////////// cilindri con asse sul parent + // cilindri con asse sul parent Vector3d vtHeight = ptEnd - ptStart ; double dHeight = vtHeight.Len() ; vtHeight.Normalize() ; @@ -512,23 +495,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v vGeo.push_back( pSurfTm) ; vCol.push_back( LGRAY) ; #endif - -// //// cilindri con la direz offset -// Point3d ptOffEnd ; vOffsetCrvs[vLines[j]].pCrv->GetEndPoint( ptOffEnd) ; -// Vector3d vtOff = ptOffEnd - ptEnd ; vtOff.Normalize() ; -// Vector3d vtHeight = ptEnd - ptStart ; -// double dHeight = vtHeight.Len() ; -// Vector3d vtNewAxis = OrthoCompo( vtHeight, vtOff) ; -// vtHeight.Normalize() ; -// vtNewAxis.Normalize() ; -// Point3d ptStartCyl = ptEnd -vtNewAxis * dHeight ; -// vCyl.emplace_back( ptStartCyl, vtNewAxis, dHeight, dRad, dLinTol) ; -//#if SAVECYL -// CurveArc ca ; ca.Set( vCyl.back().frCyl.Orig(), vCyl.back().frCyl.VersZ(), dRad) ; -// ISurfTriMesh* pSurfTm = GetSurfTriMeshByExtrusion( &ca, vCyl.back().frCyl.VersZ() * dHeight, false, 2 * EPS_SMALL) ; -// vGeo.push_back( pSurfTm) ; -// vCol.push_back( LGRAY) ; -//#endif } // controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti @@ -558,16 +524,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v bErasedSomePart = true ; if ( ! bStartInsideCyl) bCheckStart = true ; - //// se avevo un'interruzione nella zona da modificare, la colmo - //if ( ! vInters.empty() && vInters.back().first != vLines[j-1]) { - // // aggiungo tutti i precedenti che mancano - // int z = vInters.back().second ; - // for ( int h = vInters.back().first + 1 ; h < vLines[j] ; ++h) { - // vInters.emplace_back( h, z) ; - // vEditInfo.pop_back() ; - // ++z ; - // } - //} + if ( vEditZones.empty() || vEditZones.back().back().first != vLines[j-1]) vEditZones.emplace_back() ; vEditZones.back().emplace_back( vLines[j], j) ; @@ -584,11 +541,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v } } if ( bErasedSomePart) { - //// controllo che effettivamente tutti i tratti cancellati siano consecutivi - //for ( int j = 1 ; j < ssize( vInters) ; ++j) { - // if ( vInters[j].first != vInters[j-1].first + 1) - // return false ; - //} // calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati for ( int z = 0 ; z < ssize( vEditZones) ; ++z) { INTINTVECTOR& vInters = vEditZones[z] ; diff --git a/ProjectCurveSurf.cpp b/ProjectCurveSurf.cpp index 2282811..94c0808 100644 --- a/ProjectCurveSurf.cpp +++ b/ProjectCurveSurf.cpp @@ -13,6 +13,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" +#include #include "SurfTriMesh.h" #include "SurfBezier.h" #include "GeoConst.h" @@ -1292,17 +1293,24 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, Vector3d vtNormPrev = V_INVALID ; Point3d ptPrev ; bool bFirst = true ; + const ICurveComposite* pCC = GetCurveComposite( &crCrv) ; while ( bFound) { // se trovo proiezione, la salvo Point5ax Pt5ax ; Pt5ax.ptP = ptP ; Pt5ax.dPar = dPar ; - int nTria = int( crCrv.GetTempParam( dPar)) ; + double dDecimal ; + int nCrv = int( modf( dPar, &dDecimal) == 0.0 ? 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 ; 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) ;*/ @@ -1356,9 +1364,9 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, vtDir = vtDirPrev ; // in caso sia stato superato l'angolo limite dò priorità alla direzione precedente if ( vtDirPrev.IsValid() && (! bFirst || ( bFirst && bClosed))) { - double dProj = vtDir * vtDirPrev ; + double dProj = vtDirNext * vtDirPrev ; if ( dProj > COS_ANG_MAX_CORNER) - vtDir = Media( vtDir, vtDirPrev) ; + vtDir = Media( vtDirNext, vtDirPrev) ; } vtDirPrev = vtDirNext ; Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ; diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index cc6e926..3ad07ee 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -2171,7 +2171,7 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu PL.GetFirstUPoint( &dPar, &pt) ; for ( int i = 0 ; i < pLoop->GetCurveCount() ; ++i) { PL.GetNextUPoint( &dPar, &pt) ; - pLoop->SetTempProp( i, dPar) ; + pLoop->SetCurveTempProp( i, int( dPar)) ; } // ricavo il tratto di bordo da estendere, con le tangenti della superficie