diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 4068502..7755855 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -4962,6 +4962,10 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int bool bAdvance = true ; // verifico i match effettivi tra le polyline while( bAdvance) { + if( c > ssize(vMatch0) - 1 || j > ssize( vMatch1) - 1) { + LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: le due curve potrebbero non avere forme coerenti") ; + return false ; + } double dParam0 = vMatch0[c].second ; Point3d ptJoint0 = vMatch0[c].first ; double dParam1 = vMatch1[j].second ; @@ -5072,7 +5076,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int bool bEdgeFoundOnSecond = false ; if( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) { // questo caso non è previsto !!!!! e non mi aspetto che avvenga - LOG_DBG_ERR( GetEGkLogger(), "During the creation of a ruled surface in mode RLT_B_MINDIST_PLUS, a not handled mismatch was found") ; + LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found") ; } if( vEdgeSplit0[c+1]) { ++c ; @@ -5225,11 +5229,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int ++ nAddedSpan ; } - - //debug - return true ; - - return bOk ; } else if ( RLT_B_LENPAR ) { @@ -5575,6 +5574,19 @@ SurfBezier::GetAllPatchesIsocurves( bool bUOrV, ICURVEPOVECTOR& vCrv) const return true ; } +struct IsoParam { + int nCrv ; + double dParam0 ; + double dParam1 ; + IsoParam( int _nCrv, double _dParam0, double _dParam1): nCrv(_nCrv), dParam0( _dParam0), dParam1( _dParam1){ } ; + bool operator < ( IsoParam& b) + { + return ( abs(dParam0 - b.dParam0) > EPS_SMALL ? dParam0 < b.dParam0 : dParam1 < b.dParam1) ; + } +}; + +typedef vector ISOPARVECT ; + //---------------------------------------------------------------------------- bool SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const ICURVEPOVECTOR& vCrv) @@ -5608,80 +5620,143 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c // associo le isocurve passate in input ai relativi punti sulle due curve che generano la rigata INTINTVECTOR vPairs ; - vPairs.emplace_back( 0, 0) ; + //vPairs.emplace_back( 0, 0) ; // debug DBLVECTOR vdSplit0, vdSplit1 ; int nSplit0 = 0, nSplit1 = 0 ; Point3d ptLast0, ptLast1 ; double dLastParam0 = 0, dLastParam1 = 0 ; double dLenPrev0 = 0 ,dLenPrev1 = 0 ; + + // mi assicuro che le isocurve siano in ordine + ISOPARVECT vIso ; for ( int i = 0 ; i < ssize( vCrv) ; ++i) { - Point3d ptU0 ; vCrv[i]->GetEndPoint( ptU0) ; + Point3d ptU0 ; vCrv[i]->GetStartPoint( ptU0) ; Point3d ptU1 ; vCrv[i]->GetEndPoint( ptU1) ; double dParam0 ; CrvU0.GetParamAtPoint( ptU0, dParam0) ; double dParam1 ; CrvU1.GetParamAtPoint( ptU1, dParam1) ; + vIso.emplace_back( i, dParam0, dParam1) ; + } + sort( vIso.begin(), vIso.end()) ; + + for ( int i = 0 ; i < ssize( vIso) ; ++i) { + Point3d ptU0 ; vCrv[vIso[i].nCrv]->GetStartPoint( ptU0) ; + Point3d ptU1 ; vCrv[vIso[i].nCrv]->GetEndPoint( ptU1) ; + double& dParam0 = vIso[i].dParam0 ; + double& dParam1 = vIso[i].dParam1 ; + // se sono vicino ad un'intero allora considero il parametro intero ( uno split già esistente) + bool bIntParam0 = false ; + bool bIntParam1 = false ; + if ( abs( dParam0 - round( dParam0)) < EPS_SMALL) { + dParam0 = round( dParam0) ; + bIntParam0 = true ; + } + if ( abs( dParam1 - round( dParam1)) < EPS_SMALL) { + dParam1 = round( dParam1) ; + bIntParam1 = true ; + } int nParam0 = int( dParam0) ; int nParam1 = int( dParam1) ; int nLastParam0 = int( dLastParam0) ; int nLastParam1 = int( dLastParam1) ; - - // calcolo la parametrizzazione locale dei punti compresi tra le due isoparametriche double dLenCurr0 ; CrvU0.GetLengthAtParam( dParam0, dLenCurr0) ; - double dLen0 = dLenCurr0 - dLenPrev0 ; double dLenCurr1 ; CrvU1.GetLengthAtParam( dParam1, dLenCurr1) ; - double dLen1 = dLenCurr1 - dLenPrev1 ; - DBLVECTOR vdParamPos0, vdParamPos1 ; - int nPointsBetween0 = nParam0 - int( dLastParam0) ; - if( dParam0 - nParam0 > EPS_SMALL) - ++ nPointsBetween0 ; - for( int k = 0 ; k < nPointsBetween0 ; ++k) { - double dLen = 0 ; CrvU0.GetParamAtPoint( vPnt0[ nParam0 + 1 + k], dLen) ; - dLen -= dLenPrev0 ; - vdParamPos0.push_back( dLen) ; + int nPointsBetween0 = 0 ; + if( dParam0 - nLastParam0 > 1) { + if ( ! bIntParam0) + nPointsBetween0 = int( dParam0 - nLastParam0) ; + else + nPointsBetween0 = int( dParam0 - nLastParam0) - 1 ; } - vdParamPos0.push_back( 1) ; - int nPointsBetween1 = nParam1 - int( dLastParam1) ; - if( dParam1 - nParam1 > EPS_SMALL) - ++ nPointsBetween1 ; - for( int k = 0 ; k < nPointsBetween1 ; ++k) { - double dLen = 0 ; CrvU1.GetParamAtPoint( vPnt1[ nParam1 + 1 + k], dLen) ; - dLen -= dLenPrev1 ; - vdParamPos1.push_back( dLen) ; + else + nPointsBetween0 = 0 ; + int nPointsBetween1 = 0 ; + if( dParam1 - nLastParam1 > 1) { + if ( ! bIntParam1) + nPointsBetween1 = int( dParam1 - nLastParam1) ; + else + nPointsBetween1 = int( dParam1 - nLastParam1) - 1 ; } - vdParamPos1.push_back( 1) ; + else + nPointsBetween1 = 0 ; + if( nPointsBetween0 > 0 || nPointsBetween1 > 0) { + // calcolo la parametrizzazione locale dei punti compresi tra le due isoparametriche + double dLen0 = dLenCurr0 - dLenPrev0 ; + double dLen1 = dLenCurr1 - dLenPrev1 ; + DBLVECTOR vdParamPos0 ; vdParamPos0.reserve( nPointsBetween0) ; + DBLVECTOR vdParamPos1 ; vdParamPos1.reserve( nPointsBetween1) ; + for( int k = 0 ; k < nPointsBetween0 ; ++k) { + double dParamIntermed = 0 ; CrvU0.GetParamAtPoint( vPnt0[ nLastParam0 + 1 + k], dParamIntermed) ; + double dLen = 0 ; CrvU0.GetLengthAtParam( dParamIntermed, dLen) ; + dLen -= dLenPrev0 ; + vdParamPos0.push_back( dLen / dLen0) ; + } + vdParamPos0.push_back( 1) ; + for( int k = 0 ; k < nPointsBetween1 ; ++k) { + double dParamIntermed = 0 ; CrvU1.GetParamAtPoint( vPnt1[ nLastParam1 + 1 + k], dParamIntermed) ; + double dLen = 0 ; CrvU1.GetLengthAtParam( dParamIntermed, dLen) ; + dLen -= dLenPrev1 ; + vdParamPos1.push_back( dLen / dLen1) ; + } + vdParamPos1.push_back( 1) ; - bool bSplitToAdd = true ; - int c0 = 0, c1 = 0 ; - while( bSplitToAdd) { - // se ho una corrispondenza tra punti allora non aggiungo split - if( abs( vdParamPos0[c0] - vdParamPos0[c1]) < EPS_PARAM) { - ++c0 ; - ++c1 ; - ++nLastParam0 ; - ++nLastParam1 ; + bool bSplitToAdd = true ; + int c0 = 0, c1 = 0 ; + while( bSplitToAdd) { + if( c0 > ssize( vdParamPos0) - 1 && c1 > ssize( vdParamPos1) - 1) { + LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error while reparametrizing some section") ; + return false ; + } + // se ho una corrispondenza tra punti ( e non sono alla fine del tratto) allora non aggiungo split + if( abs( vdParamPos0[c0] - vdParamPos1[c1]) < EPS_PARAM && vdParamPos0[c0] < 1) { + ++c0 ; + ++c1 ; + ++nLastParam0 ; + ++nLastParam1 ; + vPairs.emplace_back( nLastParam0 + nSplit0, nLastParam1 + nSplit1) ; + } + // se non ho corrispondenza allora aggiungo uno split sulla curva a cui manca il punto corrispondente + else if( vdParamPos0[c0] < vdParamPos1[c1]) { + double dPar ; CrvU1.GetParamAtLength( dLenPrev1 + dLen1 * vdParamPos0[c0], dPar) ; + if ( abs( dPar - round( dPar)) > EPS_SMALL) { + vdSplit1.push_back( dPar) ; + nSplit1 = vdSplit1.size() ; + } + else if( dPar = round( dPar) ; dPar > nLastParam1){ + ++ nLastParam1 ; + } + ++nLastParam0 ; + vPairs.emplace_back( nLastParam0 + nSplit0, nLastParam1 + nSplit1) ; + ++c0 ; + } + else if( vdParamPos0[c0] > vdParamPos1[c1]) { + double dPar ; CrvU0.GetParamAtLength( dLenPrev0 + dLen0 * vdParamPos1[c1], dPar) ; + // se lo split non è in prossimità di una joint già esistente allora lo aggiungo + if ( abs( dPar - round( dPar)) > EPS_SMALL) { + vdSplit0.push_back( dPar) ; + nSplit0 = vdSplit0.size() ; + } + else if( dPar = round( dPar) ; dPar > nLastParam0){ + ++ nLastParam0 ; + } + ++nLastParam1 ; + vPairs.emplace_back( nLastParam0 + nSplit0, nLastParam1 + nSplit1) ; + ++c1 ; + } + bSplitToAdd = ! (c0 == ssize( vdParamPos0) - 1 && c1 == ssize( vdParamPos1) - 1) ; } - // se non ho corrispondenza allora aggiungo uno split sulla curva a cui manca il punto corrispondente - else if( vdParamPos0[c0] < vdParamPos0[c1]) { - double dPar ; CrvU0.GetParamAtLength( dLenPrev0 + dLen0 * vdParamPos0[c0], dPar) ; - vdSplit1.push_back( dPar) ; - nSplit1 = vdSplit1.size() ; - ++nLastParam0 ; - vPairs.emplace_back( nLastParam0 + nSplit0, nLastParam1 + nSplit1) ; - ++c0 ; - } - else if( vdParamPos0[c0] > vdParamPos0[c1]) { - double dPar ; CrvU1.GetParamAtLength( dLenPrev1 + dLen1 * vdParamPos1[c1], dPar) ; - vdSplit0.push_back( dPar) ; - nSplit0 = vdSplit0.size() ; - ++nLastParam1 ; - vPairs.emplace_back( nLastParam0 + nSplit0, nLastParam1 + nSplit1) ; - ++c1 ; - } - bSplitToAdd = ! (c0 == ssize( vdParamPos0) && c1 == ssize( vdParamPos1)) ; } // salvo i dati di questo accoppiamento dLenPrev0 = dLenCurr0 ; dLenPrev1 = dLenCurr1 ; + if( ! bIntParam0 && dParam0 > dLastParam0) { + vdSplit0.push_back( dParam0) ; + nSplit0 = vdSplit0.size() ; + } + if( ! bIntParam1 && dParam1 > dLastParam1) { + vdSplit1.push_back( dParam1) ; + nSplit1 = vdSplit1.size() ; + } dLastParam0 = dParam0 ; dLastParam1 = dParam1 ; ptLast0 = ptU0 ; @@ -5689,7 +5764,7 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c vPairs.emplace_back( nParam0 + nSplit0, nParam1 + nSplit1) ; } - // applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep + // applico effettivamente gli split int nUnit = 0 ; if ( ! vdSplit1.empty()) nUnit = int( vdSplit1.back()) ;