Merge branch 'master' into NewRuled

This commit is contained in:
Daniele Bariletti
2026-01-28 15:24:09 +01:00
36 changed files with 6046 additions and 972 deletions
+40 -20
View File
@@ -1,12 +1,13 @@
//----------------------------------------------------------------------------
// EgalTech 2020-2024
// EgalTech 2020-2026
//----------------------------------------------------------------------------
// File : CDeClosedSurfTmClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2
// File : CDeClosedSurfTmClosedSurfTm.h Data : 23.01.26 Versione : 3.1a3
// Contenuto : Implementazione funzione verifica collisione tra
// SurfTm e SurfTm.
//
// Modifiche : 13.11.20 LM Creazione modulo.
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
// 23.01.26 DS In TestSurfTmSurfTm aggiunto flag per collisione quando una delle due è chiusa e contiene l'altra.
//
//----------------------------------------------------------------------------
@@ -45,10 +46,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
BBox3d b3BoxA, b3BoxB ;
pSrfA->GetLocalBBox( b3BoxA) ;
pSrfB->GetLocalBBox( b3BoxB) ;
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxB.Expand( dSafeDist) ;
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
if ( ! b3BoxA.Overlaps( b3BoxB))
return false ;
// Recupero i triangoli di A che interferiscono col box di B
@@ -61,13 +62,13 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
continue ;
BBox3d b3BoxTriaA ;
trTriaA.GetLocalBBox( b3BoxTriaA) ;
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxTriaA.Expand( dSafeDist) ;
// Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vNearTria ;
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
// Settare tutti i triangoli come già processati.
// Settare tutti i triangoli come già processati.
// Al termine della chiamata i TempInt dei triangoli valgono 0.
pSrfB->ResetTempInts() ;
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
@@ -84,14 +85,14 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
// Ciclo sui vertici del triangolo.
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
// Se il triangolo adiacente al triangolo corrente su questo edge
// non è stato processato, processo il vertice e l'edge.
// non è stato processato, processo il vertice e l'edge.
int nAdjTriaTempFlag ;
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
continue ;
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
return true ;
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ;
@@ -111,10 +112,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
}
}
// Non ho trovato collisioni fra triangoli delle superfici.
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
return false ;
// La collisione c'è se una superficie è dentro l'altra.
// La collisione c'è se una superficie è dentro l'altra.
Point3d ptPointA, ptPointB ;
pSrfA->GetFirstVertex( ptPointA) ;
pSrfB->GetFirstVertex( ptPointB) ;
@@ -127,7 +128,7 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
//----------------------------------------------------------------------------
bool
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist, bool bTestEnclosion)
{
// Recupero le superfici base
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
@@ -140,10 +141,10 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
BBox3d b3BoxA, b3BoxB ;
pSrfA->GetLocalBBox( b3BoxA) ;
pSrfB->GetLocalBBox( b3BoxB) ;
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxB.Expand( dSafeDist) ;
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
if ( ! b3BoxA.Overlaps( b3BoxB))
return false ;
// Recupero i triangoli di A che interferiscono col box di B
@@ -156,13 +157,13 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
continue ;
BBox3d b3BoxTriaA ;
trTriaA.GetLocalBBox( b3BoxTriaA) ;
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxTriaA.Expand( dSafeDist) ;
// Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vNearTria ;
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
// Settare tutti i triangoli come già processati.
// Settare tutti i triangoli come già processati.
// Al termine della chiamata i TempInt dei triangoli valgono 0.
pSrfB->ResetTempInts() ;
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
@@ -179,14 +180,14 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
// Ciclo sui vertici del triangolo.
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
// Se il triangolo adiacente al triangolo corrente su questo edge
// non è stato processato, processo il vertice e l'edge.
// non è stato processato, processo il vertice e l'edge.
int nAdjTriaTempFlag ;
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
continue ;
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
return true ;
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ;
@@ -205,6 +206,25 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
pSrfB->SetTempInt( nTB, 1) ;
}
}
// Non c'è interferenza
// Se non richiesto test di inclusione, non c'è interferenza
if ( ! bTestEnclosion)
return false ;
// Se la prima superficie è chiusa, verifico se include totalmente la seconda
if ( pSrfA->IsClosed() && b3BoxA.Encloses( b3BoxB)) {
Point3d ptPointB ;
pSrfB->GetFirstVertex( ptPointB) ;
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
if ( DistPoinBSrfA.IsPointInside() || DistPoinBSrfA.IsEpsilon( dSafeDist))
return true ;
}
// Se la seconda superficie è chiusa, verifico se include totalmente la prima
if ( pSrfB->IsClosed() && b3BoxB.Encloses( b3BoxA)) {
Point3d ptPointA ;
pSrfA->GetFirstVertex( ptPointA) ;
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ;
if ( DistPoinASrfB.IsPointInside() || DistPoinASrfB.IsEpsilon( dSafeDist))
return true ;
}
// Non c'è interferenza
return false ;
}
+213 -71
View File
@@ -1047,13 +1047,12 @@ ExtendPath( ICurveComposite* pCompo, const ISurfFlatRegion* pSfr, const PocketPa
}
// angoli di rotazione ( potrebbero servirne altri)
double dAng45 = ANG_RIGHT / 2. ;
static DBLVECTOR vAngles = { 0., ANG_RIGHT, 3 * ANG_RIGHT,
dAng45, 3 * dAng45, 5 * dAng45, 7 * dAng45 } ;
const double ANG_45 = ANG_RIGHT / 2. ;
const array vAngles{ 0., ANG_RIGHT, 3 * ANG_RIGHT, ANG_45, 3 * ANG_45, 5 * ANG_45, 7 * ANG_45} ;
// ruoto il versore di uscita cercando un'entrata valida
double dMinDist = PockParams.dRad + PockParams.dRadialOffset ;
for ( int i = 0 ; i < int( vAngles.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vAngles) ; ++ i) {
// ruoto il versore d'uscita
Vector3d vtRotOut = GetRotate( vtFirstOut, Z_AX, - vAngles[i]) ;
// calcolo il punto di caduta dell'utensile
@@ -2700,7 +2699,7 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr
double dLen0, dLen2 ;
pCrvTrap->GetCurve( 0)->GetLength( dLen0) ;
pCrvTrap->GetCurve( 2)->GetLength( dLen2) ;
if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL)
if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL)
pCrvTrap->Clear() ;
}
@@ -2981,38 +2980,38 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr
// se non ho trovato delle basi, allora cerco in maniera generale un trapezoide ( se esiste)
if ( nBase == -1) {
bool bOK = false ;
for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && !bOK ; ++ u) {
for ( int nU = 0 ; nU < pCrvCompo->GetCurveCount() && ! bOK ; ++ nU) {
// cerco un lato chiuso ( esiste per forza)
if ( pCrvCompo->GetCurve( u)->GetTempProp( 0) == 0) {
if ( pCrvCompo->GetCurve( nU)->GetTempProp( 0) == 0) {
// controllo se il lato corrente può essere una base
int nType = -1 ;
if ( ! GetBoxCrvOptTrap( u, pCrvCompo, dDiam, nType, pCrvTrap))
if ( ! GetBoxCrvOptTrap( nU, pCrvCompo, dDiam, nType, pCrvTrap))
return false ;
// se è una base valida
if ( nType != -1) {
// ricavo la dimensione di svuotatura
pCrvTrap->GetCurve( 1)->GetLength( dPocketSize) ;
// ricavo la sua direzione iniziale
Vector3d vtBaseDir ; pCrvCompo->GetCurve( u)->GetStartDir( vtBaseDir) ;
Vector3d vtBaseDir ; pCrvCompo->GetCurve( nU)->GetStartDir( vtBaseDir) ;
// ricavo il suo punto iniziale
Point3d ptBaseStart ; pCrvCompo->GetCurve( u)->GetStartPoint( ptBaseStart) ;
Point3d ptBaseStart ; pCrvCompo->GetCurve( nU)->GetStartPoint( ptBaseStart) ;
// ricavo il suo punto finale
Point3d ptBaseEnd ; pCrvCompo->GetCurve( u)->GetEndPoint( ptBaseEnd) ;
Point3d ptBaseEnd ; pCrvCompo->GetCurve( nU)->GetEndPoint( ptBaseEnd) ;
// cerco il lato chiuso lineare parallelo ad esso e distante circa dPocketSize
for ( int uu = 0 ; uu < pCrvCompo->GetCurveCount() && !bOK ; ++ uu) {
if ( uu == u ||
pCrvCompo->GetCurve( uu)->GetType() != CRV_LINE ||
pCrvCompo->GetCurve( uu)->GetTempProp() != 0)
for ( int nOtherU = 0 ; nOtherU < pCrvCompo->GetCurveCount() && ! bOK ; ++ nOtherU) {
if ( nOtherU == nU ||
pCrvCompo->GetCurve( nOtherU)->GetType() != CRV_LINE ||
pCrvCompo->GetCurve( nOtherU)->GetTempProp() != 0)
continue ;
Vector3d vtSecondBaseDir ; pCrvCompo->GetCurve( uu)->GetStartDir( vtSecondBaseDir) ;
Vector3d vtSecondBaseDir ; pCrvCompo->GetCurve( nOtherU)->GetStartDir( vtSecondBaseDir) ;
if ( ! AreOppositeVectorEpsilon( vtBaseDir, vtSecondBaseDir, 5 * EPS_SMALL))
continue ;
Point3d ptSecondBaseStart ; pCrvCompo->GetCurve( uu)->GetStartPoint( ptSecondBaseStart) ;
Point3d ptSecondBaseStart ; pCrvCompo->GetCurve( nOtherU)->GetStartPoint( ptSecondBaseStart) ;
double dDist = 0. ;
DistPointCurve DPL( ptBaseStart, *pCrvCompo->GetCurve( uu), false) ;
DistPointCurve DPL( ptBaseStart, *pCrvCompo->GetCurve( nOtherU), false) ;
if ( DPL.GetDist( dDist) && abs( dDist - dDiam) < TOL_TRAPEZOID) {
nBase = u ;
nSecondBase = uu ;
nBase = nU ;
nSecondBase = nOtherU ;
if ( ! PreparareTrapezoidTwoBases( pCrvCompo, dDiam, nType, nBase, nSecondBase, bOK, pCrvTrap))
return false ;
}
@@ -3050,7 +3049,8 @@ GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, ICurveComposite* pCrvTr
//----------------------------------------------------
static bool
SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const bool bEvenClosed,
const ICurveComposite* pCrvPocket, const PocketParams& PockParams)
const ICurveComposite* pCrvPocket, const PocketParams& PockParams,
const Point3d& ptRef)
{
// parametri
double dDiam = PockParams.dRad_prec > 0 ? 2 * PockParams.dRad_prec : 2 * PockParams.dRad ;
@@ -3060,10 +3060,18 @@ SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const bool bEvenC
// calcolo gli offset dei lati obliqui
PtrOwner<ICurveLine> pLineS( GetCurveLine( pCrvPocket->GetCurve( bEvenClosed ? 0 : 3)->Clone())) ;
pLineS->SimpleOffset( - dRad) ;
pLineS->Invert() ;
PtrOwner<ICurveLine> pLineE( GetCurveLine( pCrvPocket->GetCurve( bEvenClosed ? 2 : 1)->Clone())) ;
pLineE->SimpleOffset( - dRad) ;
pLineE->Invert() ;
// verifico orientamento delle curve in base al punto di riferimento ( se valido)
double dSqDistS = 0., dSqDistE = 0. ;
if ( ! ptRef.IsValid() ||
( ( DistPointCurve( ptRef, *pCrvPocket->GetCurve( bEvenClosed ? 3 : 0)).GetSqDist( dSqDistS)) &&
( DistPointCurve( ptRef, *pCrvPocket->GetCurve( bEvenClosed ? 1 : 2)).GetSqDist( dSqDistE)) &&
dSqDistS < dSqDistE)) {
pLineS->Invert() ;
pLineE->Invert() ;
}
Point3d ptS, ptE ;
pLineS->GetEndPoint( ptS) ;
@@ -3134,10 +3142,10 @@ CalcTrapezoidSpiralXCoord( const ICurveComposite* pCrvPocket, int nBase, int nSe
double dDiam = PockParams.dRad_prec > 0 ? 2 * PockParams.dRad_prec : 2 * PockParams.dRad ;
double dOffsR = PockParams.dRad_prec > 0 ? PockParams.dRadialOffset_prec : PockParams.dRadialOffset ;
double dRad = 0.5 * dDiam + dOffsR ;
// recupero la curva di interesse
int nCrvId = ( bStart ? nSecondBase : nBase) + 1 ;
int nProp = - 1 ;
int nProp = -1 ;
if ( ! pCrvPocket->GetCurveTempProp( nCrvId, nProp))
return false ;
// se Open
@@ -3417,6 +3425,9 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
// passo in un sistema di riferimento locale avente asse X allineato con uno dei due lati paralleli
// (possibilmente aperto) e centro nel punto iniziale del lato
pCrvPocket->ToLoc( frTrap) ;
Point3d ptRef = P_INVALID ;
if ( PockParams.ptStart.IsValid())
ptRef = GetToLoc( PockParams.ptStart, frTrap) ;
// calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso)
double dLen0, dLen1, dLen2, dLen3, dMaxLarg = 0. ;
@@ -3435,14 +3446,17 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
BBox3d b3Dim ; pCrvPocket->GetBBox( frDim, b3Dim, BBF_EXACT) ;
dMaxLarg = ( vnProp[0] != 0 ? b3Dim.GetDimY() : dPocketSize) ;
}
// calcolo percorso di svuotatura
// se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale
if (( bRealTrap && dMaxLarg > PockParams.dRad * 2 + 10 * EPS_SMALL) &&
((( vnProp[0] != 0 && vnProp[2] != 0) && ( vnProp[3] == 0 && vnProp[1] == 0) && ( max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL)) ||
(( vnProp[1] != 0 && vnProp[3] != 0) && ( vnProp[0] == 0 && vnProp[2] == 0) && ( max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL)))) {
if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, vnProp[0] == 0, pCrvPocket, PockParams)) {
if ( ( bRealTrap && dMaxLarg > PockParams.dRad * 2 + 10 * EPS_SMALL) &&
( ( ( vnProp[0] != TEMP_PROP_CLOSE_EDGE && vnProp[2] != TEMP_PROP_CLOSE_EDGE) &&
( vnProp[3] == TEMP_PROP_CLOSE_EDGE && vnProp[1] == TEMP_PROP_CLOSE_EDGE) &&
( max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL)) ||
( ( vnProp[1] != TEMP_PROP_CLOSE_EDGE && vnProp[3] != TEMP_PROP_CLOSE_EDGE) &&
( vnProp[0] == TEMP_PROP_CLOSE_EDGE && vnProp[2] == TEMP_PROP_CLOSE_EDGE) &&
( max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL)))) {
if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, ( vnProp[0] == TEMP_PROP_CLOSE_EDGE), pCrvPocket, PockParams, ptRef)) {
pMCrv->Clear() ;
return false ;
}
@@ -3452,7 +3466,7 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
double dYCoord ;
// se base principale chiusa
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
dYCoord = 0.5 * dDiam + dOffsR ;
dYCoord = 0.5 * dDiam + dOffsR ;
// se base principale aperta e secondaria chiusa
else if ( pCrvPocket->GetCurve( nSecondBase)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
dYCoord = dPocketSize - 0.5 * dDiam - dOffsR ;
@@ -3463,15 +3477,32 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
// determino le quote coordinate in X inziale e finale
double dXCoordStart = -INFINITO ;
double dXCoordEnd = INFINITO ;
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, true, dYCoord, dXCoordStart,
dPocketSize, PockParams) || dXCoordStart < - INFINITO + 1)
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, true, dYCoord, dXCoordStart, dPocketSize, PockParams) ||
dXCoordStart < - INFINITO + 1)
return false ;
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, false, dYCoord, dXCoordEnd,
dPocketSize, PockParams) || dXCoordEnd > INFINITO - 1)
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, false, dYCoord, dXCoordEnd, dPocketSize, PockParams) ||
dXCoordEnd > INFINITO - 1)
return false ;
if ( dXCoordStart > dXCoordEnd + 500 * EPS_SMALL)
return false ;
// determino se devo invertire la curva dato il punto di riferimento
bool bInvertByRef = false ;
if ( ptRef.IsValid()) {
PtrOwner<ICurve> pCrvRight( pCrvPocket->CopyParamRange( nBase + 1, nSecondBase)) ;
PtrOwner<ICurve> pCrvLeft( pCrvPocket->CopyParamRange( nSecondBase + 1, nBase)) ;
if ( IsNull( pCrvRight) || IsNull( pCrvLeft) ||
! pCrvRight->IsValid() || ! pCrvLeft->IsValid())
return false ;
double dSqDistBase = INFINITO, dSqDistSecondBase = INFINITO, dSqDistLeft = INFINITO, dSqDistRight = INFINITO ;
DistPointCurve( ptRef, *pCrvPocket->GetCurve( nBase)).GetSqDist( dSqDistBase) ;
DistPointCurve( ptRef, *pCrvPocket->GetCurve( nSecondBase)).GetSqDist( dSqDistSecondBase) ;
DistPointCurve( ptRef, *pCrvRight).GetSqDist( dSqDistRight) ;
DistPointCurve( ptRef, *pCrvLeft).GetSqDist( dSqDistLeft) ;
bInvertByRef = ( dSqDistSecondBase < min( {dSqDistBase, dSqDistLeft, dSqDistRight}) ||
dSqDistRight < min( {dSqDistBase, dSqDistSecondBase, dSqDistLeft})) ;
}
// determino gli estremi del segmento di svuotatura
Point3d ptStart( dXCoordStart, dYCoord) ;
Point3d ptEnd( dXCoordEnd, dYCoord) ;
@@ -3491,7 +3522,6 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
if ( ! pLine1->SimpleOffset( - PockParams.dRad - PockParams.dRadialOffset) ||
! pLine3->SimpleOffset( - PockParams.dRad - PockParams.dRadialOffset))
return false ;
Point3d ptS, ptE ;
if ( vtDir3 * X_AX > EPS_SMALL) {
pLine1->GetStartPoint( ptS) ;
@@ -3501,7 +3531,6 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
pLine1->GetEndPoint( ptE) ;
pLine3->GetEndPoint( ptS) ;
}
if ( vnProp[0] != TEMP_PROP_CLOSE_EDGE) {
pMCrv->AddPoint( ptS) ;
if ( vnProp[2] != TEMP_PROP_CLOSE_EDGE)
@@ -3517,34 +3546,37 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
pMCrv->AddLine( ptStart) ;
pMCrv->Invert() ;
}
pMCrv->SetCurveTempProp( 0, TEMP_PROP_OPEN_EDGE) ;
// verifico se invertirla nel caso di un punto di riferimento
if ( bInvertByRef &&
vnProp[0] != TEMP_PROP_CLOSE_EDGE && vnProp[2] != TEMP_PROP_CLOSE_EDGE)
pMCrv->Invert() ;
}
}
// se estremi del segmento differenti, allora il percorso è definito
else {
// creo la linea
if ( ! pMCrv->AddPoint( ptStart))
return true ;
if ( ! pMCrv->AddLine( ptEnd))
return true ;
// aggiustamenti al percorso per rimuovere materiale residuo negli angoli
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE ||
pCrvPocket->GetCurve( nSecondBase)->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) {
Frame3d frOpen ;
bool bSwitch = false ;
// Base principale chiusa e base Secondaria aperta
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) {
// Base Principale chiusa e Base Secondaria aperta o inversione per punto di riferimento
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE ||
bInvertByRef) {
pCrvPocket->ChangeStartPoint( nSecondBase) ;
// oriento il Frame ( ho sempre l'origine nell'estremo superiore del lato aperto)
Vector3d vtDir ; pCrvPocket->GetStartDir( vtDir) ;
Point3d ptORIG ;
Point3d ptOpen ;
if ( vtDir.y > 0)
pCrvPocket->GetCurve( nBase)->GetEndPoint( ptORIG) ;
pCrvPocket->GetFirstCurve()->GetEndPoint( ptOpen) ;
else
pCrvPocket->GetCurve( nBase)->GetStartPoint( ptORIG) ;
frOpen.Set( ptORIG, Z_AX, -X_AX) ;
pCrvPocket->GetFirstCurve()->GetStartPoint( ptOpen) ;
frOpen.Set( ptOpen, Z_AX, -X_AX) ;
if ( ! frOpen.IsValid())
return false ;
pCrvPocket->ToLoc( frOpen) ;
@@ -3552,7 +3584,7 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
pMCrv->Invert() ;
bSwitch = true ;
}
// la Base principale è sempre aperta
if ( pCrvPocket->GetCurve( 3)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE &&
! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, PockParams, true)) {
pMCrv->Clear() ;
@@ -3607,7 +3639,7 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
PtrOwner<ICurveComposite> pCrvBorder( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, 0))) ;
if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid())
return false ;
pCrvBorder->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
pCrvBorder->MergeCurves( 10. * EPS_SMALL, 10. * EPS_ANG_SMALL, true, true) ;
pCrvBorder->SetExtrusion( pSfrChunk->GetNormVersor()) ;
/* SPIRALE EUCLIDEA
@@ -3620,17 +3652,35 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
if ( bOkSpiral) {
// controllo che sia una circonferenza
Point3d ptCen ; double dRad ;
if ( ! OptimizedSpiralCircle( pCrvBorder, 50 * EPS_SMALL, dRad, ptCen, bOkSpiral))
if ( ! OptimizedSpiralCircle( pCrvBorder, 50. * EPS_SMALL, dRad, ptCen, bOkSpiral))
return false ;
// se è una circonferenza
if ( bOkSpiral) {
double dOffs = PockParam.dRad + PockParam.dRadialOffset ;
// se curva tutta Open, allora ingrandisco il raggio
if ( nTempPropRef == TEMP_PROP_OPEN_EDGE)
// se curva tutta Open
if ( nTempPropRef == TEMP_PROP_OPEN_EDGE) {
// ingrandisco il raggio
dRad += 1.05 * PockParam.dRad + PockParam.dRadialOffset ;
// verifico che l'utensile ora non interferisca con la regione limite
if ( PockParam.SfrLimit.IsValid()) {
// definisco il nuovo bordo
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
bOkSpiral = ( ! IsNull( pCrvArc) &&
pCrvArc->Set( ptCen, Z_AX, dRad + PockParam.dRad)) ;
if ( bOkSpiral) {
CRVCVECTOR ccClass ;
bOkSpiral = ( PockParam.SfrLimit.GetCurveClassification( *pCrvArc, EPS_SMALL, ccClass) &&
ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT) ;
// NB. una versione più complessa dovrebbe verificare se la sottrazione tra la
// superficie dell'utensile e la regione limite non genera un'altra circonferenza...
// In questo caso si la sottrazione potrebbe essere trattata come una circonferenza
// chiusa ed essere ancora svotata a spirale...
}
}
}
// se curva chiusa, controllo che il raggio sia compatibile con il primo Offset
else
bOkSpiral = ( dRad - dOffs > 10 * EPS_SMALL) ;
bOkSpiral = ( dRad - dOffs > 10. * EPS_SMALL) ;
if ( bOkSpiral) {
double dIntRad = 0 ;
if ( PockParam.nType == POCKET_SPIRALOUT && PockParam.nLiType == LEAD_IN_HELIX)
@@ -3665,24 +3715,47 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
double dPocketSize ;
int nBase, nSecondBase ;
bool bOkTrap = ( GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) &&
dPocketSize < PockParam.dMaxOptSize + 10 * EPS_SMALL) ;
dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ;
if ( bOkTrap && pCrvTrap->IsValid()) {
pCrvTrap->SetExtrusion( Z_AX) ;
CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, PockParam, pCrvRes, bOkTrap) ;
if ( bOkTrap) {
// calcolo eventuali uscite e ingressi
if ( pCrvRes->GetTempProp( 0) > 0) {
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsStartExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
return false ;
pCrvRes->GetEndDir( vtRef) ;
bool bIsEndExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, true, PockParam.dRad + PockParam.dOpenMinSafe, bIsEndExtended))
return false ;
if ( bIsEndExtended && ! bIsStartExtended)
pCrvRes->Invert() ;
// verifico che tale curva non interferisca con la regione limite
if ( PockParam.SfrLimit.IsValid()) {
double dOffsCheck = PockParam.dRad + PockParam.dRadialOffset - 50. * EPS_SMALL ; // restrittivo per sicurezza
PtrOwner<ISurfFlatRegion> pSfrToolShape( GetSurfFlatRegionFromFatCurve( pCrvRes->Clone(), dOffsCheck, false, false)) ;
bOkTrap = ( ! IsNull( pSfrToolShape) && pSfrToolShape->IsValid()) ;
if ( bOkTrap) {
bOkTrap = ( pSfrToolShape->Intersect( PockParam.SfrLimit) &&
! pSfrToolShape->IsValid()) ;
if ( ! bOkTrap)
pCrvRes->Clear() ;
}
}
if ( bOkTrap) {
// calcolo eventuali uscite e ingressi
if ( pCrvRes->GetTempProp( 0) > 0) {
// Recupero gli estremi della curva corrente e la inverto in base alla Testa
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
Point3d ptE ; pCrvRes->GetEndPoint( ptE) ;
Point3d ptSGlob = GetToGlob( ptS, PockParam.frLocXY) ;
Point3d ptEGlob = GetToGlob( ptE, PockParam.frLocXY) ;
if ( ( PockParam.bAboveHead && ptEGlob.z > ptSGlob.z) ||
( ! PockParam.bAboveHead && ptEGlob.z < ptSGlob.z))
pCrvRes->Invert() ;
if ( PockParam.bInvert)
pCrvRes->Invert() ;
// Calcolo eventuale entrata da fuori
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsStartExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
return false ;
}
else {
if ( PockParam.bInvert)
pCrvRes->Invert() ;
}
}
}
}
@@ -3849,7 +3922,7 @@ GetParamOnOpenCurve( const ICurveComposite* pCompo, const PocketParams& PockPara
//----------------------------------------------------------------------------
static bool
GetPtStartOnOpenEdgeByOrigCurve( const ICurveComposite* pCrvOrig, const PocketParams& PockParams,
GetPtStartOnOpenEdgeByOrigCurve( const Point3d& ptRef, const ICurveComposite* pCrvOrig, const PocketParams& PockParams,
const ICurveComposite* pCrvCompo, Point3d& ptStart, Vector3d& vtMidOut,
bool& bMidOut)
{
@@ -3859,8 +3932,71 @@ GetPtStartOnOpenEdgeByOrigCurve( const ICurveComposite* pCrvOrig, const PocketPa
return false ;
bMidOut = false ;
// cerco il lato aperto più lungo ( sufficientemente lungo)
double dLenRef = ( 2 * PockParams.dRad + 2 * PockParams.dRadialOffset) - 50 * EPS_SMALL ;
// se ho un punto di riferimento, cerco il lato aperto sull'originale più vicino ad essa ( sufficientemente lungo)
if ( ptRef.IsValid()) {
double dSqMinDist = INFINITO ;
int nIndCrv = -1 ;
for ( int i = 0 ; i < pCrvOrig->GetCurveCount() ; ++ i) {
// escludo le sottocurve chiuse
if ( pCrvOrig->GetCurve( i)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
continue ;
// recupero la curva i-esima aperta dalla curva originale
const ICurve* pCrvOpen = pCrvOrig->GetCurve( i) ;
if ( pCrvOpen == nullptr || ! pCrvOpen->IsValid())
return false ;
// ricavo la lunghezza di tale curva
double dLen = 0. ;
pCrvOpen->GetLength( dLen) ;
// se lunghezza accettabile o maggiore della massima trovata
if ( dLen > dLenRef - 10. * EPS_SMALL) {
// verifico la distanza con il punto di riferimento
double dCurrSqDist = 0. ;
if ( DistPointCurve( ptRef, *pCrvOpen).GetSqDist( dCurrSqDist) && dCurrSqDist < dSqMinDist) {
dSqMinDist = dCurrSqDist ;
nIndCrv = i ;
}
}
}
// se ho un indice di curva valido, allora ricavo i valori
if ( nIndCrv != -1) {
// recupero la curva
const ICurve* pCrvOpen = pCrvOrig->GetCurve( nIndCrv) ;
if ( pCrvOpen == nullptr || ! pCrvOpen->IsValid())
return false ;
Point3d ptSTmp ;
Vector3d vtMidOutTmp ;
// ricavo il punto medio e il vettore tangente ad esso associato
if ( pCrvOpen->GetPointD1D2( 0.5, ICurve::FROM_MINUS, ptSTmp, &vtMidOutTmp)) {
// versore d'uscita
vtMidOutTmp.Normalize() ;
vtMidOutTmp.Rotate( Z_AX, 0, -1) ;
ptSTmp += vtMidOutTmp * max( PockParams.dRad - PockParams.dSideStep, 0.) ;
// cerco la sottocurva più vicina a ptSTmp
int nFlag ;
double dMyPar ;
if ( DistPointCurve( ptSTmp, *pCrvCompo).GetParamAtMinDistPoint( 0, dMyPar, nFlag)) {
int nCrv = int( floor( dMyPar)) ;
// recupero tale sottocurva e controllo che anche essa sia OPEN
const ICurve* pMyCrv = pCrvCompo->GetCurve( nCrv) ;
if ( pMyCrv != nullptr && pMyCrv->IsValid() && pMyCrv->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) {
// recupero ptStart
pMyCrv->GetMidPoint( ptStart) ;
// assegno direzione fuori
vtMidOut = vtMidOutTmp ;
// flag per possibile entrata da fuori
bMidOut = true ;
}
}
}
// esco
return true ;
}
}
// se non ho un punto di riferimento valido, o avendolo non si riesce ad entrare dal lato aperto più vicino
// cerco il lato aperto più lungo ( sufficientemente lungo)
for ( int i = 0 ; i < pCrvOrig->GetCurveCount() ; ++ i) {
// escludo le sottocurve chiuse
if ( pCrvOrig->GetCurve( i)->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE)
@@ -3944,7 +4080,7 @@ GetPtStartOnOpenEdgeByPtRef( const Point3d& ptRef, const PocketParams& PockParam
// se non ho trovato nulla, allora cerco un punto iniziale valido su una sottocurva OPEN
if ( nStartCrv == -1 && pCrvOrig != nullptr && pCrvOrig->IsValid()) {
return GetPtStartOnOpenEdgeByOrigCurve( pCrvOrig, PockParams, pCrvCompo, ptStart, vtMidOut, bMidOut) ;
return GetPtStartOnOpenEdgeByOrigCurve( ptRef, pCrvOrig, PockParams, pCrvCompo, ptStart, vtMidOut, bMidOut) ;
}
// se ho trovato la curva più vicina, cerco un punto iniziale valido
else {
@@ -4233,7 +4369,7 @@ SetPtStartForPath( ICurveComposite* pCrvOffs, const PocketParams& PockParams, co
if ( pCrvOrig != nullptr && pCrvOrig->IsValid()) {
// ... e non ho un punto di riferimento, lo cerco sulla curva originale
if ( ! ptEndPrec.IsValid()) {
if ( ! GetPtStartOnOpenEdgeByOrigCurve( pCrvOrig, PockParams, pCrvOffs, ptStart, vtMidOut, bMidOut))
if ( ! GetPtStartOnOpenEdgeByOrigCurve( P_INVALID, pCrvOrig, PockParams, pCrvOffs, ptStart, vtMidOut, bMidOut))
return false ;
}
// ... e ho un punto di riferimento
@@ -4828,7 +4964,7 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const
return false ;
// controllo se la distanza lineare tra i due punti è maggiore della tolleranza...
static double dSqTol = 4 * PockParams.dRad * PockParams.dRad + PockParams.dSideStep * PockParams.dSideStep ;
const double dSqTol = 4 * PockParams.dRad * PockParams.dRad + PockParams.dSideStep * PockParams.dSideStep ;
if ( SqDist( ptStart, ptEnd) > dSqTol)
bSpecial = ( CalcSpecialBoundedSmoothedLink( ptStart, vtStart, ptEnd, vtEnd, PockParams, pMyCrvLink)) ;
if ( ! pMyCrvLink->IsValid() || pMyCrvLink->GetCurveCount() == 0) {
@@ -5917,6 +6053,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
// ricavo le regioni progressive
double dOffsPrec = 0. ;
int nCrvFirstOffs = 0 ;
bool bLastNotValid = false ;
while ( nIter < MAX_ITER) {
// Offset della regione attuale
PtrOwner<ISurfFlatRegion> pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
@@ -5927,6 +6064,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
pSfrOffsVR.Set( pSrfAct->CreateOffsetSurf( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrOffsVR))
return false ;
bLastNotValid = true ;
}
// se primo Offset
@@ -5958,6 +6096,10 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
bool bInsert = true ;
if ( ! CheckIfOffsetIsNecessary( pSrfAct, pCrvCompoBorder, dOffs, dOffsPrec, nIter, PockParams, bInsert))
return false ;
// per evitare di allacciare una curva di regione non svuotata alla prima curva di Offset
// ( quindi avere un entrata nel pieno del grezzo) controllo di non eliminare il secondo Offset
if ( ! bInsert && nChunks == 1 && bLastNotValid)
bInsert = true ;
if ( bInsert) {
// imposto come secondo TempParam il Side di classificazione
pCrvCompoBorder->SetTempParam( j == 0 ? MDS_RIGHT : MDS_LEFT, 1) ;
+1
View File
@@ -16,6 +16,7 @@
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include <algorithm>
using namespace std ;
+45
View File
@@ -26,6 +26,7 @@
#include "/EgtDev/Include/EGkUiUnits.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkCurveByInterp.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#define EIGEN_NO_IO
#include "/EgtDev/Extern/Eigen/Dense"
@@ -2326,3 +2327,47 @@ ResetCurveVoronoi( const ICurve& crvC)
break ;
}
}
//----------------------------------------------------------------------------
bool
GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert)
{
if( ssize( vCrv) == 1)
return true ;
ChainCurves chainCrv ;
// modifico direttamente le curve passate in input
chainCrv.Init( bAllowInvert, dChainTol, ssize( vCrv)) ;
for ( int c = 0 ; c < ssize( vCrv) ; ++c) {
Point3d ptStart, ptEnd ;
Vector3d vtStart, vtEnd ;
vCrv[c]->GetStartPoint( ptStart) ;
vCrv[c]->GetEndPoint( ptEnd) ;
vCrv[c]->GetStartDir( vtStart) ;
vCrv[c]->GetEndDir( vtEnd) ;
chainCrv.AddCurve( 1 + c, ptStart, vtStart, ptEnd, vtEnd) ;
}
INTVECTOR vIds ;
Point3d ptStart = ORIG ;
while ( chainCrv.GetChainFromNear( ptStart, false, vIds)) {
ICurveComposite* pFirstCrv = vCrv[abs(vIds[0]) - 1] ;
for ( int nId : vIds) {
bool bInvert = false ;
if( nId < 0)
bInvert = true ;
nId = abs( nId) - 1 ;
if( bInvert)
vCrv[nId]->Invert() ;
if( ! pFirstCrv->AddCurve( Release( vCrv[nId]), true, dChainTol))
return false ;
}
pFirstCrv->GetEndPoint( ptStart) ;
}
// elimino gli elementi del vettore che non contengono più curve
int c = ssize( vCrv) ;
while( c > -1) {
if( IsNull( vCrv[c]))
vCrv.erase( vCrv.begin() + c) ;
--c ;
}
return true ;
}
+1
View File
@@ -35,3 +35,4 @@ bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ;
+12 -5
View File
@@ -889,14 +889,21 @@ CurveComposite::Validate( void)
//----------------------------------------------------------------------------
bool
CurveComposite::TestClosure( void)
CurveComposite::TestClosure( double dLinTol)
{
// se non è chiusa, esco subito
if ( ! IsClosed())
// se non valida o vuota, esco subito
if ( m_nStatus != OK || m_CrvSmplS.empty())
return true ;
// se non è chiusa entro la tolleranza, esco subito
Point3d ptStart, ptEnd ;
if ( ! m_CrvSmplS.front()->GetStartPoint( ptStart) ||
! m_CrvSmplS.back()->GetEndPoint( ptEnd) ||
! AreSamePointEpsilon( ptStart, ptEnd, dLinTol))
return true ;
// se singola retta, esco subito
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_LINE)
return true ;
// verifico ed eventualmente aggiusto coincidenza punti estremi
Point3d ptStart ; m_CrvSmplS.front()->GetStartPoint( ptStart) ;
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
// se distanza superiore al limite ridotto forzo i punti a coincidere
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
// se un solo arco
+1 -1
View File
@@ -198,13 +198,13 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
return *this ; }
bool RelocateFrom( CurveComposite& ccSrc) ;
bool GetApproxLength( double& dLen) const ;
bool TestClosure( double dLinTol = EPS_SMALL) ;
Voronoi* GetVoronoiObject( void) const ;
void ResetVoronoiObject( void) const ;
private :
bool CopyFrom( const CurveComposite& ccSrc) ;
bool Validate( void) ;
bool TestClosure( void) ;
bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ;
BIN
View File
Binary file not shown.
+1
View File
@@ -322,6 +322,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="IntersLineVolZmap.cpp" />
<ClCompile Include="IntersPlaneVolZmap.cpp" />
<ClCompile Include="IntersLineSurfBez.cpp" />
<ClCompile Include="Trimming.cpp" />
<ClCompile Include="MultiGeomDB.cpp" />
<ClCompile Include="SurfTriMeshOffset.cpp" />
<ClCompile Include="VolZmapOffset.cpp" />
+6
View File
@@ -55,6 +55,9 @@
<Filter Include="File di origine\GeoCollisionDetection">
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
</Filter>
<Filter Include="File di origine\GeoStriping">
<UniqueIdentifier>{54901321-08f6-4428-80c7-a1f859136a32}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Vector3d.cpp">
@@ -561,6 +564,9 @@
<ClCompile Include="IntersCurvePlane.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
<ClCompile Include="Trimming.cpp">
<Filter>File di origine\GeoStriping</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
+2 -2
View File
@@ -613,7 +613,7 @@ GeomDB::GetGdbObj( int nId) const
// radice
else if ( nId == GDB_ID_ROOT)
return &m_GrpRadix ;
// un nodo qualubque
// un nodo qualunque
else
return m_IdManager.FindObj( nId) ;
}
@@ -660,7 +660,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLo
return false ;
}
// inserisco come figlio, in testa alla lista del padre
else if ( nSonBeforeAfter == GDB_FIRST_SON){
else if ( nSonBeforeAfter == GDB_FIRST_SON) {
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
if ( pGroup == nullptr)
return false ;
+2
View File
@@ -31,6 +31,8 @@ class GeomDB : public IGeomDB
friend class GdbGeo ;
friend int CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
friend int CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
friend int DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId) ;
friend int DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp) ;
public :
~GeomDB( void) override ;
+5 -1
View File
@@ -371,12 +371,16 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
// caso NULL-NULL per corrente di prima curva
else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
if ( m_Info[i].IciB[ki].dU > m_Info[j].IciB[kj].dU + EPS_PARAM)
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
EraseCurrentInfo( i, j) ;
}
// caso NULL-NULL per precedente di prima curva
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
if ( m_Info[j].IciB[kj].dU < m_Info[i].IciB[ki].dU - EPS_PARAM)
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
EraseOtherInfo( i, j) ;
}
+39 -15
View File
@@ -47,7 +47,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
// ciclo sulle curve per verificare se da approssimare
for ( int i = 0 ; i < 2 ; ++ i) {
// se curva è arco da approssimare oppure è curva di Bezier
// se curva è arco da approssimare oppure è curva di Bezier
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
m_pCurve[i]->GetType() == CRV_BEZIER) {
// approssimo con rette
@@ -127,7 +127,7 @@ IntersCurveCurve::IsArcToApprox( const ICurve& Curve)
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
if ( pArc == nullptr)
return false ;
// verifico se non è nel piano XY o ha più di un giro al centro
// verifico se non è nel piano XY o ha più di un giro al centro
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
}
@@ -252,10 +252,10 @@ IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve&
bool
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
{
// se non ci sono intersezioni, non va fatto alcunché
// se non ci sono intersezioni, non va fatto alcunché
if ( m_Info.empty())
return true ;
// se le curve originali non sono state approssimate, non va fatto alcunché
// se le curve originali non sono state approssimate, non va fatto alcunché
if ( ! bAdjCrvA && ! bAdjCrvB)
return true ;
// procedo ad aggiustare
@@ -389,11 +389,11 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
return false ;
// ricerca del punto più vicino tra le intersezioni singole
// ricerca del punto più vicino tra le intersezioni singole
bool bFound = false ;
double dMinSqDist = SQ_INFINITO ;
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
// se è un'intersezione singola
// se è un'intersezione singola
if ( ! m_Info[i].bOverlap) {
// faccio la verifica sul punto
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
@@ -458,7 +458,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
// se esiste almeno una intersezione
if ( m_nIntersCount >= 1)
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
// altrimenti la curva è completamente interna oppure completamente esterna
// altrimenti la curva è completamente interna oppure completamente esterna
else
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
}
@@ -475,7 +475,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
// se esiste almeno una intersezione
if ( m_nIntersCount >= 1)
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
// altrimenti la curva è completamente interna oppure completamente esterna
// altrimenti la curva è completamente interna oppure completamente esterna
else
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
}
@@ -540,7 +540,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
double dU2 = Info[j].IciA[1].dU ;
if ( dU2 < dU1 && pCurve->IsClosed())
dU2 += dEndPar ;
// se cade nell'intervallo è da saltare
// se cade nell'intervallo è da saltare
if ( Info[i].IciA[0].dU >= dU1 && Info[i].IciA[0].dU <= dU2) {
bToSkip = true ;
break ;
@@ -559,7 +559,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
double dCurrPar = dStartPar ;
double dCurrLen = 0 ;
double dEndLen ; pCurve->GetLength( dEndLen) ;
// se è chiusa, recupero come finisce
// se è chiusa, recupero come finisce
if ( pCurve->IsClosed()) {
if ( ! InfoCorr[nNumInters-1].bOverlap)
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
@@ -577,7 +577,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
}
// costruisco il vettore delle classificazioni
for ( int i = 0 ; i < nNumInters ; ++ i) {
// se è definito un tratto precedente
// se è definito un tratto precedente
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
// verifico che la definizione sul tratto sia omogenea e valida
@@ -599,7 +599,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
// altrimenti, salvo il tipo
else
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
// se è definito un tratto in sovrapposizione
// se è definito un tratto in sovrapposizione
if ( InfoCorr[i].bOverlap) {
// assegno i dati
CrvClass segClass ;
@@ -639,7 +639,7 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
double dStartParB, dEndParB ;
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
return false ;
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
BBox3d boxCrvA, boxCrvB ;
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
! pCurveB->GetLocalBBox( boxCrvB))
@@ -682,13 +682,37 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
IntersCurveCurve iCC( clLine, *pCurveB) ;
// dichiaro la classe della curva per default
int nClass = CRVC_OUT ;
// se c'è almeno una intersezione
// se c'è almeno una intersezione
if ( iCC.GetIntersCount() > 0) {
// se quanto precede la prima intersezione è interno, allora la curva è interna
// se quanto precede la prima intersezione è interno, allora la curva è interna
IntCrvCrvInfo aInfo ;
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
nClass = CRVC_IN ;
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
nClass = CRVC_OUT ;
else if ( aInfo.IciA[0].nPrevTy == ICCT_NULL) {
// se il primo punto scelto non va bene allora ne cerco uno che mi dia informazioni sull'essere interno o esterno
CurveLine clLine ;
Point3d ptNewChoice ; pCurveA->GetPointD1D2( 0.25, ICurve::FROM_MINUS, ptNewChoice) ;
if ( ! clLine.SetPDL( ptNewChoice, 0, dLen))
return false ;
// calcolo l'intersezione
IntersCurveCurve iCC( clLine, *pCurveB) ;
if ( iCC.GetIntersCount() > 0) {
// se quanto precede la prima intersezione è interno, allora la curva è interna
IntCrvCrvInfo aInfo ;
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
nClass = CRVC_IN ;
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
nClass = CRVC_OUT ;
else
return false ; // se arrivo qui potrei ritentare la ricerca
}
else
return false ;
}
}
// altrimenti sono esterni tra loro
else {
+30
View File
@@ -159,6 +159,36 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
// flag per segmenti che si allontanano significativamente
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
// analisi casi speciali di quasi parallelismo
// segmento sovrapposto all'altro
double dDist1, dDist2 ;
if ( nS1Side == 0 || nE1Side == 0 || nS1Side == nE1Side) {
dDist1 = CrossXY( ptS1 - ptS2, vtDir2) ;
dDist2 = CrossXY( ptE1 - ptS2, vtDir2) ;
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen2XY) {
bParallel = true ;
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
}
}
else if ( nS2Side == 0 || nE2Side == 0 || nS2Side == nE2Side) {
dDist1 = CrossXY( ptS2 - ptS1, vtDir1) ;
dDist2 = CrossXY( ptE2 - ptS1, vtDir1) ;
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen1XY) {
bParallel = true ;
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
}
}
// estremità sovrapposte di poco
if ( ! bParallel && abs( dCrossXY) < ( 0.1 * DEGTORAD) * ( dLen1XY * dLen2XY)) {
if (( nS1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) ||
( nS1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) ||
( nE1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptE1, ptS2, 2 * EPS_SMALL)) ||
( nE1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptE1, ptE2, 2 * EPS_SMALL))) {
bParallel = true ;
bFarEnds = false ;
}
}
// se non sono paralleli e si allontanano tra loro abbastanza
if ( ! bParallel && bFarEnds) {
// posizioni parametriche dell'intersezione sulle linee
+102 -4
View File
@@ -23,9 +23,6 @@ using namespace std ;
static int
CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
{
// verifico i puntatori ai GeomDB
if ( pSouGDB == nullptr || pDstGDB == nullptr)
return GDB_ID_NULL ;
// recupero l'oggetto da copiare dal GeomDB sorgente
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
if ( IsNull( pGObj))
@@ -109,7 +106,7 @@ CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, i
nSonNewId = CopyGeoObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
// se altrimenti è un gruppo
else if ( nSonSouType == GDB_TY_GROUP)
nSonNewId = CopyGroupObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
nSonNewId = CopyGroupObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
// se copia non riuscita, esco con errore
if ( nSonNewId == GDB_ID_NULL)
return GDB_ID_NULL ;
@@ -129,6 +126,9 @@ Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nR
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
if ( pSouGDB == nullptr || pDstGDB == nullptr)
return GDB_ID_NULL ;
// il sorgente non può essere il gruppo radice
if ( nSouId == GDB_ID_ROOT)
return GDB_ID_NULL ;
// nuovo identificativo oggetto destinazione
int nNewId = GDB_ID_NULL ;
// recupero il tipo di oggetto sorgente
@@ -158,3 +158,101 @@ CopyGlob( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, in
{
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, true) ;
}
//----------------------------------------------------------------------------
static int
DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId)
{
// recupero l'oggetto da copiare dal GeomDB sorgente
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
if ( IsNull( pGObj))
return GDB_ID_NULL ;
// lo inserisco nel GeomDB destinazione
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, GDB_LAST_SON, Release( pGObj)) ;
if ( nNewId != nDestId) {
pDstGDB->Erase( nNewId) ;
return GDB_ID_NULL ;
}
// copio le caratteristiche non geometriche
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
pDstGDB->Erase( nNewId) ;
return GDB_ID_NULL ;
}
return nNewId ;
}
//----------------------------------------------------------------------------
static int
DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp)
{
int nNewId = GDB_ID_ROOT ;
if ( nSouId != GDB_ID_ROOT) {
// recupero il riferimento del gruppo
Frame3d frFrame = *( pSouGDB->GetGroupFrame( nSouId)) ;
// inserisco un nuovo gruppo nel GeomDB destinazione
nNewId = pDstGDB->InsertGroup( nDestId, nRefId, GDB_LAST_SON, frFrame) ;
if ( nNewId != nSouId) {
pDstGDB->Erase( nNewId) ;
return GDB_ID_NULL ;
}
// copio le caratteristiche non geometriche
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
pDstGDB->Erase( nNewId) ;
return GDB_ID_NULL ;
}
}
// copio gli eventuali figli
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
while ( nSonSouId != GDB_ID_NULL) {
// verifico se non richiesto di saltare i temporanei oppure non lo è
int nLevel ;
if ( ! bSkipTemp || ! pSouGDB->GetLevel( nSonSouId, nLevel) || nLevel != GDB_LV_TEMP) {
// nuovo identificativo oggetto destinazione
int nSonNewId = GDB_ID_NULL ;
// recupero il tipo di oggetto sorgente
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
// se l'oggetto da copiare è geometrico
if ( nSonSouType == GDB_TY_GEO)
nSonNewId = DuplicateGeoObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId) ;
// se altrimenti è un gruppo
else if ( nSonSouType == GDB_TY_GROUP)
nSonNewId = DuplicateGroupObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId, bSkipTemp) ;
// se copia non riuscita, esco con errore
if ( nSonNewId != nSonSouId)
return GDB_ID_NULL ;
}
// passo al figlio successivo
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
}
return nNewId ;
}
//----------------------------------------------------------------------------
bool
DuplicateGeomDB( IGeomDB* pSouGeomDB, IGeomDB* pDestGeomDB, bool bSkipTemp)
{
// adatto e verifico i GeomDB
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
if ( pSouGDB == nullptr || pDstGDB == nullptr)
return false ;
// verifico che la destinazione sia vuota
if ( pDstGDB->GetFirstInGroup( GDB_ID_ROOT) != GDB_ID_NULL)
return false ;
// eseguo la copia di tutto (se richiesto salto gli oggetti temporanei)
return ( DuplicateGroupObj( pSouGDB, GDB_ID_ROOT, pDstGDB, GDB_ID_ROOT, GDB_ID_ROOT, bSkipTemp) != GDB_ID_NULL) ;
}
+63 -74
View File
@@ -17,6 +17,7 @@
#include "NgeKeyW.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Extern/zlib/Include/zlib.h"
using namespace std ;
@@ -34,8 +35,12 @@ NgeReader::Init( const string& sFileIn)
break ;
case NGE_BINARY :
m_bBinary = true ;
m_InFile.open( stringtoW( sFileIn), ios::in | ios::binary, _SH_DENYWR) ;
return ( ! m_InFile.fail()) ;
m_InFile = gzopen_w( stringtoW( sFileIn), "rb") ;
if ( m_InFile == nullptr)
return false ;
const int DIM_BUFFER = 65536 ;
gzbuffer( m_InFile, DIM_BUFFER) ;
return true ;
break ;
}
return false ;
@@ -46,10 +51,12 @@ bool
NgeReader::Close( void)
{
if ( m_bBinary) {
bool bOk = ( m_InFile.good() && m_InFile.is_open()) ;
if ( m_InFile.is_open())
m_InFile.close() ;
return bOk ;
if ( m_InFile != nullptr) {
bool bOk = ( gzclose( m_InFile) == Z_OK) ;
m_InFile = nullptr ;
return bOk ;
}
return true ;
}
else
return m_Scan.Terminate() ;
@@ -59,31 +66,24 @@ NgeReader::Close( void)
int
NgeReader::NgeType( const string& sFile)
{
// apertura del file di ingresso
ifstream InFile ;
InFile.open( stringtoW( sFile), ios::in | ios::binary) ;
if ( InFile.fail())
// apertura file
gzFile_s* InFile = gzopen_w( stringtoW( sFile), "rb") ;
if ( InFile == nullptr)
return NGE_ERROR ;
// lettura dei primi 31 byte
char cBuff[32] ;
InFile.read( cBuff, 31) ;
cBuff[InFile.gcount()] = '\0' ;
// chiusura del file
InFile.close() ;
// verifico se file compresso (gz)
if ( cBuff[0] == '\x1F' && cBuff[1] == '\x8B')
return NGE_ASCII ;
// verifico se iniziano con "START"
string sBuff = cBuff ;
size_t nPos = sBuff.find( "START") ;
if ( nPos != string::npos && nPos < 10)
return NGE_ASCII ;
else
// lettura dei primi caratteri
char szBuff[9] = "\0\0\0\0\0\0\0\0" ;
int nLen = gzread( InFile, &szBuff, 8) ;
if ( gzclose( InFile) != Z_OK || nLen == Z_ERRNO)
return NGE_ERROR ;
// se binario
if ( szBuff[0] == '\x0F' && szBuff[1] == '\x0F')
return NGE_BINARY ;
// se testo
string sBuff{ szBuff} ;
if ( sBuff.find( "START") != string::npos)
return NGE_ASCII ;
// altrimenti errore
return NGE_ERROR ;
}
//----------------------------------------------------------------------------
@@ -91,7 +91,7 @@ int
NgeReader::GetCurrPos( void)
{
if ( m_bBinary)
return int( m_InFile.tellg()) ;
return int( gztell( m_InFile)) ;
else
return m_Scan.GetCurrLineNbr() ;
}
@@ -131,10 +131,9 @@ bool
NgeReader::ReadUchar( unsigned char& ucVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &ucVal, sizeof( ucVal)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &ucVal, sizeof( ucVal)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -154,10 +153,9 @@ bool
NgeReader::ReadBool( bool& bVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &bVal, sizeof( bVal)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &bVal, sizeof( bVal)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -173,10 +171,9 @@ bool
NgeReader::ReadInt( int& nVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &nVal, sizeof( nVal)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -203,10 +200,9 @@ bool
NgeReader::ReadDouble( double& dVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &dVal, sizeof( dVal)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &dVal, sizeof( dVal)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -222,10 +218,9 @@ bool
NgeReader::ReadVector( Vector3d& vtV, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &vtV.v, sizeof( vtV.v)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &vtV.v, sizeof( vtV.v)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -241,10 +236,9 @@ bool
NgeReader::ReadPoint( Point3d& ptP, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -260,11 +254,10 @@ bool
NgeReader::ReadPointW( Point3d& ptP, double& dW, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
m_InFile.read( (char*) &dW, sizeof( dW)) ;
return m_InFile.good() ;
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO &&
gzread( m_InFile, &dW, sizeof( dW)) != Z_ERRNO) ;
}
else {
// recupero il token
@@ -280,17 +273,13 @@ bool
NgeReader::ReadFrame( Frame3d& frF, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
Point3d ptOrig ;
m_InFile.read( (char*) &ptOrig.v, sizeof( ptOrig.v)) ;
Vector3d vtDirX ;
m_InFile.read( (char*) &vtDirX.v, sizeof( vtDirX.v)) ;
Vector3d vtDirY ;
m_InFile.read( (char*) &vtDirY.v, sizeof( vtDirY.v)) ;
Vector3d vtDirZ ;
m_InFile.read( (char*) &vtDirZ.v, sizeof( vtDirZ.v)) ;
if ( ! m_InFile.good())
Point3d ptOrig ; Vector3d vtDirX, vtDirY, vtDirZ ;
if ( gzread( m_InFile, &ptOrig.v, sizeof( ptOrig.v)) == Z_ERRNO ||
gzread( m_InFile, &vtDirX.v, sizeof( vtDirX.v)) == Z_ERRNO ||
gzread( m_InFile, &vtDirY.v, sizeof( vtDirY.v)) == Z_ERRNO ||
gzread( m_InFile, &vtDirZ.v, sizeof( vtDirZ.v)) == Z_ERRNO)
return false ;
return frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ;
}
@@ -308,18 +297,20 @@ bool
NgeReader::ReadString( string& sVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( m_InFile == nullptr)
return false ;
const int MAX_STR_DIM = 65535 ;
if ( ! m_InFile.is_open())
return false ;
int nDim ;
m_InFile.read( (char*) &nDim, sizeof( nDim)) ;
if ( nDim > MAX_STR_DIM || ! m_InFile.good())
if ( gzread( m_InFile, &nDim, sizeof( nDim)) == Z_ERRNO || nDim > MAX_STR_DIM)
return false ;
if ( nDim == 0) {
sVal = "" ;
return true ;
}
char* szBuff = new( nothrow) char[ nDim + 1] ;
if ( szBuff == nullptr)
return false ;
m_InFile.read( szBuff, nDim) ;
if ( ! m_InFile.good()) {
if ( gzread( m_InFile, szBuff, nDim) == Z_ERRNO) {
delete[] szBuff ;
return false ;
}
@@ -348,12 +339,11 @@ NgeReader::ReadKey( int& nKey)
return true ;
}
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
// leggo il dato
int nVal ;
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
if ( ! m_InFile.good())
if ( gzread( m_InFile, &nVal, sizeof( nVal)) == Z_ERRNO)
return false ;
// ricavo l'indice
for ( int i = 0 ; i <= NGE_LAST_ID ; ++ i) {
@@ -386,11 +376,10 @@ bool
NgeReader::ReadCol( Color& cCol, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_InFile.is_open())
if ( m_InFile == nullptr)
return false ;
unsigned char ucCol[4] ;
m_InFile.read( (char*) &ucCol, sizeof( ucCol)) ;
if ( ! m_InFile.good())
if ( gzread( m_InFile, &ucCol, sizeof( ucCol)) == Z_ERRNO)
return false ;
cCol.Set( ucCol[0], ucCol[1], ucCol[2], ucCol[3]) ;
return true ;
+7 -5
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
// EgalTech 2014-2025
//----------------------------------------------------------------------------
// File : NgeReader.h Data : 14.04.14 Versione : 1.5d5
// File : NgeReader.h Data : 29.12.25 Versione : 2.7l6
// Contenuto : Dichiarazione della classe NgeReader.
//
//
@@ -18,14 +18,16 @@
#include "/EgtDev/Include/EGkColor.h"
#include "/EgtDev/Include/EGnScanner.h"
#include "/EgtDev/Include/EgtStringBase.h"
#include <fstream>
struct gzFile_s ;
//----------------------------------------------------------------------------
class NgeReader
{
public :
NgeReader( void)
: m_iPosStart( std::string::npos), m_bUngetKey( false), m_nFileVer() {}
: m_bBinary( false), m_InFile( nullptr), m_iPosStart( std::string::npos),
m_bUngetKey( false), m_nLastKey(), m_nFileVer() {}
~NgeReader( void)
{ Close() ; }
bool Init( const std::string& sFileIn) ;
@@ -60,7 +62,7 @@ class NgeReader
private :
bool m_bBinary ;
// per file binari
std::ifstream m_InFile ;
gzFile_s* m_InFile ;
// per file ASCII
Scanner m_Scan ;
std::string::size_type m_iPosStart ;
+64 -84
View File
@@ -23,23 +23,23 @@
using namespace std ;
//----------------------------------------------------------------------------
inline bool
WriteStringOutTxt( gzFile OutTxtFile, const char* szVal, const char* szSep, bool bEndL)
static bool
WriteStringOutTxt( gzFile OutFile, const char* szVal, const char* szSep, bool bEndL)
{
// verifico apertura file
if ( OutTxtFile == nullptr)
if ( OutFile == nullptr)
return false ;
// scrivo stringa
if ( gzputs( OutTxtFile, szVal) == Z_ERRNO)
if ( gzputs( OutFile, szVal) == Z_ERRNO)
return false ;
// se fornito, scrivo separatore
if ( szSep != nullptr && szSep[0] != '\0') {
if ( gzputs( OutTxtFile, szSep) == Z_ERRNO)
if ( gzputs( OutFile, szSep) == Z_ERRNO)
return false ;
}
// se richiesto, scrivo fine linea
if ( bEndL) {
if ( gzputs( OutTxtFile, "\r\n") == Z_ERRNO)
if ( gzputs( OutFile, "\r\n") == Z_ERRNO)
return false ;
}
return true ;
@@ -50,25 +50,22 @@ bool
NgeWriter::Init( const string& sFileOut, int nFlag)
{
// salvo tipo file
m_bBinary = ( nFlag == GDB_SV_BIN) ;
m_bBinary = ( nFlag == GDB_SV_BIN || nFlag == GDB_SV_CMPBIN) ;
// apertura del file di uscita
if ( m_bBinary) {
m_OutBinFile.open( stringtoW( sFileOut), ios::out | ios::binary, _SH_DENYWR) ;
return m_OutBinFile.good() ;
if ( nFlag == GDB_SV_TXT || nFlag == GDB_SV_BIN) {
m_OutFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
return ( m_OutFile != nullptr) ;
}
else {
if ( nFlag == GDB_SV_TXT)
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
else // GDB_SV_CMPTXT
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wb") ;
if ( m_OutTxtFile == nullptr)
else { // GDB_SV_CMPTXT o GDB_SV_CMPBIN
m_OutFile = gzopen_w( stringtoW( sFileOut), "wb") ;
if ( m_OutFile == nullptr)
return false ;
const int DIM_BUFFER = 65536 ;
if ( gzbuffer( m_OutTxtFile, DIM_BUFFER) != Z_OK)
if ( gzbuffer( m_OutFile, DIM_BUFFER) != Z_OK)
return false ;
const int COMPR_LEVEL = 3 ; // 0 = no compression ... 9 = max compression
if ( gzsetparams( m_OutTxtFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
if ( gzsetparams( m_OutFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
return false ;
return true ;
}
@@ -78,20 +75,12 @@ NgeWriter::Init( const string& sFileOut, int nFlag)
bool
NgeWriter::Close( void)
{
if ( m_bBinary) {
bool bOk = ( m_OutBinFile.good() && m_OutBinFile.is_open()) ;
if ( m_OutBinFile.is_open())
m_OutBinFile.close() ;
if ( m_OutFile != nullptr) {
bool bOk = ( gzclose( m_OutFile) == Z_OK) ;
m_OutFile = nullptr ;
return bOk ;
}
else {
if ( m_OutTxtFile != nullptr) {
bool bOk = ( gzclose( m_OutTxtFile) == Z_OK) ;
m_OutTxtFile = nullptr ;
return bOk ;
}
return true ;
}
return true ;
}
//----------------------------------------------------------------------------
@@ -99,13 +88,12 @@ bool
NgeWriter::WriteUchar( unsigned char ucVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &ucVal, sizeof( ucVal)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &ucVal, sizeof( ucVal)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( ucVal).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( ucVal).c_str(), szSep, bEndL) ;
}
}
@@ -114,13 +102,12 @@ bool
NgeWriter::WriteBool( bool bVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &bVal, sizeof( bVal)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &bVal, sizeof( bVal)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( bVal).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( bVal).c_str(), szSep, bEndL) ;
}
}
@@ -129,13 +116,12 @@ bool
NgeWriter::WriteInt( int nVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &nVal, sizeof( nVal)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &nVal, sizeof( nVal)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( nVal).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( nVal).c_str(), szSep, bEndL) ;
}
}
@@ -144,13 +130,12 @@ bool
NgeWriter::WriteDouble( double dVal, const char* szSep, bool bEndL, int nPrec)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &dVal, sizeof( dVal)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &dVal, sizeof( dVal)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
}
}
@@ -159,15 +144,14 @@ bool
NgeWriter::WriteString( const string& sVal, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
int nDim = int( sVal.size()) ;
m_OutBinFile.write( (char*) &nDim, sizeof( nDim)) ;
m_OutBinFile.write( sVal.c_str(), sVal.size()) ;
return m_OutBinFile.good() ;
int nDim = ssize( sVal) ;
return ( gzwrite( m_OutFile, &nDim, sizeof( nDim)) > 0 &&
( nDim == 0 || gzwrite( m_OutFile, sVal.c_str(), sVal.size()) > 0)) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, sVal.c_str(), szSep, bEndL) ;
}
}
@@ -176,13 +160,12 @@ bool
NgeWriter::WriteVector( const Vector3d& vtV, const char* szSep, bool bEndL, int nPrec)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &vtV.v, sizeof( vtV.v)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &vtV.v, sizeof( vtV.v)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
}
}
@@ -191,13 +174,12 @@ bool
NgeWriter::WritePoint( const Point3d& ptP, const char* szSep, bool bEndL, int nPrec)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
}
}
@@ -206,14 +188,13 @@ bool
NgeWriter::WritePointW( const Point3d& ptP, double dW, const char* szSep, bool bEndL, int nPrecP, int nPrecW)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
m_OutBinFile.write( (char*) &dW, sizeof( dW)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0 &&
gzwrite( m_OutFile, &dW, sizeof( dW)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
}
}
@@ -222,16 +203,15 @@ bool
NgeWriter::WriteFrame( const Frame3d& frF, const char* szSep, bool bEndL, int nPrecP, int nPrecV)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &frF.Orig().v, sizeof( frF.Orig().v)) ;
m_OutBinFile.write( (char*) &frF.VersX().v, sizeof( frF.VersX().v)) ;
m_OutBinFile.write( (char*) &frF.VersY().v, sizeof( frF.VersY().v)) ;
m_OutBinFile.write( (char*) &frF.VersZ().v, sizeof( frF.VersZ().v)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &frF.Orig().v, sizeof( frF.Orig().v)) > 0 &&
gzwrite( m_OutFile, &frF.VersX().v, sizeof( frF.VersX().v)) > 0 &&
gzwrite( m_OutFile, &frF.VersY().v, sizeof( frF.VersY().v)) > 0 &&
gzwrite( m_OutFile, &frF.VersZ().v, sizeof( frF.VersZ().v)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
}
}
@@ -243,13 +223,12 @@ NgeWriter::WriteKey( int nKey)
return false ;
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
m_OutBinFile.write( (char*) &NgeBinKeyW[nKey], sizeof( int)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, &NgeBinKeyW[nKey], sizeof( int)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
return WriteStringOutTxt( m_OutFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
}
}
@@ -258,18 +237,17 @@ bool
NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
{
if ( m_bBinary) {
if ( ! m_OutBinFile.is_open())
if ( m_OutFile == nullptr)
return false ;
unsigned char ucCol[4] ;
ucCol[0] = cCol.GetIntRed() ;
ucCol[1] = cCol.GetIntGreen() ;
ucCol[2] = cCol.GetIntBlue() ;
ucCol[3] = cCol.GetIntAlpha() ;
m_OutBinFile.write( (char*) ucCol, sizeof( ucCol)) ;
return m_OutBinFile.good() ;
return ( gzwrite( m_OutFile, ucCol, sizeof( ucCol)) > 0) ;
}
else {
return WriteStringOutTxt( m_OutTxtFile, ToString( cCol).c_str(), szSep, bEndL) ;
return WriteStringOutTxt( m_OutFile, ToString( cCol).c_str(), szSep, bEndL) ;
}
}
@@ -277,9 +255,11 @@ NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
bool
NgeWriter::WriteRemark( const string& sVal)
{
if ( m_bBinary)
if ( m_bBinary) {
return true ;
else
return ( WriteStringOutTxt( m_OutTxtFile, "//", nullptr, false) &&
WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), nullptr, true)) ;
}
else {
return ( WriteStringOutTxt( m_OutFile, "//", nullptr, false) &&
WriteStringOutTxt( m_OutFile, sVal.c_str(), nullptr, true)) ;
}
}
+5 -9
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
// EgalTech 2014-2025
//----------------------------------------------------------------------------
// File : NgeWriter.h Data : 12.04.14 Versione : 1.5d5
// File : NgeWriter.h Data : 29.12.25 Versione : 2.7l6
// Contenuto : Dichiarazione della classe NgeWriter.
//
//
@@ -16,7 +16,6 @@
#include "NgeConst.h"
#include "/EgtDev/Include/EGkPoint3d.h"
#include "/EgtDev/Include/EGkColor.h"
#include <fstream>
struct gzFile_s ;
@@ -24,7 +23,7 @@ struct gzFile_s ;
class NgeWriter
{
public :
NgeWriter( void) : m_bBinary( false), m_OutTxtFile( nullptr) {}
NgeWriter( void) : m_bBinary( false), m_OutFile( nullptr) {}
~NgeWriter( void)
{ Close() ; }
bool Init( const std::string& sFileOut, int nFlag) ;
@@ -44,9 +43,6 @@ class NgeWriter
bool WriteRemark( const std::string& sVal /* bEndL = true*/) ;
private :
bool m_bBinary ;
// per file binari
std::ofstream m_OutBinFile ;
// per file ASCII
gzFile_s* m_OutTxtFile ;
bool m_bBinary ;
gzFile_s* m_OutFile ;
} ;
+3 -3
View File
@@ -775,7 +775,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
//----------------------------------------------------------------------------
bool
PolyLine::RemoveAlignedPoints( double dToler)
PolyLine::RemoveAlignedPoints( double dToler, bool bStartEnd)
{
// se non ci sono almeno 3 punti, esco subito
if ( m_lUPoints.size() < 3)
@@ -825,8 +825,8 @@ PolyLine::RemoveAlignedPoints( double dToler)
// ordino in senso crescente
sort( vInd.begin(), vInd.end()) ;
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
if ( IsClosed() && vInd.size() >= 4) {
// se richiesto e chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
if ( bStartEnd && IsClosed() && vInd.size() >= 4) {
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[int(vInd.size())-2]].first).IsEpsilon( dToler)) {
vInd.erase( vInd.begin()) ;
vInd.back() = vInd.front() ;
+22 -14
View File
@@ -172,9 +172,9 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
return true ;
}
}
else if ( ( Inters.nILTT == ILTT_VERT || Inters.nILTT == ILTT_EDGE || Inters.nILTT == ILTT_IN) && Inters.dCosDN > EPS_ZERO)
else if ( ( Inters.nILTT == ILTT_VERT || Inters.nILTT == ILTT_EDGE || Inters.nILTT == ILTT_IN) && Inters.dCosDN > EPS_ZERO)
dElev = max( dElev, Inters.dU) ;
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
dElev = max( dElev, Inters.dU2) ;
}
}
@@ -206,22 +206,30 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
continue ;
// calcolo il segmento di linea
CurveLine clLine ;
CurveLine clLine ;
if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
return false ;
// l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
IntersCurveCurve intLL( clLine, ccLoop) ;
IntCrvCrvInfo aInfo ;
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
if ( aInfo.bOverlap)
dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
// se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
dElev = max( dElev, vEdges[i].first.z) ;
// se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
dElev = max( dElev, vEdges[i].second.z) ;
if ( intLL.GetIntersCount() == 0) {
Point3d ptM = Media( vEdges[i].first, vEdges[i].second) ;
ptM.z = 0 ;
if ( IsPointInsidePolyLine( ptM, PL, -EPS_SMALL))
dElev = max( dElev, max( vEdges[i].first.z, vEdges[i].second.z)) ;
}
else {
IntCrvCrvInfo aInfo ;
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
if ( aInfo.bOverlap)
dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
// se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
dElev = max( dElev, vEdges[i].first.z) ;
// se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
dElev = max( dElev, vEdges[i].second.z) ;
}
}
}
+18 -12
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2025
// EgalTech 2023-2026
//----------------------------------------------------------------------------
// File : ProjectCurveSurfTm.cpp Data : 29.08.25 Versione : 2.7h2
// File : ProjectCurveSurfTm.cpp Data : 03.01.26 Versione : 3.1a1
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
//
//
@@ -311,9 +311,10 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
// approssimo la curva con una polilinea entro la metà della tolleranza
// approssimo la curva con una polilinea entro la tolleranza
PolyLine PL ;
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
if ( ! crCrv.ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
! PL.RemoveAlignedPoints( dLinTol, false) )
return false ;
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
@@ -443,9 +444,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const Vect
// controllo le tolleranze
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
// approssimo la curva con una polilinea alla massima risoluzione
// approssimo la curva con una polilinea entro la tolleranza
PolyLine PL ;
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
if ( ! crCrv.ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
! PL.RemoveAlignedPoints( dLinTol, false) )
return false ;
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
@@ -597,9 +600,10 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const IGeo
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
// approssimo la curva con una polilinea entro la metà della tolleranza
// approssimo la curva con una polilinea entro la tolleranza
PolyLine PL ;
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
if ( ! crCrv.ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
! PL.RemoveAlignedPoints( dLinTol, false) )
return false ;
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
@@ -736,9 +740,10 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ICur
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
// Approssimo la curva con una polilinea alla massima risoluzione
// Approssimo la curva con una polilinea entro la tolleranza
PolyLine PL ;
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
if ( ! crCrv.ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
! PL.RemoveAlignedPoints( dLinTol, false) )
return false ;
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
@@ -911,9 +916,10 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ISur
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
// approssimo la curva con una polilinea entro la metà della tolleranza
// approssimo la curva con una polilinea entro la tolleranza
PolyLine PL ;
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
if ( ! crCrv.ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ||
! PL.RemoveAlignedPoints( dLinTol, false) )
return false ;
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
+1 -1
View File
@@ -735,7 +735,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
//-------------------------------------------------------------------------------
ISurfBezier*
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const ICURVEPOVECTOR& vCrv, double dLinTol)
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const BIPNTVECTOR& vCrv, double dLinTol)
{
// verifica parametri
if ( pCurve1 == nullptr || pCurve2 == nullptr)
+9 -5
View File
@@ -37,7 +37,7 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
bool bIsRational = snData.bRat ;
// vettore dei nodi
DBLVECTOR vU ;
int nKnot = (int) snData.vU.size() ;
int nKnot = ssize( snData.vU) ;
for ( int k = 0 ; k < nKnot ; ++k ) {
double dKnot = snData.vU[k] ;
vU.push_back( dKnot) ;
@@ -69,9 +69,13 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
if ( snData.bRat)
snData.mW.resize( nuCurve.vW.size()) ;
}
for ( int i = 0 ; i < snData.nCPU ; ++i) {
for ( int i = 0 ; i < ssize( nuCurve.vCP) ; ++i) {
if ( snData.mCP[i].empty())
snData.mCP[i].resize( snData.nCPV) ;
snData.mCP[i][j] = nuCurve.vCP[i] ;
if ( snData.bRat) {
if ( snData.mW[i].empty())
snData.mW[i].resize( snData.nCPV) ;
snData.mW[i][j] = nuCurve.vW[i] ;
snData.mCP[i][j] *= nuCurve.vW[i] ;
}
@@ -80,13 +84,13 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
}
}
snData.bPeriodicU = false ;
snData.nCPU = int( snData.mCP.size()) ;
snData.nCPU = ssize( snData.mCP) ;
}
if ( snData.bPeriodicV || ! snData.bClampedV) {
bool bIsRational = snData.bRat ;
// vettore dei nodi
DBLVECTOR vV ;
int nKnot = (int) snData.vV.size() ;
int nKnot = ssize( snData.vV) ;
for ( int k = 0 ; k < nKnot ; ++k ) {
double dKnot = snData.vV[k] ;
vV.push_back( dKnot) ;
@@ -132,7 +136,7 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
}
}
snData.bPeriodicV = false ;
snData.nCPV = int( snData.mCP[0].size()) ;
snData.nCPV = ssize( snData.mCP[0]) ;
}
return true ;
}
+523 -216
View File
@@ -44,11 +44,12 @@
#define EIGEN_NO_IO
#include "/EgtDev/Extern/Eigen/Dense"
#define DEBUG
#ifdef DEBUG
#include "/EgtDev/Include/EGkGeoObjSave.h"
#define SAVEFAILEDTRIANGULATION 0
#define SAVEISO 0
#define SAVERULEDISO 0
#define SAVERULEDGUIDEDISO 0
#if SAVEFAILEDTRIANGULATION || SAVEISO || SAVERULEDISO || SAVERULEDGUIDEDISO
#include "/EgtDev/Include/EGkGeoObjSave.h"
#endif
using namespace std ;
@@ -875,8 +876,10 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc)
m_bTrimmed = true ;
m_pTrimReg = sbSrc.m_pTrimReg->Clone() ;
}
#ifndef SAVEFAILEDTRIANGULATION
if( sbSrc.GetAuxSurf() != nullptr)
m_pSTM = sbSrc.GetAuxSurf()->Clone() ;
#endif
for ( int i = 0 ; i < int( sbSrc.m_mCCEdge.size()) ; ++i) {
m_mCCEdge.emplace_back() ;
for ( int j = 0 ; j < int( sbSrc.m_mCCEdge[i].size()) ; ++j ) {
@@ -1068,6 +1071,15 @@ SurfBezier::Load( NgeReader& ngeIn)
m_bTrimmed = true ;
}
#if SAVEISO
ICURVEPOVECTOR vCrv ;
GetAllPatchesIsocurves( false, vCrv) ;
vector<IGeoObj*> vGeo ;
for( int i = 0 ; i < ssize(vCrv) ; ++i)
vGeo.push_back( vCrv[i]->Clone()) ;
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\ruled\\rebuild\\isoCrv.nge") ;
#endif
// eseguo validazione
return Validate() ;
}
@@ -1778,6 +1790,8 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
return dLen ;
}
int nSurf = 0 ;
//----------------------------------------------------------------------------
const SurfTriMesh*
SurfBezier::GetAuxSurf( void) const
@@ -1807,6 +1821,7 @@ SurfBezier::GetAuxSurf( void) const
}
// eseguo calcolo
m_pSTM = GetApproxSurf( s_dAuxSurfTol, 100 * EPS_SMALL, false) ;
++nSurf ;
if ( m_pSTM != nullptr)
m_pSTM->SetTempParam( s_dAuxSurfTol) ;
return m_pSTM ;
@@ -1846,6 +1861,10 @@ SurfBezier::GetAuxSurfRefined( void) const
return m_pSTMRefined ;
}
#if SAVEFAILEDTRIANGULATION
static int nErr = 0 ;
#endif
//----------------------------------------------------------------------------
SurfTriMesh*
SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) const
@@ -1866,7 +1885,6 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons
// costruttore della superficie
POLYLINEMATRIX vvPL ;
POLYLINEMATRIX vvPL3d ;
//POLYLINEVECTOR vPL ; // per usare i polygon basic
Tree Tree ;
if ( ! Tree.SetSurf( this))
return nullptr ;
@@ -1875,29 +1893,30 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons
// resetto il vettore degli edge
m_mCCEdge.clear() ;
m_vCCLoop.clear() ;
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
Point3d ptMin = get<0>( vTrees[i]) ;
Point3d ptMax = get<1>( vTrees[i]) ;
Tree.SetSurf( this, ptMin, ptMax) ;
Tree.BuildTree( dTol, dSideMin) ;
if( ! Tree.BuildTree( dTol, dSideMin)) {
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface parametric space couldn't be split in cells") ;
return nullptr ;
}
if ( ! Tree.GetPolygons( vvPL, vvPL3d, m_mCCEdge, m_vCCLoop, bUpdateEdges))
continue ;
//Tree.GetPolygonsBasic( vPL, true) ; // per usare i polygon basic
// aggiorno la chiusura della superficie
m_bClosedU = m_bClosedU || Tree.IsClosedU() ;
m_bClosedV = m_bClosedV || Tree.IsClosedV() ;
}
//// per usare i polygon basic//////////////////////
//for (int k = 0 ; k < (int)vPL.size(); ++k) {
// vvPL.emplace_back() ;
// vvPL.back().push_back(vPL[k]) ;
//}
//// per usare i polygon basic///////////////////
if ( vvPL.empty())
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated") ;
if ( vvPL.empty()) {
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated")
#if SAVEFAILEDTRIANGULATION
SaveGeoObj( Clone(),"D:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ;
++nErr ;
#endif
}
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start())
@@ -5055,8 +5074,10 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
// se ho uno spigolo su entrambe le curve forzo l'accoppiamento
bAdvance0 = true ;
bPerfectMatch = true ;
dParam0 = round( dParam0) ;
dParam1 = round( dParam1) ;
dParam0 = j + 1 ;
dParam1 = c + 1 ;
ptJoint0 = vPnt1[j+1] ;
ptJoint1 = vPnt0[c+1] ;
}
else if ( (vEdgeSplit0[c+1] && ! bAdvance1) || (vEdgeSplit1[j+1] && ! bAdvance0)) {
bAdvance0 = false ;
@@ -5199,189 +5220,189 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
}
}
else {
///////////OLD VRESION
//++c ;
//++j ;
//vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
//dLastParamMatch1 = c ;
//ptLastPointMatch1 = vPnt0[c] ;
//dLastParamMatch0 = j ;
//ptLastPointMatch0 = vPnt1[j] ;
/////////OLD VRESION
++c ;
++j ;
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
dLastParamMatch1 = c ;
ptLastPointMatch1 = vPnt0[c] ;
dLastParamMatch0 = j ;
ptLastPointMatch0 = vPnt1[j] ;
//// potrei avere un mismatch, senza però avere degli spigoli..
////// potrei avere un mismatch, senza però avere degli spigoli..
// identifico la zona in cui ho il mismatch e parametrizzo localmente
// // identifico la zona in cui ho il mismatch e parametrizzo localmente
//conto quanti punti ho nel mezzo
int c_temp = c, j_temp = j ;
bAdvance0 = true ;
bAdvance1 = true ;
int nParam0, nParam1 ;
while( bAdvance0) {
dParam0 = vMatch0[c_temp].second ;
nParam0 = int( round( dParam0)) ;
dParam1 = vMatch1[nParam0].second ;
nParam1 = int( round( dParam1)) ;
if( abs( nParam1 - c_temp) <= 2)
bAdvance0 = false ;
else
++ c_temp ;
}
while( bAdvance1) {
dParam1 = vMatch1[j_temp].second ;
nParam1 = int( round( dParam1)) ;
dParam0 = vMatch0[nParam1].second ;
nParam0 = int( round( dParam0)) ;
if( abs( nParam0 - j_temp) <= 2)
bAdvance1 = false ;
else
++ j_temp ;
}
// se non sono avanzato, allora mi basta accoppiare i due punti in questione
if( c_temp == c || j_temp == j) {
++c ;
++j ;
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
dLastParamMatch1 = c ;
ptLastPointMatch1 = vPnt0[c] ;
dLastParamMatch0 = j ;
ptLastPointMatch0 = vPnt1[j] ;
}
// se sono dovuto avanzare per trovare delle coppie che tornano a matchare allora ho effettivamente trovato una zona di mismatch
else {
// determino quale delle due coppie è il confine effettivo con la zona di mismatch e quale sarà la prima dopo il mismamtch
dParam0 = vMatch0[c_temp].second ;
dParam1 = vMatch1[j_temp].second ;
bool bIntParam0 = false ;
bool bIntParam1 = false ;
if ( abs( dParam0 - round( dParam0)) < EPS_SMALL) {
dParam0 = round( dParam0) ;
bIntParam0 = true ;
}
if ( abs( dParam1 - round( dParam1)) < EPS_SMALL) {
dParam1 = round( dParam1) ;
bIntParam1 = true ;
}
bAdvance0 = dParam0 < j_temp + 1 + EPS_SMALL ;
bAdvance1 = dParam1 < c_temp + 1 + EPS_SMALL ;
PtrOwner<ICurve> pCC0 ;
PtrOwner<ICurve> pCC1 ;
int nPointsBetween0 = 0 ;
int nPointsBetween1 = 0 ;
if( bAdvance0 && bAdvance1) {
pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, c_temp + 1)) ;
pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, j_temp + 1)) ;
nPointsBetween0 = c_temp - c ;
nPointsBetween1 = j_temp - j ;
}
else if( bAdvance0){
pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, c_temp + 1)) ;
pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, dParam0)) ;
nPointsBetween0 = c_temp - c ;
nPointsBetween1 = int( dParam0) - ( j + 1) ;
if ( bIntParam0)
nPointsBetween1 -= 1 ;
}
else if( bAdvance1){
pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, dParam1)) ;
pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, j_temp + 1)) ;
nPointsBetween0 = int( dParam1) - ( c + 1) ;
nPointsBetween1 = j_temp - j ;
if ( bIntParam1)
nPointsBetween0 -= 1 ;
}
double dLen0 ; pCC0->GetLength( dLen0) ;
double dLen1 ; pCC1->GetLength( dLen1) ;
DBLVECTOR vdParamPos0 ; vdParamPos0.reserve( nPointsBetween0) ;
DBLVECTOR vdParamPos1 ; vdParamPos1.reserve( nPointsBetween1) ;
for ( int k = 0 ; k <= nPointsBetween0 ; ++k) {
double dLen = 0 ; pCC0->GetLengthAtParam( k, dLen) ;
vdParamPos0.push_back( dLen / dLen0) ;
}
vdParamPos0.push_back( 1) ;
for ( int k = 0 ; k <= nPointsBetween1 ; ++k) {
double dLen = 0 ; pCC1->GetLengthAtParam( k, dLen) ;
vdParamPos1.push_back( dLen / dLen1) ;
}
vdParamPos1.push_back( 1) ;
// //conto quanti punti ho nel mezzo
// int c_temp = c, j_temp = j ;
// bAdvance0 = true ;
// bAdvance1 = true ;
// int nParam0, nParam1 ;
// while( bAdvance0) {
// dParam0 = vMatch0[c_temp].second ;
// nParam0 = int( round( dParam0)) ;
// dParam1 = vMatch1[nParam0].second ;
// nParam1 = int( round( dParam1)) ;
// if( abs( nParam1 - c_temp) <= 2)
// bAdvance0 = false ;
// else
// ++ c_temp ;
// }
// while( bAdvance1) {
// dParam1 = vMatch1[j_temp].second ;
// nParam1 = int( round( dParam1)) ;
// dParam0 = vMatch0[nParam1].second ;
// nParam0 = int( round( dParam0)) ;
// if( abs( nParam0 - j_temp) <= 2)
// bAdvance1 = false ;
// else
// ++ j_temp ;
// }
// // se non sono avanzato, allora mi basta accoppiare i due punti in questione
// if( c_temp == c || j_temp == j) {
// ++c ;
// ++j ;
// vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
// dLastParamMatch1 = c ;
// ptLastPointMatch1 = vPnt0[c] ;
// dLastParamMatch0 = j ;
// ptLastPointMatch0 = vPnt1[j] ;
// }
// // se sono dovuto avanzare per trovare delle coppie che tornano a matchare allora ho effettivamente trovato una zona di mismatch
// else {
// // determino quale delle due coppie è il confine effettivo con la zona di mismatch e quale sarà la prima dopo il mismamtch
// dParam0 = vMatch0[c_temp].second ;
// dParam1 = vMatch1[j_temp].second ;
// bool bIntParam0 = false ;
// bool bIntParam1 = false ;
// if ( abs( dParam0 - round( dParam0)) < EPS_SMALL) {
// dParam0 = round( dParam0) ;
// bIntParam0 = true ;
// }
// if ( abs( dParam1 - round( dParam1)) < EPS_SMALL) {
// dParam1 = round( dParam1) ;
// bIntParam1 = true ;
// }
// bAdvance0 = dParam0 < j_temp + 1 + EPS_SMALL ;
// bAdvance1 = dParam1 < c_temp + 1 + EPS_SMALL ;
// PtrOwner<ICurve> pCC0 ;
// PtrOwner<ICurve> pCC1 ;
// int nPointsBetween0 = 0 ;
// int nPointsBetween1 = 0 ;
// if( bAdvance0 && bAdvance1) {
// pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, c_temp + 1)) ;
// pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, j_temp + 1)) ;
// nPointsBetween0 = c_temp - c ;
// nPointsBetween1 = j_temp - j ;
// }
// else if( bAdvance0){
// pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, c_temp + 1)) ;
// pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, dParam0)) ;
// nPointsBetween0 = c_temp - c ;
// nPointsBetween1 = int( dParam0) - ( j + 1) ;
// if ( bIntParam0)
// nPointsBetween1 -= 1 ;
// }
// else if( bAdvance1){
// pCC0.Set( CrvU0.CopyParamRange( dLastParamMatch1, dParam1)) ;
// pCC1.Set( CrvU1.CopyParamRange( dLastParamMatch0, j_temp + 1)) ;
// nPointsBetween0 = int( dParam1) - ( c + 1) ;
// nPointsBetween1 = j_temp - j ;
// if ( bIntParam1)
// nPointsBetween0 -= 1 ;
// }
//
// double dLen0 ; pCC0->GetLength( dLen0) ;
// double dLen1 ; pCC1->GetLength( dLen1) ;
// DBLVECTOR vdParamPos0 ; vdParamPos0.reserve( nPointsBetween0) ;
// DBLVECTOR vdParamPos1 ; vdParamPos1.reserve( nPointsBetween1) ;
// for ( int k = 0 ; k <= nPointsBetween0 ; ++k) {
// double dLen = 0 ; pCC0->GetLengthAtParam( k, dLen) ;
// vdParamPos0.push_back( dLen / dLen0) ;
// }
// vdParamPos0.push_back( 1) ;
// for ( int k = 0 ; k <= nPointsBetween1 ; ++k) {
// double dLen = 0 ; pCC1->GetLengthAtParam( k, dLen) ;
// vdParamPos1.push_back( dLen / dLen1) ;
// }
// vdParamPos1.push_back( 1) ;
bool bSplitToAdd = true ;
int c0 = 1, c1 = 1 ;
//debug
int nCBerfore = c ;
int nJBefore = j ;
//debug
while ( bSplitToAdd) {
if ( c0 > ssize( vdParamPos0) - 1 && c1 > ssize( vdParamPos1) - 1) {
LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error 1 while reparametrizing some section") ;
return false ;
}
// se ho una corrispondenza tra punti ( e non sono alla fine del tratto) allora non aggiungo split
if ( abs( vdParamPos0[c0] - vdParamPos1[c1]) < EPS_PARAM && vdParamPos0[c0] < 1) {
++c0 ;
++c1 ;
++c ;
++j ;
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
}
// se non ho corrispondenza allora aggiungo uno split sulla curva a cui manca il punto corrispondente
else if ( vdParamPos0[c0] < vdParamPos1[c1]) {
double dPar ; CrvU1.GetParamAtLength( dLen1 * vdParamPos0[c0], dPar) ;
if ( abs( dPar - round( dPar)) > EPS_SMALL) {
vdSplit1.push_back( dPar + dLastParamMatch0) ;
nSplit1 = vdSplit1.size() ;
}
else if ( dPar = round( dPar) ; dPar > j){
++ j ;
}
++c ;
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
++c0 ;
}
else if ( vdParamPos0[c0] > vdParamPos1[c1]) {
double dPar ; CrvU0.GetParamAtLength( dLen0 * vdParamPos1[c1], dPar) ;
// se lo split non è in prossimità di una joint già esistente allora lo aggiungo
if ( abs( dPar - round( dPar)) > EPS_SMALL) {
vdSplit0.push_back( dPar + dLastParamMatch1) ;
nSplit0 = vdSplit0.size() ;
}
else if ( dPar = round( dPar) ; dPar > c){
++ c ;
}
++j ;
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
++c1 ;
}
else {
LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error 2 while reparametrizing some section") ;
return false ;
}
bSplitToAdd = ! ( c0 == ssize( vdParamPos0) - 1 && c1 == ssize( vdParamPos1) - 1) ;
}
// aggiorno i dati dell'ultima aggiunta
if( bAdvance0 && ! bAdvance1) {
ptLastPointMatch0 = vMatch0[c_temp].first ;
dLastParamMatch0 = vMatch0[c_temp].second ;
ptLastPointMatch1 = vPnt0[c_temp] ;
dLastParamMatch0 = c_temp ;
}
else if( ! bAdvance0 && bAdvance1) {
ptLastPointMatch0 = vPnt1[j_temp] ;
dLastParamMatch0 = j_temp ;
ptLastPointMatch1 = vMatch1[j_temp].first ;
dLastParamMatch0 = vMatch1[j_temp].second ;
}
else {
ptLastPointMatch0 = vPnt1[j_temp] ;
dLastParamMatch0 = j_temp ;
ptLastPointMatch1 = vPnt0[c_temp] ;
dLastParamMatch0 = c_temp ;
}
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
}
// bool bSplitToAdd = true ;
// int c0 = 1, c1 = 1 ;
// //debug
// int nCBerfore = c ;
// int nJBefore = j ;
// //debug
// while ( bSplitToAdd) {
// if ( c0 > ssize( vdParamPos0) - 1 && c1 > ssize( vdParamPos1) - 1) {
// LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error 1 while reparametrizing some section") ;
// return false ;
// }
// // se ho una corrispondenza tra punti ( e non sono alla fine del tratto) allora non aggiungo split
// if ( abs( vdParamPos0[c0] - vdParamPos1[c1]) < EPS_PARAM && vdParamPos0[c0] < 1) {
// ++c0 ;
// ++c1 ;
// ++c ;
// ++j ;
// vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
// }
// // se non ho corrispondenza allora aggiungo uno split sulla curva a cui manca il punto corrispondente
// else if ( vdParamPos0[c0] < vdParamPos1[c1]) {
// double dPar ; CrvU1.GetParamAtLength( dLen1 * vdParamPos0[c0], dPar) ;
// if ( abs( dPar - round( dPar)) > EPS_SMALL) {
// vdSplit1.push_back( dPar + dLastParamMatch0) ;
// nSplit1 = vdSplit1.size() ;
// }
// else if ( dPar = round( dPar) ; dPar > j){
// ++ j ;
// }
// ++c ;
// vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
// ++c0 ;
// }
// else if ( vdParamPos0[c0] > vdParamPos1[c1]) {
// double dPar ; CrvU0.GetParamAtLength( dLen0 * vdParamPos1[c1], dPar) ;
// // se lo split non è in prossimità di una joint già esistente allora lo aggiungo
// if ( abs( dPar - round( dPar)) > EPS_SMALL) {
// vdSplit0.push_back( dPar + dLastParamMatch1) ;
// nSplit0 = vdSplit0.size() ;
// }
// else if ( dPar = round( dPar) ; dPar > c){
// ++ c ;
// }
// ++j ;
// vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
// ++c1 ;
// }
// else {
// LOG_DBG_ERR( GetEGkLogger(), "Surf Bez Ruled Guided: error 2 while reparametrizing some section") ;
// return false ;
// }
// bSplitToAdd = ! ( c0 == ssize( vdParamPos0) - 1 && c1 == ssize( vdParamPos1) - 1) ;
// }
// // aggiorno i dati dell'ultima aggiunta
// if( bAdvance0 && ! bAdvance1) {
// ptLastPointMatch0 = vMatch0[c_temp].first ;
// dLastParamMatch0 = vMatch0[c_temp].second ;
// ptLastPointMatch1 = vPnt0[c_temp] ;
// dLastParamMatch0 = c_temp ;
// }
// else if( ! bAdvance0 && bAdvance1) {
// ptLastPointMatch0 = vPnt1[j_temp] ;
// dLastParamMatch0 = j_temp ;
// ptLastPointMatch1 = vMatch1[j_temp].first ;
// dLastParamMatch0 = vMatch1[j_temp].second ;
// }
// else {
// ptLastPointMatch0 = vPnt1[j_temp] ;
// dLastParamMatch0 = j_temp ;
// ptLastPointMatch1 = vPnt0[c_temp] ;
// dLastParamMatch0 = c_temp ;
// }
// vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
// }
}
}
bAdvance = ! (c >= int(vMatch0.size()) - 1 && j >= int(vMatch1.size()) - 1) ;
@@ -5474,7 +5495,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
++ nAddedSpan ;
}
#ifdef DEBUG
#if SAVERULEDISO
//debug
vector<IGeoObj*> vGeo ;
ICURVEPOVECTOR vCrv ;
@@ -5831,11 +5852,11 @@ SurfBezier::GetAllPatchesIsocurves( bool bUOrV, ICURVEPOVECTOR& vCrv) const
{
// restituisce tutte le isocurve di separazione tra patch in un parametro o nell'altro
if ( bUOrV) {
for ( int v = 0 ; v < m_nSpanV ; ++v)
for ( int v = 0 ; v <= m_nSpanV ; ++v)
vCrv.emplace_back( GetCurveOnU( v)) ;
}
else {
for ( int u = 0 ; u < m_nSpanU ; ++u)
for ( int u = 0 ; u <= m_nSpanU ; ++u)
vCrv.emplace_back( GetCurveOnV( u)) ;
}
return true ;
@@ -5845,7 +5866,8 @@ struct IsoParam {
int nCrv ;
double dParam0 ;
double dParam1 ;
IsoParam( int _nCrv, double _dParam0, double _dParam1): nCrv(_nCrv), dParam0( _dParam0), dParam1( _dParam1){ } ;
IsoParam( int _nCrv, double _dParam0, double _dParam1) :
nCrv(_nCrv), dParam0( _dParam0), dParam1( _dParam1){ } ;
bool operator < ( IsoParam& b)
{
return ( abs(dParam0 - b.dParam0) > EPS_SMALL ? dParam0 < b.dParam0 : dParam1 < b.dParam1) ;
@@ -5856,8 +5878,16 @@ typedef vector<IsoParam> ISOPARVECT ;
//----------------------------------------------------------------------------
bool
SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const ICURVEPOVECTOR& vCrv)
SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv)
{
// vCrv è il vettore delle isocurve (nel parametro V) che si vogliono forzare per la creazione della rigata tra Curve0 e Curve1
//controllo che siano entrambe chiuse o entrambe aperte
if( pCurve0->IsClosed() ^ pCurve1->IsClosed())
return false ;
bool bClosed = pCurve0->IsClosed() ;
// converto in bezier la curva iniziale
CurveComposite CrvU0 ; CrvU0.AddCurve( CurveToBezierCurve(pCurve0)) ;
if ( ! CrvU0.IsValid())
@@ -5893,20 +5923,53 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
double dLastParam0 = 0, dLastParam1 = 0 ;
double dLenPrev0 = 0 ,dLenPrev1 = 0 ;
// mi assicuro che le isocurve siano in ordine
// costruisco il vettore delle nuove curve isoparamtriche per la nuova superficie
bool bFirstAdded = false ;
int nSpanU0 = CrvU0.GetCurveCount() ;
int nSpanU1 = CrvU1.GetCurveCount() ;
ISOPARVECT vIso ;
for ( int i = 0 ; i < ssize( vCrv) ; ++i) {
Point3d ptU0 ; vCrv[i]->GetStartPoint( ptU0) ;
Point3d ptU1 ; vCrv[i]->GetEndPoint( ptU1) ;
Point3d ptU0 = vCrv[i].first ;
Point3d ptU1 = vCrv[i].second ;
double dParam0 ; CrvU0.GetParamAtPoint( ptU0, dParam0) ;
double dParam1 ; CrvU1.GetParamAtPoint( ptU1, dParam1) ;
if( bClosed && (dParam0 < EPS_SMALL || nSpanU0 - dParam0 < EPS_SMALL) && (dParam1 < EPS_SMALL || nSpanU1 - dParam1 < EPS_SMALL)) {
if( ! bFirstAdded) {
dParam0 = 0 ;
dParam1 = 0 ;
bFirstAdded = true ;
}
else {
dParam0 = nSpanU0 ;
dParam1 = nSpanU1 ;
}
}
vIso.emplace_back( i, dParam0, dParam1) ;
}
sort( vIso.begin(), vIso.end()) ;
// scorro vIso per verificare che non ci siano curve che si intersecano
int c = 0 ;
dLastParam0 = vIso[c].dParam0 ;
dLastParam1 = vIso[c].dParam1 ;
++c ;
while ( c < ssize( vIso)) {
if ( vIso[c].dParam0 < dLastParam0 || vIso[c].dParam1 < dLastParam1)
return false ;
dLastParam0 = vIso[c].dParam0 ;
dLastParam1 = vIso[c].dParam1 ;
++c ;
}
dLastParam0 = 0 ;
dLastParam1 = 0 ;
if( vIso[0].dParam0 > 0 || vIso[0].dParam1 > 0)
vPairs.emplace_back( 0, 0) ;
for ( int i = 0 ; i < ssize( vIso) ; ++i) {
Point3d ptU0 ; vCrv[vIso[i].nCrv]->GetStartPoint( ptU0) ;
Point3d ptU1 ; vCrv[vIso[i].nCrv]->GetEndPoint( ptU1) ;
const BIPOINT& pCrv = vCrv[vIso[i].nCrv] ;
Point3d ptU0 = pCrv.first ;
Point3d ptU1 ; pCrv.second ;
double& dParam0 = vIso[i].dParam0 ;
double& dParam1 = vIso[i].dParam1 ;
// se sono vicino ad un'intero allora considero il parametro intero ( uno split già esistente)
@@ -6059,8 +6122,8 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
CrvU0.AddJoint( dSplit) ;
}
int nSpanU0 = CrvU0.GetCurveCount() ;
int nSpanU1 = CrvU1.GetCurveCount() ;
nSpanU0 = CrvU0.GetCurveCount() ;
nSpanU1 = CrvU1.GetCurveCount() ;
// aggiungo l'ultima coppia
vPairs.emplace_back( nSpanU0, nSpanU1) ;
@@ -6117,19 +6180,263 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
++ nAddedSpan ;
}
#ifdef DEBUG
#if SAVERULEDGUIDEDISO
//debug
vector<IGeoObj*> vGeo ;
ICURVEPOVECTOR vCrv2 ;
GetAllPatchesIsocurves( false, vCrv2) ;
for( int i = 0 ; i < ssize( vCrv2) ; ++i) {
vGeo.push_back( vCrv2[i]->Clone()) ;
ICURVEPOVECTOR vCrvIso ;
GetAllPatchesIsocurves( false, vCrvIso) ;
for( int i = 0 ; i < ssize( vCrvIso) ; ++i) {
vGeo.push_back( vCrvIso[i]->Clone()) ;
}
vector<Color> vCol( ssize( vCrv2)) ;
vector<Color> vCol( ssize( vCrvIso)) ;
fill( vCol.begin(), vCol.end(), Color( 255,0,128)) ;
SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/isoCurves.nge") ;
//debug
#endif
vGeo.clear() ;
vGeo.push_back( CrvU0.Clone()) ;
vGeo.push_back( CrvU1.Clone()) ;
vCol.clear() ;
vCol.push_back(Color(0,64,128)) ;
vCol.push_back(Color(128,64,0)) ;
SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/NewCurves.nge") ;
#endif
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::RemoveCollapsedSpans()
{
double dTol = EPS_SMALL ;
//controllo se ho delle span collassate e le rimuovo
if( m_nSpanU > 1 || m_nSpanV > 1) {
CalcPoles() ;
if( ! m_vbPole[2]) {
// scorro i punti della prima riga
INTVECTOR vnCollapsedSpan ;
for( int i = 0 ; i < m_nSpanU ; ++i) {
bool bSamePoint = true ;
Point3d ptFirst = m_vPtCtrl[m_nDegU * i] ;
// cerco se trovo tutti i punti in U coincidenti in una delle Span
for( int j = 1 ; j < m_nDegU + 1 && bSamePoint ; ++j) {
if( ! AreSamePointEpsilon( ptFirst, m_vPtCtrl[m_nDegU * i + j], dTol))
bSamePoint = false ;
}
if( bSamePoint) {
// se trovo un'altra riga collassata do per scontato che tutta span sia collassata
ptFirst = m_vPtCtrl[GetInd( m_nDegU * i, 1)] ;
for( int j = 1 ; j < m_nDegU + 1 && bSamePoint ; ++j) {
if( ! AreSamePointEpsilon( ptFirst, m_vPtCtrl[GetInd( m_nDegU * i + j, 1)], dTol))
bSamePoint = false ;
}
if( bSamePoint)
vnCollapsedSpan.push_back( i) ;
}
}
int nOldSpanU = m_nSpanU ;
if( ! vnCollapsedSpan.empty()) {
// cancello le span che risultano collassate
int nNewSpanU = m_nSpanU - ssize( vnCollapsedSpan) ;
int nNewDim = ( m_nDegU * nNewSpanU + 1) * ( m_nDegV * m_nSpanV + 1) ;
PNTVECTOR vNewCtrlPnt( nNewDim) ;
DBLVECTOR vNewWeight( nNewDim) ;
int nCurrSkipInd = -1 ;
int nCurrSkip = -1 ;
for( int nIndV = 0 ; nIndV < m_nSpanV * m_nDegV + 1 ; ++nIndV) {
nCurrSkipInd = 0 ;
nCurrSkip = vnCollapsedSpan[nCurrSkipInd] ;
for( int i = 0 ; i < m_nSpanU ; ++i) {
if( i != nCurrSkip) {
for( int j = ( i - nCurrSkipInd) ==0 ? 0 : 1 ; j < m_nDegU + 1 ; ++j) {
vNewCtrlPnt[nIndV * ( m_nDegU * nNewSpanU + 1) + (i - nCurrSkipInd) * m_nDegU + j] = m_vPtCtrl[GetInd( m_nDegU * i + j, nIndV)] ;
if( m_bRat) {
vNewWeight[nIndV * ( m_nDegU * nNewSpanU + 1) + (i - nCurrSkipInd) * m_nDegU + j] = m_vWeCtrl[GetInd( m_nDegU * i + j, nIndV)] ;
}
}
}
else {
++nCurrSkipInd ;
if( nCurrSkipInd > ssize( vnCollapsedSpan) - 1)
nCurrSkip = -1 ;
else
nCurrSkip = vnCollapsedSpan[nCurrSkipInd] ;
}
}
}
// aggiorno i dati della superficie
// vettori dei punti e numero di span
ISurfFlatRegion* pSFRTrim = nullptr ;
bool bTrimmed = m_bTrimmed ;
if( bTrimmed) {
pSFRTrim = GetTrimRegion() ;
m_pTrimReg = nullptr ;
}
Init( m_nDegU, m_nDegV, nNewSpanU, m_nSpanV, m_bRat) ;
m_vPtCtrl = vNewCtrlPnt ;
if( m_bRat)
m_vWeCtrl = vNewWeight ;
if( bTrimmed) {
// elimino le span di troppo dallo spazio parametrico
PtrOwner<ISurfFlatRegion> pNewTrim( pSFRTrim->Clone()) ;
for( int i = ssize( vnCollapsedSpan) - 1 ; i >= 0 ; --i) {
int nSpan = vnCollapsedSpan[i] ;
// tolgo tutta la parte a destra della colonna da togliere
PtrOwner<ISurfFlatRegion> pSFRCut ( GetSurfFlatRegionRectangle( ( nOldSpanU - nSpan) * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF + 2)) ;
if( nSpan != 0) {
pSFRCut->Translate( Vector3d( nSpan * SBZ_TREG_COEFF, -1)) ;
pNewTrim->Subtract( *pSFRCut) ;
}
if( pNewTrim->IsValid()) {
// ritaglio dal parametrico originale la parte a destra della colonna da eliminare e la incollo alla parte a sinistra
PtrOwner<ISurfFlatRegion> pRightPart( pSFRTrim->Clone()) ;
pSFRCut.Set( GetSurfFlatRegionRectangle( ( nSpan + 1) * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF + 2)) ;
pSFRCut->Translate( Vector3d( nSpan * SBZ_TREG_COEFF, -1)) ;
if( pRightPart->Subtract( *pSFRCut) && pRightPart->IsValid()) {
if( ! pNewTrim->Add( *pRightPart) || ! pNewTrim->IsValid())
break ;
}
}
else
break ;
}
SetTrimRegion( *pSFRTrim) ;
}
}
}
if( ! m_vbPole[1]) {
// scorro i punti della prima colonna
INTVECTOR vnCollapsedSpan ;
for( int i = 0 ; i < m_nSpanV ; ++i) {
bool bSamePoint = true ;
Point3d ptFirst = m_vPtCtrl[GetInd( 0, i * m_nDegV)] ;
// cerco se trovo tutti i punti in U coincidenti in una delle Span
for( int j = 1 ; j < m_nDegV + 1 && bSamePoint ; ++j) {
if( ! AreSamePointEpsilon( ptFirst, m_vPtCtrl[GetInd( 0, i * m_nDegV + j)], dTol))
bSamePoint = false ;
}
if( bSamePoint) {
// se trovo un'altra colonna collassata do per scontato che tutta span sia collassata
ptFirst = m_vPtCtrl[GetInd( 1, i * m_nDegV)] ;
for( int j = 1 ; j < m_nDegV + 1 && bSamePoint ; ++j) {
if( ! AreSamePointEpsilon( ptFirst, m_vPtCtrl[GetInd( 1, i * m_nDegV + j)], dTol))
bSamePoint = false ;
}
if( bSamePoint)
vnCollapsedSpan.push_back( i) ;
}
}
int nOldSpanV = m_nSpanV ;
if( ! vnCollapsedSpan.empty()) {
// cancello le span che risultano collassate
int nNewSpanV = m_nSpanV - ssize( vnCollapsedSpan) ;
int nNewDim = ( m_nDegU * m_nSpanU + 1) * ( m_nDegV * nNewSpanV + 1) ;
PNTVECTOR vNewCtrlPnt( nNewDim) ;
DBLVECTOR vNewWeight( nNewDim) ;
int nCurrSkipInd = 0 ;
int nCurrSkip = vnCollapsedSpan[nCurrSkipInd] ;
for( int nIndV = 0 ; nIndV < m_nSpanV * m_nDegV + 1 ; ++nIndV) {
if( nIndV / m_nDegV != nCurrSkip) {
for( int i = 0 ; i < m_nSpanU ; ++i) {
for( int j = i==0 ? 0 : 1 ; j < m_nDegU + 1 ; ++j) {
vNewCtrlPnt[( nIndV - ( nCurrSkipInd * m_nDegV)) * ( m_nDegU * m_nSpanU + 1) + i * m_nDegU + j] = m_vPtCtrl[GetInd( m_nDegU * i + j, nIndV)] ;
if( m_bRat) {
vNewWeight[( nIndV - ( nCurrSkipInd * m_nDegV)) * ( m_nDegU * m_nSpanU + 1) + i * m_nDegU + j] = m_vWeCtrl[GetInd( m_nDegU * i + j, nIndV)] ;
}
}
}
}
else {
nIndV += m_nDegV - 1 ;
++nCurrSkipInd ;
if( nCurrSkipInd > ssize( vnCollapsedSpan) - 1)
nCurrSkip = -1 ;
else
nCurrSkip = vnCollapsedSpan[nCurrSkipInd] ;
}
}
// aggiorno i dati della superficie
// vettori dei punti e numero di span
ISurfFlatRegion* pSFRTrim = nullptr ;
bool bTrimmed = m_bTrimmed ;
if( bTrimmed) {
pSFRTrim = GetTrimRegion() ;
m_pTrimReg = nullptr ;
}
Init( m_nDegU, m_nDegV, m_nSpanU, nNewSpanV, m_bRat) ;
m_vPtCtrl = vNewCtrlPnt ;
if( m_bRat)
m_vWeCtrl = vNewWeight ;
if( bTrimmed) {
// elimino le span di troppo dallo spazio parametrico
PtrOwner<ISurfFlatRegion> pNewTrim( pSFRTrim->Clone()) ;
for( int i = ssize( vnCollapsedSpan) - 1 ; i >= 0 ; --i) {
int nSpan = vnCollapsedSpan[i] ;
// tolgo tutta la parte a sopra la riga da togliere
PtrOwner<ISurfFlatRegion> pSFRCut ( GetSurfFlatRegionRectangle( m_nSpanU * SBZ_TREG_COEFF + 2, ( nOldSpanV - nSpan) * SBZ_TREG_COEFF)) ;
if( nSpan != 0) {
pSFRCut->Translate( Vector3d( -1, nSpan * SBZ_TREG_COEFF)) ;
pNewTrim->Subtract( *pSFRCut) ;
}
if( pNewTrim->IsValid()) {
// ritaglio dal parametrico originale la parte sopra la riga da eliminare e la incollo alla parte sotto la riga
PtrOwner<ISurfFlatRegion> pUpperPart( pSFRTrim->Clone()) ;
pSFRCut.Set( GetSurfFlatRegionRectangle( m_nSpanU * SBZ_TREG_COEFF + 2, ( nSpan + 1) * SBZ_TREG_COEFF)) ;
pSFRCut->Translate( Vector3d( -1, nSpan * SBZ_TREG_COEFF)) ;
if( pUpperPart->Subtract( *pSFRCut) && pUpperPart->IsValid()) {
if( ! pNewTrim->Add( *pUpperPart) || ! pNewTrim->IsValid())
break ;
}
}
else
break ;
}
SetTrimRegion( *pSFRTrim) ;
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::SwapParameters()
{
// inverto il parametro U con il parametro V
// salvo i vecchi dati
int nSpanU = m_nSpanV ;
int nSpanV = m_nSpanU ;
int nDegU = m_nDegV ;
int nDegV = m_nDegU ;
bool bTrimmed = m_bTrimmed ;
PtrOwner<ISurfFlatRegion> pSFRTRim ;
if( m_bTrimmed) {
pSFRTRim.Set( GetTrimRegion()) ;
m_pTrimReg = nullptr ;
}
// creo il vettore dei punti di controllo
PNTVECTOR vNewCtrlPt( GetDim()) ;
DBLVECTOR vNewWeight( GetDim()) ;
for( int j = 0 ; j < m_nDegV * m_nSpanV + 1 ; ++j) {
for( int i = 0 ; i < m_nDegU * m_nSpanU + 1 ; ++ i) {
vNewCtrlPt[i * ( nDegU * nSpanU + 1) + j] = m_vPtCtrl[GetInd(i,j)] ;
if( m_bRat)
vNewWeight[i * ( nDegU * nSpanU + 1) + j] = m_vWeCtrl[GetInd(i,j)] ;
}
}
Init( nDegU, nDegV, nSpanU, nSpanV, m_bRat) ;
if( bTrimmed) {
pSFRTRim->Mirror( ORIG, Vector3d(1,-1)) ;
SetTrimRegion( *pSFRTRim) ;
}
m_vPtCtrl = vNewCtrlPt ;
m_vWeCtrl = vNewWeight ;
return true ;
}
+3 -1
View File
@@ -150,7 +150,9 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
PNTVECTOR GetAllControlPoints( void) const ;
bool GetAllPatchesIsocurves( bool bUorV, ICURVEPOVECTOR& vCrv) const ;
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const ICURVEPOVECTOR& vCrv) ;
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv) ;
bool RemoveCollapsedSpans() override ;
bool SwapParameters() ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
+50 -5
View File
@@ -871,14 +871,20 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
return false ;
// medio le normali, finchè non incontro degli spigoli
vtN = m_vTria[nT].vtN ;
double dAngW = 1 ;
GetTriangleVertexAngle( nT, nV, dAngW) ;
vtN = dAngW * m_vTria[nT].vtN ;
// parto dal triangolo e vado in direzione positiva
int nLim = nPos ;
for ( int i = NextIndAroundVertex( nPos, nTria, bCirc) ;
i != nPos && i < int( vT.size()) ;
i = NextIndAroundVertex( i, nTria, bCirc)) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
vtN += m_vTria[vT[i]].vtN ;
if ( m_vTria[nT].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng) {
int nK ; double dAngW = 1 ;
if ( FindVertexInTria( m_vTria[nT].nIdVert[nV], vT[i], nK) &&
GetTriangleVertexAngle( vT[i], nK, dAngW))
vtN += dAngW * m_vTria[vT[i]].vtN ;
}
else
break ;
nLim = i ;
@@ -887,8 +893,12 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
for ( int i = PrevIndAroundVertex( nPos, nTria, bCirc) ;
i != nLim && i >= 0 ;
i = PrevIndAroundVertex( i, nTria, bCirc)) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
vtN += m_vTria[vT[i]].vtN ;
if ( m_vTria[nT].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng) {
int nK ; double dAngW = 1 ;
if ( FindVertexInTria( m_vTria[nT].nIdVert[nV], vT[i], nK) &&
GetTriangleVertexAngle( vT[i], nK, dAngW))
vtN += dAngW * m_vTria[vT[i]].vtN ;
}
else
break ;
}
@@ -897,6 +907,23 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetTriangleVertexAngle( int nT, int nV, double& dAng) const
{
// verifico esistenza del triangolo e validità vertice
if ( nT < 0 || nT >= GetTriangleSize() || m_vTria[nT].nIdVert[0] == SVT_DEL || nV < 0 || nV > 2)
return false ;
// determino i vettori dei due lati che partono dal vertice
Point3d ptVert = m_vVert[ m_vTria[nT].nIdVert[nV]].ptP ;
Point3d ptPrev = m_vVert[ m_vTria[nT].nIdVert[Prev( nV)]].ptP ;
Point3d ptNext = m_vVert[ m_vTria[nT].nIdVert[Next( nV)]].ptP ;
Vector3d vtPrev = ptPrev - ptVert ;
Vector3d vtNext = ptNext - ptVert ;
// determino l'angolo tra i due lati
return vtPrev.GetAngle( vtNext, dAng) ;
}
//----------------------------------------------------------------------------
SurfTriMesh*
SurfTriMesh::CloneTriangle( int nT) const
@@ -4514,3 +4541,21 @@ SurfTriMesh::AdjustTopologyFromZMap( void)
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetTriaFromFace( int nF, int& nT) const
{
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico stato sfaccettatura
if ( ! VerifyFaceting())
return false ;
// l'indice della faccia deve essere nei limiti
if ( nF < 0 || nF >= int( m_vFacet.size()))
return false ;
// recupero la normale di un triangolo della faccetta
nT = m_vFacet[nF] ;
return true ;
}
+2
View File
@@ -380,6 +380,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool SetTempInt( int nId, int nTempInt) const ;
bool AddTriaFromZMap( const TRIA3DEXVECTOR& vTria, PointGrid3d& VertGrid, double dVertexTol = 2 * EPS_SMALL) ;
bool AdjustTopologyFromZMap( void) ;
bool GetTriaFromFace( int nF, int& nT) const ;
private :
typedef std::vector<StmVert> VERTVECTOR ;
@@ -413,6 +414,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
int NextIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
int PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
bool GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const ;
bool GetTriangleVertexAngle( int nT, int nV, double& dAng) const ;
bool MarchAlongLoop( int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
+2 -1
View File
@@ -733,6 +733,7 @@ CreateSurfTriMeshShell( const ISurfTriMesh* pStm, double dThick, double dPrec)
}
if ( nIndOffsCrv == -1)
return nullptr ;
vIndMatched[ nIndOffsCrv] = true ;
// associo le due curve
ICurveComposite* pCompoOffsLoop = vCompoOffsLoops[nIndOffsCrv] ;
double dParMinDist = 0. ;
@@ -787,4 +788,4 @@ CreateSurfTriMeshShell( const ISurfTriMesh* pStm, double dThick, double dPrec)
#endif
return ( ( ! IsNull( pStmRef) && pStmRef->IsValid()) ? Release( pStmRef) : nullptr) ;
}
}
+70 -37
View File
@@ -474,7 +474,8 @@ Tree::Split( int nId, double dSplitValue)
GetPoint( dSplitValue, cToSplit.GetTopLeft().y, ptP01) ;
GetPoint( cToSplit.GetTopRight().x, cToSplit.GetTopRight().y, ptP11) ;
}
if( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11))
if( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11) &&
( cToSplit.GetBottomRight().x - dSplitValue < SBZ_TREG_COEFF - EPS_SMALL || dSplitValue - cToSplit.GetBottomLeft().x < SBZ_TREG_COEFF - EPS_SMALL))
bGoodSplitVert = false ;
}
if( bGoodSplitHoriz) {
@@ -490,7 +491,8 @@ Tree::Split( int nId, double dSplitValue)
GetPoint( cToSplit.GetTopLeft().x, cToSplit.GetTopLeft().y, ptP01) ;
GetPoint( cToSplit.GetTopRight().x, cToSplit.GetTopRight().y, ptP11) ;
}
if( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11))
if( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11) &&
( cToSplit.GetTopLeft().y - dSplitValue < SBZ_TREG_COEFF - EPS_SMALL || dSplitValue - cToSplit.GetBottomLeft().y < SBZ_TREG_COEFF - EPS_SMALL))
bGoodSplitHoriz = false ;
}
@@ -786,6 +788,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
nCToSplit = pcToSplit->m_nChild1 ;
pcToSplit = &m_mTree[nCToSplit] ;
}
else
return false ;
}
else {
// sono arrivato ad una cella Leaf, quindi salvo la cella
@@ -899,6 +903,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
nCToSplit = pcToSplit->m_nChild1 ;
pcToSplit = &m_mTree[nCToSplit] ;
}
else
return false ;
}
else {
// sono arrivato ad una cella Leaf, quindi salvo la cella
@@ -1435,18 +1441,21 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vec
if ( ! TraceLoopLabelCell( vPolygonsBasic))
return false ;
// scorro sulle celle e costruisco i poligoni
int nCells = int( vPolygonsBasic.size()) ;
for ( int i = 0 ; i < nCells ; ++ i) {
int nPolyInd = 0 ; // indice del poligono corrispondente alla cella, nel vettore dei poligoni
for ( int nId: m_vnLeaves) {
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
if ( m_mTree[nId].m_nFlag == 4) {
// vettore dei poligoni ( loop) della cella nId
vvPolygons.emplace_back() ;
vvPolygons.back().push_back(std::move(vPolygonsCorrected[i])) ;
vvPolygons.back().push_back(std::move(vPolygonsCorrected[nPolyInd])) ;
vvPolygons3d.emplace_back() ;
vvPolygons3d.back().push_back(std::move(vPolygonsBasic3d[i])) ;
vvPolygons3d.back().push_back(std::move(vPolygonsBasic3d[nPolyInd])) ;
}
else if ( m_mTree[nId].m_nFlag == 0)
else if ( m_mTree[nId].m_nFlag == 0) {
++ nPolyInd ;
continue ;
}
else if( m_mTree[nId].m_nCollapsed != Cell::Collapsed::NO_COLLAPSE)
continue ;
else {
// vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella
@@ -1461,13 +1470,14 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vec
while ( ! vToCheck.empty()) {
int nPolyBefore = nPoly ;
PolyLine pl3d ;
CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
CreateCellPolygons( nId, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[nPolyInd], vPolygonsBasic3d[nPolyInd]) ;
if ( nPolyBefore == nPoly)
break ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
CreateIslandAndHoles( nId, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, vPolygonsCorrected[nPolyInd], vPolygonsBasic3d[nPolyInd]) ;
}
++ nPolyInd ;
}
}
@@ -1910,10 +1920,9 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs
nCells.push_back( nId) ;
if ( ! bRecurs) {
// se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta
Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ;
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ;
if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL ||
abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) {
int nEdge = - 2 ;
OnWhichEdge( nId, ptToAssign, nEdge) ;
if ( nEdge != - 2) {
Vector3d vtDir ;
clTrim.GetStartDir( vtDir) ;
// proseguo lungo la curva di trim di EPS_SMALL
@@ -1964,12 +1973,16 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
}
// se non ho trovato nulla vuol dire che sono su un vertice o su un lato
if ( nCells.empty() && ! bRecurs) {
int nEdge = -1 ;
int nEdge = -2 ;
for ( int nCell : vCells) {
OnWhichEdge( nCell,ptToAssign, nEdge) ;
if ( nEdge != -1)
break ;
OnWhichEdge( nCell, ptToAssign, nEdge) ;
if ( nEdge != -2 && (m_mTree.at(nCell).m_nCollapsed == Cell::Collapsed::NO_COLLAPSE || m_mTree.at(nCell).m_nCollapsed == Cell::Collapsed::TO_VERIFY))
nCells.push_back( nCell) ;
nEdge = -2 ;
}
if( ssize( nCells) == 1)
return nCells ;
Vector3d vtDir ;
cl.GetStartDir( vtDir) ;
Point3d ptIntersPlus = ptToAssign ;
@@ -1977,7 +1990,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
// potrei essere su un lato
if ( nEdge == 0 || nEdge == 1 || nEdge == 2 || nEdge == 3) {
// se è orientato con il lato mi sposto a destra
if ( ( nEdge == 0 || nEdge == 2 ) && abs(vtDir.x) > 1 - EPS_SMALL/100 ) {
if ( ( nEdge == 0 || nEdge == 2 ) && abs(vtDir.x) > 1 - EPS_SMALL/100) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
@@ -1996,10 +2009,17 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
if ( abs(vtDir.x) < 1 - EPS_SMALL/100 && abs(vtDir.y) < 1 - EPS_SMALL/100 )
ptIntersPlus = ptIntersPlus + vtDir * EPS_SMALL ;
// altrimenti ruoto a destra
else {
else if( ( nEdge == 4 && vtDir.x > 1 - EPS_SMALL / 100) || ( nEdge == 6 && vtDir.x < - 1 + EPS_SMALL / 100) ||
( nEdge == 5 && vtDir.y > 1 - EPS_SMALL / 100) || ( nEdge == 7 && vtDir.y < - 1 + EPS_SMALL / 100)) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -45) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
// altrimenti ruoto a sinistra
else /*if( ( nEdge == 4 && vtDir.y < - 1 + EPS_SMALL / 100) || ( nEdge == 6 && vtDir.y < 1 - EPS_SMALL / 100) ||
( nEdge == 5 && vtDir.x > 1 - EPS_SMALL / 100) || ( nEdge == 7 && vtDir.x < - 1 + EPS_SMALL / 100)) // + tutti gli altri casi */ {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, 45) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
}
//
else
@@ -2011,7 +2031,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
ptIntersPlus = ptToAssign + vtDirSX * EPS_SMALL ;
}
// rilancio la rigida ricerca
nCells = FindCell( ptIntersPlus, cl, vCells, true) ;
nCells = FindCell( ptIntersPlus, cl, nCells, true) ;
}
return nCells ;
@@ -2117,9 +2137,10 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
pCell->m_vInters.back().nChunk = m_mChunk[i] ;
bool bLoopInside = true ;
Point3d ptCurr ;
auto iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ;
int nIdPolygon = distance( m_vnLeaves.begin(), iter) ;
if ( nIdPolygon > int( vplPolygons.size()) - 1)
int nIdPolygon = - 1;
if( ! pCell->m_vnPolyId.empty())
nIdPolygon = pCell->m_vnPolyId[0] ;
else
return false ;
bool bEraseNextPoint = false ;
while ( plLoop.GetNextPoint( ptCurr)) {
@@ -2128,6 +2149,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
plLoop.GetNextPoint( ptTEnd) ;
CurveLine clTrim ;
clTrim.Set( ptTStart, ptTEnd) ;
Point3d ptLastInters = P_INVALID ;
int nInfiniteLoopCount = 0 ;
// qui devo mettere una tolleranza negativa per poter tener conto anche dei punti che sono SULLA curva
while ( ! IsPointInsidePolyLine( ptCurr, vplPolygons[nIdPolygon], dLinTol)) {
// sto uscendo dalla cella, quindi cerco l'intersezione
@@ -2153,13 +2176,23 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
return false ;
bEraseNextPoint = true ;
}
// ricalcolo la posizione di nId nel vettore delle foglie
iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ;
nIdPolygon = distance( m_vnLeaves.begin(), iter) ;
if ( nIdPolygon > int( vplPolygons.size()) - 1)
return false ;
// se l'intersezione e la stessa della precedente allora potrei essere entrato in un loop infinito
// se per più volte il punto di intersezione resta più o meno lo stesso allora blocco tutto
if( AreSamePointEpsilon( vptInters.back(), ptLastInters, 10 * EPS_SMALL)) {
++ nInfiniteLoopCount ;
if( nInfiniteLoopCount == 4) {
LOG_ERROR( GetEGkLogger(), "Error Triangulating SurfBezier: infinte while loop occured in Tree::TraceLoopLabelCell")
return false ;
}
}
ptLastInters = vptInters.back() ;
// aggiorno il puntatore alla cella
pCell = &m_mTree[nId] ;
// recupero l'indice del poligono base associato alla cella
if( ! pCell->m_vnPolyId.empty())
nIdPolygon = pCell->m_vnPolyId[0] ;
else
return false ;
// salvo il verso del loop
pCell->m_vInters.back().bCCW = bCCW ;
// salvo il chunk del loop
@@ -2783,11 +2816,10 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon,
//----------------------------------------------------------------------------
bool
Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly,
Tree::CreateCellPolygons( int nId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly,
INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d)
{
// conto quanti vertici in più ho per lato e creo un vettore dei vertici per lato
int nId = m_vnLeaves[nLeafId] ;
Cell& cCell = m_mTree[nId] ;
PNTMATRIX vEdgeVertex(4) ;
PNTMATRIX vEdgeVertex3d(4) ;
@@ -2795,7 +2827,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
Point3d ptTR = cCell.GetTopRight() ;
Point3d ptTl = cCell.GetTopLeft() ;
Point3d ptBr = cCell.GetBottomRight() ;
int nVertToErase = m_mTree.at(nId).m_nVertToErase ;
int nVertToErase = cCell.m_nVertToErase ;
if ( nVertToErase != 2)
vEdgeVertex[0].push_back( ptTR) ;
if ( nVertToErase != 3)
@@ -3116,11 +3148,10 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
//----------------------------------------------------------------------------
bool
Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, int& nPoly, INTVECTOR& vnParentChunk,
Tree::CreateIslandAndHoles( int nId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, int& nPoly, INTVECTOR& vnParentChunk,
const PolyLine& plPolygonsBasic, const PolyLine& plPolygonsBasic3d)
{
// costruisco i poligoni partendo dal vettore delle intersezioni
int nId = m_vnLeaves[nLeafId] ;
Cell& cCell = m_mTree[nId] ;
//capisco se sono in modalità ForTriangulation
@@ -3764,14 +3795,14 @@ Tree::CategorizeCell( int nId)
Point3d ptIntersIn = m_mTree[nNeigh].m_vInters[r].vpt[0] ;
if ( (m_mTree[nNeigh].m_vInters[r].nOut == 0 || m_mTree[nNeigh].m_vInters[r].nOut == 7) &&
( CheckIfBefore( 2, ptBr, ptIntersOut) || AreSamePointApprox( ptBr, ptIntersOut))) {
if (ptIntersOut.x < ptLeftMostInters.x) {
if (ptIntersOut.x <= ptLeftMostInters.x) {
ptLeftMostInters = ptIntersOut ;
bFound = true ;
}
}
if ( (m_mTree[nNeigh].m_vInters[r].nIn == 0 || m_mTree[nNeigh].m_vInters[r].nIn == 7) &&
( CheckIfBefore( 2, ptBr, ptIntersIn) || AreSamePointApprox( ptBr, ptIntersIn))) {
if (ptIntersIn.x < ptLeftMostInters.x) {
if (ptIntersIn.x <= ptLeftMostInters.x) {
ptLeftMostInters = ptIntersIn ;
bFound = false ;
}
@@ -3994,7 +4025,9 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
Point3d ptTl ( ptBL.x, ptTR.y) ;
Point3d ptBr ( ptTR.x, ptBL.y) ;
if ( AreSamePointXYApprox( ptToAssign, ptTR))
if( ptToAssign.y < ptBL.y - EPS_SMALL || ptToAssign.y > ptTR.y + EPS_SMALL || ptToAssign.x < ptBL.x - EPS_SMALL || ptToAssign.x > ptTR.x + EPS_SMALL)
return false ;
else if ( AreSamePointXYApprox( ptToAssign, ptTR))
nEdge = 7 ;
else if ( AreSamePointXYApprox( ptToAssign, ptTl))
nEdge = 4 ;
+4283
View File
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -21,9 +21,8 @@
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include <unordered_map>
#include <stack>
#include <mutex>
#include <atomic>
#include <tuple>
#include <atomic>
typedef std::pair<Point3d, Vector3d> PNTVEC3D ;
typedef std::vector<PNTVEC3D> PNTVEC3DVECTOR ; // vettore di intersezioni punto, vettore, tipo superficie
@@ -557,9 +556,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW
mutable std::vector<InterVoxMatter> m_SliceXY ;
mutable std::vector<InterVoxMatter> m_SliceXZ ;
mutable std::vector<InterVoxMatter> m_SliceYZ ;
mutable std::mutex m_SliceMutex ;
mutable std::atomic_flag m_SliceFlag ;
std::atomic<bool> m_bIsBox ;
bool m_bIsBox ;
int m_nCurrTool ;
std::vector<Tool> m_vTool ;
+1
View File
@@ -3177,6 +3177,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
if ( ! pLoop->AddCurve( vLine[i - 1], true, 10 * EPS_SMALL))
return false ;
}
pLoop->TestClosure( 10 * EPS_SMALL) ;
pLoop->SetExtrusion( plPlane.GetVersN()) ;
pLoop->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
// Inserisco la curva composita nella raccolta da ritornare
+24 -12
View File
@@ -1271,13 +1271,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
bDefTopology = true ;
}
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
auto it = m_SliceYZ[nSlBlockN].find( nSliceN) ;
if ( it != m_SliceYZ[nSlBlockN].end()) {
bMatOnSlice = it->second ;
bDefTopology = true ;
}
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
else if ( abs( nAdjVox3[nCount]) == 2) {
@@ -1287,13 +1289,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
bDefTopology = true ;
}
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
auto it = m_SliceXZ[nSlBlockN].find( nSliceN) ;
if ( it != m_SliceXZ[nSlBlockN].end()) {
bMatOnSlice = it->second ;
bDefTopology = true ;
}
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
else if ( abs( nAdjVox3[nCount]) == 3) {
@@ -1303,13 +1307,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
bDefTopology = true ;
}
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
auto it = m_SliceXY[nSlBlockN].find( nSliceN) ;
if ( it != m_SliceXY[nSlBlockN].end()) {
bMatOnSlice = it->second ;
bDefTopology = true ;
}
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
}
@@ -1374,27 +1380,33 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
if ( nSlBlockN == nBlock)
SliceYZ.emplace( nSliceN, bMatOnSlice) ;
else {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
m_SliceYZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
else if ( abs(nAdjVox3[nCount]) == 2) {
if ( nSlBlockN == nBlock)
SliceXZ.emplace( nSliceN, bMatOnSlice) ;
else {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
m_SliceXZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
else if ( abs(nAdjVox3[nCount]) == 3) {
if ( nSlBlockN == nBlock)
SliceXY.emplace(nSliceN, bMatOnSlice) ;
else {
m_SliceMutex.lock() ;
while ( m_SliceFlag.test_and_set( memory_order_acquire))
m_SliceFlag.wait( true, memory_order_relaxed) ;
m_SliceXY[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
m_SliceMutex.unlock() ;
m_SliceFlag.clear( memory_order_release) ;
m_SliceFlag.notify_one() ;
}
}
}
+393 -370
View File
@@ -1392,7 +1392,6 @@ IntersLineBezierSurfSet( const Point3d& ptLineStart, const Vector3d& vtLineDir,
const SurfBezForInters& srf = vSurfBez[s] ;
BBox3d bbox = srf.bbSurfOriented;
bool bNotValid = false ;
Point3d rLoc = r ;
Vector3d qLoc = q ;
if ( ! bNeedToRot) {
@@ -1550,417 +1549,441 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
{
// tolgo il volume spazzato dal tool durante il movimento
// Verifica sull'interferenza con lo Zmap
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( nGrid, ptS, ptE, vtLs, vtLe, dMaxRad, dMinRad, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( nGrid, ptS, ptE, vtLs, vtLe, dMaxRad, dMinRad, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
// vettori di riferimento per trovare i punti ausiliari
int nDegU = 3 ; int nDegV = 1 ;
int nSpanU = 1 ; int nSpanV = 1 ;
bool bRat = false ;
int nDegU = 3 ; int nDegV = 1 ;
int nSpanU = 1 ; int nSpanV = 1 ;
bool bRat = false ;
int nSub = 2 ; // numero di bezier di grado 3x1 con cui approssimare il (quasi) semi-cilindro ellissoide che descrive il volume della punta e della cima del tool
PNTVECTOR d ;
Vector3d q = Z_AX ;
int nSub = 2 ; // numero di bezier di grado 3x1 con cui approssimare il (quasi) semi-cilindro ellissoide che descrive il volume della punta e della cima del tool
PNTVECTOR d ;
Vector3d q = Z_AX ;
int nTotSurf = 4 ;
if ( n5AxisType == Move5Axis::NO_BASE_INTERS)
nTotSurf = 2 + nSub * 2 + nSub * 2 + 8 ; // sup laterali, sup superiori e inferiori, superfici verticali di inizio e fine, superfici di base dei tool
else if ( n5AxisType == Move5Axis::ACROSS)
nTotSurf = 2 + nSub * 4 + nSub * 2 + 16 ; // come sopra
int nTotSurf = 4 ;
if ( n5AxisType == Move5Axis::NO_BASE_INTERS)
nTotSurf = 2 + nSub * 2 + nSub * 2 + 8 ; // sup laterali, sup superiori e inferiori, superfici verticali di inizio e fine, superfici di base dei tool
else if ( n5AxisType == Move5Axis::ACROSS)
nTotSurf = 2 + nSub * 4 + nSub * 2 + 16 ; // come sopra
int nSurfInd = 0 ;
vector<SurfBezForInters> vSurfBez( nTotSurf) ;
double dSide = 0 ;
int nSurfInd = 0 ;
vector<SurfBezForInters> vSurfBez( nTotSurf) ;
double dSide = 0 ;
// punti di riferimento sul tool
// tip del tool
Point3d ptP1T ;
Point3d ptP2T ;
// determino la posizione della punta del tool nella posizione iniziale e in quella finale
ptP1T = ptS - dHeight * vtLs ;
ptP2T = ptE - dHeight * vtLe ;
// determino la direzione di movimento del top del tool e della punta del tool
Vector3d vtDirTop = ptE - ptS ;
Vector3d vtDirTip = ptP2T - ptP1T ;
Point3d ptP1T ;
Point3d ptP2T ;
// determino la posizione della punta del tool nella posizione iniziale e in quella finale
ptP1T = ptS - dHeight * vtLs ;
ptP2T = ptE - dHeight * vtLe ;
// determino la direzione di movimento del top del tool e della punta del tool
Vector3d vtDirTop = ptE - ptS ;
Vector3d vtDirTip = ptP2T - ptP1T ;
bool bTopIsPivot = vtDirTop.IsSmall() ;
bool bTipIsPivot = vtDirTip.IsSmall() ;
bool bTopAndTipAreEquiverse = vtDirTop * vtDirTip > 0 ;
// box dell'intero volume spazzato, nel riferimento object oriented
BBox3d bbVol ;
Frame3d frVol ; frVol.Set(ptS, vtLs, vtDirTop) ;
BBox3d bbVol ;
Frame3d frVol ; frVol.Set(ptS, vtLs, vtDirTop) ;
// punti sul top e tip del tool che servono per costruire le bilineare di congiunzione tra step
PNTVECTOR vPntTipStartFront(3) ;
PNTVECTOR vPntTipEndFront(3) ;
PNTVECTOR vPntTopStartFront(3) ;
PNTVECTOR vPntTopEndFront(3) ;
// punti addizionali che servono nei casi che rischiedono più superfici bilineari ( tutti tranne NO_BASE_INTERS)
PNTVECTOR vPntTipStartBack(3) ;
PNTVECTOR vPntTipEndBack(3) ;
PNTVECTOR vPntTopStartBack(3) ;
PNTVECTOR vPntTopEndBack(3) ;
if ( nSub > 1) {
// determino in che modo collegare il cilindro iniziale con quello finale
Vector3d vtTopBaseEnd = vtDirTop - (( vtDirTop * vtLe) * vtLe) ;
vtTopBaseEnd.Normalize() ;
vtTopBaseEnd *= dMaxRad ;
Point3d ptRefEnd = ptE - vtTopBaseEnd ;
Vector3d vtTopBaseStart = vtDirTop - (( vtDirTop * vtLs) * vtLs) ;
vtTopBaseStart.Normalize() ;
vtTopBaseStart *= dMaxRad ;
Point3d ptRefStart = ptS + vtTopBaseStart ;
dSide = ( ptRefEnd - ptRefStart) * vtLs ;
// punti sul top e tip del tool che servono per costruire le bilineare di congiunzione tra step
PNTVECTOR vPntTipStartFront(3) ;
PNTVECTOR vPntTipEndFront(3) ;
PNTVECTOR vPntTopStartFront(3) ;
PNTVECTOR vPntTopEndFront(3) ;
// punti addizionali che servono nei casi che rischiedono più superfici bilineari ( tutti tranne NO_BASE_INTERS)
PNTVECTOR vPntTipStartBack(3) ;
PNTVECTOR vPntTipEndBack(3) ;
PNTVECTOR vPntTopStartBack(3) ;
PNTVECTOR vPntTopEndBack(3) ;
if ( nSub > 1) {
if( bTopIsPivot)
vtDirTop = vtDirTip ;
if( bTipIsPivot)
vtDirTip = vtDirTop ;
// determino in che modo collegare il cilindro iniziale con quello finale
Vector3d vtTopBaseEnd = vtDirTop - (( vtDirTop * vtLe) * vtLe) ;
vtTopBaseEnd.Normalize() ;
vtTopBaseEnd *= dMaxRad ;
Point3d ptRefEnd = ptE - vtTopBaseEnd ;
Vector3d vtTopBaseStart = vtDirTop - (( vtDirTop * vtLs) * vtLs) ;
vtTopBaseStart.Normalize() ;
vtTopBaseStart *= dMaxRad ;
Point3d ptRefStart = ptS + vtTopBaseStart ;
dSide = ( ptRefEnd - ptRefStart) * vtLs ;
// calcolo anche i vettori per le basi inferiori
Vector3d vtTipBaseStart = -( vtLs ^ vtDirTip) ;
vtTipBaseStart.Normalize() ;
vtTipBaseStart *= dMinRad ;
Vector3d vtTipBaseEnd = -( vtLe ^ vtDirTip) ;
vtTipBaseEnd.Normalize() ;
vtTipBaseEnd *= dMinRad ;
// aggiungo il primo punto per ognuno dei gruppi
vtTopBaseStart.Rotate( vtLs, 90) ;
vtTopBaseEnd.Rotate( vtLe, 90) ;
vPntTopStartFront[0] = ptS - vtTopBaseStart ;
vPntTopEndFront[0] = ptE - vtTopBaseEnd ;
vPntTipStartFront[0] = ptP1T + vtTipBaseStart ;
vPntTipEndFront[0] = ptP2T + vtTipBaseEnd ;
// calcolo anche i vettori per le basi inferiori
Vector3d vtTipBaseStart = -( vtLs ^ vtDirTip) ;
vtTipBaseStart.Normalize() ;
vtTipBaseStart *= dMinRad ;
Vector3d vtTipBaseEnd = -( vtLe ^ vtDirTip) ;
vtTipBaseEnd.Normalize() ;
vtTipBaseEnd *= dMinRad ;
// aggiungo il primo punto per ognuno dei gruppi
vtTopBaseStart.Rotate( vtLs, 90) ;
vtTopBaseEnd.Rotate( vtLe, 90) ;
vPntTopStartFront[0] = ptS - vtTopBaseStart ;
vPntTopEndFront[0] = ptE - vtTopBaseEnd ;
vPntTipStartFront[0] = ptP1T + vtTipBaseStart ;
vPntTipEndFront[0] = ptP2T + vtTipBaseEnd ;
// punti addizionali per superfici bilineari
vPntTopStartBack[0] = ptS + vtTopBaseStart ;
vPntTopEndBack[0] = ptE + vtTopBaseEnd ;
vPntTipStartBack[0] = ptP1T - vtTipBaseStart ;
vPntTipEndBack[0] = ptP2T - vtTipBaseEnd ;
double dSubAng = 90 ;
// girano tutti in verso CCW rispetto alla normale del tool
for ( int i = 1; i < 3; ++i) {
// punti sulla base superiore dei cilindri
// start
// frontale
vPntTopStartFront[i] = vPntTopStartFront[i - 1] ;
vPntTopStartFront[i].Rotate( ptS, vtLs, dSubAng) ;
// posteriore
vPntTopStartBack[i] = vPntTopStartBack[i - 1];
vPntTopStartBack[i].Rotate( ptS, vtLs, dSubAng) ;
// end
// frontale
vPntTopEndFront[i] = vPntTopEndFront[i - 1] ;
vPntTopEndFront[i].Rotate( ptE, vtLe, dSubAng) ;
// posteriore
vPntTopEndBack[i] = vPntTopEndBack[i - 1] ;
vPntTopEndBack[i].Rotate( ptE, vtLe, dSubAng) ;
// punti addizionali per superfici bilineari
vPntTopStartBack[0] = ptS + vtTopBaseStart ;
vPntTopEndBack[0] = ptE + vtTopBaseEnd ;
vPntTipStartBack[0] = ptP1T - vtTipBaseStart ;
vPntTipEndBack[0] = ptP2T - vtTipBaseEnd ;
double dSubAng = 90 ;
// girano tutti in verso CCW rispetto alla normale del tool
for ( int i = 1; i < 3; ++i) {
// punti sulla base superiore dei cilindri
// start
// frontale
vPntTopStartFront[i] = vPntTopStartFront[i - 1] ;
vPntTopStartFront[i].Rotate( ptS, vtLs, dSubAng) ;
// posteriore
vPntTopStartBack[i] = vPntTopStartBack[i - 1];
vPntTopStartBack[i].Rotate( ptS, vtLs, dSubAng) ;
// end
// frontale
vPntTopEndFront[i] = vPntTopEndFront[i - 1] ;
vPntTopEndFront[i].Rotate( ptE, vtLe, dSubAng) ;
// posteriore
vPntTopEndBack[i] = vPntTopEndBack[i - 1] ;
vPntTopEndBack[i].Rotate( ptE, vtLe, dSubAng) ;
// punti sulla base inferiore dei cilindri
vPntTipStartFront[i] = vPntTipStartFront[i - 1] ;
vPntTipStartFront[i].Rotate( ptP1T, vtLs, dSubAng) ;
vPntTipStartBack[i] = vPntTipStartBack[i - 1] ;
vPntTipStartBack[i].Rotate( ptP1T, vtLs, dSubAng) ;
// punti sulla base inferiore dei cilindri
vPntTipStartFront[i] = vPntTipStartFront[i - 1] ;
vPntTipStartFront[i].Rotate( ptP1T, vtLs, dSubAng) ;
vPntTipStartBack[i] = vPntTipStartBack[i - 1] ;
vPntTipStartBack[i].Rotate( ptP1T, vtLs, dSubAng) ;
vPntTipEndFront[i] = vPntTipEndFront[i - 1] ;
vPntTipEndFront[i].Rotate( ptP2T, vtLe, dSubAng) ;
vPntTipEndBack[i] = vPntTipEndBack[i - 1] ;
vPntTipEndBack[i].Rotate( ptP2T, vtLe, dSubAng) ;
}
}
vPntTipEndFront[i] = vPntTipEndFront[i - 1] ;
vPntTipEndFront[i].Rotate( ptP2T, vtLe, dSubAng) ;
vPntTipEndBack[i] = vPntTipEndBack[i - 1] ;
vPntTipEndBack[i].Rotate( ptP2T, vtLe, dSubAng) ;
}
}
vector<PNTVECTOR> vvPtCtrl ;
// superficie laterale sinistra
CurveLine cLineLeftStart ; cLineLeftStart.Set( vPntTipStartFront.back(), vPntTopStartFront.back()) ;
PtrOwner<CurveBezier> cBezLeftStart( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftStart, nDegU, bRat))) ;
CurveLine cLineLeftEnd ; cLineLeftEnd.Set( vPntTipEndFront.back(), vPntTopEndFront.back()) ;
PtrOwner<CurveBezier> cBezLeftEnd( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftEnd, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezLeftStart->GetAllControlPoints()) ;
PNTVECTOR vPntLeft = cBezLeftEnd->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntLeft.begin(), vPntLeft.end()) ;
// superficie laterale destra
CurveLine cLineRightStart ; cLineRightStart.Set( vPntTopStartFront.front(), vPntTipStartFront.front()) ;
PtrOwner<CurveBezier> cBezRightStart( GetBasicCurveBezier( LineToBezierCurve( &cLineRightStart, nDegU, bRat))) ;
CurveLine cLineRightEnd ; cLineRightEnd.Set( vPntTopEndFront.front(), vPntTipEndFront.front()) ;
PtrOwner<CurveBezier> cBezRightEnd( GetBasicCurveBezier( LineToBezierCurve( &cLineRightEnd, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezRightStart->GetAllControlPoints()) ;
PNTVECTOR vPntRight = cBezRightEnd->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntRight.begin(), vPntRight.end()) ;
if ( nSub == 1) {
// superficie inferiore
vvPtCtrl.emplace_back( PNTVECTOR( { vPntTipStartFront.front(), vPntTipStartFront.back(), vPntTipEndFront.front(), vPntTipEndFront.back() })) ;
// superficie superiore
vvPtCtrl.emplace_back( PNTVECTOR( { vPntTopStartFront.back(), vPntTopStartFront.front(), vPntTopEndFront.back(), vPntTopEndFront.front() })) ;
}
else {
// costruisco tutti gli archi subito
// archi inferiori front
CurveArc cArcTipStartF1, cArcTipEndF1, cArcTipStartF2, cArcTipEndF2 ;
cArcTipStartF1.SetC2PN(ptP1T, vPntTipStartFront[0], vPntTipStartFront[1], vtLs);
cArcTipEndF1.SetC2PN(ptP2T, vPntTipEndFront[0], vPntTipEndFront[1], vtLe);
cArcTipStartF2.SetC2PN(ptP1T, vPntTipStartFront[1], vPntTipStartFront[2], vtLs);
cArcTipEndF2.SetC2PN(ptP2T, vPntTipEndFront[1], vPntTipEndFront[2], vtLe);
PtrOwner<CurveBezier> cBezTipStartF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipStartF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartF2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndF2, nDegU, bRat)));
// archi inferiori back
CurveArc cArcTipStartB1, cArcTipEndB1, cArcTipStartB2, cArcTipEndB2;
cArcTipStartB1.SetC2PN(ptP1T, vPntTipStartBack[0], vPntTipStartBack[1], vtLs);
cArcTipEndB1.SetC2PN(ptP2T, vPntTipEndBack[0], vPntTipEndBack[1], vtLe);
cArcTipStartB2.SetC2PN(ptP1T, vPntTipStartBack[1], vPntTipStartBack[2], vtLs);
cArcTipEndB2.SetC2PN(ptP2T, vPntTipEndBack[1], vPntTipEndBack[2], vtLe);
PtrOwner<CurveBezier> cBezTipStartB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipStartB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartB2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndB2, nDegU, bRat)));
// archi superiori front
CurveArc cArcTopStartF1, cArcTopEndF1, cArcTopStartF2, cArcTopEndF2;
cArcTopStartF1.SetC2PN(ptS, vPntTopStartFront[0], vPntTopStartFront[1], vtLs);
cArcTopEndF1.SetC2PN(ptE, vPntTopEndFront[0], vPntTopEndFront[1], vtLe);
cArcTopStartF2.SetC2PN(ptS, vPntTopStartFront[1], vPntTopStartFront[2], vtLs);
cArcTopEndF2.SetC2PN(ptE, vPntTopEndFront[1], vPntTopEndFront[2], vtLe);
PtrOwner<CurveBezier> cBezTopStartF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopStartF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartF2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndF2, nDegU, bRat)));
// archi superiori back
CurveArc cArcTopStartB1, cArcTopEndB1, cArcTopStartB2, cArcTopEndB2;
cArcTopStartB1.SetC2PN(ptS, vPntTopStartBack[0], vPntTopStartBack[1], vtLs);
cArcTopEndB1.SetC2PN(ptE, vPntTopEndBack[0], vPntTopEndBack[1], vtLe);
cArcTopStartB2.SetC2PN(ptS, vPntTopStartBack[1], vPntTopStartBack[2], vtLs);
cArcTopEndB2.SetC2PN(ptE, vPntTopEndBack[1], vPntTopEndBack[2], vtLe);
PtrOwner<CurveBezier> cBezTopStartB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopStartB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartB2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndB2, nDegU, bRat)));
vector<PNTVECTOR> vvPtCtrl ;
// superficie laterale sinistra
CurveLine cLineLeftStart ; cLineLeftStart.Set( vPntTipStartFront.back(), vPntTopStartFront.back()) ;
PtrOwner<CurveBezier> cBezLeftStart( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftStart, nDegU, bRat))) ;
CurveLine cLineLeftEnd ; cLineLeftEnd.Set( vPntTipEndFront.back(), vPntTopEndFront.back()) ;
PtrOwner<CurveBezier> cBezLeftEnd( GetBasicCurveBezier( LineToBezierCurve( &cLineLeftEnd, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezLeftStart->GetAllControlPoints()) ;
PNTVECTOR vPntLeft = cBezLeftEnd->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntLeft.begin(), vPntLeft.end()) ;
// superficie laterale destra
CurveLine cLineRightStart ; cLineRightStart.Set( vPntTopStartFront.front(), vPntTipStartFront.front()) ;
PtrOwner<CurveBezier> cBezRightStart( GetBasicCurveBezier( LineToBezierCurve( &cLineRightStart, nDegU, bRat))) ;
CurveLine cLineRightEnd ; cLineRightEnd.Set( vPntTopEndFront.front(), vPntTipEndFront.front()) ;
PtrOwner<CurveBezier> cBezRightEnd( GetBasicCurveBezier( LineToBezierCurve( &cLineRightEnd, nDegU, bRat))) ;
vvPtCtrl.emplace_back( cBezRightStart->GetAllControlPoints()) ;
PNTVECTOR vPntRight = cBezRightEnd->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntRight.begin(), vPntRight.end()) ;
if ( nSub == 1) {
// superficie inferiore
vvPtCtrl.emplace_back( PNTVECTOR( { vPntTipStartFront.front(), vPntTipStartFront.back(), vPntTipEndFront.front(), vPntTipEndFront.back() })) ;
// superficie superiore
vvPtCtrl.emplace_back( PNTVECTOR( { vPntTopStartFront.back(), vPntTopStartFront.front(), vPntTopEndFront.back(), vPntTopEndFront.front() })) ;
}
else {
// costruisco tutti gli archi subito
// archi inferiori front
CurveArc cArcTipStartF1, cArcTipEndF1, cArcTipStartF2, cArcTipEndF2 ;
if ( ! cArcTipStartF1.SetC2PN(ptP1T, vPntTipStartFront[0], vPntTipStartFront[1], vtLs) ||
! cArcTipEndF1.SetC2PN(ptP2T, vPntTipEndFront[0], vPntTipEndFront[1], vtLe) ||
! cArcTipStartF2.SetC2PN(ptP1T, vPntTipStartFront[1], vPntTipStartFront[2], vtLs) ||
! cArcTipEndF2.SetC2PN(ptP2T, vPntTipEndFront[1], vPntTipEndFront[2], vtLe))
return false ;
PtrOwner<CurveBezier> cBezTipStartF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipStartF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartF2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndF2, nDegU, bRat)));
// archi inferiori back
CurveArc cArcTipStartB1, cArcTipEndB1, cArcTipStartB2, cArcTipEndB2;
if ( ! cArcTipStartB1.SetC2PN(ptP1T, vPntTipStartBack[0], vPntTipStartBack[1], vtLs) ||
! cArcTipEndB1.SetC2PN(ptP2T, vPntTipEndBack[0], vPntTipEndBack[1], vtLe) ||
! cArcTipStartB2.SetC2PN(ptP1T, vPntTipStartBack[1], vPntTipStartBack[2], vtLs) ||
! cArcTipEndB2.SetC2PN(ptP2T, vPntTipEndBack[1], vPntTipEndBack[2], vtLe))
return false ;
PtrOwner<CurveBezier> cBezTipStartB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipStartB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipStartB2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTipEndB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTipEndB2, nDegU, bRat)));
if ( IsNull( cBezTipStartB1) || IsNull( cBezTipEndB1) || IsNull( cBezTipStartB2) || IsNull( cBezTipEndB2))
return false ;
// archi superiori front
CurveArc cArcTopStartF1, cArcTopEndF1, cArcTopStartF2, cArcTopEndF2;
if ( ! cArcTopStartF1.SetC2PN(ptS, vPntTopStartFront[0], vPntTopStartFront[1], vtLs) ||
! cArcTopEndF1.SetC2PN(ptE, vPntTopEndFront[0], vPntTopEndFront[1], vtLe) ||
! cArcTopStartF2.SetC2PN(ptS, vPntTopStartFront[1], vPntTopStartFront[2], vtLs) ||
! cArcTopEndF2.SetC2PN(ptE, vPntTopEndFront[1], vPntTopEndFront[2], vtLe))
return false ;
PtrOwner<CurveBezier> cBezTopStartF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndF1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndF1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopStartF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartF2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndF2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndF2, nDegU, bRat)));
if ( IsNull( cBezTopStartF1) || IsNull( cBezTopEndF1) || IsNull( cBezTopStartF2) || IsNull( cBezTopEndF2))
return false ;
// archi superiori back
CurveArc cArcTopStartB1, cArcTopEndB1, cArcTopStartB2, cArcTopEndB2;
if ( ! cArcTopStartB1.SetC2PN(ptS, vPntTopStartBack[0], vPntTopStartBack[1], vtLs) ||
! cArcTopEndB1.SetC2PN(ptE, vPntTopEndBack[0], vPntTopEndBack[1], vtLe) ||
! cArcTopStartB2.SetC2PN(ptS, vPntTopStartBack[1], vPntTopStartBack[2], vtLs) ||
! cArcTopEndB2.SetC2PN(ptE, vPntTopEndBack[1], vPntTopEndBack[2], vtLe))
return false ;
PtrOwner<CurveBezier> cBezTopStartB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndB1(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndB1, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopStartB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopStartB2, nDegU, bRat)));
PtrOwner<CurveBezier> cBezTopEndB2(GetBasicCurveBezier(ArcToBezierCurve(&cArcTopEndB2, nDegU, bRat)));
if ( IsNull( cBezTopStartB1) || IsNull( cBezTopEndB1) || IsNull( cBezTopStartB2) || IsNull( cBezTopEndB2))
return false ;
if ( n5AxisType == Move5Axis::NO_BASE_INTERS || n5AxisType == Move5Axis::ACROSS) {
if ( n5AxisType == Move5Axis::NO_BASE_INTERS || n5AxisType == Move5Axis::ACROSS) {
if ( ! bTipIsPivot) {
// inferiori
CurveArc cArcTipStart1, cArcTipEnd1, cArcTipStart2, cArcTipEnd2 ;
if ( dSide > 0) {
vvPtCtrl.emplace_back(cBezTipStartF1->GetAllControlPoints());
PNTVECTOR vPntTipEnd1 = cBezTipEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd1.begin(), vPntTipEnd1.end());
vvPtCtrl.emplace_back(cBezTipStartF2->GetAllControlPoints());
PNTVECTOR vPntTipEnd2 = cBezTipEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd2.begin(), vPntTipEnd2.end());
vvPtCtrl.emplace_back(cBezTipStartF1->GetAllControlPoints());
PNTVECTOR vPntTipEnd1 = cBezTipEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd1.begin(), vPntTipEnd1.end());
vvPtCtrl.emplace_back(cBezTipStartF2->GetAllControlPoints());
PNTVECTOR vPntTipEnd2 = cBezTipEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd2.begin(), vPntTipEnd2.end());
}
else {
PNTVECTOR vPntTipEnd01 = cBezTipStartB1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTipEnd01.rbegin(), vPntTipEnd01.rend());
PNTVECTOR vPntTipEnd1 = cBezTipEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd1.rbegin(), vPntTipEnd1.rend());
PNTVECTOR vPntTipEnd02 = cBezTipStartB2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTipEnd02.rbegin(), vPntTipEnd02.rend());
PNTVECTOR vPntTipEnd2 = cBezTipEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd2.rbegin(), vPntTipEnd2.rend());
PNTVECTOR vPntTipEnd01 = cBezTipStartB1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTipEnd01.rbegin(), vPntTipEnd01.rend());
PNTVECTOR vPntTipEnd1 = cBezTipEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd1.rbegin(), vPntTipEnd1.rend());
PNTVECTOR vPntTipEnd02 = cBezTipStartB2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTipEnd02.rbegin(), vPntTipEnd02.rend());
PNTVECTOR vPntTipEnd2 = cBezTipEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTipEnd2.rbegin(), vPntTipEnd2.rend());
}
}
if ( ! bTopIsPivot) {
// superiori
if ( dSide > 0) {
vvPtCtrl.emplace_back(cBezTopStartB1->GetAllControlPoints());
PNTVECTOR vPntTopEnd1 = cBezTopEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd1.begin(), vPntTopEnd1.end());
vvPtCtrl.emplace_back(cBezTopStartB2->GetAllControlPoints());
PNTVECTOR vPntTopEnd2 = cBezTopEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd2.begin(), vPntTopEnd2.end());
vvPtCtrl.emplace_back(cBezTopStartB1->GetAllControlPoints());
PNTVECTOR vPntTopEnd1 = cBezTopEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd1.begin(), vPntTopEnd1.end());
vvPtCtrl.emplace_back(cBezTopStartB2->GetAllControlPoints());
PNTVECTOR vPntTopEnd2 = cBezTopEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd2.begin(), vPntTopEnd2.end());
}
else {
PNTVECTOR vPntTopEnd01 = cBezTopStartF1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTopEnd01.rbegin(), vPntTopEnd01.rend());
PNTVECTOR vPntTopEnd1 = cBezTopEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd1.rbegin(), vPntTopEnd1.rend());
PNTVECTOR vPntTopEnd02 = cBezTopStartF2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTopEnd02.rbegin(), vPntTopEnd02.rend());
PNTVECTOR vPntTopEnd2 = cBezTopEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd2.rbegin(), vPntTopEnd2.rend());
PNTVECTOR vPntTopEnd01 = cBezTopStartF1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTopEnd01.rbegin(), vPntTopEnd01.rend());
PNTVECTOR vPntTopEnd1 = cBezTopEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd1.rbegin(), vPntTopEnd1.rend());
PNTVECTOR vPntTopEnd02 = cBezTopStartF2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTopEnd02.rbegin(), vPntTopEnd02.rend());
PNTVECTOR vPntTopEnd2 = cBezTopEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTopEnd2.rbegin(), vPntTopEnd2.rend());
}
}
// aggiungo le superfici bilineari anche nell'altro verso sia per il top che per il tip
if ( n5AxisType == Move5Axis::ACROSS) {
if ( ! bTipIsPivot) {
// inferiori
if ( dSide > 0) {
PNTVECTOR vPntTip01 = cBezTipStartB1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTip01.rbegin(), vPntTip01.rend());
PNTVECTOR vPntTip1 = cBezTipEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip1.rbegin(), vPntTip1.rend());
PNTVECTOR vPntTip02 = cBezTipStartB2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTip02.rbegin(), vPntTip02.rend());
PNTVECTOR vPntTip2 = cBezTipEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip2.rbegin(), vPntTip2.rend());
}
else {
vvPtCtrl.emplace_back(cBezTipStartF1->GetAllControlPoints());
PNTVECTOR vPntTip1 = cBezTipEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip1.begin(), vPntTip1.end());
vvPtCtrl.emplace_back(cBezTipStartF2->GetAllControlPoints());
PNTVECTOR vPntTip2 = cBezTipEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip2.begin(), vPntTip2.end());
}
}
// aggiungo le superfici bilineari anche nell'altro verso sia per il top che per il tip
if ( n5AxisType == Move5Axis::ACROSS) {
// inferiori
if ( dSide > 0) {
PNTVECTOR vPntTip01 = cBezTipStartB1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTip01.rbegin(), vPntTip01.rend());
PNTVECTOR vPntTip1 = cBezTipEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip1.rbegin(), vPntTip1.rend());
PNTVECTOR vPntTip02 = cBezTipStartB2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTip02.rbegin(), vPntTip02.rend());
PNTVECTOR vPntTip2 = cBezTipEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip2.rbegin(), vPntTip2.rend());
}
else {
vvPtCtrl.emplace_back(cBezTipStartF1->GetAllControlPoints());
PNTVECTOR vPntTip1 = cBezTipEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip1.begin(), vPntTip1.end());
vvPtCtrl.emplace_back(cBezTipStartF2->GetAllControlPoints());
PNTVECTOR vPntTip2 = cBezTipEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTip2.begin(), vPntTip2.end());
}
// superiori
if ( dSide > 0) {
PNTVECTOR vPntTop01 = cBezTopStartF1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTop01.rbegin(), vPntTop01.rend());
PNTVECTOR vPntTop1 = cBezTopEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop1.rbegin(), vPntTop1.rend());
PNTVECTOR vPntTop02 = cBezTopStartF2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTop02.rbegin(), vPntTop02.rend());
PNTVECTOR vPntTop2 = cBezTopEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop2.rbegin(), vPntTop2.rend());
}
else {
vvPtCtrl.emplace_back(cBezTopStartB1->GetAllControlPoints());
PNTVECTOR vPntTop1 = cBezTopEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop1.begin(), vPntTop1.end());
vvPtCtrl.emplace_back(cBezTopStartB2->GetAllControlPoints());
PNTVECTOR vPntTop2 = cBezTopEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop2.begin(), vPntTop2.end());
}
if( ! bTopIsPivot) {
// superiori
if ( dSide > 0) {
PNTVECTOR vPntTop01 = cBezTopStartF1->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTop01.rbegin(), vPntTop01.rend());
PNTVECTOR vPntTop1 = cBezTopEndF1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop1.rbegin(), vPntTop1.rend());
PNTVECTOR vPntTop02 = cBezTopStartF2->GetAllControlPoints();
vvPtCtrl.emplace_back(vPntTop02.rbegin(), vPntTop02.rend());
PNTVECTOR vPntTop2 = cBezTopEndF2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop2.rbegin(), vPntTop2.rend());
}
else {
vvPtCtrl.emplace_back(cBezTopStartB1->GetAllControlPoints());
PNTVECTOR vPntTop1 = cBezTopEndB1->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop1.begin(), vPntTop1.end());
vvPtCtrl.emplace_back(cBezTopStartB2->GetAllControlPoints());
PNTVECTOR vPntTop2 = cBezTopEndB2->GetAllControlPoints();
vvPtCtrl.back().insert(vvPtCtrl.back().end(), vPntTop2.begin(), vPntTop2.end());
}
}
}
}
}
// chiudo il volume con le superfici verticali e le basi dei tool
// chiudo il volume con le superfici verticali e le basi dei tool
// chiudo il volume con le superici verticali end 1
vvPtCtrl.emplace_back( cBezTipEndF1->GetAllControlPoints()) ;
PNTVECTOR vPntEnd1 = cBezTopEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntEnd1.begin(), vPntEnd1.end()) ;
// chiudo il volume con le superici verticali end 2
vvPtCtrl.emplace_back( cBezTipEndF2->GetAllControlPoints()) ;
PNTVECTOR vPntEnd2 = cBezTopEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntEnd2.begin(), vPntEnd2.end()) ;
// chiudo il volume con le superici verticali end 1
vvPtCtrl.emplace_back( cBezTipEndF1->GetAllControlPoints()) ;
PNTVECTOR vPntEnd1 = cBezTopEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntEnd1.begin(), vPntEnd1.end()) ;
// chiudo il volume con le superici verticali end 2
vvPtCtrl.emplace_back( cBezTipEndF2->GetAllControlPoints()) ;
PNTVECTOR vPntEnd2 = cBezTopEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntEnd2.begin(), vPntEnd2.end()) ;
// chiudo il volume con le superici verticali start 1
vvPtCtrl.emplace_back( cBezTipStartB1->GetAllControlPoints()) ;
PNTVECTOR vPntStart1 = cBezTopStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntStart1.begin(), vPntStart1.end()) ;
// chiudo il volume con le superfici verticali start 2
vvPtCtrl.emplace_back( cBezTipStartB2->GetAllControlPoints()) ;
PNTVECTOR vPntStart2 = cBezTopStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntStart2.begin(), vPntStart2.end()) ;
// chiudo il volume con le superici verticali start 1
vvPtCtrl.emplace_back( cBezTipStartB1->GetAllControlPoints()) ;
PNTVECTOR vPntStart1 = cBezTopStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntStart1.begin(), vPntStart1.end()) ;
// chiudo il volume con le superfici verticali start 2
vvPtCtrl.emplace_back( cBezTipStartB2->GetAllControlPoints()) ;
PNTVECTOR vPntStart2 = cBezTopStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntStart2.begin(), vPntStart2.end()) ;
// superfici di base dei tool
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide < 0)) {
// start back tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartBack1 = cBezTipStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartBack1.begin(), vPntTipStartBack1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartBack2 = cBezTipStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartBack2.begin(), vPntTipStartBack2.end()) ;
// start front tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartFront1 = cBezTipStartF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartFront1.begin(), vPntTipStartFront1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartFront2 = cBezTipStartF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartFront2.begin(), vPntTipStartFront2.end()) ;
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide > 0)) {
// end front tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndFront1 = cBezTipEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndFront1.begin(), vPntTipEndFront1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndFront2 = cBezTipEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndFront2.begin(), vPntTipEndFront2.end()) ;
// end back tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndBack1 = cBezTipEndB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndBack1.begin(), vPntTipEndBack1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndBack2 = cBezTipEndB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndBack2.begin(), vPntTipEndBack2.end()) ;
}
// superfici di base dei tool
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide < 0)) {
// start back tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartBack1 = cBezTipStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartBack1.begin(), vPntTipStartBack1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartBack2 = cBezTipStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartBack2.begin(), vPntTipStartBack2.end()) ;
// start front tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartFront1 = cBezTipStartF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartFront1.begin(), vPntTipStartFront1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP1T, ptP1T, ptP1T, ptP1T }) ;
PNTVECTOR vPntTipStartFront2 = cBezTipStartF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipStartFront2.begin(), vPntTipStartFront2.end()) ;
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide > 0)) {
// end front tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndFront1 = cBezTipEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndFront1.begin(), vPntTipEndFront1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndFront2 = cBezTipEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndFront2.begin(), vPntTipEndFront2.end()) ;
// end back tip
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndBack1 = cBezTipEndB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndBack1.begin(), vPntTipEndBack1.end()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptP2T, ptP2T, ptP2T, ptP2T }) ;
PNTVECTOR vPntTipEndBack2 = cBezTipEndB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTipEndBack2.begin(), vPntTipEndBack2.end()) ;
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide > 0)) {
// start back top
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartBack1 = cBezTopStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartBack1.rbegin(), vPntTopStartBack1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartBack2 = cBezTopStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartBack2.rbegin(), vPntTopStartBack2.rend()) ;
// start front top
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartFront1 = cBezTopStartF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartFront1.rbegin(), vPntTopStartFront1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartFront2 = cBezTopStartF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartFront2.rbegin(), vPntTopStartFront2.rend()) ;
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide < 0)) {
// end front top
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndFront1 = cBezTopEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndFront1.rbegin(), vPntTopEndFront1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndFront2 = cBezTopEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndFront2.rbegin(), vPntTopEndFront2.rend()) ;
// end back top
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndBack1 = cBezTopEndB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndBack1.rbegin(), vPntTopEndBack1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndBack2 = cBezTopEndB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndBack2.rbegin(), vPntTopEndBack2.rend()) ;
}
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide > 0)) {
// start back top
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartBack1 = cBezTopStartB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartBack1.rbegin(), vPntTopStartBack1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartBack2 = cBezTopStartB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartBack2.rbegin(), vPntTopStartBack2.rend()) ;
// start front top
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartFront1 = cBezTopStartF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartFront1.rbegin(), vPntTopStartFront1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptS, ptS, ptS, ptS }) ;
PNTVECTOR vPntTopStartFront2 = cBezTopStartF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopStartFront2.rbegin(), vPntTopStartFront2.rend()) ;
}
if ( ! ( n5AxisType == Move5Axis::NO_BASE_INTERS && dSide < 0)) {
// end front top
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndFront1 = cBezTopEndF1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndFront1.rbegin(), vPntTopEndFront1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndFront2 = cBezTopEndF2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndFront2.rbegin(), vPntTopEndFront2.rend()) ;
// end back top
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndBack1 = cBezTopEndB1->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndBack1.rbegin(), vPntTopEndBack1.rend()) ;
vvPtCtrl.emplace_back( PNTVECTOR{ ptE, ptE, ptE, ptE }) ;
PNTVECTOR vPntTopEndBack2 = cBezTopEndB2->GetAllControlPoints() ;
vvPtCtrl.back().insert( vvPtCtrl.back().end(), vPntTopEndBack2.rbegin(), vPntTopEndBack2.rend()) ;
}
}
// inizializzo le superfici bilineari e i parametri per le intersezioni
for ( int z = 0 ; z < int( vvPtCtrl.size()) ; ++z) {
vSurfBez[nSurfInd].sBez.Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 0, vvPtCtrl[z][0]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 1, vvPtCtrl[z][1]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 2, vvPtCtrl[z][2]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 3, vvPtCtrl[z][3]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 4, vvPtCtrl[z][4]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 5, vvPtCtrl[z][5]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 6, vvPtCtrl[z][6]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 7, vvPtCtrl[z][7]) ;
// inizializzo le superfici bilineari e i parametri per le intersezioni
for ( int z = 0 ; z < int( vvPtCtrl.size()) ; ++z) {
vSurfBez[nSurfInd].sBez.Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 0, vvPtCtrl[z][0]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 1, vvPtCtrl[z][1]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 2, vvPtCtrl[z][2]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 3, vvPtCtrl[z][3]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 4, vvPtCtrl[z][4]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 5, vvPtCtrl[z][5]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 6, vvPtCtrl[z][6]) ;
vSurfBez[nSurfInd].sBez.SetControlPoint( 7, vvPtCtrl[z][7]) ;
Vector3d A = vvPtCtrl[z][4] - vvPtCtrl[z][0] ;
Vector3d B = vvPtCtrl[z][5] - vvPtCtrl[z][1] ;
Vector3d C = vvPtCtrl[z][6] - vvPtCtrl[z][2] ;
Vector3d D = vvPtCtrl[z][7] - vvPtCtrl[z][3] ;
Vector3d E = vvPtCtrl[z][0] - ORIG ;
Vector3d F = vvPtCtrl[z][1] - ORIG ;
Vector3d G = vvPtCtrl[z][2] - ORIG ;
Vector3d H = vvPtCtrl[z][3] - ORIG ;
Vector3d A = vvPtCtrl[z][4] - vvPtCtrl[z][0] ;
Vector3d B = vvPtCtrl[z][5] - vvPtCtrl[z][1] ;
Vector3d C = vvPtCtrl[z][6] - vvPtCtrl[z][2] ;
Vector3d D = vvPtCtrl[z][7] - vvPtCtrl[z][3] ;
Vector3d E = vvPtCtrl[z][0] - ORIG ;
Vector3d F = vvPtCtrl[z][1] - ORIG ;
Vector3d G = vvPtCtrl[z][2] - ORIG ;
Vector3d H = vvPtCtrl[z][3] - ORIG ;
vSurfBez[nSurfInd].a3 = -A + 3 * B - 3 * C + D ;
vSurfBez[nSurfInd].a2 = 3 * A - 6 * B + 3 * C ;
vSurfBez[nSurfInd].a1 = -3 * A + 3 * B ;
vSurfBez[nSurfInd].a0 = A ;
vSurfBez[nSurfInd].a3 = -A + 3 * B - 3 * C + D ;
vSurfBez[nSurfInd].a2 = 3 * A - 6 * B + 3 * C ;
vSurfBez[nSurfInd].a1 = -3 * A + 3 * B ;
vSurfBez[nSurfInd].a0 = A ;
vSurfBez[nSurfInd].b3 = -E + 3 * F - 3 * G + H ;
vSurfBez[nSurfInd].b2 = 3 * E - 6 * F + 3 * G ;
vSurfBez[nSurfInd].b1 = -3 * E + 3 * F ;
vSurfBez[nSurfInd].b0 = E ;
vSurfBez[nSurfInd].b3 = -E + 3 * F - 3 * G + H ;
vSurfBez[nSurfInd].b2 = 3 * E - 6 * F + 3 * G ;
vSurfBez[nSurfInd].b1 = -3 * E + 3 * F ;
vSurfBez[nSurfInd].b0 = E ;
Vector3d vtDirZ = vvPtCtrl[z][4] - vvPtCtrl[z][0] ;
Vector3d vtDirX = vvPtCtrl[z][3] - vvPtCtrl[z][0] ;
Vector3d vtDirZ = vvPtCtrl[z][4] - vvPtCtrl[z][0] ;
Vector3d vtDirX = vvPtCtrl[z][3] - vvPtCtrl[z][0] ;
// devo gestire il caso in cui uno dei due vettori sia == 0
if (vtDirZ.IsSmall()) {
vtDirZ = vvPtCtrl[z][7] - vvPtCtrl[z][4];
}
if (vtDirX.IsSmall()) {
vtDirX = vvPtCtrl[z][7] - vvPtCtrl[z][3];
}
// calcolo il box in un riferimento che usi come asse x la direzione P10 - P00 o P11 - P01 ( proiettata sul piano perperndicolare a Z)
if ( vSurfBez[nSurfInd].frBox.Set( ORIG, vtDirZ, vtDirX)) {
// porto tutti i punti in quel riferimento e calcolo il box
PNTVECTOR vPtCtrlLoc = vvPtCtrl[z] ;
for ( int p = 0 ; p < int( vPtCtrlLoc.size()) ; ++p)
vPtCtrlLoc[p].ToLoc( vSurfBez[nSurfInd].frBox) ;
vSurfBez[nSurfInd].bbSurfOriented.Add( vPtCtrlLoc) ;
}
// devo gestire il caso in cui uno dei due vettori sia == 0
if (vtDirZ.IsSmall()) {
vtDirZ = vvPtCtrl[z][7] - vvPtCtrl[z][4];
}
if (vtDirX.IsSmall()) {
vtDirX = vvPtCtrl[z][7] - vvPtCtrl[z][3];
}
// calcolo il box in un riferimento che usi come asse x la direzione P10 - P00 o P11 - P01 ( proiettata sul piano perperndicolare a Z)
if ( vSurfBez[nSurfInd].frBox.Set( ORIG, vtDirZ, vtDirX)) {
// porto tutti i punti in quel riferimento e calcolo il box
PNTVECTOR vPtCtrlLoc = vvPtCtrl[z] ;
for ( int p = 0 ; p < int( vPtCtrlLoc.size()) ; ++p)
vPtCtrlLoc[p].ToLoc( vSurfBez[nSurfInd].frBox) ;
vSurfBez[nSurfInd].bbSurfOriented.Add( vPtCtrlLoc) ;
}
// aggiungo i punti al box del volume spazzato
PNTVECTOR vPtCtrlLoc = vvPtCtrl[z] ;
for (int p = 0; p < int(vPtCtrlLoc.size()); ++p)
vPtCtrlLoc[p].ToLoc(frVol);
bbVol.Add(vPtCtrlLoc) ;
// aggiungo i punti al box del volume spazzato
PNTVECTOR vPtCtrlLoc = vvPtCtrl[z] ;
for (int p = 0; p < int(vPtCtrlLoc.size()); ++p)
vPtCtrlLoc[p].ToLoc(frVol);
bbVol.Add(vPtCtrlLoc) ;
++ nSurfInd ;
}
++ nSurfInd ;
}
// scorro tutti gli spilloni interessati
int j = 0 ;
@@ -2375,7 +2398,7 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
InitializePointsAndVectors( ptSti, ptEni, vtDSi, vtDEi, ptLs, ptLe, vtLs, vtLe) ;
// Standard è multithread
constexpr bool MULTITHREAD = true ;
constexpr bool MULTITHREAD = false ;
if ( MULTITHREAD) {
// Ciclo sulle mappe
vector<future<bool>> vRes( m_nMapNum) ;