Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2023ba3f7d | |||
| 27c1823a54 | |||
| f111827545 | |||
| 7cdc1ba5a3 | |||
| 1d68a1ee8e | |||
| 6f7b614c3a | |||
| f02f29c543 | |||
| 06cfe1bb96 | |||
| 736353bbac | |||
| f4b3312672 | |||
| 3178bb5f27 | |||
| 552ce70231 | |||
| c2a79b2665 | |||
| f72c949563 | |||
| bdcb00d1bd | |||
| 42fcb1847b | |||
| a7b36280f3 | |||
| cdef3931be | |||
| d3f2587cc2 | |||
| d343f474e4 | |||
| b7fee9696e | |||
| 4f48337f62 | |||
| 96907d5952 | |||
| 3c5d2571fe | |||
| 7005bf43a4 | |||
| 4726cf4d35 | |||
| b971eda771 | |||
| 3ded6fe87d | |||
| 5195c23dfb | |||
| 5f1255a625 |
@@ -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
|
// Contenuto : Implementazione funzione verifica collisione tra
|
||||||
// SurfTm e SurfTm.
|
// SurfTm e SurfTm.
|
||||||
//
|
//
|
||||||
// Modifiche : 13.11.20 LM Creazione modulo.
|
// Modifiche : 13.11.20 LM Creazione modulo.
|
||||||
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
|
// 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 ;
|
BBox3d b3BoxA, b3BoxB ;
|
||||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
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)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxB.Expand( dSafeDist) ;
|
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))
|
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||||
return false ;
|
return false ;
|
||||||
// Recupero i triangoli di A che interferiscono col box di B
|
// Recupero i triangoli di A che interferiscono col box di B
|
||||||
@@ -61,13 +62,13 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
continue ;
|
continue ;
|
||||||
BBox3d b3BoxTriaA ;
|
BBox3d b3BoxTriaA ;
|
||||||
trTriaA.GetLocalBBox( 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)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxTriaA.Expand( dSafeDist) ;
|
b3BoxTriaA.Expand( dSafeDist) ;
|
||||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, 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.
|
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||||
pSrfB->ResetTempInts() ;
|
pSrfB->ResetTempInts() ;
|
||||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
// 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.
|
// Ciclo sui vertici del triangolo.
|
||||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
// 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 ;
|
int nAdjTriaTempFlag ;
|
||||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||||
continue ;
|
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))
|
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||||
return true ;
|
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) ;
|
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||||
double dEdgeLen = vtEdgeV.Len() ;
|
double dEdgeLen = vtEdgeV.Len() ;
|
||||||
vtEdgeV /= dEdgeLen ;
|
vtEdgeV /= dEdgeLen ;
|
||||||
@@ -111,10 +112,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
// 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))
|
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||||
return false ;
|
return false ;
|
||||||
// La collisione c'è se una superficie è dentro l'altra.
|
// La collisione c'è se una superficie è dentro l'altra.
|
||||||
Point3d ptPointA, ptPointB ;
|
Point3d ptPointA, ptPointB ;
|
||||||
pSrfA->GetFirstVertex( ptPointA) ;
|
pSrfA->GetFirstVertex( ptPointA) ;
|
||||||
pSrfB->GetFirstVertex( ptPointB) ;
|
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.
|
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
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
|
// Recupero le superfici base
|
||||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||||
@@ -140,10 +141,10 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
BBox3d b3BoxA, b3BoxB ;
|
BBox3d b3BoxA, b3BoxB ;
|
||||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
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)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxB.Expand( dSafeDist) ;
|
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))
|
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||||
return false ;
|
return false ;
|
||||||
// Recupero i triangoli di A che interferiscono col box di B
|
// 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 ;
|
continue ;
|
||||||
BBox3d b3BoxTriaA ;
|
BBox3d b3BoxTriaA ;
|
||||||
trTriaA.GetLocalBBox( 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)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxTriaA.Expand( dSafeDist) ;
|
b3BoxTriaA.Expand( dSafeDist) ;
|
||||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, 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.
|
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||||
pSrfB->ResetTempInts() ;
|
pSrfB->ResetTempInts() ;
|
||||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
// 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.
|
// Ciclo sui vertici del triangolo.
|
||||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
// 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 ;
|
int nAdjTriaTempFlag ;
|
||||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||||
continue ;
|
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))
|
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||||
return true ;
|
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) ;
|
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||||
double dEdgeLen = vtEdgeV.Len() ;
|
double dEdgeLen = vtEdgeV.Len() ;
|
||||||
vtEdgeV /= dEdgeLen ;
|
vtEdgeV /= dEdgeLen ;
|
||||||
@@ -205,6 +206,25 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
pSrfB->SetTempInt( nTB, 1) ;
|
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 ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,233 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2026
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : CalcDerivate.cpp Data : 03.02.26 Versione : 1.5h1
|
||||||
|
// Contenuto : Funzioni per calcolo derivate secondo Bessel e Akima.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 03.02.26 DB Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "CalcDerivate.h"
|
||||||
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||||
|
{
|
||||||
|
// pulisco i vettori dei parametri e delle tangenti
|
||||||
|
vPrevDer.clear() ;
|
||||||
|
vNextDer.clear() ;
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// calcolo le derivate
|
||||||
|
vPrevDer.reserve( nSize) ;
|
||||||
|
vNextDer.reserve( nSize) ;
|
||||||
|
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||||
|
if ( nSize == 2) {
|
||||||
|
// non esiste derivata prima del primo punto
|
||||||
|
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||||
|
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||||
|
vPrevDer.push_back( vNextDer[0]) ;
|
||||||
|
// non esiste derivata dopo il secondo e ultimo punto
|
||||||
|
vNextDer.emplace_back( 0, 0, 0) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||||
|
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||||
|
// calcolo le derivate
|
||||||
|
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||||
|
Vector3d vtPrevDer ;
|
||||||
|
Vector3d vtNextDer ;
|
||||||
|
// primo punto
|
||||||
|
if ( i == 0) {
|
||||||
|
// se curva chiusa, come precedente uso il penultimo punto
|
||||||
|
if ( bClosed) {
|
||||||
|
// se non ci sono almeno 5 punti
|
||||||
|
if ( nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = vtNextDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[nSize-3] - vPar[nSize-1], vPnt[nSize-3], vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// altrimenti, uso arco sui primi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcCircleStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ultimo punto
|
||||||
|
else if ( i == nSize - 1) {
|
||||||
|
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||||
|
if ( bClosed) {
|
||||||
|
vtPrevDer = vPrevDer[0] ;
|
||||||
|
vtNextDer = vNextDer[0] ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso arco sugli ultimi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcCircleEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// punti intermedi
|
||||||
|
else {
|
||||||
|
// se secondo punto
|
||||||
|
if ( i == 1) {
|
||||||
|
// se curva aperta o non ci sono almeno 5 punti
|
||||||
|
if ( ! bClosed || nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se penultimo punto
|
||||||
|
else if ( i == nSize - 2) {
|
||||||
|
// se curva aperta o non ci sono almeno 5 punti
|
||||||
|
if ( ! bClosed || nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[1] + vPar[i+1], vPnt[1], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// salvo la derivata
|
||||||
|
vPrevDer.push_back( vtPrevDer) ;
|
||||||
|
vNextDer.push_back( vtNextDer) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||||
|
{
|
||||||
|
// pulisco i vettori dei parametri e delle tangenti
|
||||||
|
vPrevDer.clear() ;
|
||||||
|
vNextDer.clear() ;
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// calcolo le derivate
|
||||||
|
vPrevDer.reserve( nSize) ;
|
||||||
|
vNextDer.reserve( nSize) ;
|
||||||
|
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||||
|
if ( nSize == 2) {
|
||||||
|
// non esiste derivata prima del primo punto
|
||||||
|
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||||
|
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||||
|
vPrevDer.push_back( vNextDer[0]) ;
|
||||||
|
// non esiste derivata dopo il secondo e ultimo punto
|
||||||
|
vNextDer.emplace_back( 0, 0, 0) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||||
|
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||||
|
// calcolo le derivate
|
||||||
|
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||||
|
Vector3d vtPrevDer ;
|
||||||
|
Vector3d vtNextDer ;
|
||||||
|
// primo punto
|
||||||
|
if ( i == 0) {
|
||||||
|
// se curva chiusa, come precedente uso il penultimo punto
|
||||||
|
if ( bClosed) {
|
||||||
|
if ( ! CalcBesselMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = vtNextDer ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso i primi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ultimo punto
|
||||||
|
else if ( i == nSize - 1) {
|
||||||
|
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||||
|
if ( bClosed) {
|
||||||
|
vtPrevDer = vPrevDer[0] ;
|
||||||
|
vtNextDer = vNextDer[0] ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso gli ultimi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// punti intermedi
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// salvo la derivata
|
||||||
|
vPrevDer.push_back( vtPrevDer) ;
|
||||||
|
vNextDer.push_back( vtNextDer) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -179,3 +181,6 @@ CalcAkimaMidDer( double dU0, const Point3d& ptP0, double dU1, const Point3d& ptP
|
|||||||
}
|
}
|
||||||
return ( ! vtPrevDer.IsZero() && ! vtNextDer.IsZero()) ;
|
return ( ! vtPrevDer.IsZero() && ! vtNextDer.IsZero()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||||
|
bool ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||||
+20
-5
@@ -3735,16 +3735,25 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
|
|||||||
if ( bOkTrap) {
|
if ( bOkTrap) {
|
||||||
// calcolo eventuali uscite e ingressi
|
// calcolo eventuali uscite e ingressi
|
||||||
if ( pCrvRes->GetTempProp( 0) > 0) {
|
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) ;
|
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
|
||||||
vtRef.Invert() ;
|
vtRef.Invert() ;
|
||||||
bool bIsStartExtended = false ;
|
bool bIsStartExtended = false ;
|
||||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
|
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
|
||||||
return false ;
|
return false ;
|
||||||
pCrvRes->GetEndDir( vtRef) ;
|
}
|
||||||
bool bIsEndExtended = false ;
|
else {
|
||||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, true, PockParam.dRad + PockParam.dOpenMinSafe, bIsEndExtended))
|
if ( PockParam.bInvert)
|
||||||
return false ;
|
|
||||||
if ( bIsEndExtended && ! bIsStartExtended)
|
|
||||||
pCrvRes->Invert() ;
|
pCrvRes->Invert() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6044,6 +6053,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
|
|||||||
// ricavo le regioni progressive
|
// ricavo le regioni progressive
|
||||||
double dOffsPrec = 0. ;
|
double dOffsPrec = 0. ;
|
||||||
int nCrvFirstOffs = 0 ;
|
int nCrvFirstOffs = 0 ;
|
||||||
|
bool bLastNotValid = false ;
|
||||||
while ( nIter < MAX_ITER) {
|
while ( nIter < MAX_ITER) {
|
||||||
// Offset della regione attuale
|
// Offset della regione attuale
|
||||||
PtrOwner<ISurfFlatRegion> pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
|
PtrOwner<ISurfFlatRegion> pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
|
||||||
@@ -6054,6 +6064,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
|
|||||||
pSfrOffsVR.Set( pSrfAct->CreateOffsetSurf( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ;
|
pSfrOffsVR.Set( pSrfAct->CreateOffsetSurf( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ;
|
||||||
if ( IsNull( pSfrOffsVR))
|
if ( IsNull( pSfrOffsVR))
|
||||||
return false ;
|
return false ;
|
||||||
|
bLastNotValid = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// se primo Offset
|
// se primo Offset
|
||||||
@@ -6085,6 +6096,10 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
|
|||||||
bool bInsert = true ;
|
bool bInsert = true ;
|
||||||
if ( ! CheckIfOffsetIsNecessary( pSrfAct, pCrvCompoBorder, dOffs, dOffsPrec, nIter, PockParams, bInsert))
|
if ( ! CheckIfOffsetIsNecessary( pSrfAct, pCrvCompoBorder, dOffs, dOffsPrec, nIter, PockParams, bInsert))
|
||||||
return false ;
|
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) {
|
if ( bInsert) {
|
||||||
// imposto come secondo TempParam il Side di classificazione
|
// imposto come secondo TempParam il Side di classificazione
|
||||||
pCrvCompoBorder->SetTempParam( j == 0 ? MDS_RIGHT : MDS_LEFT, 1) ;
|
pCrvCompoBorder->SetTempParam( j == 0 ? MDS_RIGHT : MDS_LEFT, 1) ;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||||
#include "/EgtDev/Include/EGkCurve.h"
|
#include "/EgtDev/Include/EGkCurve.h"
|
||||||
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|||||||
+338
-29
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "CalcDerivate.h"
|
||||||
|
#include "Bernstein.h"
|
||||||
#include "CurveAux.h"
|
#include "CurveAux.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
@@ -23,12 +25,21 @@
|
|||||||
#include "IntersLineLine.h"
|
#include "IntersLineLine.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
#include "/EgtDev/Include/EGkCurveByInterp.h"
|
#include "/EgtDev/Include/EGkCurveByInterp.h"
|
||||||
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
#define EIGEN_NO_IO
|
#define EIGEN_NO_IO
|
||||||
#include "/EgtDev/Extern/Eigen/Dense"
|
#include "/EgtDev/Extern/Eigen/Dense"
|
||||||
|
|
||||||
|
#define SAVEAPPROX 0
|
||||||
|
#define SAVECURVEPASSED 0
|
||||||
|
#define SAVELINEARAPPROX 0
|
||||||
|
#if SAVEAPPROX || SAVECURVEPASSED || SAVELINEARAPPROX
|
||||||
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
static bool FindSpan( double dU, int nDeg, const DBLVECTOR& vKnots, int& nSpan) ;
|
static bool FindSpan( double dU, int nDeg, const DBLVECTOR& vKnots, int& nSpan) ;
|
||||||
@@ -524,7 +535,8 @@ LineToBezierCurve( const ICurveLine* pCrvLine, int nDeg, bool bMakeRatOrNot)
|
|||||||
PtrOwner<ICurveBezier> pCrvBezier( CreateCurveBezier()) ;
|
PtrOwner<ICurveBezier> pCrvBezier( CreateCurveBezier()) ;
|
||||||
// rendo tutte le curve di grado 2 e razionali così posso convertire anche archi e avere tutte curve dello stesso grado e razionali
|
// rendo tutte le curve di grado 2 e razionali così posso convertire anche archi e avere tutte curve dello stesso grado e razionali
|
||||||
pCrvBezier->Init( nDeg, true) ;
|
pCrvBezier->Init( nDeg, true) ;
|
||||||
pCrvBezier->FromLine( *pCrvLine) ;
|
if( ! pCrvBezier->FromLine( *pCrvLine))
|
||||||
|
return nullptr ;
|
||||||
if ( bMakeRatOrNot)
|
if ( bMakeRatOrNot)
|
||||||
pCrvBezier->MakeRational() ;
|
pCrvBezier->MakeRational() ;
|
||||||
return Release( pCrvBezier) ;
|
return Release( pCrvBezier) ;
|
||||||
@@ -1186,7 +1198,8 @@ CalcBasisFunc( double dU, int nSpan, int nDeg, const DBLVECTOR& vKnots, DBLVECTO
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ICurve*
|
ICurve*
|
||||||
InterpolatePointSetWithBezierNoIntermedLines( const PNTVECTOR& vPnt, int nStart, int nEnd, int nDeg, const DBLVECTOR& vLen, double dLenTot)
|
InterpolatePointSetWithBezierNoIntermedLines( const PNTVECTOR& vPnt, int nStart, int nEnd, int nDeg, const DBLVECTOR& vLen, double dLenTot,
|
||||||
|
const Vector3d& vtStartDir = V_NULL, const Vector3d& vtEndDir = V_NULL)
|
||||||
{
|
{
|
||||||
PtrOwner<ICurve> pCrvInt ;
|
PtrOwner<ICurve> pCrvInt ;
|
||||||
|
|
||||||
@@ -1215,6 +1228,8 @@ InterpolatePointSetWithBezierNoIntermedLines( const PNTVECTOR& vPnt, int nStart,
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bUseStartEndDir = vtStartDir.IsValid() && vtEndDir.IsValid() ;
|
||||||
|
|
||||||
DBLVECTOR vPntParam ;
|
DBLVECTOR vPntParam ;
|
||||||
vPntParam.resize( nPoints) ;
|
vPntParam.resize( nPoints) ;
|
||||||
vPntParam[0] = 0 ;
|
vPntParam[0] = 0 ;
|
||||||
@@ -1223,13 +1238,15 @@ InterpolatePointSetWithBezierNoIntermedLines( const PNTVECTOR& vPnt, int nStart,
|
|||||||
vPntParam[i] = vPntParam[i-1] + vLen[i-1] / dLenTot ;
|
vPntParam[i] = vPntParam[i-1] + vLen[i-1] / dLenTot ;
|
||||||
|
|
||||||
DBLVECTOR vKnots ;
|
DBLVECTOR vKnots ;
|
||||||
vKnots.resize( nPoints + nDeg - 1) ;
|
int nKnots = bUseStartEndDir ? nPoints + nDeg - 1 + 2 : nPoints + nDeg - 1 ;
|
||||||
|
vKnots.resize( nKnots) ;
|
||||||
for ( int i = 0 ; i < nDeg ; ++i) {
|
for ( int i = 0 ; i < nDeg ; ++i) {
|
||||||
vKnots[i] = 0 ;
|
vKnots[i] = 0 ;
|
||||||
vKnots.end()[-i-1] = 1 ;
|
vKnots.end()[-i-1] = 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = nDeg ; i < nPoints - 1 ; ++i) {
|
int nKnotsToEdit = bUseStartEndDir ? nPoints + 1 : nPoints - 1 ;
|
||||||
|
for ( int i = nDeg ; i < nKnotsToEdit ; ++i) {
|
||||||
double dKnot = 0 ;
|
double dKnot = 0 ;
|
||||||
for ( int j = i + 1 ; j < i + nDeg + 1 ; ++j)
|
for ( int j = i + 1 ; j < i + nDeg + 1 ; ++j)
|
||||||
dKnot += vPntParam[j - nDeg] ;
|
dKnot += vPntParam[j - nDeg] ;
|
||||||
@@ -1237,13 +1254,14 @@ InterpolatePointSetWithBezierNoIntermedLines( const PNTVECTOR& vPnt, int nStart,
|
|||||||
vKnots[i] = dKnot ;
|
vKnots[i] = dKnot ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::MatrixXd mA( nPoints, nPoints) ;
|
int nEq = bUseStartEndDir ? nPoints + 2 : nPoints ;
|
||||||
|
Eigen::MatrixXd mA( nEq, nEq) ;
|
||||||
mA.fill( 0) ;
|
mA.fill( 0) ;
|
||||||
for ( int i = 0 ; i < nPoints ; ++i) {
|
for ( int i = 0 ; i < nEq ; ++i) {
|
||||||
if ( i == 0)
|
if ( i == 0)
|
||||||
mA.row(0).col(0) << 1 ;
|
mA.row(0).col(0) << 1 ;
|
||||||
else if ( i == nPoints - 1)
|
else if ( i == nEq - 1)
|
||||||
mA.row(i).col(nPoints - 1) << 1 ;
|
mA.row(i).col( nEq - 1) << 1 ;
|
||||||
else {
|
else {
|
||||||
int nSpan = 0 ; FindSpan( vPntParam[i], nDeg, vKnots, nSpan) ;
|
int nSpan = 0 ; FindSpan( vPntParam[i], nDeg, vKnots, nSpan) ;
|
||||||
DBLVECTOR vBasis ; vBasis.resize( nDeg + 1) ;
|
DBLVECTOR vBasis ; vBasis.resize( nDeg + 1) ;
|
||||||
@@ -1345,7 +1363,13 @@ InterpolatePointSetWithBezier( const PNTVECTOR& vPnt, double dLinTol, double dMa
|
|||||||
if ( vLen.size() != 0) {
|
if ( vLen.size() != 0) {
|
||||||
if ( nEnd == 0)
|
if ( nEnd == 0)
|
||||||
nEnd = nPoints - 1 ;
|
nEnd = nPoints - 1 ;
|
||||||
pCrvInt->AddCurve( InterpolatePointSetWithBezierNoIntermedLines( vPnt, nStart, nEnd, nDeg, vLen, dLenTot)) ;
|
Vector3d vtStartDir = V_INVALID ;
|
||||||
|
Vector3d vtEndDir = V_INVALID ;
|
||||||
|
//if ( nStart != 0 && nEnd != nPoints - 1) {
|
||||||
|
// pCrvInt->GetEndDir( vtStartDir) ;
|
||||||
|
// vtEndDir =
|
||||||
|
//}
|
||||||
|
pCrvInt->AddCurve( InterpolatePointSetWithBezierNoIntermedLines( vPnt, nStart, nEnd, nDeg, vLen, dLenTot, vtStartDir, vtEndDir)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bFoundLine) {
|
if ( bFoundLine) {
|
||||||
@@ -1357,6 +1381,7 @@ InterpolatePointSetWithBezier( const PNTVECTOR& vPnt, double dLinTol, double dMa
|
|||||||
nStart = nEnd ;
|
nStart = nEnd ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dErr = 0 ;
|
||||||
CalcApproxError( pCrvOri, pCrvInt, dErr) ;
|
CalcApproxError( pCrvOri, pCrvInt, dErr) ;
|
||||||
if ( dErr > dLinTol && dMaxLen > 200 * EPS_SMALL)
|
if ( dErr > dLinTol && dMaxLen > 200 * EPS_SMALL)
|
||||||
dMaxLen /= 2 ;
|
dMaxLen /= 2 ;
|
||||||
@@ -1371,42 +1396,282 @@ InterpolatePointSetWithBezier( const PNTVECTOR& vPnt, double dLinTol, double dMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ICurve*
|
static bool
|
||||||
ApproxCurveWithBezier( const ICurve* pCrv , double dTol, int nType)
|
ParamByLen( const PNTVECTOR& vPnt, DBLVECTOR& vParam, int nFirst, int nLast)
|
||||||
{
|
{
|
||||||
PolyLine plApprox ;
|
int nPoints = nLast - nFirst + 1 ;
|
||||||
double dAngTolFine = 2 ;
|
if ( nPoints < 2)
|
||||||
pCrv->ApproxWithLines( dTol, dAngTolFine, ICurve::APL_STD, plApprox) ;
|
return false ;
|
||||||
|
if( ssize(vParam) == 0)
|
||||||
|
vParam.resize( nPoints) ;
|
||||||
|
if( vParam[nFirst] == 0 && vParam[nLast] == 1)
|
||||||
|
return true ;
|
||||||
|
vParam[nFirst] = 0 ;
|
||||||
|
for ( int i = nFirst + 1 ; i <= nLast ; ++i) {
|
||||||
|
double dDist = Dist( vPnt[i], vPnt[i-1]) ;
|
||||||
|
vParam[i] = vParam[i- 1] + dDist ;
|
||||||
|
}
|
||||||
|
for ( int i = nFirst + 1 ; i < nLast ; ++i)
|
||||||
|
vParam[i] /= vParam[nLast] ;
|
||||||
|
vParam[nLast] = 1 ;
|
||||||
|
|
||||||
PNTVECTOR vPnt ;
|
return true ;
|
||||||
Point3d pt ; plApprox.GetFirstPoint( pt) ;
|
}
|
||||||
do {
|
|
||||||
vPnt.push_back( pt) ;
|
|
||||||
} while ( plApprox.GetNextPoint( pt)) ;
|
|
||||||
|
|
||||||
// campiono punti lungo la curva e poi li interpolo
|
//----------------------------------------------------------------------------
|
||||||
|
ICurveBezier*
|
||||||
|
ApproxPointSetWithSingleBezier( const PNTVECTOR& vPnt, int nFirst, int nLast, const Vector3d& vtStartDir, const Vector3d& vtEndDir,
|
||||||
|
const DBLVECTOR& vParam)
|
||||||
|
{
|
||||||
|
// cerco di approssimare un set di punti con una sola bezier cubica non razionale
|
||||||
|
int nPoints = nLast - nFirst + 1 ;
|
||||||
|
// se ho solo quattro punti allora costruisco direttamente la curva
|
||||||
|
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||||
|
int nDeg = 3 ;
|
||||||
|
bool bRat = false ;
|
||||||
|
pCrvBez->Init( nDeg, bRat) ;
|
||||||
|
const Point3d& pt0 = vPnt[nFirst] ;
|
||||||
|
const Point3d& pt3 = vPnt[nLast] ;
|
||||||
|
pCrvBez->SetControlPoint( 0, pt0) ;
|
||||||
|
pCrvBez->SetControlPoint( 3, pt3) ;
|
||||||
|
Eigen::Vector2d mA ;
|
||||||
|
if( nPoints > 4) {
|
||||||
|
// risoluzione sistema
|
||||||
|
Eigen::Matrix2d mC ; mC.setZero() ;
|
||||||
|
Eigen::Vector2d mX ; mX.setZero() ;
|
||||||
|
for ( int i = nFirst ; i <= nLast ; ++i) {
|
||||||
|
double dU = vParam[i] ;
|
||||||
|
DBLVECTOR vBern(4) ;
|
||||||
|
GetAllBernstein( dU, 3, vBern) ;
|
||||||
|
|
||||||
PtrOwner<ICurve> pCC( InterpolatePointSetWithBezier( vPnt, dTol, 100)) ;
|
Vector3d A1 = vtStartDir * vBern[1] ;
|
||||||
if ( ! IsNull( pCC) && pCC->IsValid())
|
Vector3d A2 = vtEndDir * vBern[2] ;
|
||||||
return Release( pCC) ;
|
|
||||||
else
|
Vector3d tmp = vPnt[i] - ( pt0 * ( vBern[0] + vBern[1])) - (( pt3 * ( vBern[2] + vBern[3])) - ORIG) ; // ORIG serve solo per trasformare l'ultimo termine in un vettore
|
||||||
return nullptr ;
|
|
||||||
|
mC(0,0) += A1 * A1 ;
|
||||||
|
mC(0,1) += A1 * A2 ;
|
||||||
|
mC(1,0) += A1 * A2 ;
|
||||||
|
mC(1,1) += A2 * A2 ;
|
||||||
|
|
||||||
|
mX(0) += A1 * tmp ;
|
||||||
|
mX(1) += A2 * tmp ;
|
||||||
|
}
|
||||||
|
mA = mC.fullPivLu().solve(mX) ;
|
||||||
|
}
|
||||||
|
// l'algoritmo è fatto in modo che alpha1 e alpha2 siano positivi ( se tutto va bene)
|
||||||
|
// io invece ho tenuto le tangenti con la direzione originale, quindi il primo dovrebbe essere positivo e il secondo negativo
|
||||||
|
if ( mA(0) < 0 || mA(1) > 0 || nPoints < 4) {
|
||||||
|
if( mA(0) < 0 || mA(1) > 0)
|
||||||
|
LOG_DBG_ERR( GetEGkLogger(), "valori di alfa sballati, potrebbe essere la spaziatura dismogenea tra punti")
|
||||||
|
double dDistCorr = Dist( pt3, pt0) / 3 ;
|
||||||
|
mA(0) = dDistCorr ;
|
||||||
|
mA(1) = - dDistCorr ;
|
||||||
|
}
|
||||||
|
|
||||||
|
double alpah1 = mA(0) ;
|
||||||
|
double alpha2 = mA(1) ;
|
||||||
|
Point3d pt1 = pt0 + vtStartDir * mA(0) ;
|
||||||
|
Point3d pt2 = pt3 + vtEndDir * mA(1) ;
|
||||||
|
pCrvBez->SetControlPoint( 1, pt1) ;
|
||||||
|
pCrvBez->SetControlPoint( 2, pt2) ;
|
||||||
|
return Release( pCrvBez) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CalcPointSetApproxError( const PNTVECTOR& vPntOrig, const DBLVECTOR& vParam, int nFirst, int nLast, const ICurve* pCrvNew, double& dErr, int& nPointMaxErr)
|
||||||
|
{
|
||||||
|
dErr = 0 ;
|
||||||
|
// calcolo l'errore di approssimazione
|
||||||
|
for ( int i = nFirst ; i <= nLast ; ++i) {
|
||||||
|
Point3d ptBez ; pCrvNew->GetPointD1D2( vParam[i], ICurve::Side::FROM_MINUS, ptBez) ;
|
||||||
|
double dErrTemp = Dist( vPntOrig[i], ptBez) ;
|
||||||
|
if( dErrTemp > dErr) {
|
||||||
|
dErr = dErrTemp ;
|
||||||
|
nPointMaxErr = i ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ICurve*
|
ICurve*
|
||||||
ApproxPointSetWithBezier( const ICurve* pCrv, double dTol)
|
FitWithBezier( const ICurve* pCrvOrig, const PNTVECTOR& vPnt, DBLVECTOR& vParam, int nFirst, int nLast, const VCT3DVECTOR& vPrevDer, const VCT3DVECTOR& vNextDer, double dTol)
|
||||||
{
|
{
|
||||||
// campiono punti lungo la curva e poi li interpolo
|
ParamByLen(vPnt, vParam, nFirst, nLast) ;
|
||||||
|
PtrOwner<ICurveComposite> pCrvFit( CreateCurveComposite()) ;
|
||||||
|
PtrOwner<ICurveBezier> pCrvBez( CreateCurveBezier()) ;
|
||||||
|
double dErr = INFINITO ;
|
||||||
|
double dErrSplit = dTol * 25 ;
|
||||||
|
int nIter = 0 ;
|
||||||
|
while ( dErr > dTol && nIter < 10) {
|
||||||
|
if( dErr < INFINITO) {
|
||||||
|
// riparametrizzo i punti
|
||||||
|
for ( int i = nFirst + 1 ; i < nLast ; ++i) {
|
||||||
|
//questo potrebbe diventare un while appena capisco di quanto si aggiusta il parametro ad ogni iterazione
|
||||||
|
double dCorr = 1 ;
|
||||||
|
do {
|
||||||
|
Vector3d vtDer1, vtDer2 ;
|
||||||
|
Point3d ptBez ; pCrvBez->GetPointD1D2( vParam[i], ICurve::Side::FROM_MINUS, ptBez, &vtDer1, &vtDer2) ;
|
||||||
|
Vector3d vtLink = ptBez - vPnt[i] ;
|
||||||
|
double dNum = vtLink * vtDer1 ;
|
||||||
|
double dDen = vtLink * vtDer2 + vtDer1 * vtDer1 ;
|
||||||
|
dCorr = dDen > EPS_ZERO ? dNum / dDen : 0 ;
|
||||||
|
vParam[i] = vParam[i] - dCorr ;
|
||||||
|
} while ( abs( dCorr) > EPS_ZERO) ;
|
||||||
|
Clamp( vParam[i], 0., 1.) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PtrOwner<ICurveComposite> pCC( CreateBasicCurveComposite()) ;
|
// fit della curva
|
||||||
return Release( pCC) ;
|
pCrvBez.Set( ApproxPointSetWithSingleBezier( vPnt, nFirst, nLast, vNextDer[nFirst], vPrevDer[nLast], vParam)) ;
|
||||||
|
if( IsNull( pCrvBez) || ! pCrvBez->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
#if SAVEAPPROX
|
||||||
|
SaveGeoObj( pCrvBez->Clone(), "D:\\Temp\\bezier\\approxWithBezier\\first_approx.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int nPointMaxErr = 0 ;
|
||||||
|
CalcPointSetApproxError( vPnt, vParam, nFirst, nLast, pCrvBez, dErr, nPointMaxErr) ;
|
||||||
|
// se sto unendo due punti consecutivi e l'errore è oltre quello richiesto allora restituisco un segmento che unisce i punti
|
||||||
|
if( nLast - nFirst == 1 && dErr > dTol) {
|
||||||
|
CurveLine CL ; CL.Set( vPnt[nFirst], vPnt[nLast]) ;
|
||||||
|
pCrvBez.Set( GetCurveBezier( CurveToBezierCurve( &CL))) ;
|
||||||
|
dErr = 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
++nIter ;
|
||||||
|
bool bSplit = false ;
|
||||||
|
if( nIter == 10 && dErr > dTol)
|
||||||
|
bSplit = true ;
|
||||||
|
// se la curva di approssimazione è ancora molto lontana dalla curva originale allora divido il set di punti in due
|
||||||
|
if ( dErr > dErrSplit || bSplit) {
|
||||||
|
if ( nLast - nFirst > 1) {
|
||||||
|
if( ! pCrvFit->AddCurve( FitWithBezier( pCrvOrig, vPnt, vParam, nFirst, nPointMaxErr, vPrevDer, vNextDer,dTol)) ||
|
||||||
|
! pCrvFit->AddCurve( FitWithBezier( pCrvOrig, vPnt, vParam, nPointMaxErr, nLast, vPrevDer, vNextDer, dTol)))
|
||||||
|
return nullptr ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pCrvFit->GetCurveCount() > 0)
|
||||||
|
return Release( pCrvFit) ;
|
||||||
|
else if ( dErr < dTol && ! IsNull( pCrvBez) && pCrvBez->IsValid())
|
||||||
|
return Release( pCrvBez) ;
|
||||||
|
else
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nCrvPassed = 0 ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ICurve*
|
||||||
|
ApproxCurveWithBezier( const ICurve* pCrv , double dTol, int nType)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if SAVECURVEPASSED
|
||||||
|
SaveGeoObj( pCrv->Clone(), "D:\\Temp\\bezier\\approxWithBezier\\CurveDaApprossimare\\"+ToString(nCrvPassed) + ".nge") ;
|
||||||
|
++nCrvPassed ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//// uso l'algoritmo di Schneider in Grafic Gems I
|
||||||
|
// mi aspetto che non ci siano angoli ( discontinuità della derivata prima) nel risultato desiderato
|
||||||
|
PolyLine plApprox ;
|
||||||
|
double dAngTolFine = 1 ;
|
||||||
|
double dLinTolFine = 0.05 ;
|
||||||
|
pCrv->ApproxWithLines( dLinTolFine, dAngTolFine, ICurve::APL_STD, plApprox) ;
|
||||||
|
|
||||||
|
#if SAVELINEARAPPROX
|
||||||
|
CurveComposite CC ; CC.FromPolyLine(plApprox) ;
|
||||||
|
SaveGeoObj( CC.Clone(), "D:\\Temp\\bezier\\approxWithBezier\\approssimazione_lineare.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CurveByInterp cbi ;
|
||||||
|
PNTVECTOR vPnt ;
|
||||||
|
Point3d pt ; plApprox.GetFirstPoint( pt) ;
|
||||||
|
do {
|
||||||
|
if ( ssize(vPnt) != 0) {
|
||||||
|
vPnt.push_back( Media(vPnt.back(), pt,1./3.)) ;
|
||||||
|
vPnt.push_back( Media(vPnt.back(), pt,2./3.)) ;
|
||||||
|
}
|
||||||
|
vPnt.push_back( pt) ;
|
||||||
|
cbi.AddPoint( pt) ;
|
||||||
|
} while ( plApprox.GetNextPoint( pt)) ;
|
||||||
|
|
||||||
|
// calcolo la curvatura nei vari punti per identificare zone a curvatura costante
|
||||||
|
DBLVECTOR vCrvVal( ssize(vPnt)) ;
|
||||||
|
DBLVECTOR vRad ( ssize( vPnt)) ;
|
||||||
|
for( int i = 1 ; i < ssize( vPnt) - 1 ; ++i) {
|
||||||
|
Vector3d vtA = vPnt[i] - vPnt[i-1] ;
|
||||||
|
Vector3d vtB = vPnt[i+1] - vPnt[i-1] ;
|
||||||
|
double dR = ( vtA.Len() * vtB.Len() * ( vtA - vtB).Len()) / ( 2 * (vtA ^ vtB).Len()) ;
|
||||||
|
double dCurvature = dR > 0 ? 1. / dR : 0 ;
|
||||||
|
vRad[i] = dR ;
|
||||||
|
vCrvVal[i] = dCurvature ;
|
||||||
|
}
|
||||||
|
vCrvVal[0] = vCrvVal[1] ;
|
||||||
|
vCrvVal.back() = vCrvVal.end()[-2] ;
|
||||||
|
// identifico le zone a curvatura costante // primo e ultimo punto degli intervalli non devono avere curvatura uguale agli altri perché sono di frontiera
|
||||||
|
INTINTVECTOR vConstCurv ;
|
||||||
|
double dCurvaturePrec = vCrvVal[0] ;
|
||||||
|
int nStart = 0 ;
|
||||||
|
int nEnd = 1 ;
|
||||||
|
while ( nStart < ssize( vPnt) - 1) {
|
||||||
|
dCurvaturePrec = vCrvVal[nEnd] ;
|
||||||
|
while ( nEnd < ssize( vPnt) - 1 && abs( vCrvVal[nEnd] - dCurvaturePrec) < 0.1) {
|
||||||
|
dCurvaturePrec = vCrvVal[nEnd] ;
|
||||||
|
++nEnd ;
|
||||||
|
}
|
||||||
|
vConstCurv.emplace_back( nStart, nEnd) ;
|
||||||
|
nStart = nEnd ;
|
||||||
|
++nEnd ;
|
||||||
|
}
|
||||||
|
if( ssize(vConstCurv) == 0)
|
||||||
|
vConstCurv.emplace_back( 0, ssize( vPnt) - 1) ;
|
||||||
|
|
||||||
|
int nPoints = ssize( vPnt) ;
|
||||||
|
DBLVECTOR vParam( nPoints) ;
|
||||||
|
int nFirst = 0 ;
|
||||||
|
int nLast = ssize( vPnt) - 1 ;
|
||||||
|
ParamByLen( vPnt, vParam, nFirst, nLast) ;
|
||||||
|
|
||||||
|
VCT3DVECTOR vPrevDer ;
|
||||||
|
VCT3DVECTOR vNextDer ;
|
||||||
|
ComputeAkimaTangents( false, vParam, vPnt, vPrevDer, vNextDer) ;
|
||||||
|
//normalizzo tutte le derivate
|
||||||
|
for( int i = 0 ; i < ssize( vPrevDer) ; ++i) {
|
||||||
|
vPrevDer[i].Normalize() ;
|
||||||
|
vNextDer[i].Normalize() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
PtrOwner<ICurveComposite> pCCApproxTot( CreateCurveComposite()) ;
|
||||||
|
for( INTINT iiSE : vConstCurv) {
|
||||||
|
nFirst = iiSE.first ;
|
||||||
|
nLast = iiSE.second ;
|
||||||
|
//definisco la bezier che vado a raffinare iterativamente
|
||||||
|
PtrOwner<ICurve> pCApprox( FitWithBezier( pCrv, vPnt, vParam, nFirst, nLast, vPrevDer, vNextDer, dTol)) ;
|
||||||
|
if( IsNull( pCApprox) || ! pCApprox->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
if( ! pCCApproxTot->AddCurve( Release( pCApprox)))
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Release( pCCApproxTot) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CalcApproxError( const ICurve* pCrvOri, const ICurve* pCrvNew, double& dErr, int nPoints)
|
CalcApproxError( const ICurve* pCrvOri, const ICurve* pCrvNew, double& dErr, int nPoints)
|
||||||
{
|
{
|
||||||
|
if( pCrvOri == nullptr || ! pCrvOri->IsValid() || pCrvNew == nullptr || ! pCrvNew->IsValid()){
|
||||||
|
dErr = INFINITO ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
// controllo l'errore effettivo campionando più finemente
|
// controllo l'errore effettivo campionando più finemente
|
||||||
double dLenOri = 0 ; pCrvOri->GetLength( dLenOri) ;
|
double dLenOri = 0 ; pCrvOri->GetLength( dLenOri) ;
|
||||||
double dLenNew = 0 ; pCrvNew->GetLength( dLenNew) ;
|
double dLenNew = 0 ; pCrvNew->GetLength( dLenNew) ;
|
||||||
@@ -2326,3 +2591,47 @@ ResetCurveVoronoi( const ICurve& crvC)
|
|||||||
break ;
|
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) ;
|
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||||
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
|
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
|
||||||
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
||||||
|
bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ;
|
||||||
|
|||||||
+2
-201
@@ -202,213 +202,14 @@ CurveByApprox::CalcParameterization( void)
|
|||||||
bool
|
bool
|
||||||
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||||
{
|
{
|
||||||
// pulisco i vettori delle tangenti
|
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
// se non ci sono almeno 5 punti
|
|
||||||
if ( nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sui primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sugli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
// se secondo punto
|
|
||||||
if ( i == 1) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se penultimo punto
|
|
||||||
else if ( i == nSize - 2) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveByApprox::CalcBesselTangents( void)
|
CurveByApprox::CalcBesselTangents( void)
|
||||||
{
|
{
|
||||||
// pulisco i vettori delle tangenti
|
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso i primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso gli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+34
-235
@@ -50,12 +50,42 @@ CurveByInterp::AddPoint( const Point3d& ptP)
|
|||||||
ICurve*
|
ICurve*
|
||||||
CurveByInterp::GetCurve( int nMethod, int nType)
|
CurveByInterp::GetCurve( int nMethod, int nType)
|
||||||
{
|
{
|
||||||
// calcolo le tangenti
|
// se richieste curve di Bezier cubiche (ottenute da interpolazione con Nurbs)
|
||||||
|
if ( nType == CUBIC_BEZIERS_LONG) {
|
||||||
|
// creo la curva composita
|
||||||
|
PtrOwner<ICurve> pCrv ;
|
||||||
|
//pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 50 * EPS_SMALL, 50)) ;
|
||||||
|
//debug
|
||||||
|
pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 0.1, 100)) ;
|
||||||
|
if ( IsNull(pCrv) || ! pCrv->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
return Release( pCrv) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( m_vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// calcolo le distanze tra i punti per derivarne i parametri
|
||||||
|
m_vPar.reserve( nSize) ;
|
||||||
|
double dPar = 0 ;
|
||||||
|
m_vPar.push_back( dPar) ;
|
||||||
|
|
||||||
|
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||||
|
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||||
|
dPar += dDist ;
|
||||||
|
m_vPar.push_back( dPar) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcolo le tangenti
|
||||||
if ( nMethod == BESSEL) {
|
if ( nMethod == BESSEL) {
|
||||||
if ( ! CalcBesselTangents())
|
if ( ! CalcBesselTangents())
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
else if ( nType != CUBIC_BEZIERS_LONG) {
|
else {
|
||||||
if ( ! CalcAkimaTangents( nMethod == AKIMA_CORNER))
|
if ( ! CalcAkimaTangents( nMethod == AKIMA_CORNER))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
@@ -103,16 +133,6 @@ CurveByInterp::GetCurve( int nMethod, int nType)
|
|||||||
return ::Release( pCrvCompo) ;
|
return ::Release( pCrvCompo) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// se richieste curve di Bezier cubiche (ottenute da interpolazione con Nurbs)
|
|
||||||
if ( nType == CUBIC_BEZIERS_LONG) {
|
|
||||||
// creo la curva composita
|
|
||||||
PtrOwner<ICurve> pCrv ;
|
|
||||||
pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 50 * EPS_SMALL, 50)) ;
|
|
||||||
if ( IsNull(pCrv) || ! pCrv->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
return Release( pCrv) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,233 +140,12 @@ CurveByInterp::GetCurve( int nMethod, int nType)
|
|||||||
bool
|
bool
|
||||||
CurveByInterp::CalcAkimaTangents( bool bDetectCorner)
|
CurveByInterp::CalcAkimaTangents( bool bDetectCorner)
|
||||||
{
|
{
|
||||||
// pulisco i vettori dei parametri e delle tangenti
|
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPar.clear() ;
|
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le distanze tra i punti per derivarne i parametri
|
|
||||||
m_vPar.reserve( nSize) ;
|
|
||||||
double dPar = 0 ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
|
||||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
|
||||||
dPar += dDist ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
// se non ci sono almeno 5 punti
|
|
||||||
if ( nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sui primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sugli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
// se secondo punto
|
|
||||||
if ( i == 1) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se penultimo punto
|
|
||||||
else if ( i == nSize - 2) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveByInterp::CalcBesselTangents( void)
|
CurveByInterp::CalcBesselTangents( void)
|
||||||
{
|
{
|
||||||
// pulisco i vettori dei parametri e delle tangenti
|
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPar.clear() ;
|
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le distanze tra i punti per derivarne i parametri
|
|
||||||
m_vPar.reserve( nSize) ;
|
|
||||||
double dPar = 0 ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
|
||||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
|
||||||
dPar += dDist ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso i primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso gli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -281,6 +281,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="BBox3d.cpp" />
|
<ClCompile Include="BBox3d.cpp" />
|
||||||
<ClCompile Include="BiArcs.cpp" />
|
<ClCompile Include="BiArcs.cpp" />
|
||||||
<ClCompile Include="CalcPocketing.cpp" />
|
<ClCompile Include="CalcPocketing.cpp" />
|
||||||
|
<ClCompile Include="CalcDerivate.cpp" />
|
||||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
||||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||||
|
|||||||
@@ -567,6 +567,9 @@
|
|||||||
<ClCompile Include="Trimming.cpp">
|
<ClCompile Include="Trimming.cpp">
|
||||||
<Filter>File di origine\GeoStriping</Filter>
|
<Filter>File di origine\GeoStriping</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="CalcDerivate.cpp">
|
||||||
|
<Filter>File di origine\Geo</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
|
|||||||
@@ -371,12 +371,16 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// caso NULL-NULL per corrente di prima curva
|
// 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) {
|
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 ;
|
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)
|
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
}
|
}
|
||||||
// caso NULL-NULL per precedente di prima curva
|
// 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) {
|
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)
|
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
||||||
EraseOtherInfo( i, j) ;
|
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
|
// ciclo sulle curve per verificare se da approssimare
|
||||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
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])) ||
|
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
|
||||||
m_pCurve[i]->GetType() == CRV_BEZIER) {
|
m_pCurve[i]->GetType() == CRV_BEZIER) {
|
||||||
// approssimo con rette
|
// approssimo con rette
|
||||||
@@ -127,7 +127,7 @@ IntersCurveCurve::IsArcToApprox( const ICurve& Curve)
|
|||||||
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
||||||
if ( pArc == nullptr)
|
if ( pArc == nullptr)
|
||||||
return false ;
|
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()) ||
|
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
||||||
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||||
}
|
}
|
||||||
@@ -252,10 +252,10 @@ IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve&
|
|||||||
bool
|
bool
|
||||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
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())
|
if ( m_Info.empty())
|
||||||
return true ;
|
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)
|
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||||
return true ;
|
return true ;
|
||||||
// procedo ad aggiustare
|
// procedo ad aggiustare
|
||||||
@@ -389,11 +389,11 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
|||||||
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
|
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// ricerca del punto più vicino tra le intersezioni singole
|
// ricerca del punto più vicino tra le intersezioni singole
|
||||||
bool bFound = false ;
|
bool bFound = false ;
|
||||||
double dMinSqDist = SQ_INFINITO ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||||
// se è un'intersezione singola
|
// se è un'intersezione singola
|
||||||
if ( ! m_Info[i].bOverlap) {
|
if ( ! m_Info[i].bOverlap) {
|
||||||
// faccio la verifica sul punto
|
// faccio la verifica sul punto
|
||||||
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
|
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
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
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
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
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
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
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
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
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 ;
|
double dU2 = Info[j].IciA[1].dU ;
|
||||||
if ( dU2 < dU1 && pCurve->IsClosed())
|
if ( dU2 < dU1 && pCurve->IsClosed())
|
||||||
dU2 += dEndPar ;
|
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) {
|
if ( Info[i].IciA[0].dU >= dU1 && Info[i].IciA[0].dU <= dU2) {
|
||||||
bToSkip = true ;
|
bToSkip = true ;
|
||||||
break ;
|
break ;
|
||||||
@@ -559,7 +559,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
double dCurrPar = dStartPar ;
|
double dCurrPar = dStartPar ;
|
||||||
double dCurrLen = 0 ;
|
double dCurrLen = 0 ;
|
||||||
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
||||||
// se è chiusa, recupero come finisce
|
// se è chiusa, recupero come finisce
|
||||||
if ( pCurve->IsClosed()) {
|
if ( pCurve->IsClosed()) {
|
||||||
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
||||||
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
|
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
|
||||||
@@ -577,7 +577,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
}
|
}
|
||||||
// costruisco il vettore delle classificazioni
|
// costruisco il vettore delle classificazioni
|
||||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
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) ;
|
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||||
// verifico che la definizione sul tratto sia omogenea e valida
|
// 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
|
// altrimenti, salvo il tipo
|
||||||
else
|
else
|
||||||
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
|
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
|
||||||
// se è definito un tratto in sovrapposizione
|
// se è definito un tratto in sovrapposizione
|
||||||
if ( InfoCorr[i].bOverlap) {
|
if ( InfoCorr[i].bOverlap) {
|
||||||
// assegno i dati
|
// assegno i dati
|
||||||
CrvClass segClass ;
|
CrvClass segClass ;
|
||||||
@@ -639,7 +639,7 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
|||||||
double dStartParB, dEndParB ;
|
double dStartParB, dEndParB ;
|
||||||
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
|
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
|
||||||
return false ;
|
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 ;
|
BBox3d boxCrvA, boxCrvB ;
|
||||||
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
|
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
|
||||||
! pCurveB->GetLocalBBox( boxCrvB))
|
! pCurveB->GetLocalBBox( boxCrvB))
|
||||||
@@ -682,13 +682,37 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
|||||||
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
||||||
// dichiaro la classe della curva per default
|
// dichiaro la classe della curva per default
|
||||||
int nClass = CRVC_OUT ;
|
int nClass = CRVC_OUT ;
|
||||||
// se c'è almeno una intersezione
|
// se c'è almeno una intersezione
|
||||||
if ( iCC.GetIntersCount() > 0) {
|
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 ;
|
IntCrvCrvInfo aInfo ;
|
||||||
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
||||||
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||||
nClass = CRVC_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
|
// altrimenti sono esterni tra loro
|
||||||
else {
|
else {
|
||||||
|
|||||||
+24
-4
@@ -158,12 +158,32 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ;
|
bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ;
|
||||||
// flag per segmenti che si allontanano significativamente
|
// flag per segmenti che si allontanano significativamente
|
||||||
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
||||||
|
|
||||||
// analisi casi speciali di quasi parallelismo
|
// 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 ( ! bParallel && abs( dCrossXY) < ( 0.1 * DEGTORAD) * ( dLen1XY * dLen2XY)) {
|
||||||
if (( nS1Side == 0 && nS2Side == 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) ||
|
if (( nS1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) ||
|
||||||
( nS1Side == 0 && nE2Side == 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) ||
|
( nS1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) ||
|
||||||
( nE1Side == 0 && nS2Side == 0 && ! AreSamePointXYEpsilon( ptE1, ptS2, 2 * EPS_SMALL)) ||
|
( nE1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptE1, ptS2, 2 * EPS_SMALL)) ||
|
||||||
( nE1Side == 0 && nE2Side == 0 && ! AreSamePointXYEpsilon( ptE1, ptE2, 2 * EPS_SMALL))) {
|
( nE1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptE1, ptE2, 2 * EPS_SMALL))) {
|
||||||
bParallel = true ;
|
bParallel = true ;
|
||||||
bFarEnds = false ;
|
bFarEnds = false ;
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-14
@@ -172,9 +172,9 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
return true ;
|
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) ;
|
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) ;
|
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)
|
if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
|
||||||
continue ;
|
continue ;
|
||||||
// calcolo il segmento di linea
|
// calcolo il segmento di linea
|
||||||
CurveLine clLine ;
|
CurveLine clLine ;
|
||||||
if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
|
if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
|
||||||
return false ;
|
return false ;
|
||||||
// l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
|
// l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
|
||||||
IntersCurveCurve intLL( clLine, ccLoop) ;
|
IntersCurveCurve intLL( clLine, ccLoop) ;
|
||||||
IntCrvCrvInfo aInfo ;
|
if ( intLL.GetIntersCount() == 0) {
|
||||||
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
Point3d ptM = Media( vEdges[i].first, vEdges[i].second) ;
|
||||||
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
ptM.z = 0 ;
|
||||||
if ( aInfo.bOverlap)
|
if ( IsPointInsidePolyLine( ptM, PL, -EPS_SMALL))
|
||||||
dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
|
dElev = max( dElev, max( vEdges[i].first.z, vEdges[i].second.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)
|
else {
|
||||||
dElev = max( dElev, vEdges[i].first.z) ;
|
IntCrvCrvInfo aInfo ;
|
||||||
// se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
|
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
||||||
else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
|
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
||||||
dElev = max( dElev, vEdges[i].second.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) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -735,8 +735,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfBezier*
|
ISurfBezier*
|
||||||
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const ICURVEPOVECTOR& vCrv, const ICURVEPOVECTOR& vNewCrv,
|
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const BIPNTVECTOR& vCrv, double dLinTol)
|
||||||
const INTVECTOR& vShown, const INTINTVECTOR& vNewOrEdited, double dLinTol)
|
|
||||||
{
|
{
|
||||||
// verifica parametri
|
// verifica parametri
|
||||||
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||||
@@ -763,7 +762,7 @@ GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const IC
|
|||||||
|
|
||||||
// creo e setto la superficie trimesh
|
// creo e setto la superficie trimesh
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByIsoParamSet( pCC1, pCC2, vCrv, vNewCrv, vShown, vNewOrEdited))
|
if ( IsNull( pSbz) || ! pSbz->CreateByIsoParamSet( pCC1, pCC2, vCrv))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
|
|||||||
+301
-133
@@ -46,7 +46,9 @@
|
|||||||
|
|
||||||
#define SAVEFAILEDTRIANGULATION 0
|
#define SAVEFAILEDTRIANGULATION 0
|
||||||
#define SAVEISO 0
|
#define SAVEISO 0
|
||||||
#if SAVEFAILEDTRIANGULATION || SAVEISO
|
#define SAVERULEDISO 0
|
||||||
|
#define SAVERULEDGUIDEDISO 0
|
||||||
|
#if SAVEFAILEDTRIANGULATION || SAVEISO || SAVERULEDISO || SAVERULEDGUIDEDISO
|
||||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4057,6 +4059,9 @@ SurfBezier::CreateByFlatContour( const PolyLine& PL)
|
|||||||
bool
|
bool
|
||||||
SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
|
SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
|
||||||
{
|
{
|
||||||
|
// la regione passata è riferita al parametrico di una superficie quadrata.
|
||||||
|
// La superficie viene creata come se fosse una flatregion a partire dai loop passati.
|
||||||
|
|
||||||
// le polyline in input devono essere già ordinate per area e orientate con il verso giusto ( tenendo conto di chunk e isole)
|
// le polyline in input devono essere già ordinate per area e orientate con il verso giusto ( tenendo conto di chunk e isole)
|
||||||
// la prima polyline quindi è il loop esterno del chunk più grande
|
// la prima polyline quindi è il loop esterno del chunk più grande
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
@@ -4124,39 +4129,37 @@ SurfBezier::CreateByRegion( const POLYLINEVECTOR& vPL)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfBezier::CreateByExtrusion( const ICurve* pCrv, const Vector3d& vtExtr, bool bDeg3orDeg2)
|
SurfBezier::CreateByExtrusion( const ICurve* pCrv, const Vector3d& vtExtr)
|
||||||
{
|
{
|
||||||
if ( pCrv == nullptr)
|
if ( pCrv == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico che la curva passata sia una bezier semplice o una composita di bezier
|
|
||||||
if ( pCrv->GetType() != CRV_COMPO && pCrv->GetType() != CRV_BEZIER)
|
|
||||||
return false ;
|
|
||||||
// se composita verifico che curve siano con lo stesso grado e uniformi come tipo
|
|
||||||
|
|
||||||
CurveComposite CC ;
|
CurveComposite CC ;
|
||||||
CC.AddCurve( pCrv->Clone()) ;
|
// se composita verifico che curve siano con lo stesso grado e uniformi come tipo
|
||||||
bool bRat = false ;
|
bool bRat = false ;
|
||||||
int nDegU = 1 ;
|
int nDegU = 3 ;
|
||||||
for ( int i = 0 ; i < CC.GetCurveCount() ; ++i) {
|
if( pCrv->GetType() != CRV_COMPO) {
|
||||||
if ( CC.GetCurve( i)->GetType() != CRV_BEZIER)
|
CC.AddCurve( CurveToBezierCurve( pCrv, nDegU, bRat)) ;
|
||||||
return false ;
|
}
|
||||||
const ICurveBezier* pCrvBez = GetCurveBezier( CC.GetCurve( i)) ;
|
else {
|
||||||
if ( i == 0 ) {
|
const ICurveComposite* pCCOrig = GetCurveComposite( pCrv) ;
|
||||||
bRat = pCrvBez->IsRational() ;
|
for ( int i = 0 ; i < pCCOrig->GetCurveCount() ; ++i) {
|
||||||
nDegU = pCrvBez->GetDegree() ;
|
if ( pCCOrig->GetCurve( i)->GetType() != CRV_BEZIER)
|
||||||
}
|
CC.AddCurve( CurveToBezierCurve( pCCOrig->GetCurve(i), nDegU, bRat)) ;
|
||||||
else {
|
else
|
||||||
if ( pCrvBez->GetDegree() != nDegU || pCrvBez->IsRational() != bRat)
|
CC.AddCurve( EditBezierCurve( GetCurveBezier( pCCOrig->GetCurve(i)), nDegU, bRat)) ;
|
||||||
return false ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( CC.GetCurveCount() == 0 || ! CC.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
// riempio la matrice dei punti di controllo
|
// riempio la matrice dei punti di controllo
|
||||||
// parto dalla curva che sto estrudendo e mi alzo progressivamente seguendo il vettore vtExtr
|
// parto dalla curva che sto estrudendo e mi alzo progressivamente seguendo il vettore vtExtr
|
||||||
int nDegV = bDeg3orDeg2 ? 3 : 2 ;
|
int nDegV = 1 ;
|
||||||
int nSpanU = CC.GetCurveCount() ;
|
int nSpanU = CC.GetCurveCount() ;
|
||||||
int nSpanV = 1 ;
|
int nSpanV = 1 ;
|
||||||
Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
||||||
|
|
||||||
for ( int k = 0 ; k < nSpanU ; ++k) {
|
for ( int k = 0 ; k < nSpanU ; ++k) {
|
||||||
const ICurveBezier* pCrvBezier = GetCurveBezier( CC.GetCurve( k)) ;
|
const ICurveBezier* pCrvBezier = GetCurveBezier( CC.GetCurve( k)) ;
|
||||||
@@ -5058,8 +5061,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
bool bAdvance0 = dParam0 < j + 1 + EPS_SMALL ;
|
bool bAdvance0 = dParam0 < j + 1 + EPS_SMALL ;
|
||||||
bool bAdvance1 = dParam1 < c + 1 + EPS_SMALL ;
|
bool bAdvance1 = dParam1 < c + 1 + EPS_SMALL ;
|
||||||
// controllo se ho un match biunivoco
|
// controllo se ho un match biunivoco
|
||||||
bool bPerfectMatch = dParam0 - int( dParam0) < EPS_SMALL && int( dParam0) == j + 1 &&
|
bool bPerfectMatch = abs( dParam0 - round( dParam0)) < EPS_SMALL && round( dParam0) == j + 1 &&
|
||||||
dParam1 - int( dParam1) < EPS_SMALL && int( dParam1) == c + 1 ;
|
abs( dParam1 - round( dParam1)) < EPS_SMALL && round( dParam1) == c + 1 ;
|
||||||
int nSplit1 = vdSplit1.size() ;
|
int nSplit1 = vdSplit1.size() ;
|
||||||
int nSplit0 = vdSplit0.size() ;
|
int nSplit0 = vdSplit0.size() ;
|
||||||
// se con una polyline sono arrivato alla fine non posso più avanzare
|
// se con una polyline sono arrivato alla fine non posso più avanzare
|
||||||
@@ -5068,7 +5071,16 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
if ( j == vMatch1.size())
|
if ( j == vMatch1.size())
|
||||||
bAdvance1 = false ;
|
bAdvance1 = false ;
|
||||||
// se trovo che ho uno spigolo allora procedo con la gestione spigoli
|
// se trovo che ho uno spigolo allora procedo con la gestione spigoli
|
||||||
if ( vEdgeSplit0[c+1] || vEdgeSplit1[j+1]) {
|
if( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) {
|
||||||
|
// se ho uno spigolo su entrambe le curve forzo l'accoppiamento
|
||||||
|
bAdvance0 = true ;
|
||||||
|
bPerfectMatch = true ;
|
||||||
|
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 ;
|
bAdvance0 = false ;
|
||||||
bAdvance1 = false ;
|
bAdvance1 = false ;
|
||||||
}
|
}
|
||||||
@@ -5152,7 +5164,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
bool bEdgeFoundOnSecond = false ;
|
bool bEdgeFoundOnSecond = false ;
|
||||||
if ( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) {
|
if ( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) {
|
||||||
// questo caso non è previsto !!!!! e non mi aspetto che avvenga
|
// questo caso non è previsto !!!!! e non mi aspetto che avvenga
|
||||||
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found") ;
|
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found, type 0") ;
|
||||||
}
|
}
|
||||||
if ( vEdgeSplit0[c+1]) {
|
if ( vEdgeSplit0[c+1]) {
|
||||||
++c ;
|
++c ;
|
||||||
@@ -5177,6 +5189,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
dLastParamMatch0 = j - 1 ;
|
dLastParamMatch0 = j - 1 ;
|
||||||
ptLastPointMatch0 = vPnt1[j] ;
|
ptLastPointMatch0 = vPnt1[j] ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found, type 1") ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( vEdgeSplit1[j+1]) {
|
else if ( vEdgeSplit1[j+1]) {
|
||||||
++c ;
|
++c ;
|
||||||
@@ -5201,10 +5216,12 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
dLastParamMatch1 = c - 1 ;
|
dLastParamMatch1 = c - 1 ;
|
||||||
ptLastPointMatch1 = vPnt0[c] ;
|
ptLastPointMatch1 = vPnt0[c] ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found, type 2") ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// potrei avere un mismatch, senza però avere degli spigoli..
|
/////////OLD VRESION
|
||||||
// gestisco comunque con un'accoppiamento
|
|
||||||
++c ;
|
++c ;
|
||||||
++j ;
|
++j ;
|
||||||
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
|
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
|
||||||
@@ -5212,12 +5229,187 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
ptLastPointMatch1 = vPnt0[c] ;
|
ptLastPointMatch1 = vPnt0[c] ;
|
||||||
dLastParamMatch0 = j ;
|
dLastParamMatch0 = j ;
|
||||||
ptLastPointMatch0 = vPnt1[j] ;
|
ptLastPointMatch0 = vPnt1[j] ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////// potrei avere un mismatch, senza però avere degli spigoli..
|
||||||
|
|
||||||
|
// // 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) ;
|
||||||
|
|
||||||
|
// 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) ;
|
bAdvance = ! (c >= int(vMatch0.size()) - 1 && j >= int(vMatch1.size()) - 1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
|
// applico effettivamente gli split
|
||||||
int nUnit = 0 ;
|
int nUnit = 0 ;
|
||||||
if ( ! vdSplit1.empty())
|
if ( ! vdSplit1.empty())
|
||||||
nUnit = int( vdSplit1.back()) ;
|
nUnit = int( vdSplit1.back()) ;
|
||||||
@@ -5304,6 +5496,28 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
|||||||
++ nAddedSpan ;
|
++ nAddedSpan ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SAVERULEDISO
|
||||||
|
//debug
|
||||||
|
vector<IGeoObj*> vGeo ;
|
||||||
|
ICURVEPOVECTOR vCrv ;
|
||||||
|
GetAllPatchesIsocurves( false, vCrv) ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrv) ; ++i) {
|
||||||
|
vGeo.push_back( vCrv[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
vector<Color> vCol( ssize( vCrv)) ;
|
||||||
|
fill( vCol.begin(), vCol.end(), Color( 255,0,128)) ;
|
||||||
|
SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/isoCurves.nge") ;
|
||||||
|
//debug
|
||||||
|
|
||||||
|
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 bOk ;
|
return bOk ;
|
||||||
}
|
}
|
||||||
else if ( RLT_B_LENPAR ) {
|
else if ( RLT_B_LENPAR ) {
|
||||||
@@ -5653,10 +5867,8 @@ struct IsoParam {
|
|||||||
int nCrv ;
|
int nCrv ;
|
||||||
double dParam0 ;
|
double dParam0 ;
|
||||||
double dParam1 ;
|
double dParam1 ;
|
||||||
bool bNew ;
|
IsoParam( int _nCrv, double _dParam0, double _dParam1) :
|
||||||
bool bShown ;
|
nCrv(_nCrv), dParam0( _dParam0), dParam1( _dParam1){ } ;
|
||||||
IsoParam( int _nCrv, double _dParam0, double _dParam1, bool _bNew = false, bool _bShown = false) :
|
|
||||||
nCrv(_nCrv), dParam0( _dParam0), dParam1( _dParam1), bNew( _bNew), bShown( _bShown){ } ;
|
|
||||||
bool operator < ( IsoParam& b)
|
bool operator < ( IsoParam& b)
|
||||||
{
|
{
|
||||||
return ( abs(dParam0 - b.dParam0) > EPS_SMALL ? dParam0 < b.dParam0 : dParam1 < b.dParam1) ;
|
return ( abs(dParam0 - b.dParam0) > EPS_SMALL ? dParam0 < b.dParam0 : dParam1 < b.dParam1) ;
|
||||||
@@ -5667,12 +5879,15 @@ typedef vector<IsoParam> ISOPARVECT ;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const ICURVEPOVECTOR& vCrv, const ICURVEPOVECTOR& vNewCrv, const INTVECTOR& vShown , const INTINTVECTOR& vNewOrEdited)
|
SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv)
|
||||||
{
|
{
|
||||||
// vCrv è il vettore delle isocurve (nel parametro V) di una surf ( creata come rigata) che si vuole modificare ( già ordinato)
|
// vCrv è il vettore delle isocurve (nel parametro V) che si vogliono forzare per la creazione della rigata tra Curve0 e Curve1
|
||||||
// vNewCrv è il vettore delle isocurve mostrate durante l'editing, che comprende le curve editate e le curve nuove
|
|
||||||
// vShown indica gli indici delle curve in vCrv che sono mostrate in vCrv
|
//controllo che siano entrambe chiuse o entrambe aperte
|
||||||
// vNewOrEdited indica la coppia di indici (nId1, nId2) (in vCrv, in vNewCrv) per le curve editate e una coppia (-1, nId) per le curve aggiunte
|
if( pCurve0->IsClosed() ^ pCurve1->IsClosed())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
bool bClosed = pCurve0->IsClosed() ;
|
||||||
|
|
||||||
// converto in bezier la curva iniziale
|
// converto in bezier la curva iniziale
|
||||||
CurveComposite CrvU0 ; CrvU0.AddCurve( CurveToBezierCurve(pCurve0)) ;
|
CurveComposite CrvU0 ; CrvU0.AddCurve( CurveToBezierCurve(pCurve0)) ;
|
||||||
@@ -5710,121 +5925,52 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
|
|||||||
double dLenPrev0 = 0 ,dLenPrev1 = 0 ;
|
double dLenPrev0 = 0 ,dLenPrev1 = 0 ;
|
||||||
|
|
||||||
// costruisco il vettore delle nuove curve isoparamtriche per la nuova superficie
|
// costruisco il vettore delle nuove curve isoparamtriche per la nuova superficie
|
||||||
|
bool bFirstAdded = false ;
|
||||||
|
int nSpanU0 = CrvU0.GetCurveCount() ;
|
||||||
|
int nSpanU1 = CrvU1.GetCurveCount() ;
|
||||||
ISOPARVECT vIso ;
|
ISOPARVECT vIso ;
|
||||||
int nNewCounter = 0 ;
|
|
||||||
int nShowCounter = 0 ;
|
|
||||||
// inserisco solo le isocurve che non sono state modificate
|
|
||||||
for ( int i = 0 ; i < ssize( vCrv) ; ++i) {
|
for ( int i = 0 ; i < ssize( vCrv) ; ++i) {
|
||||||
if( i != vNewOrEdited[nNewCounter].first) {
|
Point3d ptU0 = vCrv[i].first ;
|
||||||
Point3d ptU0 ; vCrv[i]->GetStartPoint( ptU0) ;
|
Point3d ptU1 = vCrv[i].second ;
|
||||||
Point3d ptU1 ; vCrv[i]->GetEndPoint( ptU1) ;
|
double dParam0 ; CrvU0.GetParamAtPoint( ptU0, dParam0) ;
|
||||||
double dParam0 ; CrvU0.GetParamAtPoint( ptU0, dParam0) ;
|
double dParam1 ; CrvU1.GetParamAtPoint( ptU1, dParam1) ;
|
||||||
double dParam1 ; CrvU1.GetParamAtPoint( ptU1, dParam1) ;
|
if( bClosed && (dParam0 < EPS_SMALL || nSpanU0 - dParam0 < EPS_SMALL) && (dParam1 < EPS_SMALL || nSpanU1 - dParam1 < EPS_SMALL)) {
|
||||||
if( i != vShown[nShowCounter])
|
if( ! bFirstAdded) {
|
||||||
vIso.emplace_back( i, dParam0, dParam1) ;
|
dParam0 = 0 ;
|
||||||
|
dParam1 = 0 ;
|
||||||
|
bFirstAdded = true ;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
vIso.emplace_back( i, dParam0, dParam1, false, true) ;
|
dParam0 = nSpanU0 ;
|
||||||
++ nShowCounter ;
|
dParam1 = nSpanU1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
vIso.emplace_back( i, dParam0, dParam1) ;
|
||||||
++ nNewCounter ;
|
|
||||||
while( nNewCounter < ssize( vNewOrEdited) - 1 && vNewOrEdited[nNewCounter].first == -1)
|
|
||||||
++ nNewCounter ;
|
|
||||||
if( i == vShown[nShowCounter])
|
|
||||||
++nShowCounter ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// vNewCrv contiene tutto il nuovo set di curve
|
|
||||||
for( INTINT ii : vNewOrEdited) {
|
|
||||||
Point3d ptU0 ; vNewCrv[ii.second]->GetStartPoint( ptU0) ;
|
|
||||||
Point3d ptU1 ; vNewCrv[ii.second]->GetEndPoint( ptU1) ;
|
|
||||||
double dParam0 ; CrvU0.GetParamAtPoint( ptU0, dParam0) ;
|
|
||||||
double dParam1 ; CrvU1.GetParamAtPoint( ptU1, dParam1) ;
|
|
||||||
vIso.emplace_back( ii.second, dParam0, dParam1, true) ;
|
|
||||||
}
|
|
||||||
sort( vIso.begin(), vIso.end()) ;
|
sort( vIso.begin(), vIso.end()) ;
|
||||||
|
|
||||||
// scorro vIso per eliminare le isocurve non più necessarie
|
// scorro vIso per verificare che non ci siano curve che si intersecano
|
||||||
int c = 0 ;
|
int c = 0 ;
|
||||||
dLastParam0 = vIso[c].dParam0 ;
|
dLastParam0 = vIso[c].dParam0 ;
|
||||||
dLastParam1 = vIso[c].dParam1 ;
|
dLastParam1 = vIso[c].dParam1 ;
|
||||||
++c ;
|
++c ;
|
||||||
while( c < ssize( vIso)) {
|
while ( c < ssize( vIso)) {
|
||||||
if ( vIso[c].dParam1 >= dLastParam1 && ! vIso[c].bNew)
|
if ( vIso[c].dParam0 < dLastParam0 || vIso[c].dParam1 < dLastParam1)
|
||||||
; // non devo fare nulla
|
return false ;
|
||||||
else {
|
|
||||||
dLastParam0 = vIso[c].dParam0 ;
|
|
||||||
dLastParam1 = vIso[c].dParam1 ;
|
|
||||||
// cancello tutte le curve avanti e indietro finché incontro una show che non viene intersecata
|
|
||||||
int c_temp = c + 1 ;
|
|
||||||
while( ! (vIso[c_temp].bShown && vIso[c_temp].dParam0 >= dLastParam0 && vIso[c_temp].dParam1 >= dLastParam1)) {
|
|
||||||
if( vIso[c_temp].bNew)
|
|
||||||
++c_temp ;
|
|
||||||
else
|
|
||||||
vIso.erase(vIso.begin() + c_temp) ;
|
|
||||||
}
|
|
||||||
c_temp = c - 1 ;
|
|
||||||
while( ! (vIso[c_temp].bShown && vIso[c_temp].dParam0 <= dLastParam0 && vIso[c_temp].dParam1 <= dLastParam1)) {
|
|
||||||
if( vIso[c_temp].bNew)
|
|
||||||
--c_temp ;
|
|
||||||
else {
|
|
||||||
vIso.erase(vIso.begin() + c_temp) ;
|
|
||||||
--c_temp ;
|
|
||||||
--c ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dLastParam0 = vIso[c].dParam0 ;
|
dLastParam0 = vIso[c].dParam0 ;
|
||||||
dLastParam1 = vIso[c].dParam1 ;
|
dLastParam1 = vIso[c].dParam1 ;
|
||||||
++c ;
|
++c ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////QUESTI CONTROLLI LI DOVREI FARE IO SE NON AVESSI INFORMAZIONI SU QUALI CURVE SONO QUELLE NUOVE( o MODIFICATE) (da finire nel caso)
|
|
||||||
//// controllo anche se le curve sono ordinate anche nel parametro sulla seconda curva ( se sono state modificate delle curve)
|
|
||||||
//// elimino eventuali curve intersecate da curve modificate
|
|
||||||
//double dLastParam0 = 0 ;
|
|
||||||
//double dLastParam1 = 0 ;
|
|
||||||
//int nCountOrig = 0 ;
|
|
||||||
//int nCountOrigTemp = 0 ;
|
|
||||||
//int nErased = 0 ;
|
|
||||||
//for( int i = 0 ; i < ssize( vNewCrv); ++i) {
|
|
||||||
// bool bFoundPos = false ;
|
|
||||||
// bool bNew = false ;
|
|
||||||
// nCountOrigTemp = nCountOrig ;
|
|
||||||
// while( ! bFoundPos) {
|
|
||||||
// bool bSameCrv = false ;
|
|
||||||
// bool bEdited = false ;
|
|
||||||
// Point3d ptStartOrig ; vCrv[nCountOrig]->GetStartPoint( ptStartOrig) ;
|
|
||||||
// Point3d ptStartNew ; vNewCrv[i]->GetStartPoint( ptStartNew) ;
|
|
||||||
// bool bSameStart = false ;
|
|
||||||
// bool bSameEnd = false ;
|
|
||||||
// if( AreSamePointExact( ptStartOrig, ptStartNew))
|
|
||||||
// bSameStart = true ;
|
|
||||||
// Point3d ptEndOrig ; vCrv[nCountOrig]->GetEndPoint( ptEndOrig) ;
|
|
||||||
// Point3d ptEndNew ; vNewCrv[i]->GetEndPoint( ptEndNew) ;
|
|
||||||
// if( AreSamePointExact( ptEndOrig, ptEndNew))
|
|
||||||
// bSameEnd = true ;
|
|
||||||
// bSameCrv = bSameStart && bSameEnd ;
|
|
||||||
// bEdited = bSameStart ^ bSameEnd ;
|
|
||||||
// if( bEdited || bNew) {
|
|
||||||
// // cancello eventuali curve intersecate da questa modificata
|
|
||||||
// }
|
|
||||||
// bFoundPos = bSameCrv || bEdited || bNew ;
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
dLastParam0 = 0 ;
|
dLastParam0 = 0 ;
|
||||||
dLastParam1 = 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) {
|
for ( int i = 0 ; i < ssize( vIso) ; ++i) {
|
||||||
ICurve* pCrv = vIso[i].bNew ? vNewCrv[vIso[i].nCrv] : vCrv[vIso[i].nCrv] ;
|
const BIPOINT& pCrv = vCrv[vIso[i].nCrv] ;
|
||||||
Point3d ptU0 ; pCrv->GetStartPoint( ptU0) ;
|
Point3d ptU0 = pCrv.first ;
|
||||||
Point3d ptU1 ; pCrv->GetEndPoint( ptU1) ;
|
Point3d ptU1 = pCrv.second ;
|
||||||
double& dParam0 = vIso[i].dParam0 ;
|
double& dParam0 = vIso[i].dParam0 ;
|
||||||
double& dParam1 = vIso[i].dParam1 ;
|
double& dParam1 = vIso[i].dParam1 ;
|
||||||
// se sono vicino ad un'intero allora considero il parametro intero ( uno split già esistente)
|
// se sono vicino ad un'intero allora considero il parametro intero ( uno split già esistente)
|
||||||
@@ -5977,8 +6123,8 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
|
|||||||
CrvU0.AddJoint( dSplit) ;
|
CrvU0.AddJoint( dSplit) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nSpanU0 = CrvU0.GetCurveCount() ;
|
nSpanU0 = CrvU0.GetCurveCount() ;
|
||||||
int nSpanU1 = CrvU1.GetCurveCount() ;
|
nSpanU1 = CrvU1.GetCurveCount() ;
|
||||||
// aggiungo l'ultima coppia
|
// aggiungo l'ultima coppia
|
||||||
vPairs.emplace_back( nSpanU0, nSpanU1) ;
|
vPairs.emplace_back( nSpanU0, nSpanU1) ;
|
||||||
|
|
||||||
@@ -6035,6 +6181,28 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c
|
|||||||
++ nAddedSpan ;
|
++ nAddedSpan ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SAVERULEDGUIDEDISO
|
||||||
|
//debug
|
||||||
|
vector<IGeoObj*> vGeo ;
|
||||||
|
ICURVEPOVECTOR vCrvIso ;
|
||||||
|
GetAllPatchesIsocurves( false, vCrvIso) ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrvIso) ; ++i) {
|
||||||
|
vGeo.push_back( vCrvIso[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
vector<Color> vCol( ssize( vCrvIso)) ;
|
||||||
|
fill( vCol.begin(), vCol.end(), Color( 255,0,128)) ;
|
||||||
|
SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/isoCurves.nge") ;
|
||||||
|
//debug
|
||||||
|
|
||||||
|
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 ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -143,14 +143,14 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
bool IsPlanar( void) const override ;
|
bool IsPlanar( void) const override ;
|
||||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
bool CreateByFlatContour( const PolyLine& PL) override ;
|
||||||
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
||||||
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, bool bDeg3OrDeg2 = false) override ;
|
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr) override ;
|
||||||
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) override ;
|
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) override ;
|
||||||
bool CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
|
bool CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
|
||||||
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
||||||
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
||||||
PNTVECTOR GetAllControlPoints( void) const ;
|
PNTVECTOR GetAllControlPoints( void) const ;
|
||||||
bool GetAllPatchesIsocurves( bool bUorV, ICURVEPOVECTOR& vCrv) const ;
|
bool GetAllPatchesIsocurves( bool bUorV, ICURVEPOVECTOR& vCrv) const ;
|
||||||
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const ICURVEPOVECTOR& vCrv, const ICURVEPOVECTOR& vNewCrv, const INTVECTOR& vShown ,const INTINTVECTOR& vNewOrEdited) ;
|
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv) ;
|
||||||
bool RemoveCollapsedSpans() override ;
|
bool RemoveCollapsedSpans() override ;
|
||||||
bool SwapParameters() ;
|
bool SwapParameters() ;
|
||||||
|
|
||||||
|
|||||||
+1661
-855
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,8 @@
|
|||||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <mutex>
|
|
||||||
#include <atomic>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
typedef std::pair<Point3d, Vector3d> PNTVEC3D ;
|
typedef std::pair<Point3d, Vector3d> PNTVEC3D ;
|
||||||
typedef std::vector<PNTVEC3D> PNTVEC3DVECTOR ; // vettore di intersezioni punto, vettore, tipo superficie
|
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_SliceXY ;
|
||||||
mutable std::vector<InterVoxMatter> m_SliceXZ ;
|
mutable std::vector<InterVoxMatter> m_SliceXZ ;
|
||||||
mutable std::vector<InterVoxMatter> m_SliceYZ ;
|
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 ;
|
int m_nCurrTool ;
|
||||||
std::vector<Tool> m_vTool ;
|
std::vector<Tool> m_vTool ;
|
||||||
|
|||||||
+24
-12
@@ -1271,13 +1271,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
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) ;
|
auto it = m_SliceYZ[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceYZ[nSlBlockN].end()) {
|
if ( it != m_SliceYZ[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs( nAdjVox3[nCount]) == 2) {
|
else if ( abs( nAdjVox3[nCount]) == 2) {
|
||||||
@@ -1287,13 +1289,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
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) ;
|
auto it = m_SliceXZ[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceXZ[nSlBlockN].end()) {
|
if ( it != m_SliceXZ[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs( nAdjVox3[nCount]) == 3) {
|
else if ( abs( nAdjVox3[nCount]) == 3) {
|
||||||
@@ -1303,13 +1307,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
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) ;
|
auto it = m_SliceXY[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceXY[nSlBlockN].end()) {
|
if ( it != m_SliceXY[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
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)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceYZ.emplace( nSliceN, bMatOnSlice) ;
|
SliceYZ.emplace( nSliceN, bMatOnSlice) ;
|
||||||
else {
|
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_SliceYZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs(nAdjVox3[nCount]) == 2) {
|
else if ( abs(nAdjVox3[nCount]) == 2) {
|
||||||
if ( nSlBlockN == nBlock)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceXZ.emplace( nSliceN, bMatOnSlice) ;
|
SliceXZ.emplace( nSliceN, bMatOnSlice) ;
|
||||||
else {
|
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_SliceXZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs(nAdjVox3[nCount]) == 3) {
|
else if ( abs(nAdjVox3[nCount]) == 3) {
|
||||||
if ( nSlBlockN == nBlock)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceXY.emplace(nSliceN, bMatOnSlice) ;
|
SliceXY.emplace(nSliceN, bMatOnSlice) ;
|
||||||
else {
|
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_SliceXY[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1585,7 +1585,6 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
|
|||||||
Vector3d vtDirTip = ptP2T - ptP1T ;
|
Vector3d vtDirTip = ptP2T - ptP1T ;
|
||||||
bool bTopIsPivot = vtDirTop.IsSmall() ;
|
bool bTopIsPivot = vtDirTop.IsSmall() ;
|
||||||
bool bTipIsPivot = vtDirTip.IsSmall() ;
|
bool bTipIsPivot = vtDirTip.IsSmall() ;
|
||||||
bool bTopAndTipAreEquiverse = vtDirTop * vtDirTip > 0 ;
|
|
||||||
|
|
||||||
// box dell'intero volume spazzato, nel riferimento object oriented
|
// box dell'intero volume spazzato, nel riferimento object oriented
|
||||||
BBox3d bbVol ;
|
BBox3d bbVol ;
|
||||||
|
|||||||
Reference in New Issue
Block a user