diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index 604464a..94f3253 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -320,6 +320,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
@@ -332,6 +333,8 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
@@ -463,8 +466,6 @@ copy $(TargetPath) \EgtProg\Dll64
-
-
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index 4f6765b..477d1e3 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -531,6 +531,9 @@
File di origine\Base
+
+ File di origine\Base
+
@@ -1199,11 +1202,11 @@
File di intestazione\Include
-
- File di intestazione
+
+ File di intestazione\Include
-
- File di intestazione
+
+ File di intestazione\Include
diff --git a/RotationMinimizingFrame.cpp b/RotationMinimizingFrame.cpp
index edb3366..cbb878c 100644
--- a/RotationMinimizingFrame.cpp
+++ b/RotationMinimizingFrame.cpp
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// EgalTech 2015-2024
+// EgalTech 2024-2024
//----------------------------------------------------------------------------
// File : RotationMinimizingFrame.cpp Data : 05.03.24 Versione : 2.6d1
// Contenuto : Classe per RotationMinimizeFrame
@@ -13,23 +13,26 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
-#include "RotationMinimizingFrame.h"
#include "GeoConst.h"
+#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
using namespace std ;
//----------------------------------------------------------------------------
-RotationMinimizingFrame::RotationMinimizingFrame( const ICurve* pCrv, const Frame3d& fr_Start)
+bool
+RotationMinimizingFrame::Set( const ICurve* pCrv, const Frame3d& fr_Start)
{
+ // pulisco
+ Clear() ;
+ // verifico i parametri
+ if ( pCrv == nullptr || ! pCrv->IsValid() ||
+ ! fr_Start.IsValid())
+ return false ;
// assegno i parametri
m_pCrv = pCrv->Clone() ;
m_Frame0 = fr_Start ;
-}
-//----------------------------------------------------------------------------
-RotationMinimizingFrame::~RotationMinimizingFrame( void)
-{
- Clear() ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -40,7 +43,6 @@ RotationMinimizingFrame::Clear( void)
if ( m_pCrv != nullptr)
delete m_pCrv ;
m_pCrv = nullptr ;
-
// reset del frame di partenza
m_Frame0.Reset() ;
@@ -49,7 +51,7 @@ RotationMinimizingFrame::Clear( void)
//----------------------------------------------------------------------------
bool
-RotationMinimizingFrame::IsValid()
+RotationMinimizingFrame::IsValid( void)
{
// controllo validità della curva
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
@@ -69,12 +71,11 @@ RotationMinimizingFrame::IsValid()
return false ;
return true ;
-
}
//----------------------------------------------------------------------------
bool
-RotationMinimizingFrame::GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext)
+RotationMinimizingFrame::GetFrameAtParam( const Frame3d& frAct, const double dParNext, Frame3d& frNext)
{
/*
Double Reflection
@@ -86,28 +87,21 @@ RotationMinimizingFrame::GetFrameAtLength( const Frame3d& frAct, const double dL
if ( ! frAct.IsValid())
return false ;
- // origine del frame e versori ( ptAct, [ vt_r, vt_s, vt_t])
+ // origine del frame e versori ( ptCurr, [ vtCurrR, vtCurrS, vtCurrT])
Point3d ptCurr = frAct.Orig() ;
- Vector3d vt_r = frAct.VersX() ;
- Vector3d vt_t = frAct.VersZ() ;
- // ( vt_s è implicito )
+ Vector3d vtCurrR = frAct.VersX() ;
+ Vector3d vtCurrT = frAct.VersZ() ;
- double dUNext ; // parametro sulla curva nello step successivo
- Point3d ptNext ; // punto sulla curva allo step successivo
-
- // parametro (i+1)-esimo sulla curva
- if ( ! m_pCrv->GetParamAtLength( dLenNext, dUNext))
- return false ;
-
- // punto (i+1)-esimo sulla curva e suo vettore tangente
- Vector3d vt_t_next ;
- if ( ! m_pCrv->GetPointD1D2( dUNext, ICurve::FROM_MINUS, ptNext, &vt_t_next) ||
- ! vt_t_next.IsValid() || ! vt_t_next.Normalize()) // versore tangente
+ // punto i-esimo sulla curva e suo vettore tangente
+ Point3d ptNext ;
+ Vector3d vtNextT ;
+ if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNextT) ||
+ ! vtNextT.Normalize())
return false ;
// controllo per casi degeneri
- if ( AreSamePointEpsilon( ptCurr, ptNext, EPS_ZERO) || // non esiste il piano R1
- abs(( ptNext - ptCurr) * ( vt_t_next + vt_t)) < EPS_ZERO) // non esiste il piano R2
+ if ( AreSamePointEpsilon( ptCurr, ptNext, EPS_ZERO) || // non esiste il piano R1
+ abs( ( ptNext - ptCurr) * ( vtNextT + vtCurrT)) < EPS_ZERO) // non esiste il piano R2
return false ;
// ricavo il vettore di riflessione rispetto al piano R1
@@ -119,11 +113,11 @@ RotationMinimizingFrame::GetFrameAtLength( const Frame3d& frAct, const double dL
double dPar1 = vR1_norm * vR1_norm ;
// riflessione rispetto al piano R1 ( sistema sinistrorso L )
- Vector3d vt_r_L = vt_r - ( 2 / dPar1) * ( vR1_norm * vt_r) * vR1_norm ;
- Vector3d vt_t_L = vt_t - ( 2 / dPar1) * ( vR1_norm * vt_t) * vR1_norm ;
+ Vector3d vt_r_L = vtCurrR - ( 2 / dPar1) * ( vR1_norm * vtCurrR) * vR1_norm ;
+ Vector3d vt_t_L = vtCurrT - ( 2 / dPar1) * ( vR1_norm * vtCurrT) * vR1_norm ;
// ricavo il vettore di riflessione rispetto al piano R1
- Vector3d vR2_norm = vt_t_next - vt_t_L ;
+ Vector3d vR2_norm = vtNextT - vt_t_L ;
if ( ! vR2_norm.IsValid())
return false ;
@@ -131,65 +125,47 @@ RotationMinimizingFrame::GetFrameAtLength( const Frame3d& frAct, const double dL
double dPar2 = vR2_norm * vR2_norm ;
// versore r del nuovo frame
Vector3d vt_r_next = vt_r_L - ( 2 / dPar2) * ( vR2_norm * vt_r_L) * vR2_norm ;
- // versore t del nuovo frame
- Vector3d vt_s_next = vt_t_next ^ vt_r_next ;
// imposto il nuovo frame
- frNext.Set( ptNext, vt_r_next, vt_s_next, vt_t_next) ;
- if ( ! frNext.IsValid()) { // il frame potrebbe non essere nelle tolleranze...
- // ... sistemo ricavando il versore "s" mediante "t" ed "r" ...
- frNext.Set( ptNext, vt_t_next, vt_r_next) ;
- if ( ! frNext.IsValid())
- return false ;
- }
-
- return true ;
-
+ return frNext.Set( ptNext, vtNextT, vt_r_next) ;
}
//----------------------------------------------------------------------------
bool
-RotationMinimizingFrame::GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform)
+RotationMinimizingFrame::GetFramesByStep( double dStep, bool bUniform, FRAME3DVECTOR& vRMFrames)
{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
// controllo sullo step
dStep = max( 10 * EPS_SMALL, dStep) ;
- // controllo validità
- if ( ! IsValid()) {
- Clear() ;
+ // lunghezza della curva
+ double dCrvLen = 0. ;
+ if ( ! m_pCrv->GetLength( dCrvLen) || dCrvLen < 10 * EPS_SMALL)
return false ;
- }
-
- // calcolo lunghezza della curva
- double dLen = 0. ;
- if ( ! m_pCrv->GetLength( dLen))
- return false ;
-
- // in prima posizione viene inserito il frame iniziale
- vRMFrames.push_back( m_Frame0) ;
// ricavo il numero degli step
- int nStep = int( ceil( dLen / dStep)) ;
- if ( nStep == 0) // se non ho step allora serve sono il frame iniziale
- return true ;
+ int nStep = int( ceil( dCrvLen / dStep)) ;
+ double dMyStep = ( bUniform ? dCrvLen / nStep : dStep) ;
- // lunghezza della curva identificata dal punto successivo
- double dLenNext ;
-
- // step corrente
- double dMyStep = dStep ;
- if ( bUniform)
- dMyStep = dLen / nStep ;
+ // inserisco il frame iniziale nel vettore dei riferimenti
+ vRMFrames.clear() ;
+ vRMFrames.reserve( nStep + 1) ;
+ vRMFrames.push_back( m_Frame0) ;
// ciclo sugli step in cui la curva è suddivisa
- for ( int i = 0 ; i < nStep ; ++ i) {
- // ricavo la lunghezza della curva relativo allo step (i+1)-esimo
- dLenNext = min( dLen - 10 * EPS_SMALL, ( i + 1) * dMyStep) ;
- // ricavo il frame alla lunghezza calcolata
- Frame3d frNext ;
- if ( ! GetFrameAtLength( vRMFrames[i], dLenNext, frNext))
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ // ricavo il parametro della curva allo step i-esimo
+ double dParNext ;
+ if ( ! m_pCrv->GetParamAtLength( min( i * dMyStep, dCrvLen - EPS_SMALL), dParNext))
return false ;
- // aggiornamento vettore dei frame
+ // ricavo il frame alla posizione calcolata
+ Frame3d frNext ;
+ if ( ! GetFrameAtParam( vRMFrames[i-1], dParNext, frNext))
+ return false ;
+ // inserisco nuovo frame nel vettore dei riferimenti
vRMFrames.push_back( frNext) ;
}
@@ -198,70 +174,57 @@ RotationMinimizingFrame::GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep
//----------------------------------------------------------------------------
bool
-RotationMinimizingFrame::GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals)
+RotationMinimizingFrame::GetFramesBySplit( int nIntervals, FRAME3DVECTOR& vRMFrames)
{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
// controllo sul numero di intervalli
nIntervals = max( 1, nIntervals) ;
- // ricavo lo step associato
+ // ricavo lo step
double dLen = 0 ;
if ( ! m_pCrv->GetLength( dLen))
return false ;
-
- // ricavo lo step associato
double dStep = dLen / nIntervals ;
- return GetFramesByStep( vRMFrames, dStep) ;
+ return GetFramesByStep( dStep, true, vRMFrames) ;
}
//----------------------------------------------------------------------------
bool
-RotationMinimizingFrame::GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol)
+RotationMinimizingFrame::GetFramesByTolerance( double dTol, FRAME3DVECTOR& vRMFrames)
{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
// controllo sulla tolleranza
dTol = max( EPS_SMALL, dTol) ;
- // controllo validità
- if ( ! IsValid()) {
- Clear() ;
- return false ;
- }
-
// ricavo la PolyLine associata alla curva mediante tale tolleranza
PolyLine PL ;
if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return false ;
+ int nStep = PL.GetLineNbr() ;
- // ricavo la lunghezza della curva
- double dCrvLen = 0 ;
- if ( ! m_pCrv->GetLength( dCrvLen))
- return false ;
+ // inserisco il frame iniziale nel vettore dei riferimenti
+ vRMFrames.clear() ;
+ vRMFrames.reserve( nStep + 1) ;
+ vRMFrames.push_back( m_Frame0) ;
- // devo calcolare il RMF su ogni punto ricavato dall'approssimazione
+ // eseguo il calcolo dei frame su ogni punto ricavato dall'approssimazione
Point3d ptCurr ;
- bool bPoint = PL.GetFirstPoint( ptCurr) ;
- bool bFirst = true ;
- while ( bPoint) {
- if ( bFirst) {
- // in prima posizione viene inserito il frame iniziale
- vRMFrames.push_back( m_Frame0) ;
- bFirst = false ;
- }
- else {
- // ricavo la lunghezza della curva al punto corrente
- double dLen = 0. ;
- if ( ! m_pCrv->GetLengthAtPoint( ptCurr, dLen))
- return false ;
- // per sicurezza controllo che sia minore della lunghezza complessiva
- dLen = min( dCrvLen - 10 * EPS_SMALL , dLen) ;
- // ricavo il Frame associato a tale lunghezza
- Frame3d frNext ;
- if ( ! GetFrameAtLength( vRMFrames.back(), dLen, frNext))
- return false ;
- vRMFrames.emplace_back( frNext) ;
- }
- // passo al punto successivo
- bPoint = PL.GetNextPoint( ptCurr) ;
+ PL.GetFirstPoint( ptCurr) ;
+ double dParNext ;
+ Point3d ptNext ;
+ while ( PL.GetNextUPoint( &dParNext, &ptNext)) {
+ // ricavo il Frame associato a questa posizione
+ Frame3d frNext ;
+ if ( ! GetFrameAtParam( vRMFrames.back(), dParNext, frNext))
+ return false ;
+ vRMFrames.emplace_back( frNext) ;
}
return true ;
diff --git a/RotationMinimizingFrame.h b/RotationMinimizingFrame.h
deleted file mode 100644
index d382125..0000000
--- a/RotationMinimizingFrame.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//----------------------------------------------------------------------------
-// EgalTech 2015-2024
-//----------------------------------------------------------------------------
-// File : RotationMinimizingFrame.h Data : 05.03.24 Versione : 2.6d1
-// Contenuto : Dichiarazione della classe RotationMinimizingFrame.
-//
-//
-//
-// Modifiche : 05.03.24 RE Creazione modulo.
-
-//
-//----------------------------------------------------------------------------
-
-#pragma once
-
-#include "/EgtDev/Include/EGkFrame3d.h"
-#include "/EgtDev/Include/EGkCurve.h"
-#include
-
-//----------------------------------------------------------------------------
-typedef std::vector FRAME3DVECTOR ;
-
-//----------------------------------------------------------------------------
-class RotationMinimizingFrame
-{
- public :
- RotationMinimizingFrame( const ICurve* pCrv, const Frame3d& fr_Start) ;
- ~RotationMinimizingFrame( void) ;
-
- public :
- bool GetFramesByStep( FRAME3DVECTOR& vRMFrames, double dStep, bool bUniform = false) ;
- bool GetFramesBySplit( FRAME3DVECTOR& vRMFrames, int nIntervals) ;
- bool GetFramesByTollerance( FRAME3DVECTOR& vRMFrames, double dTol) ;
-
- private :
- bool Clear( void) ;
- bool IsValid( void) ;
- bool GetFrameAtLength( const Frame3d& frAct, const double dLenNext, Frame3d& frNext) ;
-
- private :
- ICurve* m_pCrv ; // curva per il calcolo del rotation minimize frame
- Frame3d m_Frame0 ; // frame iniziale della curva
-} ;
diff --git a/RotationXplaneFrame.cpp b/RotationXplaneFrame.cpp
new file mode 100644
index 0000000..1bbe710
--- /dev/null
+++ b/RotationXplaneFrame.cpp
@@ -0,0 +1,223 @@
+//----------------------------------------------------------------------------
+// EgalTech 2024-2024
+//----------------------------------------------------------------------------
+// File : RotationXplaneFrame.cpp Data : 05.04.24 Versione : 2.6d1
+// Contenuto : Classe per RotationXplaneFrame.
+//
+//
+//
+// Modifiche : 05.04.24 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "GeoConst.h"
+#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::Set( const ICurve* pCrv, const Vector3d& vtNorm, const Vector3d& vtNearX)
+{
+ // pulisco
+ Clear() ;
+ // verifico i parametri
+ if ( pCrv == nullptr || ! pCrv->IsValid() ||
+ ! vtNorm.IsValid() || vtNorm.IsSmall() || ! vtNearX.IsValid())
+ return false ;
+ // assegno i parametri
+ m_pCrv = pCrv->Clone() ;
+ m_vtNorm = vtNorm ;
+ m_vtNearX = vtNearX ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::Clear( void)
+{
+ // pulizia della curva
+ if ( m_pCrv != nullptr)
+ delete m_pCrv ;
+ m_pCrv = nullptr ;
+ // reset dei vettori
+ m_vtNorm = V_NULL ;
+ m_vtNearX = V_NULL ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::IsValid( void)
+{
+ // controllo validità della curva
+ if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
+ return false ;
+
+ // controllo della normale al piano
+ if ( m_vtNorm.IsSmall())
+ return false ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::GetFrameAtParam( const Frame3d& frAct, const double dParNext, Frame3d& frNext)
+{
+ // verifico il riferimento corrente
+ if ( ! frAct.IsValid())
+ return false ;
+
+ // recupero punto e tangente nel nuovo punto
+ Point3d ptNext ;
+ Vector3d vtNext ;
+ if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNext) ||
+ ! vtNext.Normalize())
+ return false ;
+
+ // calcolo il nuovo riferimento
+ Vector3d vtAxX = m_vtNorm ^ vtNext ;
+ if ( vtAxX.IsSmall())
+ vtAxX = frAct.VersX() ;
+ else if ( vtAxX * frAct.VersX() < 0)
+ vtAxX.Invert() ;
+
+ // lo imposto
+ return frNext.Set( ptNext, vtNext, vtAxX) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::GetFramesByStep( double dStep, bool bUniform, FRAME3DVECTOR& vRXFrames)
+{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
+ // controllo sullo step
+ dStep = max( 10 * EPS_SMALL, dStep) ;
+
+ // lunghezza della curva
+ double dCrvLen = 0. ;
+ if ( ! m_pCrv->GetLength( dCrvLen) || dCrvLen < 10 * EPS_SMALL)
+ return false ;
+
+ // numero e lunghezza effettiva di ogni step
+ int nStep = int( ceil( dCrvLen / dStep)) ;
+ double dMyStep = ( bUniform ? dCrvLen / nStep : dStep) ;
+
+ // calcolo il riferimento iniziale
+ Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ;
+ Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ;
+ Vector3d vtAxX = m_vtNorm ^ vtStart ;
+ if ( vtAxX.IsSmall()) {
+ vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ;
+ if ( vtAxX.IsSmall()) {
+ vtAxX = FromUprightOrtho( m_vtNorm) ;
+ vtAxX.Rotate( m_vtNorm, 0, 1) ;
+ }
+ }
+ Frame3d frStart ;
+ if ( ! frStart.Set( ptStart, vtStart, vtAxX))
+ return false ;
+
+ // inserisco questo frame nel vettore dei riferimenti
+ vRXFrames.clear() ;
+ vRXFrames.reserve( nStep + 1) ;
+ vRXFrames.push_back( frStart) ;
+
+ // ciclo sugli step in cui la curva è suddivisa
+ for ( int i = 1 ; i <= nStep ; ++ i) {
+ // ricavo il parametro della curva allo step i-esimo
+ double dParNext ;
+ if ( ! m_pCrv->GetParamAtLength( min( i * dMyStep, dCrvLen - EPS_SMALL), dParNext))
+ return false ;
+ // ricavo il frame alla posizione calcolata
+ Frame3d frNext ;
+ if ( ! GetFrameAtParam( vRXFrames[i-1], dParNext, frNext))
+ return false ;
+ // inserisco nuovo frame nel vettore dei riferimenti
+ vRXFrames.push_back( frNext) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::GetFramesBySplit( int nIntervals, FRAME3DVECTOR& vRXFrames)
+{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
+ // controllo sul numero di intervalli
+ nIntervals = max( 1, nIntervals) ;
+
+ // ricavo lo step
+ double dLen = 0 ;
+ if ( ! m_pCrv->GetLength( dLen))
+ return false ;
+ double dStep = dLen / nIntervals ;
+
+ return GetFramesByStep( dStep, true, vRXFrames) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+RotationXplaneFrame::GetFramesByTolerance( double dTol, FRAME3DVECTOR& vRXFrames)
+{
+ // controllo validità
+ if ( ! IsValid())
+ return false ;
+
+ // controllo sulla tolleranza
+ dTol = max( EPS_SMALL, dTol) ;
+
+ // ricavo la PolyLine associata alla curva mediante tale tolleranza
+ PolyLine PL ;
+ if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
+ return false ;
+ int nStep = PL.GetLineNbr() ;
+
+ // calcolo il riferimento iniziale
+ Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ;
+ Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ;
+ Vector3d vtAxX = m_vtNorm ^ vtStart ;
+ if ( vtAxX.IsSmall()) {
+ vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ;
+ if ( vtAxX.IsSmall()) {
+ vtAxX = FromUprightOrtho( m_vtNorm) ;
+ vtAxX.Rotate( m_vtNorm, 0, 1) ;
+ }
+ }
+ Frame3d frStart ;
+ if ( ! frStart.Set( ptStart, vtStart, vtAxX))
+ return false ;
+
+ // inserisco questo frame nel vettore dei riferimenti
+ vRXFrames.clear() ;
+ vRXFrames.reserve( nStep + 1) ;
+ vRXFrames.push_back( frStart) ;
+
+ // eseguo il calcolo dei frame sui punti della polyline approssimante
+ Point3d ptCurr ;
+ PL.GetFirstPoint( ptCurr) ;
+ double dParNext ;
+ Point3d ptNext ;
+ while ( PL.GetNextUPoint( &dParNext, &ptNext)) {
+ // ricavo il Frame associato a questa posizione
+ Frame3d frNext ;
+ if ( ! GetFrameAtParam( vRXFrames.back(), dParNext, frNext))
+ return false ;
+ vRXFrames.emplace_back( frNext) ;
+ }
+
+ return true ;
+}
diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp
index 7ee3d52..97f9540 100644
--- a/StmFromCurves.cpp
+++ b/StmFromCurves.cpp
@@ -19,16 +19,15 @@
#include "CurveComposite.h"
#include "SurfTriMesh.h"
#include "Voronoi.h"
-#include "RotationMinimizingFrame.h"
+#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
+#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
+#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
-#include "/EgtDev/Include/EGkSfrCreate.h"
-#include
-#include
#include
-#include
using namespace std ;
@@ -652,284 +651,36 @@ GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBev
}
//-------------------------------------------------------------------------------
-ISurfTriMesh*
-GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol, Vector3d* vtStatic)
+static ISurfTriMesh*
+GetSurfTriMeshSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
{
- // verifica parametri
- if ( pSect == nullptr || pGuide == nullptr)
- return nullptr ;
+ // determino se la sezione è chiusa
+ bool bSectClosed = pSect->IsClosed() ;
+ // determino se la guida è chiusa
+ bool bGuideClosed = pGuide->IsClosed() ;
- // calcolo la polilinea che approssima la sezione
+ // riferimento all'inizio della linea guida
+ Frame3d frStart ;
+ Point3d ptStart ;
+ pGuide->GetStartPoint( ptStart) ;
+ Vector3d vtStart ;
+ pGuide->GetStartDir( vtStart) ;
+ frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
+
+ // calcolo la polilinea che approssima la sezione
PolyLine PL ;
if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return nullptr ;
- // determino se la sezione è chiusa
- bool bSectClosed = PL.IsClosed() ;
- // determino se la guida è chiusa
- bool bGuideClosed = pGuide->IsClosed() ;
-
- // definisco la superficie da restituire ( definendo la sua tolleranza )
- PtrOwner pSTM( CreateBasicSurfTriMesh()) ;
- if ( IsNull( pSTM))
- return nullptr ;
- pSTM->SetLinearTolerance( dLinTol) ;
-
- // calcolo punto e versore tangente iniziale
- Point3d ptStart ; pGuide->GetStartPoint( ptStart) ;
- Vector3d vtStart ; pGuide->GetStartDir( vtStart) ;
- // inizializzazione del frame iniziale ( viene definito a seconda dei casi )
- Frame3d frStart ;
-
- /* GUIDA PIANA */
-
- // verifico che la linea guida sia piana
- Plane3d plGuide ;
- if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL)) {
-
- /*
- La guida non è piana, l'estrusione può essere definita mediante :
- ( 1) un versore statico
- ( 2) mediante l'algoritmo del Rotation Minimize Frame
- */
-
- // recupero la sezione dalla PolyLine approssimata come Curva
- PtrOwner pSecLocApprox( CreateBasicCurveComposite()) ;
- if ( IsNull( pSecLocApprox) ||
- ! pSecLocApprox->FromPolyLine( PL) ||
- ! pSecLocApprox->IsValid())
- return nullptr ;
-
- // recupero il frame iniziale sulla guida ( Origine sul punto iniziale e asse Z tangente )
- frStart.Set( ptStart, vtStart) ;
- if ( ! frStart.IsValid())
- return nullptr ;
-
- // tengo in memoria il frame nel punto iniziale e finale della guida in caso di caps
- Frame3d frCaps_start ;
- Frame3d frCaps_end ;
-
- // (1) versore statico
- if ( vtStatic != nullptr) {
-
- // creo il piano di proiezione con normale definita dal vettore
- Plane3d plProj ;
- plProj.Set( ORIG, *vtStatic) ;
- if ( ! plProj.IsValid())
- return nullptr ;
-
- // porto la sezione nel frame definito dalla guida, tenendo il versore X del frame nel piano
- // definito da vtStatic
- Vector3d vtX = vtStart ; // versore tangente alla curva
- vtX.Rotate( *vtStatic, 90) ; // ruoto di 90 gradi rispetto a vtStatic
- OrthoCompo( vtX, *vtStatic) ; // tengo la componente nel piano
- vtX.Normalize() ; // normalizzo
- Frame3d frInitial ; frInitial.Set( ptStart, vtStart, vtX) ; // creo il frame
- if ( ! frInitial.IsValid())
- return nullptr ;
-
- // porto la sezione nel riferimento
- pSecLocApprox->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))
- return nullptr ;
-
- // punto attuale e punto successivo sulla guida su cui definire il frame
- Point3d ptCurr, ptSucc ;
- if ( ! PL_G.GetFirstPoint( ptCurr))
- return nullptr ;
- bool bNextPoint = PL_G.GetNextPoint( ptSucc) ;
- if ( ! bNextPoint)
- return nullptr ;
-
- // parametro attuale e successivo riferito ai punti sulla guida
- double dParCurr = 0 ;
- double dParSucc ;
-
- // versore attuale e successivo riferito ai punti sulla guida
- Vector3d vtTanCurr, vtTanSucc ;
- if ( ! pGuide->GetStartDir( vtTanCurr))
- return nullptr ;
-
- // frame iniziale e successivo riferito alla curva
- Frame3d frCurr, frSucc ;
-
- bool bFirstIter = true ; // per salvare il frame iniziale nel caso di caps
- while ( bNextPoint) { // finchè recupero un punto sucessivo...
-
- // recupero il parametro successivo riferito alla guida
- if ( ! pGuide->GetParamAtPoint( ptSucc, dParSucc))
- return nullptr ;
-
- // recupero il versore tangente riferito al punto successivo sulla guida
- if ( ! pGuide->GetPointD1D2( dParSucc, ICurve::FROM_MINUS, ptSucc, &vtTanSucc) ||
- ! vtTanSucc.Normalize())
- return nullptr ;
-
- // creazione del frame nel punto corrente
- Vector3d vtX_curr = vtTanCurr ;
- vtX_curr.Rotate( *vtStatic, 90) ;
- OrthoCompo( vtX_curr, *vtStatic) ;
- vtX_curr.Normalize() ;
- frCurr.Set( ptCurr, vtTanCurr, vtX_curr) ;
- if ( ! frCurr.IsValid())
- return nullptr ;
-
- // memorizzo il primo frame di caso di caps
- if ( bFirstIter) {
- frCaps_start = frCurr ;
- bFirstIter = false ;
- }
-
- // creazione del frame nel punto successivo
- Vector3d vtX_succ = vtTanSucc ;
- vtX_succ.Rotate( *vtStatic, 90) ;
- OrthoCompo( vtX_curr, *vtStatic) ;
- vtX_succ.Normalize() ;
- frSucc.Set( ptSucc, vtTanSucc, vtX_succ) ;
- if ( ! frSucc.IsValid())
- return nullptr ;
-
-
- frCaps_end = frSucc ; // aggiorno il frame finale ad ogni step
-
- // definisco la sezione allo step corrente
- PtrOwner pSecCurr( pSecLocApprox->Clone()) ;
- if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
- return nullptr ;
-
- // considero la sezione ( in locale ) come vista dal globale
- if ( ! pSecCurr->ToGlob( frCurr))
- return nullptr ;
-
- // definisco la sezione allo step successivo
- PtrOwner pSecSucc( pSecLocApprox->Clone()) ;
- if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
- return nullptr ;
-
- // considero la sezione ( in locale ) come vista dal globale
- if ( ! pSecSucc->ToGlob( frSucc))
- return nullptr ;
-
- // creo la rigata tra queste due sezioni
- PtrOwner pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
- if ( IsNull( pSr) || ! pSr->IsValid())
- return nullptr ;
-
- // attacco la rigata alla superficie da restituire
- pSTM->DoSewing( *pSr) ;
-
- // aggiornamento dei parametri
- ptCurr = ptSucc ; // il punto corrente diventa il successivo
- bNextPoint = PL_G.GetNextPoint( ptSucc) ; // il successivo lo recupero dalla PolyLine
- vtTanCurr = vtTanSucc ; // il versore tangete corrente diventa il successivo
- }
- // la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
- pSTM->Invert() ;
-
- }
-
- // (2) Rotation Minimizing Frame
- else {
-
- // porto la PolyLine e la curva della sezione nel riferimento nel punto iniziale della guida
- pSecLocApprox->ToLoc( frStart) ;
- PL.ToLoc( frStart) ;
-
- // calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
- RotationMinimizingFrame RMF( pGuide, frStart) ;
- FRAME3DVECTOR vRMF ;
- if ( ! RMF.GetFramesByTollerance( vRMF, dLinTol) || vRMF.empty())
- return nullptr ;
-
- // per ogni RMF calcolato, la sezione va roto-traslata lungo la guida
- for ( int i = 0 ; i < int( vRMF.size()) - 1 ; ++ i) {
-
- // definisco la sezione allo step corrente
- PtrOwner pSecCurr( pSecLocApprox->Clone()) ;
- if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
- return nullptr ;
-
- // considero la sezione ( in locale ) come vista dal globale
- if ( ! pSecCurr->ToGlob( vRMF[i]))
- return nullptr ;
-
- // definisco la sezione allo step successivo
- PtrOwner pSecSucc( pSecLocApprox->Clone()) ;
- if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
- return nullptr ;
-
- // considero la sezione ( in locale ) come vista dal globale
- if ( ! pSecSucc->ToGlob( vRMF[i+1]))
- return nullptr ;
-
- // creo la rigata tra queste due sezioni
- PtrOwner pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
- if ( IsNull( pSr) || ! pSr->IsValid())
- return nullptr ;
-
- // attacco la rigata alla superficie da restituire
- pSTM->DoSewing( *pSr) ;
- }
- // la superficie definita dal RMF è invertita, il versore Z è diretto come la tangente della curva
- pSTM->Invert() ;
-
- // assegno frame iniziale e finale per caps
- frCaps_start = vRMF[0] ;
- frCaps_end = vRMF.back() ;
- }
-
- // se richiesti caps e sezione chiusa e guida aperta
- // (1) vtStatic, (2) Rotation Minimize Frame
- if ( bCapEnds && bSectClosed && ! bGuideClosed) {
-
- // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
- PtrOwner pSci( CreateBasicSurfTriMesh()) ;
- if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
- return nullptr ;
- pSci->ToGlob( frCaps_start) ;
- // unisco
- pSTM->DoSewing( *pSci) ;
-
- // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
- PtrOwner pSce( CreateBasicSurfTriMesh()) ;
- if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
- return nullptr ;
- pSce->ToGlob( frCaps_end) ;
-
- pSce->Invert() ; // il versore z è definito dalle tangenti alla curva
-
- // unisco
- pSTM->DoSewing( *pSce) ;
- }
-
- // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
- double dVol ;
- if ( pSTM->GetVolume( dVol) && dVol < 0)
- pSTM->Invert() ;
-
- // restituisco la superficie
- return Release( pSTM) ;
-
- }
-
- /*
- GUIDA PIANA
- La guida è piana, l'estrusione viene definita mediante Offset della guida sulla sezione
- */
-
- // il frame iniziale è definito dal versore tangente e dalla normale al piano
- // che contiene la guida
- Vector3d vtNorm = plGuide.GetVersN() ;
- frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
-
- // porto la sezione in questo riferimento e ve la appiattisco
+ // porto la sezione in questo riferimento e ve la appiattisco
if ( ! PL.ToLoc( frStart) || ! PL.Flatten())
return nullptr ;
+ // preparo collettore delle superfici componenti
+ StmFromTriangleSoup StmFts ;
+ if ( ! StmFts.Start())
+ return nullptr ;
+
// superficie swept
PtrOwner pPrevCrv ;
Point3d ptP ;
@@ -943,23 +694,29 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
if ( IsNull( pCurrCrv))
return nullptr ;
pCurrCrv->Translate( ptP.y * frStart.VersY()) ;
-
// se esiste la curva precedente, costruisco la rigata ( di tipo minima distanza)
if ( ! IsNull( pPrevCrv)) {
PtrOwner pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
if ( IsNull( pSr))
return nullptr ;
- // unisco
- pSTM->DoSewing( *pSr) ;
+ // inserisco nel collettore
+ StmFts.AddSurfTriMesh( *pSr) ;
}
-
// salvo la curva come prossima precedente
pPrevCrv.Set( pCurrCrv) ;
-
// prossimo punto
bPoint = PL.GetNextPoint( ptP) ;
}
+ // recupero la supeficie risultante
+ if ( ! StmFts.End())
+ return nullptr ;
+ PtrOwner pSTM( GetBasicSurfTriMesh( StmFts.GetSurf())) ;
+ if ( IsNull( pSTM))
+ return nullptr ;
+ // salvo tolleranza lineare usata
+ pSTM->SetLinearTolerance( dLinTol) ;
+
// se richiesti caps e sezione chiusa e guida aperta
if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// verifico che le due estremità siano chiuse e piatte
@@ -1002,59 +759,222 @@ GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, d
return Release( pSTM) ;
}
+//-------------------------------------------------------------------------------
+static ISurfTriMesh*
+GetSurfTriMeshSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol)
+{
+ // determino se la sezione è chiusa
+ bool bSectClosed = pSect->IsClosed() ;
+ // determino se la guida è chiusa
+ bool bGuideClosed = pGuide->IsClosed() ;
+ // determino algoritmo da usare per calcolare i riferimenti lungo la curva
+ bool bRMF = vtAx.IsSmall() ;
+
+ // riferimento all'inizio della linea guida
+ Point3d ptStart ;
+ pGuide->GetStartPoint( ptStart) ;
+ Vector3d vtStart ;
+ pGuide->GetStartDir( vtStart) ;
+ Frame3d frStart ;
+ if ( bRMF) {
+ if ( ! frStart.Set( ptStart, vtStart))
+ return nullptr ;
+ }
+ else {
+ Vector3d vtAxX = vtAx ^ vtStart ;
+ if ( vtAxX.IsSmall()) {
+ vtAxX = FromUprightOrtho( vtAx) ;
+ vtAxX.Rotate( vtAx, 0, 1) ;
+ }
+ if ( ! frStart.Set( ptStart, vtStart, vtAxX))
+ return nullptr ;
+ }
+
+ // calcolo la polilinea che approssima la sezione
+ PolyLine PL ;
+ if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
+ return nullptr ;
+
+ // recupero la sezione dalla PolyLine approssimata come Curva
+ PtrOwner pSecLocApprox( CreateBasicCurveComposite()) ;
+ if ( IsNull( pSecLocApprox) ||
+ ! pSecLocApprox->FromPolyLine( PL) ||
+ ! pSecLocApprox->IsValid())
+ return nullptr ;
+
+ // porto la PolyLine e la curva della sezione nel riferimento nel punto iniziale della guida
+ PL.ToLoc( frStart) ;
+ pSecLocApprox->ToLoc( frStart) ;
+
+ // calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
+ FRAME3DVECTOR vFrames ;
+ if ( bRMF) {
+ RotationMinimizingFrame RMF ;
+ if ( ! RMF.Set( pGuide, frStart) ||
+ ! RMF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
+ return nullptr ;
+ }
+ else {
+ RotationXplaneFrame RXF ;
+ if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
+ ! RXF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
+ return nullptr ;
+ }
+
+ // preparo collettore delle superfici componenti
+ StmFromTriangleSoup StmFts ;
+ if ( ! StmFts.Start())
+ return nullptr ;
+
+ // per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
+ for ( int i = 0 ; i < int( vFrames.size()) - 1 ; ++ i) {
+
+ // definisco la sezione allo step corrente
+ PtrOwner pSecCurr( pSecLocApprox->Clone()) ;
+ if ( IsNull( pSecCurr) || ! pSecCurr->IsValid())
+ return nullptr ;
+
+ // considero la sezione ( in locale ) come vista dal globale
+ if ( ! pSecCurr->ToGlob( vFrames[i]))
+ return nullptr ;
+
+ // definisco la sezione allo step successivo
+ PtrOwner pSecSucc( pSecLocApprox->Clone()) ;
+ if ( IsNull( pSecSucc) || ! pSecSucc->IsValid())
+ return nullptr ;
+
+ // considero la sezione ( in locale ) come vista dal globale
+ if ( ! pSecSucc->ToGlob( vFrames[i+1]))
+ return nullptr ;
+
+ // creo la rigata tra queste due sezioni
+ PtrOwner pSr( GetSurfTriMeshRuled( pSecCurr, pSecSucc, ISurfTriMesh::RLT_ISOPAR_SMOOTH, dLinTol)) ;
+ if ( IsNull( pSr) || ! pSr->IsValid())
+ return nullptr ;
+ // la inverto
+ pSr->Invert() ;
+ // inserisco la superficie nel collettore
+ StmFts.AddSurfTriMesh( *pSr) ;
+ }
+
+ // se richiesti caps e sezione chiusa e guida aperta
+ if ( bCapEnds && bSectClosed && ! bGuideClosed) {
+
+ // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
+ PtrOwner pSci( CreateBasicSurfTriMesh()) ;
+ if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
+ return nullptr ;
+ pSci->ToGlob( vFrames.front()) ;
+ // aggiungo
+ StmFts.AddSurfTriMesh( *pSci) ;
+
+ // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
+ PtrOwner pSce( CreateBasicSurfTriMesh()) ;
+ if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
+ return nullptr ;
+ pSce->ToGlob( vFrames.back()) ;
+ // inverto
+ pSce->Invert() ;
+ // aggiungo
+ StmFts.AddSurfTriMesh( *pSce) ;
+ }
+
+ // recupero la supeficie risultante
+ if ( ! StmFts.End())
+ return nullptr ;
+ PtrOwner pSTM( GetBasicSurfTriMesh( StmFts.GetSurf())) ;
+ if ( IsNull( pSTM))
+ return nullptr ;
+ // salvo tolleranza lineare usata
+ pSTM->SetLinearTolerance( dLinTol) ;
+
+ // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
+ double dVol ;
+ if ( pSTM->GetVolume( dVol) && dVol < 0)
+ pSTM->Invert() ;
+
+ // restituisco la superficie
+ return Release( pSTM) ;
+}
+
//-------------------------------------------------------------------------------
ISurfTriMesh*
-GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, bool bCapEnds,
- double dLinTol, Vector3d* vtStatic)
+GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx,
+ bool bCapEnds, double dLinTol)
+{
+ // verifica parametri
+ if ( pSect == nullptr || pGuide == nullptr)
+ return nullptr ;
+
+ // se la guida è piana
+ Plane3d plGuide ;
+ if ( pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
+ return GetSurfTriMeshSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ;
+
+ // altrimenti swept 3d
+ return GetSurfTriMeshSwept3d( pSect, pGuide, vtAx, bCapEnds, dLinTol) ;
+}
+
+//-------------------------------------------------------------------------------
+ISurfTriMesh*
+GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, const Vector3d& vtAx,
+ bool bCapEnds, double dLinTol)
{
// 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 ;
-
+ // predispongo collettore superfici componenti
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) {
+ for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
+ for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
// recupero il loop
- PtrOwner pCrvLoop( pSfrSect->GetLoop( c, l)) ;
+ PtrOwner pCrvLoop( pSfrSect->GetLoop( nC, nL)) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
return nullptr ;
// creo la Trimesh Swept
- PtrOwner pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, false, dLinTol, vtStatic)) ;
+ PtrOwner pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, vtAx, false, dLinTol)) ;
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
+ // Recupero la superficie
+ if ( ! StmSoup.End())
+ return nullptr ;
+ PtrOwner pStmSwept( StmSoup.GetSurf()) ;
+ if ( IsNull( pStmSwept))
+ return nullptr ;
+
+ // se rischiesta chiusura...
+ // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa
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())
+ // recupero i loop all'inizio (dalla regione e apportunamente approssimati)
+ POLYLINEVECTOR vPLi ;
+ for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
+ for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
+ vPLi.emplace_back() ;
+ if ( ! pSfrSect->ApproxLoopWithLines( nC, nL, dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLi.back()))
+ return nullptr ;
+ }
+ }
+ // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
+ PtrOwner pSci( CreateSurfTriMesh()) ;
+ if ( ! pSci->CreateByRegion( vPLi))
return nullptr ;
pStmSwept->DoSewing( *pSci) ;
// recupero i loops alla fine
- POLYLINEVECTOR vPL ;
- if ( ! pStmSwept->GetLoops( vPL))
+ POLYLINEVECTOR vPLe ;
+ if ( ! pStmSwept->GetLoops( vPLe))
return nullptr ;
// creo la superficie alla fine e la attacco
PtrOwner pSce( CreateSurfTriMesh()) ;
- if ( ! pSce->CreateByRegion( vPL))
+ if ( ! pSce->CreateByRegion( vPLe))
return nullptr ;
// attacco la superficie finale alla swept
pSce->Invert() ;
diff --git a/Vector3d.cpp b/Vector3d.cpp
index 927768b..61a9305 100644
--- a/Vector3d.cpp
+++ b/Vector3d.cpp
@@ -169,6 +169,10 @@ Vector3d::ToSpherical( double* pdLen, double* pdAngVertDeg, double* pdAngOrizzDe
bool
Vector3d::Normalize( double dEps)
{
+ // verifico validità
+ if ( ! IsValid())
+ return false ;
+
// se già normalizzato, ok
double dSqLen = x * x + y * y + z * z ;
if ( abs( 1.0 - dSqLen) < ( 2 * 1000 * DBL_EPSILON))