Merge branch 'master' into NewRuled
This commit is contained in:
@@ -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
@@ -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) ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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 ;
|
||||
|
||||
Binary file not shown.
@@ -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" />
|
||||
|
||||
@@ -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
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 ;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 ;
|
||||
|
||||
@@ -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
@@ -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
@@ -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) ;
|
||||
|
||||
Reference in New Issue
Block a user