From 42c5ffb0148858a4424b41696e55ed095b7749e0 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 19 Mar 2026 10:33:18 +0100 Subject: [PATCH] EgtGeomKernel : - correzioni e migliorie a IntersCurveCurve. --- IntersCrvCompoCrvCompo.cpp | 220 +++++++++++++++++++------------------ SurfFlatRegion.cpp | 14 +++ Voronoi.cpp | 2 +- 3 files changed, 131 insertions(+), 105 deletions(-) diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp index 20d9597..e30969c 100644 --- a/IntersCrvCompoCrvCompo.cpp +++ b/IntersCrvCompoCrvCompo.cpp @@ -26,7 +26,7 @@ using namespace std ; static bool CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2, bool bCrvAClosed, double dCrvASpan) ; static bool CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2, - bool bCrvBClosed, double dCrvBSpan) ; + bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB = false) ; static void MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crvCompo) ; static int GetCrvBDirAPrev( IntCrvCrvInfo& Icci) ; static int GetCrvBDirANext( IntCrvCrvInfo& Icci) ; @@ -34,7 +34,6 @@ static bool CalcATypeFromDisk( const ICurve& CurveA, double dUA, ICurve::Side nS const ICurve& CurveB, double dUB, int& nType) ; static bool CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA, const ICurve& CurveB, double dUB1, double dUB2, int& nType) ; -//static bool CalcSide( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2, const ICurve* pThisCrv, const ICurve* pOtherCrv, bool bCrvAOrB, int& nType) ; //---------------------------------------------------------------------------- IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, @@ -430,13 +429,13 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, continue ; } // calcolo sottoindici - int ki = 0 ; // del successivo si prende sempre il primo - int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap + int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ; + int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ; // verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL) if ( AreSamePointXYEpsilon( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI, 10 * EPS_SMALL) && AreSamePointXYEpsilon( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI, 10 * EPS_SMALL) && CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan) && - CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan)) { + CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan, true)) { // caso entrambi Overlap ma di tipo opposto e sullo stesso tratto if ( m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq && abs( m_Info[i].IciB[0].dU - m_Info[j].IciB[0].dU) < EPS_PARAM && @@ -599,18 +598,19 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ; for ( int i = 0 ; i < m_nNumInters ; ++ i) { // se il tipo di accostamento per la curva B non è definito - if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) { + int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ; + if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL) { if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) { int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; - m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ; + m_Info[i].IciB[ki].nPrevTy = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ; } } // se il tipo di allontanamento per la curva B non è definito - int ki = ( m_Info[i].bOverlap ? 1 : 0) ; + ki = ( m_Info[i].bOverlap && m_Info[i].bCBOverEq ? 1 : 0) ; if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL) { if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) { int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; - m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[0].nPrevTy ; + m_Info[i].IciB[ki].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ; } } } @@ -781,7 +781,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, } // verifico se una curva ha tutte le info e queste info sono coerenti - if ( m_nNumInters > 1) { + if ( m_nNumInters > 1 && ! bAutoInters) { bool bCoherent = true ; INTVECTOR vIncoherenceWithPrev ; INTVECTOR vNewOverlap ; @@ -822,9 +822,10 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, // salvo eventuali incoerenze col precedente for ( int i = bCrvBClosed ? 0 : 1 ; i < m_nNumInters ; ++i) { int j = i == 0 ? m_nNumInters - 1 : i - 1 ; - int kj = m_Info[j].bOverlap ? 1 : 0 ; - if ( ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL || m_Info[i].IciB[0].nPrevTy == ICCT_NULL || m_Info[j].IciB[kj].nNextTy != m_Info[i].IciB[0].nPrevTy) && - m_Info[j].IciB[kj].nNextTy != ICCT_SPK && m_Info[i].IciB[0].nPrevTy != ICCT_SPK) { + int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ; + int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ; + if ( ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL || m_Info[i].IciB[ki].nPrevTy == ICCT_NULL || m_Info[j].IciB[kj].nNextTy != m_Info[i].IciB[ki].nPrevTy) && + m_Info[j].IciB[kj].nNextTy != ICCT_SPK && m_Info[i].IciB[ki].nPrevTy != ICCT_SPK) { vIncoherenceWithPrev.push_back( i) ; bCoherent = false ; } @@ -833,11 +834,12 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, if ( ! bCoherent) { for ( int i : vIncoherenceWithPrev) { int j = i == 0 ? m_nNumInters - 1 : i - 1 ; - int kj = m_Info[j].bOverlap ? 1 : 0 ; + int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ; + int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ; int nType = 0 ; CalcSide( j, i, &CCompoB, &CCompoA, false, nType) ; if ( nType != ICCT_ON) { - m_Info[i].IciB[0].nPrevTy = nType ; + m_Info[i].IciB[ki].nPrevTy = nType ; m_Info[j].IciB[kj].nNextTy = nType ; } else @@ -909,91 +911,91 @@ IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICu nType = ICCT_IN ; else if ( nType == MDS_RIGHT) nType = ICCT_OUT ; - //// se lo trovo sulla curva controllo se posso definire un tratto overlap - //if ( nType == MDS_ON) { - // double dFactor = 1./3. ; - // DBLVECTOR vdU(2) ; - // bool bIsOn = false ; - // if ( bCrvAOrB) { - // if ( bPrevIsBefore) { - // vdU[0] = ( 1 - dFactor) * Icci2.IciA[0].dU + dFactor * Icci1.IciA[kj].dU ; - // vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[0].dU + 2 * dFactor * Icci1.IciA[kj].dU ; - // } - // else if ( Icci2.IciA[0].dU > 2 * EPS_SMALL){ - // vdU[0] = ( Icci2.IciA[0].dU + 0.) * dFactor ; - // vdU[1] = ( Icci2.IciA[0].dU + 0.) * 2 * dFactor ; - // } - // else - // bIsOn = true ; - // } - // else { - // if ( bPrevIsBefore) { - // vdU[0] = ( 1 - dFactor) * Icci2.IciB[0].dU + dFactor * Icci1.IciB[kj].dU ; - // vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[0].dU + 2 * dFactor * Icci1.IciB[kj].dU ; - // } - // else if ( Icci2.IciB[0].dU > 2 * EPS_SMALL) { - // vdU[0] = ( Icci2.IciB[0].dU + 0.) * dFactor ; - // vdU[1] = ( Icci2.IciB[0].dU + 0.) * 2 * dFactor ; - // } - // else - // bIsOn = true ; - // } - // if ( ! bIsOn) { - // bIsOn = true ; - // for ( int k = 0 ; k < ssize(vdU) && bIsOn ; ++k) { - // Point3d ptTest2 ; pThisCrv->GetPointD1D2( vdU[k], ICurve::FROM_MINUS, ptTest2) ; - // DistPointCurve dpc2( ptTest2, *pOtherCrv) ; - // dpc2.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ; - // if ( nType != MDS_ON) - // bIsOn = false ; - // } - // } - // if ( bIsOn) { - // m_Info[i].bOverlap = true ; - // Vector3d vtDirThis, vtDirOther ; - // Point3d ptCommon ; - // double dUThis = 0 ; - // if ( bCrvAOrB) - // dUThis = m_Info[i].IciA[0].dU ; - // else - // dUThis = m_Info[i].IciB[0].dU ; - // pThisCrv->GetPointD1D2( dUThis, ICurve::Side::FROM_MINUS, ptCommon, &vtDirThis) ; - // double dUOther = 0 ; pOtherCrv->GetParamAtPoint( ptCommon, dUOther) ; - // pOtherCrv->GetPointD1D2( dUOther, ICurve::Side::FROM_MINUS, ptCommon, &vtDirOther) ; - // m_Info[i].bCBOverEq = vtDirThis * vtDirOther > 0 ; - // if ( m_Info[i].bCBOverEq) { - // m_Info[i].IciA[1] = m_Info[i].IciA[0] ; - // m_Info[i].IciB[1] = m_Info[i].IciB[0] ; - // m_Info[i].IciA[0] = m_Info[j].IciA[kj] ; - // m_Info[i].IciB[0] = m_Info[j].IciB[kj] ; - // m_Info[i].IciA[1].nPrevTy = ICCT_ON ; - // m_Info[i].IciB[1].nPrevTy = ICCT_ON ; - // m_Info[i].IciA[0].nNextTy = ICCT_ON ; - // m_Info[i].IciB[0].nNextTy = ICCT_ON ; - // } - // else { - // if ( bCrvAOrB) { - // m_Info[i].IciA[1] = m_Info[i].IciA[0] ; - // m_Info[i].IciA[0] = m_Info[j].IciA[kj] ; - // m_Info[i].IciA[1].nPrevTy = ICCT_ON ; - // m_Info[i].IciA[0].nNextTy = ICCT_ON ; - // m_Info[i].IciB[1] = m_Info[j].IciB[kj] ; - // m_Info[i].IciB[0].nPrevTy = ICCT_ON ; - // m_Info[i].IciB[1].nNextTy = ICCT_ON ; - // } - // else { - // m_Info[i].IciB[1] = m_Info[i].IciB[0] ; - // m_Info[i].IciB[0] = m_Info[j].IciB[kj] ; - // m_Info[i].IciB[1].nPrevTy = ICCT_ON ; - // m_Info[i].IciB[0].nNextTy = ICCT_ON ; - // m_Info[i].IciA[1] = m_Info[j].IciA[kj] ; - // m_Info[i].IciA[0].nPrevTy = ICCT_ON ; - // m_Info[i].IciA[1].nNextTy = ICCT_ON ; - // } - // } - // nType = ICCT_ON ; - // } - //} + // se lo trovo sulla curva controllo se posso definire un tratto overlap + if ( nType == MDS_ON) { + double dFactor = 1./3. ; + DBLVECTOR vdU(2) ; + bool bIsOn = false ; + if ( bCrvAOrB) { + if ( bPrevIsBefore) { + vdU[0] = ( 1 - dFactor) * Icci2.IciA[0].dU + dFactor * Icci1.IciA[kj].dU ; + vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[0].dU + 2 * dFactor * Icci1.IciA[kj].dU ; + } + else if ( Icci2.IciA[0].dU > 2 * EPS_SMALL){ + vdU[0] = ( Icci2.IciA[0].dU + 0.) * dFactor ; + vdU[1] = ( Icci2.IciA[0].dU + 0.) * 2 * dFactor ; + } + else + bIsOn = true ; + } + else { + if ( bPrevIsBefore) { + vdU[0] = ( 1 - dFactor) * Icci2.IciB[0].dU + dFactor * Icci1.IciB[kj].dU ; + vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[0].dU + 2 * dFactor * Icci1.IciB[kj].dU ; + } + else if ( Icci2.IciB[0].dU > 2 * EPS_SMALL) { + vdU[0] = ( Icci2.IciB[0].dU + 0.) * dFactor ; + vdU[1] = ( Icci2.IciB[0].dU + 0.) * 2 * dFactor ; + } + else + bIsOn = true ; + } + if ( ! bIsOn) { + bIsOn = true ; + for ( int k = 0 ; k < ssize(vdU) && bIsOn ; ++k) { + Point3d ptTest2 ; pThisCrv->GetPointD1D2( vdU[k], ICurve::FROM_MINUS, ptTest2) ; + DistPointCurve dpc2( ptTest2, *pOtherCrv) ; + dpc2.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ; + if ( nType != MDS_ON) + bIsOn = false ; + } + } + if ( bIsOn) { + m_Info[i].bOverlap = true ; + Vector3d vtDirThis, vtDirOther ; + Point3d ptCommon ; + double dUThis = 0 ; + if ( bCrvAOrB) + dUThis = m_Info[i].IciA[0].dU ; + else + dUThis = m_Info[i].IciB[0].dU ; + pThisCrv->GetPointD1D2( dUThis, ICurve::Side::FROM_MINUS, ptCommon, &vtDirThis) ; + double dUOther = 0 ; pOtherCrv->GetParamAtPoint( ptCommon, dUOther) ; + pOtherCrv->GetPointD1D2( dUOther, ICurve::Side::FROM_MINUS, ptCommon, &vtDirOther) ; + m_Info[i].bCBOverEq = vtDirThis * vtDirOther > 0 ; + if ( m_Info[i].bCBOverEq) { + m_Info[i].IciA[1] = m_Info[i].IciA[0] ; + m_Info[i].IciB[1] = m_Info[i].IciB[0] ; + m_Info[i].IciA[0] = m_Info[j].IciA[kj] ; + m_Info[i].IciB[0] = m_Info[j].IciB[kj] ; + m_Info[i].IciA[1].nPrevTy = ICCT_ON ; + m_Info[i].IciB[1].nPrevTy = ICCT_ON ; + m_Info[i].IciA[0].nNextTy = ICCT_ON ; + m_Info[i].IciB[0].nNextTy = ICCT_ON ; + } + else { + if ( bCrvAOrB) { + m_Info[i].IciA[1] = m_Info[i].IciA[0] ; + m_Info[i].IciA[0] = m_Info[j].IciA[kj] ; + m_Info[i].IciA[1].nPrevTy = ICCT_ON ; + m_Info[i].IciA[0].nNextTy = ICCT_ON ; + m_Info[i].IciB[1] = m_Info[j].IciB[kj] ; + m_Info[i].IciB[0].nPrevTy = ICCT_ON ; + m_Info[i].IciB[1].nNextTy = ICCT_ON ; + } + else { + m_Info[i].IciB[1] = m_Info[i].IciB[0] ; + m_Info[i].IciB[0] = m_Info[j].IciB[kj] ; + m_Info[i].IciB[1].nPrevTy = ICCT_ON ; + m_Info[i].IciB[0].nNextTy = ICCT_ON ; + m_Info[i].IciA[1] = m_Info[j].IciA[kj] ; + m_Info[i].IciA[0].nPrevTy = ICCT_ON ; + m_Info[i].IciA[1].nNextTy = ICCT_ON ; + } + } + nType = ICCT_ON ; + } + } return true ; } @@ -1245,11 +1247,21 @@ CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2, //---------------------------------------------------------------------------- static bool CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2, - bool bCrvBClosed, double dCrvBSpan) + bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB) { - int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap - if ( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) > 0.1 * SPAN_PARAM && - ( ! bCrvBClosed || abs( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM)) + int j = 0 ; + int k = 0 ; + if ( ! bOrderedOnB) { + j = 0 ; + k = Icci1.bOverlap ? 1 : 0 ; + } + else { + j = Icci2.bOverlap && ! Icci2.bCBOverEq ? 1 : 0 ; + k = Icci1.bOverlap && Icci1.bCBOverEq ? 1 : 0 ; + } + + if ( abs( Icci1.IciB[k].dU - Icci2.IciB[j].dU) > 0.1 * SPAN_PARAM && + ( ! bCrvBClosed || abs( abs( Icci1.IciB[k].dU - Icci2.IciB[j].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM)) return false ; return true ; } diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index b841594..80f3859 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -28,6 +28,11 @@ #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#define SAVECLASSCRV 0 +#if SAVECLASSCRV +#include "/EgtDev/Include/EGkGeoObjSave.h" +#endif + using namespace std ; //---------------------------------------------------------------------------- @@ -1374,6 +1379,15 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRV for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) { const ICurve* pLoop = GetMyLoop( nChunk, nLoop) ; // intersezione + +#if SAVECLASSCRV + //debug + vector vGeo ; + vGeo.push_back( Crv.Clone()) ; + vGeo.push_back( pLoop->Clone()) ; + SaveGeoObj( vGeo, "D:\\Temp\\inters\\CrvCrvInters\\crv_and_loop.nge") ; +#endif + IntersCurveCurve ccInt( Crv, *pLoop) ; // classificazione CRVCVECTOR ccPart ; diff --git a/Voronoi.cpp b/Voronoi.cpp index bc92e76..39a4966 100644 --- a/Voronoi.cpp +++ b/Voronoi.cpp @@ -1155,7 +1155,7 @@ Voronoi::AdjustOffsetStart( ICurveComposite* pCrv) const //--------------------------------------------------------------------------- bool -Voronoi::Translate( const Vector3d & vtMove) +Voronoi::Translate( const Vector3d& vtMove) { if ( ! IsValid()) return false ;