EgtGeomKernel :

- modifica Swept con vettore statico.
- aggiunta Swep con FlatRegion come sezione
- migliorie varie.
This commit is contained in:
Riccardo Elitropi
2024-03-18 13:20:35 +01:00
parent 9880fa0173
commit e2445c0a15
+88 -23
View File
@@ -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 <algorithm>
#include <thread>
#include <future>
@@ -687,7 +688,7 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
( 2) mediante l'algoritmo del Rotation Minimize Frame
*/
PtrOwner<ICurveComposite> pSecLocApprox( CreateCurveComposite()) ;
PtrOwner<CurveComposite> 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<ISurfTriMesh> 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<ICurve> pCrvLoop( pSfrSect->GetLoop( c, l)) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
return nullptr ;
// creo la Trimesh Swept
PtrOwner<ISurfTriMesh> 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<ISurfTriMesh> 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<ISurfTriMesh> 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) ;
}
//-------------------------------------------------------------------------------