From e2445c0a157ee2352dfd5daad144b2075fefb242 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Mon, 18 Mar 2024 13:20:35 +0100 Subject: [PATCH] EgtGeomKernel : - modifica Swept con vettore statico. - aggiunta Swep con FlatRegion come sezione - migliorie varie. --- StmFromCurves.cpp | 111 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 23 deletions(-) diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index a2a4d7a..9b71de6 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -24,6 +24,7 @@ #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkSfrCreate.h" #include #include #include @@ -687,7 +688,7 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d ( 2) mediante l'algoritmo del Rotation Minimize Frame */ - PtrOwner pSecLocApprox( CreateCurveComposite()) ; + PtrOwner pSecLocApprox( CreateBasicCurveComposite()) ; if ( IsNull( pSecLocApprox) || ! pSecLocApprox->FromPolyLine( PL) || ! pSecLocApprox->IsValid()) @@ -708,18 +709,20 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d plProj.Set( ORIG, *vtStatic) ; if ( ! plProj.IsValid()) return nullptr ; - // porto la sezione nel frame definito dalla guida proeittando la Z nel piano definito da vtStatic - Point3d ptS_proj( vtStart.x, vtStart.y, vtStart.z) ; - ptS_proj = ProjectPointOnPlane( ptS_proj, plProj) ; - Vector3d vtStartH( ptS_proj.x, ptS_proj.y, ptS_proj.z) ; - if ( ! vtStartH.Normalize()) + // porto la sezione nel frame definito dalla guida, tenendo il versore X nel piano definito da vtStatic + Vector3d vtX = vtStart ; + vtX.Rotate( *vtStatic, 90) ; + Point3d ptX_proj( vtX.x, vtX.y, vtX.z) ; + ptX_proj = ProjectPointOnPlane( ptX_proj, plProj) ; + vtX.Set( ptX_proj.x, ptX_proj.y, ptX_proj.z) ; + if ( ! vtX.Normalize()) return nullptr ; Frame3d frInitial ; - frInitial.Set( ptStart, vtStartH) ; + frInitial.Set( ptStart, vtStart, vtX) ; if ( ! frInitial.IsValid()) return nullptr ; pSecLocApprox->ToLoc( frInitial) ; - PL.ToLoc( frInitial) ; + PL.ToLoc( frInitial) ; //... porto anche la PolyLine del bordo della sezione // approssimo la guida mediante la tolleranza richiesta PolyLine PL_G ; if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL_G)) @@ -750,19 +753,15 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d if ( ! pGuide->GetPointD1D2( dParSucc, ICurve::FROM_MINUS, ptSucc, &vtTanSucc) || ! vtTanSucc.Normalize()) return nullptr ; - // proietto i versori tangenti sul piano - Point3d ptS_proj( vtTanCurr.x, vtTanCurr.y, vtTanCurr.z) ; - ptS_proj = ProjectPointOnPlane( ptS_proj, plProj) ; - vtTanCurr.Set( ptS_proj.x, ptS_proj.y, ptS_proj.z) ; - if ( ! vtTanCurr.Normalize()) - return nullptr ; // se tangente alla guida in ptCurr perpendicolare al piano... - Point3d ptE_proj( vtTanSucc.x, vtTanSucc.y, vtTanSucc.z) ; - ptE_proj = ProjectPointOnPlane( ptE_proj, plProj) ; - vtTanSucc.Set( ptE_proj.x, ptE_proj.y, ptE_proj.z) ; - if ( ! vtTanSucc.Normalize()) - return nullptr ; // se tangente alla guida in ptSucc perpendicolare al piano... // creazione del frame corrente - frCurr.Set( ptCurr, vtTanCurr, *vtStatic ^ vtTanCurr) ; + Vector3d vtX_curr = vtTanCurr ; + vtX_curr.Rotate( *vtStatic, 90) ; + Point3d ptX_proj( vtX_curr.x, vtX_curr.y, vtX_curr.z) ; + ptX_proj = ProjectPointOnPlane( ptX_proj, plProj) ; + vtX_curr.Set( ptX_proj.x, ptX_proj.y, ptX_proj.z) ; + if ( ! vtX_curr.Normalize()) + return nullptr ; + frCurr.Set( ptCurr, vtTanCurr, vtX_curr) ; if ( ! frCurr.IsValid()) return nullptr ; if ( bFirstIter) { // memorizzo il primo frame di caso di caps @@ -770,7 +769,14 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d bFirstIter = false ; } // creazione del frame successivo - frSucc.Set( ptSucc, vtTanSucc, *vtStatic ^ vtTanSucc) ; + Vector3d vtX_succ = vtTanSucc ; + vtX_succ.Rotate( *vtStatic, 90) ; + ptX_proj.Set( vtX_succ.x, vtX_succ.y, vtX_succ.z) ; + ptX_proj = ProjectPointOnPlane( ptX_proj, plProj) ; + vtX_succ.Set( ptX_proj.x, ptX_proj.y, ptX_proj.z) ; + if ( ! vtX_succ.Normalize()) + return nullptr ; + frSucc.Set( ptSucc, vtTanSucc, vtX_succ) ; if ( ! frSucc.IsValid()) return nullptr ; frCaps_end = frSucc ; // aggiorno il frame finale @@ -949,9 +955,68 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d //------------------------------------------------------------------------------- ISurfTriMesh* -GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, bool bCapEnds, double dLinTol, Vector3d* vtStatic) +GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, bool bCapEnds, + double dLinTol, Vector3d* vtStatic) { - return nullptr ; + // verifica dei parametri + if ( pSfrSect == nullptr || pGuide == nullptr) + return nullptr ; + + // creo la Trimesh da restituire + PtrOwner pStmSwept( CreateBasicSurfTriMesh()) ; + if ( IsNull( pStmSwept) || ! pStmSwept->AdjustTopology()) + return nullptr ; + + StmFromTriangleSoup StmSoup ; + StmSoup.Start() ; + // per ogni loop della superficie, creo una Swept + for ( int c = 0 ; c < pSfrSect->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSfrSect->GetLoopCount( c) ; ++ l) { + // recupero il loop + PtrOwner pCrvLoop( pSfrSect->GetLoop( c, l)) ; + if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) + return nullptr ; + // creo la Trimesh Swept + PtrOwner pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, false, dLinTol, vtStatic)) ; + if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid()) + return nullptr ; + // aggiungo la Swept ricavata al risultato finale ( come triangoli ) + StmSoup.AddSurfTriMesh( *pStmLoopSwept) ; + } + } + StmSoup.End() ; + if ( ! pStmSwept.Set( StmSoup.GetSurf()) || IsNull( pStmSwept) || + ! pStmSwept->IsValid() || ! pStmSwept->AdjustTopology()) + return nullptr ; + + + // se rischista chiusura... + // NB. Controllo solo che al guida non sia chiusa, la sezione derivando da una Flatregion è chiusa per + // definizione + if ( bCapEnds && ! pGuide->IsClosed()) { + // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta ) + PtrOwner pSci( pSfrSect->GetAuxSurf()->Clone()) ; + if ( IsNull( pSci) || ! pSci->IsValid()) + return nullptr ; + pStmSwept->DoSewing( *pSci) ; + // recupero i loops alla fine + POLYLINEVECTOR vPL ; + if ( ! pStmSwept->GetLoops( vPL)) + return nullptr ; + // creo la superficie alla fine e la attacco + PtrOwner pSce( CreateSurfTriMesh()) ; + if ( ! pSce->CreateByRegion( vPL)) + return nullptr ; + // attacco la superficie finale alla swept + pSce->Invert() ; + pStmSwept->DoSewing( *pSce) ; + } + // se superficie risultante chiusa, verifico che la normale sia verso l'esterno + double dVol ; + if ( pStmSwept->GetVolume( dVol) && dVol < 0) + pStmSwept->Invert() ; + + return Release( pStmSwept) ; } //-------------------------------------------------------------------------------