EgtGeomKernel :
- miglioramenti e correzioni alle rigate con le bezier.
This commit is contained in:
+128
-31
@@ -48,7 +48,7 @@
|
||||
#define SAVEREBUILTISO 0
|
||||
#define SAVERULEDISO 1
|
||||
#define SAVERULEDGUIDEDISO 0
|
||||
#define SAVEMATCHCURVES 0
|
||||
#define SAVEMATCHCURVES 1
|
||||
#if SAVEFAILEDTRIANGULATION || SAVEREBUILTISO || SAVERULEDISO || SAVERULEDGUIDEDISO || SAVEMATCHCURVES
|
||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||
std::vector<IGeoObj*> vGeo ;
|
||||
@@ -4511,6 +4511,60 @@ GetEdgeSplitByAngTol( const PolyLine& PL, double dAngTol, BOOLVECTOR& vEdgeSplit
|
||||
return true ;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetEdgeSplitByAngTol( const ICurveComposite* pCC, double dAngTol, BOOLVECTOR& vEdgeSplit)
|
||||
{
|
||||
int nCrvs = pCC->GetCurveCount() ;
|
||||
vEdgeSplit.clear() ;
|
||||
vEdgeSplit.resize( nCrvs) ;
|
||||
fill( vEdgeSplit.begin(), vEdgeSplit.end(), false) ;
|
||||
bool bClosed = pCC->IsClosed() ;
|
||||
Vector3d vtTanCurr = V_INVALID, vtTanNext = V_INVALID ;
|
||||
// cos della tolleranza angolare massima
|
||||
double dCosTol = cos( dAngTol * DEGTORAD) ;
|
||||
for ( int nC = 0 ; nC < nCrvs ; ++ nC) {
|
||||
const ICurve* pSubCrvCurr = pCC->GetCurve( nC) ;
|
||||
int nNext = nC < nCrvs - 1 ? nC + 1 : 0 ;
|
||||
const ICurve* pSubCrvNext = pCC->GetCurve( nNext) ;
|
||||
pSubCrvCurr->GetEndDir( vtTanCurr) ; vtTanCurr.Normalize() ;
|
||||
pSubCrvNext->GetStartDir( vtTanNext) ; vtTanNext.Normalize() ;
|
||||
// Calcolo il Coseno tra i due versori
|
||||
double dCos = vtTanCurr * vtTanNext ;
|
||||
// Se oltre la tolleranza allora ho incontrato un edge
|
||||
if ( dCos < dCosTol)
|
||||
vEdgeSplit[nC] = true ;
|
||||
}
|
||||
|
||||
if ( ! bClosed)
|
||||
vEdgeSplit[nCrvs - 1] = false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
AdjustParamFromApprox( const PolyLine& plApprox, double& dParam)
|
||||
{
|
||||
// il parametro in ingresso è riferito al numero di linee della polilinea
|
||||
// questa variabile verrà sostituita con il valore del parametro corrispondente alla curva che è stata approssimata dalla polilinea
|
||||
int nCrv = int( dParam) ;
|
||||
if ( nCrv > plApprox.GetPointNbr())
|
||||
return false ;
|
||||
double dParamPrev = 0 ;
|
||||
plApprox.GetFirstU( dParamPrev) ;
|
||||
int c = 0 ;
|
||||
while ( c < nCrv) {
|
||||
plApprox.GetNextU( dParamPrev) ;
|
||||
++c ;
|
||||
}
|
||||
double dParamNext = 0 ;
|
||||
plApprox.GetNextU( dParamNext) ;
|
||||
double dFactor = dParam - nCrv ;
|
||||
dParam = dFactor * dParamNext + ( 1 - dFactor) * dParamPrev ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int nRuledType)
|
||||
@@ -4947,11 +5001,18 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
vector<vector<Color>> vvCol0(4) ;
|
||||
#endif
|
||||
|
||||
// approssimo le curve con delle polyline per il calcolo delle distanze
|
||||
PolyLine plApproxU0, plApproxU1 ;
|
||||
double dLinTol = 10 * EPS_SMALL ;
|
||||
double dAngTol = 5 ;
|
||||
CrvU0.ApproxWithLines( dLinTol, dAngTol, ICurve::APL_STD, plApproxU0) ;
|
||||
CrvU1.ApproxWithLines( dLinTol, dAngTol, ICurve::APL_STD, plApproxU1) ;
|
||||
|
||||
// prima trovo le associazioni senza aggiunte di punti
|
||||
bool bIsClosed0 = plU0.IsClosed() ;
|
||||
bool bIsClosed1 = plU1.IsClosed() ;
|
||||
CurveComposite ccPoly0 ; ccPoly0.FromPolyLine( plU0) ;
|
||||
CurveComposite ccPoly1 ; ccPoly1.FromPolyLine( plU1) ;
|
||||
CurveComposite ccPoly0 ; ccPoly0.FromPolyLine( plApproxU0) ;
|
||||
CurveComposite ccPoly1 ; ccPoly1.FromPolyLine( plApproxU1) ;
|
||||
Point3d ptP1 ; plU1.GetFirstPoint( ptP1) ;
|
||||
PNTUVECTOR vMatch1 ;
|
||||
PNTUVECTOR vMatch1b ;
|
||||
@@ -4962,13 +5023,23 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
double dParam ;
|
||||
Point3d ptJoint ;
|
||||
|
||||
DistPointCurve dpc( ptP1, CrvU0, false) ;
|
||||
DistPointCurve dpc( ptP1, ccPoly0, false) ;
|
||||
int nFlag = 0 ;
|
||||
dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
||||
AdjustParamFromApprox( plApproxU0, dParam) ;
|
||||
dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
||||
vMatch1b.emplace_back( ptJoint, dParam) ;
|
||||
if ( icp.GetIntersCount() > 0)
|
||||
|
||||
double dParamMinDist = dParam ;
|
||||
Point3d ptMinDist = ptJoint ;
|
||||
if ( icp.GetIntersCount() > 0) {
|
||||
icp.GetIntersPointNearTo( ptP1, ptJoint, dParam) ;
|
||||
AdjustParamFromApprox( plApproxU0, dParam) ;
|
||||
if ( Dist( ptP1, ptJoint) > 2 * Dist( ptP1, ptMinDist)) {
|
||||
ptJoint = ptMinDist ;
|
||||
dParam = dParamMinDist ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
;
|
||||
}
|
||||
@@ -5011,14 +5082,22 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
Vector3d vtDir ; CrvU0.GetCurve( vPnt0.size() - 1)->GetEndDir( vtDir) ;
|
||||
IntersCurvePlane icp( ccPoly1, ptP0, vtDir) ;
|
||||
|
||||
DistPointCurve dpc( ptP0, CrvU1, false) ;
|
||||
DistPointCurve dpc( ptP0, ccPoly1, false) ;
|
||||
int nFlag = 0 ;
|
||||
dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
||||
dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
||||
AdjustParamFromApprox( plApproxU1, dParam) ;
|
||||
vMatch0b.emplace_back( ptJoint, dParam) ;
|
||||
|
||||
double dParamMinDist = dParam ;
|
||||
Point3d ptMinDist = ptJoint ;
|
||||
if ( icp.GetIntersCount() > 0) {
|
||||
icp.GetIntersPointNearTo( ptP0, ptJoint, dParam) ;
|
||||
AdjustParamFromApprox( plApproxU1, dParam) ;
|
||||
if ( Dist( ptP0, ptJoint) > 2 * Dist( ptP0, ptMinDist)) {
|
||||
ptJoint = ptMinDist ;
|
||||
dParam = dParamMinDist ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
;
|
||||
@@ -5068,7 +5147,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
// tramite due misure diverse della distanza
|
||||
INTINTVECTOR vMismatch0 ;
|
||||
INTINTVECTOR vMismatch1 ;
|
||||
double dMaxDist = Dist( vPnt0[0], vPnt1[0]) / 20 ;
|
||||
//double dMaxDist = Dist( vPnt0[0], vPnt1[0]) / 20 ;
|
||||
double dMaxDist = Dist( vPnt0[0], vPnt1[0]) / 3 ;
|
||||
for( int i = 0 ; i < ssize( vMatch0) ; ++i) {
|
||||
if( ! AreSamePointEpsilon( vMatch0[i].first, vMatch0b[i].first, dMaxDist)) {
|
||||
int c = i + 1 ;
|
||||
@@ -5116,9 +5196,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
|
||||
// verifico la presenza di eventuali "edge" lungo le polyline ( punti di passaggio di un edge e quindi cambi bruschi di direzione della polyline)
|
||||
BOOLVECTOR vEdgeSplit0, vEdgeSplit1 ;
|
||||
double dAngTol = 55 ;
|
||||
GetEdgeSplitByAngTol( plU0, dAngTol, vEdgeSplit0) ;
|
||||
GetEdgeSplitByAngTol( plU1, dAngTol, vEdgeSplit1) ;
|
||||
double dAngTolSplit = 55 ;
|
||||
GetEdgeSplitByAngTol( &CrvU0, dAngTolSplit, vEdgeSplit0) ;
|
||||
GetEdgeSplitByAngTol( &CrvU1, dAngTolSplit, vEdgeSplit1) ;
|
||||
|
||||
int c = 0 ;
|
||||
double dLastParamMatch0 = 0 ;
|
||||
@@ -5135,18 +5215,20 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
bool bAdvance = true ;
|
||||
int m0 = 0, m1 = 0 ; // contatori delle zone di mismatch
|
||||
// verifico i match effettivi tra le polyline
|
||||
while ( bAdvance) {
|
||||
int nPairs = 0 ;
|
||||
while ( bAdvance && ssize( vPairs) > nPairs) {
|
||||
nPairs = ssize( vPairs) ;
|
||||
if ( c > ssize(vMatch0) - 1 || j > ssize( vMatch1) - 1) {
|
||||
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: le due curve potrebbero non avere forme coerenti") ;
|
||||
return false ;
|
||||
}
|
||||
// aggiorno il contatore delle eventuali zone di mismatch
|
||||
if( ssize(vMismatch0) > 0) {
|
||||
while( m0 < ssize(vMismatch0) && c > vMismatch0[m0].second)
|
||||
if( ssize( vMismatch0) > 0) {
|
||||
while( m0 < ssize( vMismatch0) - 1 && c > vMismatch0[m0].second)
|
||||
++m0 ;
|
||||
}
|
||||
if( ssize(vMismatch1) > 0) {
|
||||
while( m1 < ssize(vMismatch1) && j > vMismatch1[m1].second)
|
||||
if( ssize( vMismatch1) > 0) {
|
||||
while( m1 < ssize( vMismatch1) - 1 && j > vMismatch1[m1].second)
|
||||
++m1 ;
|
||||
}
|
||||
|
||||
@@ -5165,9 +5247,12 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
// capisco con quale delle due polyline avanzo
|
||||
bool bAdvance0 = dParam0 < j + 1 + EPS_SMALL ;
|
||||
bool bAdvance1 = dParam1 < c + 1 + EPS_SMALL ;
|
||||
// controllo se ho un match biunivoco
|
||||
bool bPerfectMatch = abs( dParam0 - round( dParam0)) < EPS_SMALL && round( dParam0) == j + 1 &&
|
||||
abs( dParam1 - round( dParam1)) < EPS_SMALL && round( dParam1) == c + 1 ;
|
||||
// controllo se ho un match biunivoco ( controllo parametri e punti)
|
||||
bool bPerfectMatch = ( abs( dParam0 - round( dParam0)) < 10 * EPS_SMALL && round( dParam0) == j + 1 &&
|
||||
abs( dParam1 - round( dParam1)) < 10 * EPS_SMALL && round( dParam1) == c + 1) ||
|
||||
( AreSamePointEpsilon( vPnt0[c+1], ptJoint1, 100 * EPS_SMALL) && AreSamePointEpsilon( vPnt1[j+1], ptJoint0, 100 * EPS_SMALL)) ;
|
||||
if ( bPerfectMatch)
|
||||
bAdvance0 = true ;
|
||||
int nSplit1 = vdSplit1.size() ;
|
||||
int nSplit0 = vdSplit0.size() ;
|
||||
// se con una polyline sono arrivato alla fine non posso più avanzare
|
||||
@@ -5188,7 +5273,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
bMismatch = (bMismatch0 && bMismatch1) || (bMismatch0 && ! bAdvance1) || (bMismatch1 && ! bAdvance0);
|
||||
}
|
||||
// se trovo che ho uno spigolo allora procedo con la gestione spigoli
|
||||
else if( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) {
|
||||
if ( vEdgeSplit0[c] && vEdgeSplit1[j]) {
|
||||
// se ho uno spigolo su entrambe le curve forzo l'accoppiamento
|
||||
bAdvance0 = true ;
|
||||
bPerfectMatch = true ;
|
||||
@@ -5197,7 +5282,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
ptJoint0 = vPnt1[j+1] ;
|
||||
ptJoint1 = vPnt0[c+1] ;
|
||||
}
|
||||
else if ( (vEdgeSplit0[c+1] && ! bAdvance1) || (vEdgeSplit1[j+1] && ! bAdvance0)) {
|
||||
else if ( ( vEdgeSplit0[c] && ! bAdvance1) || (vEdgeSplit1[j] && ! bAdvance0)) {
|
||||
// da una parte ho uno spigolo e dall'altra non posso avanzare
|
||||
bAdvance0 = false ;
|
||||
bAdvance1 = false ;
|
||||
@@ -5220,8 +5305,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
}
|
||||
else {
|
||||
// ho un match con una joint esistente
|
||||
if ( dParam0 - int( dParam0) < EPS_SMALL) {
|
||||
if ( dParam0 > dLastParamMatch0)
|
||||
if ( abs( dParam0 - round( dParam0)) < EPS_SMALL) {
|
||||
if ( dParam0 > dLastParamMatch0 + EPS_SMALL)
|
||||
vPairs.emplace_back( c + nSplit0, j + nSplit1 + 1) ;
|
||||
else
|
||||
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
|
||||
@@ -5257,8 +5342,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
}
|
||||
else {
|
||||
// ho un match con una joint esistente
|
||||
if ( dParam1 - int( dParam1) < EPS_SMALL) {
|
||||
if ( dParam1 > dLastParamMatch1)
|
||||
if ( abs( dParam1 - round( dParam1)) < EPS_SMALL) {
|
||||
if ( dParam1 > dLastParamMatch1 + EPS_SMALL)
|
||||
vPairs.emplace_back( c + nSplit0 + 1, j + nSplit1) ;
|
||||
else
|
||||
vPairs.emplace_back( c + nSplit0, j + nSplit1) ;
|
||||
@@ -5281,11 +5366,11 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
//2. se sono in una zona di mismatch faccio il match usando la parametrizzazione sulla lunghezza dei tratti di curve interessati
|
||||
//3. sennò accoppio comunque ( la coppia corrente)
|
||||
bool bEdgeFoundOnSecond = false ;
|
||||
if ( vEdgeSplit0[c+1] && vEdgeSplit1[j+1]) {
|
||||
if ( vEdgeSplit0[c] && vEdgeSplit1[j]) {
|
||||
// questo caso non è previsto !!!!! e non mi aspetto che avvenga
|
||||
LOG_DBG_ERR( GetEGkLogger(), "RLT_B_MINDIST_PLUS: a not handled mismatch was found, type 0") ;
|
||||
}
|
||||
if ( vEdgeSplit0[c+1] && ! bMismatch) {
|
||||
if ( vEdgeSplit0[c] && ! bMismatch) {
|
||||
++c ;
|
||||
++j ;
|
||||
//cerco se ho uno split anche su U1 entro una distanza che sia al massimo il doppio di quella che c'è col punto a mindist
|
||||
@@ -5308,10 +5393,13 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
dLastParamMatch0 = j - 1 ;
|
||||
ptLastPointMatch0 = vPnt1[j] ;
|
||||
}
|
||||
else
|
||||
else {
|
||||
bMismatch = true ;
|
||||
--c ;
|
||||
--j ;
|
||||
}
|
||||
}
|
||||
else if ( vEdgeSplit1[j+1] && ! bMismatch) {
|
||||
else if ( vEdgeSplit1[j] && ! bMismatch) {
|
||||
++c ;
|
||||
++j ;
|
||||
//cerco se ho uno split anche su U1 entro una distanza che sia al massimo il doppio di quella che c'è col punto a mindist
|
||||
@@ -5334,11 +5422,14 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
dLastParamMatch1 = c - 1 ;
|
||||
ptLastPointMatch1 = vPnt0[c] ;
|
||||
}
|
||||
else
|
||||
else {
|
||||
bMismatch = true ;
|
||||
--c ;
|
||||
--j ;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ! vEdgeSplit0[c+1] && ! vEdgeSplit1[j+1]) || bMismatch) {
|
||||
if( ( ! vEdgeSplit0[c] && ! vEdgeSplit1[j]) || bMismatch) {
|
||||
// non ci sono riferimenti per fare un match, quindi li cerco io
|
||||
|
||||
///////////OLD VRESION
|
||||
@@ -5357,7 +5448,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
// identifico la zona in cui ho il mismatch e parametrizzo localmente
|
||||
|
||||
//conto quanti punti ho nel mezzo
|
||||
int c_temp, j_temp ;
|
||||
int c_temp = c, j_temp = j ;
|
||||
if( ! bMismatch) {
|
||||
c_temp = c, j_temp = j ;
|
||||
bAdvance0 = true ;
|
||||
@@ -5435,6 +5526,12 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( j_temp == ssize( vMatch1))
|
||||
--j_temp ;
|
||||
if ( c_temp == ssize( vMatch0))
|
||||
-- c_temp ;
|
||||
|
||||
// se non sono avanzato, allora mi basta accoppiare i due punti in questione
|
||||
if( c_temp == c || j_temp == j) {
|
||||
++c ;
|
||||
|
||||
Reference in New Issue
Block a user