diff --git a/SurfFlatRegionOffset.cpp b/SurfFlatRegionOffset.cpp index 4d549a3..2bc7780 100644 --- a/SurfFlatRegionOffset.cpp +++ b/SurfFlatRegionOffset.cpp @@ -16,6 +16,7 @@ #include "GeoConst.h" #include "CurveComposite.h" #include "SurfFlatRegion.h" +#include "AdjustLoops.h" #include "Voronoi.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" @@ -146,51 +147,23 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const if ( ! m_pVoronoiObj->CalcOffset( vOffs, dDist, nType)) return nullptr ; + // costruisco la superficie if ( vOffs.size() > 0) { - BOOLVECTOR vbAddOrSub( vOffs.size(), true) ; - int nFirstId = -1 ; - for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) { - // porto nel frame della flat region + PCRV_DEQUE vLoops ; + for ( int i = 0 ; i < int( vOffs.size()) ; i ++) { vOffs[i]->ToLoc( m_frF) ; - // calcolo orientamento della curva - double dAreaXY ; - if ( ! vOffs[i]->GetAreaXY( dAreaXY)) - return nullptr ; - vbAddOrSub[i] = ( dAreaXY > SQ_EPS_SMALL) ; - // verifico se è il primo loop esterno - if ( nFirstId == -1 && vbAddOrSub[i]) - nFirstId = i ; - } - - // inizializzo la superficie - if ( nFirstId != -1 && ! pSfr->AddExtLoop( Release( vOffs[nFirstId]))) - return nullptr ; - if ( pSfr->IsValid()) { - - for ( int i = 0 ; i < ( int)vOffs.size() ; i ++) { - // verifico non sia il primo loop esterno - if ( i == nFirstId) - continue ; - // costruisco la superficie associata - PtrOwner pSrfCrv( CreateBasicSurfFlatRegion()) ; - if ( IsNull( pSrfCrv) || ! pSrfCrv->AddExtLoop( Release( vOffs[i]))) - return nullptr ; - if ( ! pSrfCrv->IsValid()) - continue ; - - // aggiungo o sottraggo - if ( vbAddOrSub[i]) { - if ( ! pSfr->Add( *pSrfCrv)) - return nullptr ; - } - else { - pSrfCrv->Invert() ; - if ( ! pSfr->Subtract( *pSrfCrv)) - return nullptr ; - } - } - + // rimuovo eventuali sovrapposizioni + ICURVEPLIST CrvLst ; + AdjustLoops( Release( vOffs[i]), CrvLst, true) ; + for ( auto pCrv : CrvLst) + vLoops.emplace_back( pCrv) ; } + + pSfr.Set( MyNewSurfFromLoops( vLoops)) ; + if ( IsNull( pSfr)) { + MyTestAndDelete( vLoops) ; + return nullptr ; + } } } diff --git a/Voronoi.cpp b/Voronoi.cpp index 60d02bc..400b6d3 100644 --- a/Voronoi.cpp +++ b/Voronoi.cpp @@ -818,12 +818,29 @@ Voronoi::VerifyCurvesValidityForOffset() // se curva con orientamento principale verifico sia esterna a tutte le altre curve con orientamento principale if ( vArea[i] * dRefArea > EPS_SMALL) { - for ( int j = i + 1 ; j < ( int)vArea.size() ; j++) { - if ( vArea[i] * vArea[j] > EPS_SMALL) { + for ( int j = 0 ; j < ( int)vArea.size() ; j++) { + if ( j != i && vArea[i] * vArea[j] > EPS_SMALL) { IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[j]) ; int nRes = ccInt.GetRegionCurveClassification() ; - if ( ( bRefCCW && nRes != CCREGC_OUT) || ( ! bRefCCW && nRes != CCREGC_IN1)) + if ( nRes == CCREGC_NULL || nRes == CCREGC_SAME || nRes == CCREGC_INTERS) return false ; + if ( ( bRefCCW && nRes == CCREGC_IN1) || ( ! bRefCCW && nRes == CCREGC_IN2)) { + // se è interna ad una curva con orientamento principale, verifico sia esterna ad almeno una curva con orientamento + // diverso dal principale + bool bFound = false ; + for ( int k = 0 ; k < ( int)vArea.size() ; k++) { + if ( k != i && vArea[i] * vArea[k] < EPS_SMALL) { + IntersCurveCurve ccInt( *m_vpCrvs[i], *m_vpCrvs[k]) ; + int nRes = ccInt.GetRegionCurveClassification() ; + if ( ( bRefCCW && nRes == CCREGC_OUT) || ( ! bRefCCW && nRes == CCREGC_IN1)) { + bFound = true ; + break ; + } + } + } + if ( ! bFound) + return false ; + } } } }