From 6f2de64ae67092cbbcdef2d18320b8ad17218d99 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Sun, 20 Sep 2015 09:13:05 +0000 Subject: [PATCH] EgtExecutor : - CreateFlatPartsByRegion e CreateFlatPartsByLayer migliorate e modificate per uso regioni. --- EXE_Nesting.cpp | 158 ++++++++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 86 deletions(-) diff --git a/EXE_Nesting.cpp b/EXE_Nesting.cpp index 6e614ab..ef6596e 100644 --- a/EXE_Nesting.cpp +++ b/EXE_Nesting.cpp @@ -19,7 +19,7 @@ #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkIntersCurves.h" -#include "/EgtDev/Include/EGkStmFromCurves.h" +#include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -147,7 +147,7 @@ CreateFlatPartsByRegions( int nLay) PtrOwner pEnt( CreateGdbIterator( pGeomDB)) ; if ( IsNull( pEnt)) return false ; - // separo le curve aperte da quelle chiuse e salvo vettore aree di quest ultime + // separo le curve aperte da quelle chiuse e salvo vettore aree di queste ultime INTVECTOR vOpenIds ; INTVECTOR vClosedIds ; typedef std::pair INDAREA ; // coppia indice, area @@ -331,7 +331,6 @@ VerifyAndAdjustFlatParts( void) int nRegId = ExeCreateGroup( pPar->GetId(), Frame3d(), RTY_GLOB) ; bOk = bOk && nRegId != GDB_ID_NULL ; bOk = bOk && pGeomDB->SetName( nRegId, "Region") ; - bOk = bOk && pGeomDB->SetLevel( nRegId, GDB_LV_SYSTEM) ; // concateno tutte le curve INTVECTOR vIds ; vIds.push_back( GDB_ID_SEL) ; @@ -340,9 +339,10 @@ VerifyAndAdjustFlatParts( void) bOk = bOk && nFirstId != GDB_ID_NULL ; // deseleziono tutto pGeomDB->ClearSelection() ; - // elimino le curve non chiuse e salvo i puntatori alle altre + // elimino le curve aperte del nuovo layer e uso le chiuse per creare la regione INTVECTOR vOpenIds ; - ICURVEPVECTOR vCrvP ; + STRVECTOR vClosedIds ; + SurfFlatRegionByContours SfrCntr( false, false) ; bool bEok = pEnt->GoToFirstInGroup( nRegId) ; while ( bEok) { ICurve* pCrv = GetCurve( pEnt->GetGeoObj()) ; @@ -350,103 +350,89 @@ VerifyAndAdjustFlatParts( void) bEok = pEnt->EraseAndGoToNext() ; } else if ( ! pCrv->IsClosed()) { - string sOrig ; + // salvo Id di origine nell'elenco curve aperte da controllare INTVECTOR vTmpIds ; - if ( pGeomDB->GetInfo( pEnt->GetId(), "ORIG", vTmpIds)) { - for ( auto Id : vTmpIds) - vOpenIds.push_back( Id) ; - } + if ( pGeomDB->GetInfo( pEnt->GetId(), "ORIG", vTmpIds)) + vOpenIds.insert( vOpenIds.end(), vTmpIds.begin(), vTmpIds.end()) ; bEok = pEnt->EraseAndGoToNext() ; } else { - vCrvP.push_back( pCrv) ; + // salvo Id entità corrente e preparo passaggio a prossima + int nEntId = pEnt->GetId() ; bEok = pEnt->GoToNext() ; + // salvo stringa con elenco Id di origine + string sInfo ; + if ( pGeomDB->GetInfo( nEntId, "ORIG", sInfo)) { + vClosedIds.emplace_back( sInfo) ; + pCrv->SetTempProp( int( vClosedIds.size())) ; + } + // estraggo curva da entità che viene cancellata + SfrCntr.AddCurve( pCrv) ; + pGeomDB->RemoveGeoObjAndErase( nEntId) ; } } - // ne calcolo le aree, le ordino in senso decrescente - typedef std::pair INDAREA ; // coppia indice, area - typedef std::vector INDAREAVECTOR ; // vettore di coppie indice, area - INDAREAVECTOR vArea ; - vArea.reserve( vCrvP.size()) ; - for ( int i = 0 ; i < int( vCrvP.size()) ; ++ i) { - double dArea ; - vCrvP[i]->GetAreaXY( dArea) ; - vArea.emplace_back( i, dArea) ; + // creo la regione + ISurfFlatRegion* pSfr = SfrCntr.GetSurf() ; + bOk = bOk && ( pSfr != nullptr) ; + // inserisco eventuali curve chiuse non usate nell'elenco delle aperte + if ( ! SfrCntr.AllCurvesUsed()) { + // recupero indice da proprietà temporanea di curve non usate + INTVECTOR vUnId ; + SfrCntr.GetUnusedCurveTempProps( vUnId) ; + // recupero Id originali associati + for ( auto nUnId : vUnId) { + if ( nUnId > 0 && nUnId <= int( vClosedIds.size())) { + INTVECTOR vTmpIds ; + if ( FromString( vClosedIds[nUnId - 1], vTmpIds)) + vOpenIds.insert( vOpenIds.end(), vTmpIds.begin(), vTmpIds.end()) ; + } + } } - sort( vArea.begin(), vArea.end(), - []( const INDAREA& a, const INDAREA&b) { return fabs( a.second) > fabs( b.second) ; }) ; - // verifico e sistemo il senso di rotazione delle curve - for ( int i = 0 ; i < int( vArea.size()) ; ++ i) { - if ( ( i == 0 && vArea[i].second < 0) || ( i > 0 && vArea[i].second > 0)) - vCrvP[vArea[i].first]->Invert() ; - } - // creo il riempimento - CICURVEPVECTOR vCCrvP ; - vCCrvP.reserve( vCrvP.size()) ; - for ( auto pCrv : vCrvP) - vCCrvP.push_back( pCrv) ; - ISurfTriMesh* pSTM = ( bOk ? GetSurfTriMeshByRegion( vCCrvP, 0.1) : nullptr) ; - bOk = bOk && ( pSTM != nullptr) ; - // elimino punti ripetuti - bOk = bOk && pSTM->DoCompacting() ; // inserisco la superficie nel DB - int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nRegId, pSTM) : GDB_ID_NULL) ; + int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nRegId, pSfr) : GDB_ID_NULL) ; // assegno il colore Color cCol = AQUA ; cCol.SetAlpha( 0.3) ; bOk = bOk && pGeomDB->SetMaterial( nNewId, cCol) ; - // taglio le curve aperte con i contorni - for ( int i = 0 ; i < int( vOpenIds.size()) ; ++i) { + // taglio le curve aperte con la regione + for ( int i = 0 ; bOk && i < int( vOpenIds.size()) ; ++i) { ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( vOpenIds[i])) ; - Intervals inCrv ; + // calcolo la classificazione della curva rispetto alla regione + CRVCVECTOR ccClass ; + if ( ! pSfr->GetCurveClassification( *pCrv, ccClass)) + continue ; + // conservo solo gli intervalli di curva interni + Intervals inOk ; + for ( auto& ccOne : ccClass) { + if ( ccOne.nClass == CRVC_IN) + inOk.Add( ccOne.dParE, ccOne.dParS) ; + } + // recupero un intervallo di id contigui per tutte le parti + int nFirstId = pGeomDB->GetNewId() ; + pGeomDB->ChangeId( vOpenIds[i], nFirstId) ; + int nCurrId = nFirstId ; + // eseguo la divisione + nCount = 0 ; double dParS, dParE ; - pCrv->GetDomain( dParS, dParE) ; - inCrv.Set( dParS, dParE) ; - for ( int j = 0 ; j < int( vCrvP.size()) ; ++ j) { - // intersezione e classificazione - CRVCVECTOR ccClass ; - IntersCurveCurve intCC( *pCrv, *vCrvP[j]) ; - if ( ! intCC.GetCurveClassification( 0, ccClass)) - continue ; - // conservo solo le parti interne - for ( int k = 0 ; k < int( ccClass.size()) ; ++ k) { - if ( ccClass[k].nClass != CRVC_IN) - inCrv.Subtract( ccClass[k].dParS, ccClass[k].dParE) ; - } - } - // tratti di curva rimasti - int nNum = inCrv.GetCount() ; - // se non sono rimasti pezzi, elimino la curva - if ( nNum == 0) { - pGeomDB->Erase( vOpenIds[i]) ; - } - // se uno solo, lo adatto - else if ( nNum == 1) { - double dParS, dParE ; - inCrv.GetFirst( dParS, dParE) ; - pCrv->TrimStartEndAtParam( dParS, dParE) ; - } - // altrimenti creo le opportune copie parzializzate - else { - int nOriId = vOpenIds[i] ; - int nCopyId = GDB_ID_NULL ; - double dParS, dParE ; - bool bInt = inCrv.GetFirst( dParS, dParE) ; - while ( bInt) { - // copio la curva - nCopyId = pGeomDB->Copy( nOriId, GDB_ID_NULL, nOriId, GDB_AFTER) ; - // modifico l'originale - ICurve* pOriCrv = GetCurve( pGeomDB->GetGeoObj( nOriId)) ; - pOriCrv->TrimStartEndAtParam( dParS, dParE) ; - // la copia è il nuovo originale - nOriId = nCopyId ; - // passo al successivo intervallo - bInt = inCrv.GetNext( dParS, dParE) ; - } - // cancello l'ultima copia - if ( nCopyId != GDB_ID_NULL) - pGeomDB->Erase( nCopyId) ; + bool bFound = inOk.GetFirst( dParS, dParE) ; + while ( bFound) { + // copio la curva + int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; + ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; + if ( pCopyCrv == nullptr) + break ; + ++ nCount ; + // modifico l'originale + bOk = bOk && pCrv->TrimStartEndAtParam( dParS, dParE) ; + // la copia diventa il nuovo corrente + nCurrId = nCopyId ; + pCrv = pCopyCrv ; + // passo alla successiva divisione + bFound = inOk.GetNext( dParS, dParE) ; } + // cancello l'ultima copia (se non c'erano intervalli validi è l'originale) + if ( nCurrId != GDB_ID_NULL) + pGeomDB->Erase( nCurrId) ; } // se errore sul pezzo, lo elimino if ( ! bOk)