EgtGeomKernel :

- rimozione parametro in SubtractProjectedFacesOnStmFace
- migliorie varie.
This commit is contained in:
Riccardo Elitropi
2023-10-10 13:34:31 +02:00
parent 9ec04bff06
commit 3c52ca3fef
2 changed files with 54 additions and 56 deletions
BIN
View File
Binary file not shown.
+54 -56
View File
@@ -497,8 +497,7 @@ AddClosedEdges( const ISurfTriMesh& StmOrig, int nFaceInd, const ISurfFlatRegion
//----------------------------------------------------------------------------
bool
SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
ISURFTMPOVECTOR& vStmOthers, INTVECTOR& vFIndOthers, bool bOCFlag,
SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd, ISURFTMPOVECTOR& vStmOthers, bool bOCFlag,
bool& bExistProjection, ISurfTriMesh*& pStmRes, int& nNewFaceNbr)
{
// verifico validità della superificie originale
@@ -518,20 +517,15 @@ SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
// dimensione dei vettori passati come parametri
int nVStm_size = ( int)vStmOthers.size() ;
int nVId_size = ( int)vFIndOthers.size() ;
// se vettori di dimensioni diverse -> incoerenza
if ( nVStm_size != nVId_size)
return false ;
// se entrambi sono vuoti, alora considero di proiettare tutte le altre facce della TriMesh
bool bIsSize0 = ( nVStm_size == 0) ;
if ( bIsSize0) {
// se entrambi i vettori sono vuoti, allora considero da proiettare tutte le altre facce della TriMesh
// se il vettore delle Trimesh dal proiettare è vuoto, la proeizione è fatta con le altre facce delle TriMesh
PtrOwner<ISurfTriMesh> pStmNoSelFace( Stm.Clone()) ;
if ( IsNull( pStmNoSelFace) || ! pStmNoSelFace->IsValid())
return false ;
// se la superficie ha solo una faccia e cerco di toglierla, allora non devo proiettare nulla...
if ( pStmNoSelFace->GetFacetCount() == 1)
return true ;
return true ; // il flag BOCFlag non importa, ho tutti lati aperti
// rimuovo la faccia da proiettare
if ( ! pStmNoSelFace->RemoveFacet( nFaceInd))
return false ;
@@ -557,10 +551,16 @@ SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
// creo un piano passante per la faccia selezionata ( di normale inversa per il taglio)
// ( tutto ciò che sta nel semipiano negativo della faccia selezionata, non viene proiettato ma tagliato)
Plane3d plFace ;
plFace.Set( ptORIG, -vtN) ;
if ( ! plFace.IsValid())
return false ;
Plane3d plFace ;
plFace.Set( ptORIG, -vtN) ;
if ( ! plFace.IsValid())
return false ;
// ricavo il Box3D della faccia selezionata nel frame della faccia stessa
Frame3d frH = frFace ; frH.Invert() ;
BBox3d BBoxSelFace ;
if ( ! pStm_face->GetBBox( frH, BBoxSelFace))
return false ;
// superficie finale della proeizione
PtrOwner<ISurfFlatRegion> pSfr_proj( CreateSurfFlatRegion()) ;
@@ -570,70 +570,65 @@ SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
// scorro le parti di superfici da proiettare...
for ( int t = 0 ; t < nVStm_size ; ++ t) {
// proiezione corrente
PtrOwner<ISurfTriMesh> pStm_CurrProj( CreateSurfTriMesh()) ;
if ( IsNull( pStm_CurrProj))
// TriMesh da proiettare
PtrOwner<ISurfTriMesh> pStm_CurrProj( CloneSurfTriMesh( vStmOthers[t])) ;
if ( IsNull( pStm_CurrProj) || ! pStm_CurrProj->IsValid())
return false ;
// *** se sono stati passati alla funzione vettori non vuoti, allora pStm_CurrProj è la faccia
// *** corrente da proiettare
if ( ! bIsSize0) {
// se la faccia da proiettare è perpendicolare alla faccia selezionata, non la considero
// rimuovo dalla TriMesh tutte le facce che sono perpendicolari e tutte le facce il cui Box3D nel piano di
// proeizione non fa overlap con quello della faccia selezionata
// scorro tutte le facce da proiettare
PtrOwner<ISurfTriMesh> pStmForProj_noPerpFaces( CreateSurfTriMesh()) ;
StmFromTriangleSoup StmFts ; StmFts.Start() ;
for ( int f = 0 ; f < pStm_CurrProj->GetFacetCount() ; ++ f) {
Vector3d vtN_curr ;
if ( ! vStmOthers[t]->GetFacetNormal( vFIndOthers[t], vtN_curr) ||
abs( vtN_curr * vtN) < 5 * EPS_SMALL) // <--- | prodotto scalare | < 5 * EPS_SMALL
continue ;
// recupero la faccia da proiettare ( controllando la sua validità)
pStm_CurrProj.Set( vStmOthers[t]->CloneFacet( vFIndOthers[t])) ;
if ( IsNull( pStm_CurrProj) || ! pStm_CurrProj->IsValid())
return false ;
}
// *** se sono stati passati alla funzione vettori vuoti allora pStm_CurrProj contiene tutta la TriMesh
// *** meno la faccia scelta
else {
PtrOwner<ISurfTriMesh> pStmForProj( CloneSurfTriMesh( vStmOthers[0])) ;
PtrOwner<ISurfTriMesh> pStmForProj_noPerpFaces( CreateSurfTriMesh()) ;
if ( IsNull( pStmForProj) || ! pStmForProj->IsValid() || IsNull( pStmForProj_noPerpFaces))
return false ;
StmFromTriangleSoup StmFts ;
StmFts.Start() ;
// rimuovo le facce perpendicolari
for ( int f = 0 ; f < pStmForProj->GetFacetCount() ; ++ f) {
Vector3d vtN_curr ;
if ( pStmForProj->GetFacetNormal( f, vtN_curr) && abs( vtN_curr * vtN) > 5 * EPS_SMALL) {
PtrOwner<ISurfTriMesh> pStm_face( pStmForProj->CloneFacet( f)) ;
if ( IsNull( pStm_face) || ! pStm_face->IsValid())
// se perpendicolari alla faccia selezionata, le trascuro
if ( pStm_CurrProj->GetFacetNormal( f, vtN_curr) && abs( vtN_curr * vtN) > 5 * EPS_SMALL) {
BBox3d BBoxFace_f ;
if ( ! pStm_CurrProj->GetFacetBBox( f, frH, BBoxFace_f))
return false ;
// se non c'è OverlapXY tra i due Box3D, la trascuro
if ( BBoxSelFace.OverlapsXY( BBoxFace_f)) {
PtrOwner<ISurfTriMesh> pStm_Currface( pStm_CurrProj->CloneFacet( f)) ;
if ( IsNull( pStm_Currface) || ! pStm_Currface->IsValid())
return false ;
Triangle3d Tria ;
int nT = pStm_face->GetFirstTriangle( Tria) ;
int nT = pStm_Currface->GetFirstTriangle( Tria) ;
while ( nT != SVT_NULL) {
// inserisco il triangolo nella nuova superficie
StmFts.AddTriangle( Tria) ;
// passo al triangolo successivo
nT = pStm_face->GetNextTriangle( nT, Tria) ;
nT = pStm_Currface->GetNextTriangle( nT, Tria) ;
}
}
}
StmFts.End() ;
pStmForProj_noPerpFaces.Set( StmFts.GetSurf()) ;
// se la superficie senza le facce perpendicolari non è valida, allora ho finito
if ( ! pStmForProj_noPerpFaces->IsValid())
return true ;
// sistemo
pStmForProj_noPerpFaces->Repair() ;
// sostituisco
pStm_CurrProj.Set( Release( pStmForProj_noPerpFaces)) ;
}
StmFts.End() ;
pStmForProj_noPerpFaces.Set( StmFts.GetSurf()) ;
// se la nuova superficie da proittare non contiene nulla, allora passo alla successiva
if ( ! pStmForProj_noPerpFaces->IsValid())
continue ;
// ricostruisco la nuova superificie semplificata da proiettare
if ( ! pStmForProj_noPerpFaces->Repair() ||
! pStm_CurrProj.Set( Release( pStmForProj_noPerpFaces)) ||
IsNull( pStm_CurrProj) ||
! pStm_CurrProj->IsValid())
return false ;
// taglio la superficie con il piano creato ( la proiezione esclude le parti nel semipiano negativo)
// controllo la validità di questa operazione ( la faccia potrebbe essere tutta nel semipiano negativo)
if ( ! pStm_CurrProj->Cut( plFace, true))
return false ;
// controllo la validità di questa operazione ( la faccia potrebbe essere tutta nel semipiano negativo)
if ( IsNull( pStm_CurrProj) || ! pStm_CurrProj->IsValid() || pStm_CurrProj->GetTriangleCount() == 0)
continue ;
// recupero la PolyLine della Silhouette
POLYLINEVECTOR vPL ;
if ( ! pStm_CurrProj->GetSilhouette( vtN, 100 * EPS_SMALL, vPL, true))
return false ;
// converto le curve in composite
// NB. Potrei ottenere più curve, quindi creo la FlatRegion associata
SurfFlatRegionByContours sfrBCProj_face ;
@@ -656,13 +651,16 @@ SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
// se proeizione non valida, allora passo all'entità successiva
if ( ! bValidCurrProj)
continue ;
// ricavo la FlatRegion associata alla proiezione delle faccia
PtrOwner<ISurfFlatRegion> pSfr_proj_faceCurr( sfrBCProj_face.GetSurf()) ;
if ( IsNull( pSfr_proj_faceCurr) || ! pSfr_proj_faceCurr->IsValid())
return false ;
// inverto se necessario
if ( AreOppositeVectorApprox( pSfr_proj_faceCurr->GetNormVersor(), vtN))
pSfr_proj_faceCurr->Invert() ;
// la sommo alla regione di proeizione globale
if ( ! pSfr_proj->IsValid() || pSfr_proj->GetChunkCount() == 0)
pSfr_proj.Set( Release( pSfr_proj_faceCurr)) ;
@@ -671,7 +669,7 @@ SubtractProjectedFacesOnStmFace( const ISurfTriMesh& Stm, int nFaceInd,
return false ;
}
// se non c'è nulla d proiettare e flag bOCFlag false, allora esco
// se non c'è nulla da proiettare e flag bOCFlag false, allora esco
if ( ! bExistProj && ! bOCFlag)
return true ;