From 3f02119ef782f120859f4d67b015bfdff2486baa Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Wed, 20 Mar 2024 11:56:50 +0100 Subject: [PATCH] EgtGeomKernel : - corretta la funzione che restituisce gli edge 3D di una Bezier. --- SurfBezier.cpp | 93 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/SurfBezier.cpp b/SurfBezier.cpp index c97719b..99c853f 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -3039,9 +3039,9 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg // calcolo le autointersezioni a mano // le premesse sono che le compo è formata da curveLine e che i tratti eventualmente sovrapposti sono linee interamente coincidenti ( start-end e viceversa) - //double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ; - //Intervals inDomain ; inDomain.Set( dStart, dEnd) ; - DBLVECTOR vdU ; + double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ; + Intervals inDomain ; inDomain.Set( dStart, dEnd) ; + //DBLVECTOR vdU ; BOOLVECTOR vbErased( m_vCCLoop[i]->GetCurveCount()) ; fill( vbErased.begin(), vbErased.end(), false) ; // scorro tutte le curve singole della compo @@ -3056,34 +3056,65 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg const ICurve* pCrvB = m_vCCLoop[i]->GetCurve( w) ; Point3d ptStartB ; pCrvB->GetStartPoint( ptStartB) ; Point3d ptEndB ; pCrvB->GetEndPoint( ptEndB) ; - if ( ( AreSamePointApprox( ptStartA, ptEndB) && AreSamePointApprox( ptEndA, ptStartB)) || - ( AreSamePointApprox( ptStartA, ptStartB) && AreSamePointApprox( ptEndA, ptEndB))) { + //if ( ( AreSamePointApprox( ptStartA, ptEndB) && AreSamePointApprox( ptEndA, ptStartB)) || + // ( AreSamePointApprox( ptStartA, ptStartB) && AreSamePointApprox( ptEndA, ptEndB))) { + // vbErased[k] = true ; + // //inDomain.Subtract(k, k+1) ; + // vbErased[w] = true ; + // //inDomain.Subtract(w, w+1) ; + // break ; + //} + IntCrvCrvInfo iccInfo ; + Vector3d vtDirSA ; pCrvA->GetStartDir( vtDirSA) ; + Vector3d vtDirSB ; pCrvB->GetStartDir( vtDirSB) ; + if ( AreSameOrOppositeVectorApprox( vtDirSA, Z_AX) || AreSameOrOppositeVectorApprox( vtDirSB, Z_AX)) { + Frame3d frOptimal ; + if ( (vtDirSA ^ vtDirSB).Len() > EPS_SMALL) + frOptimal.Set( ORIG, vtDirSA ^ vtDirSB, vtDirSA) ; + else + frOptimal.Set( ORIG, X_AX, vtDirSA) ; + PtrOwner pCrvNewA( pCrvA->Clone()) ; + pCrvNewA->ToLoc( frOptimal) ; + PtrOwner pCrvNewB( pCrvB->Clone()) ; + pCrvNewB->ToLoc( frOptimal) ; + IntersCurveCurve icc( *pCrvNewA, *pCrvNewB) ; + icc.GetIntCrvCrvInfo( 0, iccInfo) ; + } + else { + IntersCurveCurve icc( *pCrvA, *pCrvB) ; + icc.GetIntCrvCrvInfo( 0, iccInfo) ; + } + // se sono sovrapposte allora devo eliminare la parte comune + if ( iccInfo.bOverlap && ( AreSamePointApprox( ptStartA, ptEndB) || AreSamePointApprox( ptEndA, ptStartB) || + AreSamePointApprox( ptStartA, ptStartB) || AreSamePointApprox( ptEndA, ptEndB))) { + inDomain.Subtract( k + iccInfo.IciA[0].dU, k + iccInfo.IciA[1].dU) ; vbErased[k] = true ; - //inDomain.Subtract(k, k+1) ; + inDomain.Subtract( w + iccInfo.IciB[0].dU, w + iccInfo.IciB[1].dU) ; vbErased[w] = true ; - //inDomain.Subtract(w, w+1) ; break ; } } // quando raggiungo la prima intersezione potrei anche uscire dal for.. però devo salvarmi da qualche parte tra quali sottocurve // ci sono intersezioni sennò non posso accorgermene } - double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ; - if ( vbErased[0]) - vdU.emplace_back( dStart) ; - for ( int w = 1 ; w < int( vbErased.size()) ; ++w) { - if ( (vbErased[w] && ! vbErased[w - 1]) || (! vbErased[w] && vbErased[w - 1])) - vdU.emplace_back( w) ; - } - if ( vbErased.back()) - vdU.emplace_back( dEnd) ; + //double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ; + //if ( vbErased[0]) + // vdU.emplace_back( dStart) ; + //for ( int w = 1 ; w < int( vbErased.size()) ; ++w) { + // if ( (vbErased[w] && ! vbErased[w - 1]) || (! vbErased[w] && vbErased[w - 1])) + // vdU.emplace_back( w) ; + //} + //if ( vbErased.back()) + // vdU.emplace_back( dEnd) ; + ICRVCOMPOPOVECTOR vpCCOpen ; //double dStartA, dEndA ; inDomain.GetFirst( dStartA, dEndA) ; //double dStartB, dEndB ; inDomain.GetLast( dStartB, dEndB) ; //Point3d ptTest0 ; m_vCCLoop[i]->GetPointD1D2( dStartA + EPS_SMALL, ICurve::FROM_MINUS, ptTest0) ; //Point3d ptTest1 ; m_vCCLoop[i]->GetPointD1D2( dEndB - EPS_SMALL, ICurve::FROM_MINUS, ptTest1) ; - + ////questo pezzo in teoria non serve perché gli intervalli segnalati sono quelli da cancellare( con dU) + //// con Intervals, quello che resta è quello da tenere //Point3d ptTest0 ; m_vCCLoop[i]->GetPointD1D2( vdU[0] + EPS_SMALL, ICurve::FROM_MINUS, ptTest0) ; //Point3d ptTest1 ; m_vCCLoop[i]->GetPointD1D2( vdU.back() - EPS_SMALL, ICurve::FROM_MINUS, ptTest1) ; //// scopro quali sono gli intervalli da tenere e quali da cancellare @@ -3094,16 +3125,26 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg // vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( 0, vdU[0]))) ; //} - if ( vdU[0] > EPS_SMALL) - vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( 0, vdU[0]))) ; - for ( int j = 0 ; j < int(vdU.size() / 2) - 1 ; ++j) - vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU[j*2 + 1], vdU[(j+ 1)*2]))) ; - - // se dopo l'ultimo dU ho ancora un pezzo di curva allora lo aggiungo - if ( dEnd - vdU.back() > EPS_SMALL) { - vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU.end()[-2], vdU.back()))) ; - } + //// ricostruisco la curva finale prendendo tutto tranne i tratti sovrapposti + // + //// con vdU + //if ( vdU[0] > EPS_SMALL) + // vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( 0, vdU[0]))) ; + + //for ( int j = 0 ; j < int(vdU.size() / 2) - 1 ; ++j) + // vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU[j*2 + 1], vdU[(j+ 1)*2]))) ; + // + //// se dopo l'ultimo dU ho ancora un pezzo di curva allora lo aggiungo + //if ( dEnd - vdU.back() > EPS_SMALL) { + // vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU.end()[-2], vdU.back()))) ; + //} + + // con Intervals + double dStart0, dEnd0 ; inDomain.GetFirst( dStart0, dEnd0) ; + vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( dStart0, dEnd0))) ; + while ( inDomain.GetNext( dStart0, dEnd0)) + vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( dStart0, dEnd0))) ; // creo la chain a mano con le compo BOOLVECTOR vbAdded( vpCCOpen.size()) ;