EgtExecutor :

- CreateFlatPartsByRegion e CreateFlatPartsByLayer migliorate e modificate per uso regioni.
This commit is contained in:
Dario Sassi
2015-09-20 09:13:05 +00:00
parent d7c8a61456
commit 6f2de64ae6
+72 -86
View File
@@ -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<IGdbIterator> 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<int,double> 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<int,double> INDAREA ; // coppia indice, area
typedef std::vector<INDAREA> 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)