diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc new file mode 100644 index 0000000..0d08d6a Binary files /dev/null and b/EgtGeomKernel.rc differ diff --git a/SubtractProjectedFacesOnStmFace.cpp b/SubtractProjectedFacesOnStmFace.cpp index e6cc25d..8d0509a 100644 --- a/SubtractProjectedFacesOnStmFace.cpp +++ b/SubtractProjectedFacesOnStmFace.cpp @@ -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 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 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 pStm_CurrProj( CreateSurfTriMesh()) ; - if ( IsNull( pStm_CurrProj)) + + // TriMesh da proiettare + PtrOwner 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 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 pStmForProj( CloneSurfTriMesh( vStmOthers[0])) ; - PtrOwner 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 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 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 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 ;