From d96e356607bb602390268527da17bb4e9a1c67a6 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 14 Apr 2020 15:19:06 +0000 Subject: [PATCH] EgtGeomKernel : - modifiche per Regioni. --- AdjustLoops.cpp | 224 +++++++++++++++++++++++++ RemoveCurveOverlaps.h => AdjustLoops.h | 10 +- EgtGeomKernel.vcxproj | 4 +- EgtGeomKernel.vcxproj.filters | 16 +- GeoObjFactory.h | 2 +- IntersCrvCompoCrvCompo.cpp | 56 +++++-- RemoveCurveOverlaps.cpp | 161 ------------------ SelfIntersCurve.cpp | 24 +++ SurfFlatRegion.cpp | 75 +++++---- SurfFlatRegion.h | 2 +- SurfFlatRegionBooleans.cpp | 2 +- 11 files changed, 355 insertions(+), 221 deletions(-) create mode 100644 AdjustLoops.cpp rename RemoveCurveOverlaps.h => AdjustLoops.h (59%) delete mode 100644 RemoveCurveOverlaps.cpp diff --git a/AdjustLoops.cpp b/AdjustLoops.cpp new file mode 100644 index 0000000..92d0415 --- /dev/null +++ b/AdjustLoops.cpp @@ -0,0 +1,224 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2020 +//---------------------------------------------------------------------------- +// File : AdjustLoops.cpp Data : 14.04.20 Versione : 2.2d2 +// Contenuto : Implementazione funzione di sistemazione curve chiuse per +// poter formare loop validi. +// +// +// Modifiche : 02.11.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "GeoConst.h" +#include "CurveComposite.h" +#include "RemoveCurveSpikes.h" +#include "AdjustLoops.h" +#include "/EgtDev/Include/EGkIntersCurves.h" +#include "/EgtDev/Include/EGkIntervals.h" +#include "/EgtDev/Include/EgtPointerOwner.h" +#include + +using namespace std ; + +//---------------------------------------------------------------------------- +static bool +MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) +{ + // Pulisco lista di ritorno + CrvLst.clear() ; + + // Acquisisco la curva + PtrOwner pMyCrv( pCurve) ; + + // Verifico validità curva + if ( IsNull( pMyCrv) || ! pMyCrv->IsValid() || ! pMyCrv->IsClosed()) + return false ; + + // --- la verifica ed eventuale rimozione va effettuata in un piano perpendicolare al vettore estrusione --- + + // verifico il vettore estrusione + Vector3d vtExtr ; + pMyCrv->GetExtrusion( vtExtr) ; + bool bNeedRef = ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) ; + + // se necessario cambio il riferimento + Frame3d frExtr ; + if ( bNeedRef) { + // calcolo il riferimento OCS con VtExtr come asse Z + if ( ! frExtr.Set( ORIG, vtExtr)) + return false ; + // esprimo la curva in questo riferimento + pMyCrv->ToLoc( frExtr) ; + } + + // Calcolo le auto intersezioni + SelfIntersCurve sintC( *pMyCrv) ; + // se ci sono auto-intersezioni che si attraversano (anche con sovrapposizione), errore + if ( sintC.GetCrossIntersCount() > 0) + return false ; + // se non ci sono auto-intersezioni che si toccano (anche con sovrapposizione), non devo fare alcunché + if ( sintC.GetTouchIntersCount() == 0) { + // riporto la curva nel riferimento originale + if ( bNeedRef) + pMyCrv->ToGlob( frExtr) ; + // la inserisco in lista + CrvLst.push_back( Release( pMyCrv)) ; + return true ; + } + + // Determino intervallo complessivo della curva + double dStart, dEnd ; + if ( ! pMyCrv->GetDomain( dStart, dEnd)) + return false ; + Intervals inOk( EPS_PARAM) ; + inOk.Set( dStart, dEnd) ; + + // Tolgo le parti in sovrapposizione da eliminare + IntCrvCrvInfo iccInfo ; + for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) { + // se sovrapposti + if ( iccInfo.bOverlap) { + // se equiversi, elimino solo uno dei due tratti + if ( iccInfo.bCBOverEq) { + inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; + } + // se altrimenti controversi, elimino entrambi i tratti + else if ( ! iccInfo.bCBOverEq) { + inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ; + inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; + } + } + // altrimenti sono touch + else { + inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ; + inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].dU) ; + } + } + + // Copio le parti da conservare + double dParS, dParE ; + bool bFound = inOk.GetFirst( dParS, dParE) ; + while ( bFound) { + ICurve* pCrv = pMyCrv->CopyParamRange( dParS, dParE) ; + if ( pCrv != nullptr) { + if ( pCrv->GetType() == CRV_COMPO) + CrvLst.push_back( pCrv) ; + else { + CurveComposite* pCrvCo = new( std::nothrow) CurveComposite ; + if ( pCrvCo != nullptr) { + pCrvCo->AddCurve( pCrv) ; + CrvLst.push_back( pCrvCo) ; + } + } + } + bFound = inOk.GetNext( dParS, dParE) ; + } + + // Concateno i percorsi risultanti (senza cambiare verso e ignorando le curve già chiuse) : + // primo ciclo con loop di due sole curve + for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) { + CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ; + // recupero punti iniziale e finale della curva + Point3d ptStart ; pCrvCo->GetStartPoint( ptStart) ; + Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ; + // se aperta, cerco di concatenarla + if ( ! AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) { + // ciclo sulle curve successive per verificare se possibile concatenamento + for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) { + CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ; + // recupero punti iniziale e finale della curva + Point3d ptStart2 ; pCrvCo2->GetStartPoint( ptStart2) ; + Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ; + // se aperta, verifico se concatenabile alla principale + if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) { + if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL) && + AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) { + pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ; + CrvLst.erase( iIter2) ; + ptEnd = ptEnd2 ; + iIter2 = next( iIter) ; + } + else + ++ iIter2 ; + } + else + ++ iIter2 ; + } + } + ++ iIter ; + } + // secondo ciclo con loop generici + for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) { + CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ; + // recupero punti iniziale e finale della curva + Point3d ptStart ; pCrvCo->GetStartPoint( ptStart) ; + Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ; + // se aperta, cerco di concatenarla + if ( ! AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) { + // ciclo sulle curve successive per verificare se possibile concatenamento + for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) { + CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ; + // recupero punti iniziale e finale della curva + Point3d ptStart2 ; pCrvCo2->GetStartPoint( ptStart2) ; + Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ; + // se aperta, verifico se concatenabile alla principale + if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) { + if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) { + pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ; + CrvLst.erase( iIter2) ; + ptEnd = ptEnd2 ; + iIter2 = next( iIter) ; + } + else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) { + pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ; + CrvLst.erase( iIter2) ; + ptStart = ptStart2 ; + iIter2 = next( iIter) ; + } + else + ++ iIter2 ; + } + else + ++ iIter2 ; + } + } + ++ iIter ; + } + + // riporto le curve nel riferimento originale + if ( bNeedRef) { + for ( auto pCrv : CrvLst) + pCrv->ToGlob( frExtr) ; + } + // assegno il versore estrusione originale + for ( auto pCrv : CrvLst) + pCrv->SetExtrusion( vtExtr) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) +{ + // elimino eventuali sovrapposizioni e accostamenti + if ( ! MyAdjustLoops( pCurve, CrvLst)) + return false ; + // unisco eventuali tratti allineati ed elimino eventuali spikes + for ( auto pCrv : CrvLst) { + // se curva composita + CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ; + if ( pCrvCo != nullptr) { + // unisco eventuali tratti allineati + pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ; + // elimino eventuali spikes + RemoveCurveSpikes( pCrvCo) ; + } + } + + return true ; +} diff --git a/RemoveCurveOverlaps.h b/AdjustLoops.h similarity index 59% rename from RemoveCurveOverlaps.h rename to AdjustLoops.h index fa085de..78f30c5 100644 --- a/RemoveCurveOverlaps.h +++ b/AdjustLoops.h @@ -1,9 +1,9 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2020 //---------------------------------------------------------------------------- -// File : RemoveCurveOverlaps.h Data : 02.11.15 Versione : 1.6k1 -// Contenuto : Dichiarazione funzione rimozione sovrapposizioni curve. -// +// File : AdjustLoops.h Data : 14.04.20 Versione : 2.2d2 +// Contenuto : Dichiarazione funzione di sistemazione curve chiuse per +// poter formare loop validi. // // // Modifiche : 02.11.15 DS Creazione modulo. @@ -17,4 +17,4 @@ //---------------------------------------------------------------------------- -bool RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) ; +bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) ; diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 223d544..d65dbd4 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -352,7 +352,7 @@ copy $(TargetPath) \EgtProg\Dll64 - + @@ -568,7 +568,7 @@ copy $(TargetPath) \EgtProg\Dll64 - + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 33a2bf8..95946db 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -324,9 +324,6 @@ File di origine\Geo - - File di origine\GeoInters - File di origine\GeoOffset @@ -414,8 +411,8 @@ File di origine\Geo - - File di intestazione + + File di origine\GeoInters @@ -797,9 +794,6 @@ File di intestazione - - File di intestazione - File di intestazione\Include @@ -998,6 +992,12 @@ File di intestazione\Include + + File di intestazione + + + File di intestazione + diff --git a/GeoObjFactory.h b/GeoObjFactory.h index 1c46f07..841bb62 100644 --- a/GeoObjFactory.h +++ b/GeoObjFactory.h @@ -41,7 +41,7 @@ class GeoObjRegister GetNgeIdPrivate() = nNgeId ; return true ; } static IGeoObj* Create( void) - { return new(nothrow) T ; } + { return new( std::nothrow) T ; } static int GetType( void) { return GetTypePrivate() ; } static const std::string& GetKey( void) diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp index 4ad7cfb..5d00aaf 100644 --- a/IntersCrvCompoCrvCompo.cpp +++ b/IntersCrvCompoCrvCompo.cpp @@ -473,7 +473,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, if ( i == 0 && ! bCrvAClosed) continue ; int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; - m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ; + m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ; } // se il tipo di allontanamento per la curva A non è definito if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) { @@ -492,14 +492,14 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, if ( i == 0 && ! bCrvBClosed) continue ; 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[0].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 if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) { if ( i == m_nNumInters - 1 && ! bCrvBClosed) continue ; int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; - m_Info[i].IciB[0].nNextTy = m_Info[j].IciB[0].nPrevTy ; + m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ; } } // ripristino ordinamento su prima curva @@ -550,11 +550,12 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, else { // se il tipo di accostamento è non definito per la curva A if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) { - // devo studiare un intorno dell'intersezione - int nType ; - if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS, - CCompoB, m_Info[i].IciB[0].dU, nType)) { - // aggiorno il tipo di accostamento della curva A alla curva B + // se autointersezione con spike + double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ; + if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) { + // è punta di spike + int nType = ICCT_SPK ; + // aggiorno il tipo di allontanamento della curva A dalla curva B m_Info[i].IciA[0].nPrevTy = nType ; // aggiorno anche il corrispondente tipo sulla curva B if ( m_Info[i].bCBOverEq) @@ -562,13 +563,29 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, else m_Info[i].IciB[0].nNextTy = nType ; } + // caso standard + else { + // devo studiare un intorno dell'intersezione + int nType ; + if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS, + CCompoB, m_Info[i].IciB[0].dU, nType)) { + // aggiorno il tipo di accostamento della curva A alla curva B + m_Info[i].IciA[0].nPrevTy = nType ; + // aggiorno anche il corrispondente tipo sulla curva B + if ( m_Info[i].bCBOverEq) + m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ; + else + m_Info[i].IciB[0].nNextTy = nType ; + } + } } // se il tipo di allontanamento è non definito per la curva A if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) { - // devo studiare un intorno dell'intersezione - int nType ; - if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS, - CCompoB, m_Info[i].IciB[1].dU, nType)) { + // se autointersezione con spike + double dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ; + if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) { + // è punta di spike + int nType = ICCT_SPK ; // aggiorno il tipo di allontanamento della curva A dalla curva B m_Info[i].IciA[1].nNextTy = nType ; // aggiorno anche il corrispondente tipo sulla curva B @@ -577,6 +594,21 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, else m_Info[i].IciB[1].nPrevTy = nType ; } + // caso standard + else { + // devo studiare un intorno dell'intersezione + int nType ; + if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS, + CCompoB, m_Info[i].IciB[1].dU, nType)) { + // aggiorno il tipo di allontanamento della curva A dalla curva B + m_Info[i].IciA[1].nNextTy = nType ; + // aggiorno anche il corrispondente tipo sulla curva B + if ( m_Info[i].bCBOverEq) + m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ; + else + m_Info[i].IciB[1].nPrevTy = nType ; + } + } } } } diff --git a/RemoveCurveOverlaps.cpp b/RemoveCurveOverlaps.cpp deleted file mode 100644 index ef8c957..0000000 --- a/RemoveCurveOverlaps.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2015 -//---------------------------------------------------------------------------- -// File : RemoveCurveOverlaps.cpp Data : 02.11.15 Versione : 1.6K1 -// Contenuto : Implementazione rimozione sovrapposizioni di curva. -// -// -// -// Modifiche : 02.11.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -//--------------------------- Include ---------------------------------------- -#include "stdafx.h" -#include "GeoConst.h" -#include "CurveComposite.h" -#include "RemoveCurveOverlaps.h" -#include "/EgtDev/Include/EGkIntersCurves.h" -#include "/EgtDev/Include/EGkIntervals.h" -#include "/EgtDev/Include/EgtPointerOwner.h" -#include - -using namespace std ; - -//---------------------------------------------------------------------------- -bool -RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) -{ - // Pulisco lista di ritorno - CrvLst.clear() ; - - // Acquisisco la curva - PtrOwner pMyCrv( pCurve) ; - - // Verifico validità curva - if ( IsNull( pMyCrv) || ! pMyCrv->IsValid()) - return false ; - - // Se nulla da rimuovere, non devo fare alcunché - if ( ! bRemoveSam && ! bRemoveCtr) { - CrvLst.push_back( Release( pMyCrv)) ; - return true ; - } - - // --- la verifica ed eventuale rimozione va effettuata in un piano perpendicolare al vettore estrusione --- - - // verifico il vettore estrusione - Vector3d vtExtr ; - pMyCrv->GetExtrusion( vtExtr) ; - bool bNeedRef = ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) ; - - // se necessario cambio il riferimento - Frame3d frExtr ; - if ( bNeedRef) { - // calcolo il riferimento OCS con VtExtr come asse Z - if ( ! frExtr.Set( ORIG, vtExtr)) - return false ; - // esprimo la curva in questo riferimento - pMyCrv->ToLoc( frExtr) ; - } - - // Calcolo le auto intersezioni - SelfIntersCurve sintC( *pMyCrv) ; - // se non ci sono sovrapposizioni, non devo fare alcunché - if ( ! sintC.GetOverlaps()) { - // riporto la curva nel riferimento originale - if ( bNeedRef) - pMyCrv->ToGlob( frExtr) ; - // la inserisco in lista - CrvLst.push_back( Release( pMyCrv)) ; - return true ; - } - - // Determino intervallo complessivo della curva - double dStart, dEnd ; - if ( ! pMyCrv->GetDomain( dStart, dEnd)) - return false ; - Intervals inOk( EPS_PARAM) ; - inOk.Set( dStart, dEnd) ; - - // Tolgo le parti in sovrapposizione da eliminare - IntCrvCrvInfo iccInfo ; - for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) { - // se sovrapposti - if ( iccInfo.bOverlap) { - // se equiversi e da eliminare, elimino solo uno dei due tratti - if ( iccInfo.bCBOverEq && bRemoveSam) { - inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; - } - // se altrimenti controversi e da eliminare, elimino entrambi i tratti - else if ( ! iccInfo.bCBOverEq && bRemoveCtr) { - inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ; - inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; - } - } - } - - // Copio le parti da conservare - double dParS, dParE ; - bool bFound = inOk.GetFirst( dParS, dParE) ; - while ( bFound) { - ICurve* pCrv = pMyCrv->CopyParamRange( dParS, dParE) ; - if ( pCrv != nullptr) { - if ( pCrv->GetType() == CRV_COMPO) - CrvLst.push_back( pCrv) ; - else { - CurveComposite* pCrvCo = new( std::nothrow) CurveComposite ; - if ( pCrvCo != nullptr) { - pCrvCo->AddCurve( pCrv) ; - CrvLst.push_back( pCrvCo) ; - } - } - } - bFound = inOk.GetNext( dParS, dParE) ; - } - - // Concateno i percorsi risultanti (senza cambiare verso) - for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) { - CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ; - // recupero punti iniziale e finale della curva - Point3d ptStart, ptEnd ; - pCrvCo->GetStartPoint( ptStart) ; - pCrvCo->GetEndPoint( ptEnd) ; - // ciclo sulle curve successive per verificare se possibile concatenamento - for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) { - CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ; - // recupero punti iniziale e finale della curva - Point3d ptStart2, ptEnd2 ; - pCrvCo2->GetStartPoint( ptStart2) ; - pCrvCo2->GetEndPoint( ptEnd2) ; - // verifiche di concatenamento - if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) { - pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ; - CrvLst.erase( iIter2) ; - ptEnd = ptEnd2 ; - iIter2 = next( iIter) ; - } - else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) { - pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ; - CrvLst.erase( iIter2) ; - ptStart = ptStart2 ; - iIter2 = next( iIter) ; - } - else - ++ iIter2 ; - } - ++ iIter ; - } - - // riporto le curve nel riferimento originale - if ( bNeedRef) { - for ( auto pCrv : CrvLst) - pCrv->ToGlob( frExtr) ; - } - // assegno il versore estrusione originale - for ( auto pCrv : CrvLst) - pCrv->SetExtrusion( vtExtr) ; - - return true ; -} \ No newline at end of file diff --git a/SelfIntersCurve.cpp b/SelfIntersCurve.cpp index 9b9f0d7..399cc39 100644 --- a/SelfIntersCurve.cpp +++ b/SelfIntersCurve.cpp @@ -177,6 +177,7 @@ SelfIntersCurve::GetCrossIntersCount( void) // se con sovrapposizione if ( m_Info[i].bOverlap) { if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[1].nNextTy && + m_Info[i].IciA[0].nPrevTy != ICCT_SPK && m_Info[i].IciA[1].nNextTy != ICCT_SPK && m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[1].nNextTy != ICCT_NULL) ++ nCrossIntersCount ; } @@ -207,6 +208,29 @@ SelfIntersCurve::GetCrossOrOverlapIntersCount( void) return nCrossOverIntersCount ; } +//---------------------------------------------------------------------------- +int +SelfIntersCurve::GetTouchIntersCount( void) +{ + int nTouchIntersCount = 0 ; + for ( int i = 0 ; i < m_nIntersCount ; ++ i) { + // se con sovrapposizione + if ( m_Info[i].bOverlap) { + if ( ( m_Info[i].IciA[0].nPrevTy == m_Info[i].IciA[1].nNextTy || + m_Info[i].IciA[0].nPrevTy == ICCT_SPK || m_Info[i].IciA[1].nNextTy == ICCT_SPK) && + m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[1].nNextTy != ICCT_NULL) + ++ nTouchIntersCount ; + } + // altrimenti + else { + if ( m_Info[i].IciA[0].nPrevTy == m_Info[i].IciA[0].nNextTy && + m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[0].nNextTy != ICCT_NULL) + ++ nTouchIntersCount ; + } + } + return nTouchIntersCount ; +} + //---------------------------------------------------------------------------- bool SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo) diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index ab96739..44b2eae 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -19,8 +19,7 @@ #include "NgeReader.h" #include "CurveAux.h" #include "CurveComposite.h" -#include "RemoveCurveOverlaps.h" -#include "RemoveCurveSpikes.h" +#include "AdjustLoops.h" #include "GeoConst.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUiUnits.h" @@ -100,20 +99,11 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv) pMyCrv->SetThickness( 0) ; // rimuovo eventuali sovrapposizioni (calcolate nel suo piano) ICURVEPLIST CrvLst ; - if ( ! RemoveCurveOverlaps( Release( pMyCrv), true, true, CrvLst)) + if ( ! AdjustLoops( Release( pMyCrv), CrvLst)) return false ; // aggiungo le singole curve bool bOk = true ; for ( auto& pSingCrv : CrvLst) { - // se curva composita - CurveComposite* pCrvCo = GetBasicCurveComposite( pSingCrv) ; - if ( pCrvCo != nullptr) { - // unisco eventuali tratti allineati - pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ; - // elimino eventuali spikes - RemoveCurveSpikes( pCrvCo) ; - } - // aggiungo il loop if ( ! AddSimpleExtLoop( pSingCrv)) bOk = false ; } @@ -253,20 +243,11 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv) pMyCrv->SetThickness( 0) ; // rimuovo eventuali sovrapposizioni (calcolate nel suo piano) ICURVEPLIST CrvLst ; - if ( ! RemoveCurveOverlaps( Release( pMyCrv), true, true, CrvLst)) + if ( ! AdjustLoops( Release( pMyCrv), CrvLst)) return false ; // aggiungo le singole curve bool bOk = true ; for ( auto& pSingCrv : CrvLst) { - // se curva composita - CurveComposite* pCrvCo = GetBasicCurveComposite( pSingCrv) ; - if ( pCrvCo != nullptr) { - // unisco eventuali tratti allineati - pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ; - // elimino eventuali spikes - RemoveCurveSpikes( pCrvCo) ; - } - // aggiungo il loop if ( ! AddSimpleIntLoop( pSingCrv)) bOk = false ; } @@ -307,17 +288,39 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv) SelfIntersCurve sInt( *pMyCrv) ; if ( sInt.GetCrossOrOverlapIntersCount() > 0) return false ; - // verifico non abbia intersezioni e non sia esterna ai loop già definiti del medesimo chunk - CRVCVECTOR ccClass ; - for ( int i = m_vExtInd.back() ; i < int( m_vpLoop.size()) ; ++ i) { - IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ; + // ricerca del chunk in cui andrebbe inserito + int nChunk = -1 ; + for ( int i = 0 ; i < int( m_vExtInd.size()) ; ++ i) { + // verifica rispetto al loop esterno + IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ; + CRVCVECTOR ccClass ; if ( ccInt.GetCrossOrOverlapIntersCount() > 0 || ! ccInt.GetCurveClassification( 0, ccClass) || ccClass.empty() || ccClass[0].nClass != CRVC_IN) - return false ; + continue ; + // verifica rispetto ai loop interni + bool bOk = true ; + int nLoopCnt = GetLoopCount( i) ; + for ( int j = 0 ; j < nLoopCnt ; ++ j) { + int k = m_vExtInd[i] + j ; + IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[k]) ; + CRVCVECTOR ccClass ; + if ( ccInt.GetCrossOrOverlapIntersCount() > 0 || + ! ccInt.GetCurveClassification( 0, ccClass) || + ccClass.empty() || ccClass[0].nClass != CRVC_IN) { + bOk = false ; + break ; + } + } + if ( bOk) { + nChunk = i ; + break ; + } } + if ( nChunk == -1) + return false ; // aggiungo la curva all'elenco dei loop - if ( MyAddIntLoop( pMyCrv)) + if ( MyAddIntLoop( pMyCrv, nChunk)) Release( pMyCrv) ; // imposto ricalcolo della grafica ResetAuxSurf() ; @@ -327,10 +330,22 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv) //---------------------------------------------------------------------------- bool -SurfFlatRegion::MyAddIntLoop( ICurve* pCrv) +SurfFlatRegion::MyAddIntLoop( ICurve* pCrv, int nChunk) { try { - m_vpLoop.push_back( pCrv) ; + // se da aggiungere all'ultimo chunk + if ( nChunk == -1) + m_vpLoop.push_back( pCrv) ; + // altrimenti aggiungo al chunck indicato + else { + int nLoopCnt = GetLoopCount( nChunk) ; + if ( nLoopCnt == 0) + return false ; + int nOffset = m_vExtInd[nChunk] + nLoopCnt ; + m_vpLoop.insert( m_vpLoop.begin() + nOffset, pCrv) ; + for ( int i = nChunk + 1 ; i < int( m_vExtInd.size()) ; ++ i) + ++ m_vExtInd[i] ; + } } catch (...) { return false ; diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index ab9f1d1..0f11868 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -122,7 +122,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW bool AddSimpleExtLoop( ICurve* pCrv) ; bool MyAddExtLoop( ICurve* pCrv) ; bool AddSimpleIntLoop( ICurve* pCrv) ; - bool MyAddIntLoop( ICurve* pCrv) ; + bool MyAddIntLoop( ICurve* pCrv, int nChunk) ; int GetIndFromChunkLoop( int nChunk, int nLoop) const ; bool GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const ; ICurve* GetMyLoop( int nInd) const ; // indice nel vettore di tutti i loop diff --git a/SurfFlatRegionBooleans.cpp b/SurfFlatRegionBooleans.cpp index c658c10..c01d6bf 100644 --- a/SurfFlatRegionBooleans.cpp +++ b/SurfFlatRegionBooleans.cpp @@ -443,7 +443,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop) ccClass.empty() || ccClass[0].nClass != CRVC_IN) continue ; // lo inserisco - if ( pSfr->MyAddIntLoop( vpLoop[l])) { + if ( pSfr->MyAddIntLoop( vpLoop[l], -1)) { vpLoop[l] = nullptr ; vArea[k].first = - 1 ; }