EgtGeomKernel :
- modifica Swept con vettore statico. - aggiunta Swep con FlatRegion come sezione - migliorie varie.
This commit is contained in:
+88
-23
@@ -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) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user