diff --git a/PolyLine.cpp b/PolyLine.cpp index ca205e6..a88a2e1 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -18,6 +18,8 @@ #include "PolygonPlane.h" #include "PointsPCA.h" #include "GeoConst.h" +#include "CurveComposite.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkPlane3d.h" #include "/EgtDev/Include/EGkDistPointLine.h" @@ -1767,5 +1769,311 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV } } + return true ; +} + +//---------------------------------------------------------------------------- +bool +MatchPolyLinesAddingPoints( const PolyLine& PL1, const PolyLine& PL2, int nType, PNTIVECTOR& vPnt1, PNTIVECTOR& vPnt2) +{ + // prima trovo le associazioni senza aggiunte di punti + Point3d ptP2 ; + CurveComposite cc1, cc2 ; + cc1.FromPolyLine( PL1) ; + cc2.FromPolyLine( PL2) ; + int nPnt1 = PL1.GetPointNbr() ; + int nPnt2 = PL2.GetPointNbr() ; + vector> vMatch2 ; + PL2.GetFirstPoint( ptP2) ; + while ( PL2.GetNextPoint( ptP2, true)) { + DistPointCurve dpc( ptP2, cc1, false) ; + int nFlag = 0 ; + double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ; + Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ; + vMatch2.push_back( pair( ptJoint, dParam)) ; + } + + int nAtStart2 = 0 ; // match ripetuti dalla curva U0 allo start della curva U1 + int nAtEnd2 = 0 ; + Point3d ptP1 ; PL1.GetFirstPoint( ptP1) ; + int c = 0 ; + int nRep1 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1 + int nRep2 = 0 ; + double dLastParamMatch = 0 ; + Point3d ptLastPointMatch = ptP1 ; + BOOLVECTOR vbRep1( nPnt1) ; + INTVECTOR vnAddedOrNextIsRep1 ; // 0 non Rep, 1 Rep, 2 Next is Rep ; + DBLVECTOR vdSplit1 ; + DBLVECTOR vdMatch1 ; + fill( vbRep1.begin(), vbRep1.end(), false) ; + while ( PL1.GetNextPoint( ptP1, true)) { + // devo salvarmi se matcho più punti con lo start o l'end della curva totale + DistPointCurve dpc( ptP1, cc2, false) ; + int nFlag = 0 ; + double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ; + Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ; + vdMatch1.push_back( dParam) ; + if ( dParam < EPS_SMALL ) { + ++nAtStart2 ; + vbRep1[c] = true ; + ++c ; + continue ; + } + else if ( dParam > nPnt2 - EPS_SMALL ) { + vbRep1[c] = nAtEnd2 == 0 ? false : true ; + vbRep1.back() = true ; + ++ nAtEnd2 ; + ++c ; + continue ; + } + if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) { + dParam = dLastParamMatch ; + vbRep1[c] = true ; + ++ nRep1 ; + ++c ; + continue ; + } + else { + dLastParamMatch = dParam ; + ptLastPointMatch = ptJoint ; + // se sono già troppo vicino ad un split esistente allora non faccio nulla + if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { + ++c ; + continue ; + } + vdSplit1.push_back( dParam) ; + // verifico se ho un match per questo punto + // in tal caso vuol dire che sto creando una ripetizione nRep1 + int nCase = 0 ; + for ( int j = 0 ; j < int( vMatch2.size()) ; ++j) { + if ( abs(vMatch2[j].second - (c + 1)) < EPS_SMALL) { + // devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione + bool bFoundMatch = false ; + for ( int z = int( vMatch2[j].second) ; z < int( vdMatch1.size()) ; ++z) { + if ( abs( vdMatch1[z] - ( j + 1 )) < EPS_SMALL ) { + bFoundMatch = true ; + break ; + } + } + + if ( ! bFoundMatch) { + ++nRep2 ; + // capisco se il punto è rep o se lo è il suo successivo + if( j + 1 < dParam) + nCase = 1 ; + else + nCase = 2 ; + } + break ; + } + } + vnAddedOrNextIsRep1.push_back( nCase) ; + } + ++c ; + } + int nAtStart1 = 0 ; + int nAtEnd1 = 0 ; + PL2.GetFirstPoint( ptP2) ; + c = 0 ; + dLastParamMatch = 0 ; + ptLastPointMatch = ptP2 ; + INTVECTOR vnAddedOrNextIsRep2 ; // 0 non Rep, 1 Rep, 2 Next is Rep ; + DBLVECTOR vdSplit2 ; + BOOLVECTOR vbRep2( nPnt2) ; + fill( vbRep2.begin(), vbRep2.end(), false) ; + while ( PL2.GetNextPoint( ptP2, true)) { + DistPointCurve dpc( ptP2, cc1, false) ; + int nFlag = 0 ; + double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ; + Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ; + if ( dParam < EPS_SMALL ) { + ++nAtStart1 ; + vbRep2[c] = true ; + ++c ; + continue ; + } + else if ( dParam > nPnt1 - EPS_SMALL ) { + vbRep2[c] = nAtEnd1 == 0 ? false : true ; + vbRep2.back() = true ; + ++ nAtEnd1 ; + ++c ; + continue ; + } + if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) { + dParam = dLastParamMatch ; + vbRep2[c] = true ; + ++ nRep2 ; + ++c ; + continue ; + } + else { + dLastParamMatch = dParam ; + ptLastPointMatch = ptJoint ; + //se sono troppo vicino ad uno split esistente allora non faccio nulla + if( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { + ++c ; + continue ; + } + vdSplit2.push_back( dParam) ; + // verifico se ho un match per questo punto + // in tal caso vuol dire che sto creando una ripetizione nRep0 + int nCase = 0 ; + for ( int j = 0 ; j < int( vdMatch1.size()) ; ++j) { + if ( abs(vdMatch1[j] - (c + 1)) < EPS_SMALL) { + // devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione + bool bFoundMatch = false ; + for ( int z = int( vdMatch1[j]) ; z < int( vMatch2.size()) ; ++z) { + if ( abs( vMatch2[z].second - ( j + 1 )) < EPS_SMALL ) { + bFoundMatch = true ; + break ; + } + } + + if ( ! bFoundMatch) { + ++nRep1 ; + // capisco se il punto è rep o se lo è il suo successivo + if( j + 1 < dParam) + nCase = 1 ; + else + nCase = 2 ; + } + break ; + } + } + vnAddedOrNextIsRep2.push_back( nCase) ; + } + ++c ; + } + + // applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep + int nUnit = 0 ; + if ( ! vdSplit1.empty()) + nUnit = int( vdSplit1.back()) ; + for ( int z = int( vdSplit1.size() - 1) ; z >= 0 ; --z) { + double dSplit = vdSplit1[z] ; + int nSplit = int( dSplit) ; + // se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo + // riscalare + if ( nSplit == nUnit && z < int( vdSplit1.size() - 1)) { + dSplit = nSplit + ( dSplit - nSplit) / (vdSplit1[z+1] - nSplit); + } + nUnit = nSplit ; + cc2.AddJoint( dSplit) ; + switch( vnAddedOrNextIsRep1[z]) { + case 0 : if( vbRep2[nSplit]) + ++ nRep2 ; + // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo + vbRep2.insert( vbRep2.begin() + nSplit, vbRep2[nSplit]) ; break ; + case 1 : vbRep2.insert( vbRep2.begin() + nSplit, true) ; break ; + case 2 : if ( vbRep2[nSplit]) + --nRep2 ; + else + vbRep2[nSplit] = true ; + vbRep2.insert( vbRep2.begin() + nSplit, false) ; break ; + } + } + if( ! vdSplit2.empty()) + nUnit = int( vdSplit2.back()) ; + for ( int z = int( vdSplit2.size() - 1) ; z >= 0 ; --z) { + double dSplit = vdSplit2[z] ; + int nSplit = int( dSplit) ; + // se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo + // riscalare + if ( nSplit == nUnit && z < int( vdSplit2.size() - 1)) { + dSplit = nSplit + ( dSplit - nSplit) / (vdSplit2[z+1] - nSplit); + } + nUnit = nSplit ; + cc1.AddJoint( dSplit) ; + switch( vnAddedOrNextIsRep2[z]) { + case 0 : if( vbRep1[nSplit]) + ++ nRep1 ; + // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo + vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ; break ; + case 1 : vbRep1.insert( vbRep1.begin() + nSplit, true) ; break ; + case 2 : if( vbRep1[nSplit]) + -- nRep1 ; + else + vbRep1[nSplit] = true ; + vbRep1.insert( vbRep1.begin() + nSplit, false) ; break ; + } + } + + nPnt1 = cc1.GetCurveCount() ; + nPnt2 = cc2.GetCurveCount() ; + //aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true + int nAddedSpan = 0 ; + int nCrv1 = 0 ; + int nCrv2 = 0 ; + while ( nAddedSpan < nPnt1 + nAtStart1 + nAtEnd1 + nRep2) { + if ( nCrv1 >= nPnt1) + nCrv1 = nPnt1 - 1; + if ( nCrv2 >= nPnt2) + nCrv2 = nPnt2 - 1; + bool bRep1 = vbRep1[nCrv1] ; + bool bRep2 = vbRep2[nCrv2] ; + if ( bRep1 && bRep2 ) { + vbRep1[nCrv1] = false ; + bRep1 = false ; + vbRep2[nCrv2] = false ; + bRep2 = false ; + -- nRep1 ; + -- nRep2 ; + } + if ( ! bRep1 || nCrv2 == nPnt2 - 1) + ++ nCrv2 ; + if ( ! bRep2 || nCrv1 == nPnt1 - 1) + ++ nCrv1 ; + ++nAddedSpan ; + } + // se non sono arrivato all'ultima curva su U0 o U1 vuol dire che ho creato delle ripetizioni che non ho contato prima + if( nCrv2 < nPnt2) { + nRep2 += nPnt2 - nCrv2 ; + for ( int z = int( vbRep2.size() - 1) ; z >= nCrv2 ; --z) + vbRep2[z] = true ; + } + if( nCrv1 < nPnt1) { + nRep1 += nPnt1 - nCrv1 ; + for ( int z = int( vbRep1.size() - 1) ; z >= nCrv1 ; --z) + vbRep1[z] = true ; + } + + // trovo il numero di span che dovrà avere la superficie + // ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0) + int nPnt = nPnt1 + nAtStart1 + nAtEnd1 + nRep2 ; + + if( nPnt != nPnt2 + nAtStart2 + nAtEnd2 + nRep1) + LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ; + + + // aggiungo i punti di controllo scorrendo in contemporanea le due curve + nAddedSpan = 0 ; + nCrv1 = 0 ; + nCrv2 = 0 ; + bool bLast1 = false ; + bool bLast2 = false ; + while ( nAddedSpan < nPnt) { + if ( nCrv1 >= nPnt1){ + nCrv1 = nPnt1 - 1; + bLast1 = true ; + } + if ( nCrv2 >= nPnt2) { + nCrv2 = nPnt2 - 1; + bLast2 = true ; + } + bool bRep1 = vbRep1[nCrv1] ; + bool bRep2 = vbRep2[nCrv2] ; + const ICurve* pSubCrv1 = cc1.GetCurve( nCrv1) ; + Point3d ptStart1 ; pSubCrv1->GetStartPoint( ptStart1) ; + vPnt1.emplace_back( ptStart1, nAddedSpan) ; + const ICurve* pSubCrv2 = cc2.GetCurve( nCrv2) ; + Point3d ptStart2 ; pSubCrv2->GetStartPoint( ptStart2) ; + vPnt2.emplace_back( ptStart2, nAddedSpan) ; + if ( ! bRep2) + ++ nCrv1 ; + if ( ! bRep1) + ++ nCrv2 ; + ++ nAddedSpan ; + } + return true ; } \ No newline at end of file