EgtGeomKernel.rc 1.6i2 :

- possibilità di impostare tolleranza sul costruttore di Intervals
- corretto errore su operatori booleani di Region con tratti piccoli su oggetti grandi
- estesi operatori booleani di regioni anche a regioni su piani paralleli.
This commit is contained in:
Dario Sassi
2015-09-13 17:00:17 +00:00
parent 78ec13da8c
commit c044f0c785
7 changed files with 44 additions and 29 deletions
+3 -3
View File
@@ -2159,9 +2159,9 @@ CurveComposite::IsParamAtJoint( double dU) const
{
// se aperta e all'inizio o alla fine o lontano dagli interi non è giunzione
bool bClosed = IsClosed() ;
if ( ( ! bClosed && fabs( dU) < EPS_ZERO) ||
( ! bClosed && fabs( dU - double( m_CrvSmplS.size())) < EPS_ZERO) ||
fabs( dU - (int) ( dU + EPS_ZERO)) > EPS_ZERO)
if ( ( ! bClosed && fabs( dU) < EPS_PARAM) ||
( ! bClosed && fabs( dU - double( m_CrvSmplS.size())) < EPS_PARAM) ||
fabs( dU - (int) ( dU + EPS_PARAM)) > EPS_PARAM)
return false ;
else
return true ;
+6 -6
View File
@@ -111,7 +111,7 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
// contatore iterazioni
nCount ++ ;
// calcolo P, D1 e D2
nSide = ( fabs( dPar - approxMin.dParMin) < EPS_ZERO) ? ICurve::FROM_PLUS : ICurve::FROM_MINUS ;
nSide = ( fabs( dPar - approxMin.dParMin) < EPS_PARAM) ? ICurve::FROM_PLUS : ICurve::FROM_MINUS ;
cCurve.GetPointD1D2( dPar, nSide, ptQ, &vtDer1, &vtDer2) ;
// vettore dal punto al piede sulla curva
vtDiff = ptQ - ptP ;
@@ -143,7 +143,7 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
else
dPar = approxMin.dParMax ;
}
} while ( nCount < MAX_COUNT && fabs( dPar - dPrevPar) > EPS_ZERO &&
} while ( nCount < MAX_COUNT && fabs( dPar - dPrevPar) > EPS_PARAM &&
fabs( dSqCosA) > COS_ORTO_ANG_ZERO * COS_ORTO_ANG_ZERO) ;
if ( nCount == MAX_COUNT)
@@ -168,14 +168,14 @@ FilterMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
if ( bFound && fabs( (*Iter).dDist - dMinDist) < EPS_SMALL) {
// se abbastanza lontano e non su bordi intervallino lo aggiungo
if ( SqDist( (*Iter).ptQ, Info.back().ptQ) > MIN_LEN_CONT_MDPC &&
! bLastOnEnd && fabs( (*Iter).dPar - (*Iter).dParMin) > EPS_ZERO) {
! bLastOnEnd && fabs( (*Iter).dPar - (*Iter).dParMin) > EPS_PARAM) {
Info.emplace_back( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ) ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_ZERO ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_PARAM ;
}
// altrimenti lo sostituisco se distanza minore
else if ( (*Iter).dDist < dMinDist) {
Info.back() = MinDistPCInfo( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ) ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_ZERO ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_PARAM ;
}
}
// primo punto o punto con minima distanza più bassa
@@ -186,7 +186,7 @@ FilterMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
// il nuovo vettore deve contenere solo quest'ultimo minimo
Info.clear() ;
Info.emplace_back( MDPCI_NORMAL, (*Iter).dPar, (*Iter).ptQ) ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_ZERO ;
bLastOnEnd = fabs( (*Iter).dPar - (*Iter).dParMax) < EPS_PARAM ;
}
}
if ( Info.empty())
BIN
View File
Binary file not shown.
+6 -6
View File
@@ -52,7 +52,7 @@ Intervals::Add( double dMin, double dMax)
auto iIter = m_lInts.begin() ;
while ( iIter != m_lInts.end()) {
// se interseca l'intervallo corrente
if ( dMin < iIter->second + EPS_SMALL && dMax > iIter->first - EPS_SMALL) {
if ( dMin < iIter->second + m_dToler && dMax > iIter->first - m_dToler) {
// se ha già interessato un intervallo precedente
if ( iInsert != m_lInts.end()) {
// aggiorno il massimo dell'intervallo già interessato
@@ -73,7 +73,7 @@ Intervals::Add( double dMin, double dMax)
}
}
// se il nuovo intervallo finisce prima
else if ( dMax <= iIter->first - EPS_SMALL) {
else if ( dMax <= iIter->first - m_dToler) {
// se non già inserito, lo faccio ora
if ( iInsert == m_lInts.end())
iInsert = m_lInts.emplace( iIter, dMin, dMax) ;
@@ -81,7 +81,7 @@ Intervals::Add( double dMin, double dMax)
break ;
}
// se il nuovo intervallo inizia dopo
else if ( dMin > iIter->second + EPS_SMALL)
else if ( dMin > iIter->second + m_dToler)
// passo al successivo
++ iIter ;
}
@@ -104,19 +104,19 @@ Intervals::Subtract( double dMin, double dMax)
// se interseca l'intervallo corrente
if ( dMin < iIter->second && dMax > iIter->first) {
// se devo limitarlo inferiormente
if ( dMin < ( iIter->first + EPS_SMALL) && dMax < ( iIter->second - EPS_SMALL)) {
if ( dMin < ( iIter->first + m_dToler) && dMax < ( iIter->second - m_dToler)) {
iIter->first = dMax ;
// passo al successivo
++ iIter ;
}
// se devo limitarlo superiormente
else if ( dMin > ( iIter->first + EPS_SMALL) && dMax > ( iIter->second - EPS_SMALL)) {
else if ( dMin > ( iIter->first + m_dToler) && dMax > ( iIter->second - m_dToler)) {
iIter->second = dMin ;
// passo al successivo
++ iIter ;
}
// se devo dividerlo in due parti
else if ( dMin > ( iIter->first + EPS_SMALL) && dMax < ( iIter->second - EPS_SMALL)) {
else if ( dMin > ( iIter->first + m_dToler) && dMax < ( iIter->second - m_dToler)) {
// inserisco il nuovo intervallo che corrisponde alla parte inferiore
iIter = m_lInts.emplace( iIter, iIter->first, dMin) ;
// modifico l'intervallo successivo
+2 -2
View File
@@ -144,9 +144,9 @@ PolyArc::ParamLinearTransform( double dStartU, double dEndU)
double dOriEndU = m_lUPointBs.back().dU ;
// determino i coefficienti di riparametrizzazione
double dCoeff ;
if ( fabs( dEndU - dStartU) < EPS_ZERO)
if ( fabs( dEndU - dStartU) < EPS_PARAM)
dCoeff = 0 ;
else if ( fabs( dOriEndU - dOriStartU) > EPS_ZERO)
else if ( fabs( dOriEndU - dOriStartU) > EPS_PARAM)
dCoeff = ( dEndU - dStartU) / ( dOriEndU - dOriStartU) ;
else
return false ;
+2 -2
View File
@@ -952,12 +952,12 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
return false ;
// intervalli totali delle diverse classi
Intervals inTIn, inTOut, inTOnP, inTOnM ;
Intervals inTIn( EPS_PARAM), inTOut( EPS_PARAM), inTOnP( EPS_PARAM), inTOnM( EPS_PARAM) ;
inTOut.Set( dStart, dEnd) ; // inizializzo come tutta la linea per poi poter rimuovere parti
// ciclo sui chunk
for ( int nChunk = 0 ; nChunk < GetChunkCount() ; ++ nChunk) {
// intervalli di Chunk delle diverse classi
Intervals inCIn, inCOut, inCOnP, inCOnM ;
Intervals inCIn( EPS_PARAM), inCOut( EPS_PARAM), inCOnP( EPS_PARAM), inCOnM( EPS_PARAM) ;
inCIn.Set( dStart, dEnd) ; // inizializzo come tutta la linea per poi poter rimuovere parti
// classifico la curva con tutti i loop presenti nel chunk
for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) {
+25 -10
View File
@@ -31,9 +31,8 @@ SurfFlatRegion::Add( const ISurfFlatRegion& Other)
if ( &SfrOther == nullptr)
return false ;
// verifico che le due regioni giacciano nello stesso piano
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()) ||
fabs( ( m_frF.Orig() - SfrOther.m_frF.Orig()) * m_frF.VersZ()) > EPS_SMALL)
// verifico che le due regioni giacciano in piani paralleli
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
return false ;
// gestione eventuale copia dell'altra per trasformare il riferimento
@@ -51,6 +50,12 @@ SurfFlatRegion::Add( const ISurfFlatRegion& Other)
// trasformo le curve
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->ToGlob( frTransf) ;
// calcolo vettore di movimento per portarle nel piano XY (Z=0)
Vector3d vtMove( 0, 0, - frTransf.Orig().z) ;
if ( ! vtMove.IsSmall()) {
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->Translate( vtMove) ;
}
// assegno il nuovo riferimento
pCopyOth->m_frF = m_frF ;
// aggiorno puntatore della copia in lavoro
@@ -105,9 +110,8 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
if ( &SfrOther == nullptr)
return false ;
// verifico che le due regioni giacciano nello stesso piano
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()) ||
fabs( ( m_frF.Orig() - SfrOther.m_frF.Orig()) * m_frF.VersZ()) > EPS_SMALL)
// verifico che le due regioni giacciano in piani paralleli
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
return false ;
// gestione eventuale copia dell'altra per trasformare il riferimento
@@ -125,6 +129,12 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
// trasformo le curve
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->ToGlob( frTransf) ;
// calcolo vettore di movimento per portarle nel piano XY (Z=0)
Vector3d vtMove( 0, 0, - frTransf.Orig().z) ;
if ( ! vtMove.IsSmall()) {
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->Translate( vtMove) ;
}
// assegno il nuovo riferimento
pCopyOth->m_frF = m_frF ;
// aggiorno puntatore della copia in lavoro
@@ -179,9 +189,8 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
if ( &SfrOther == nullptr)
return false ;
// verifico che le due regioni giacciano nello stesso piano
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()) ||
fabs( ( m_frF.Orig() - SfrOther.m_frF.Orig()) * m_frF.VersZ()) > EPS_SMALL)
// verifico che le due regioni giacciano in piani paralleli
if ( ! AreSameVectorApprox( m_frF.VersZ(), SfrOther.m_frF.VersZ()))
return false ;
// gestione eventuale copia dell'altra per trasformare il riferimento
@@ -199,6 +208,12 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
// trasformo le curve
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->ToGlob( frTransf) ;
// calcolo vettore di movimento per portarle nel piano XY (Z=0)
Vector3d vtMove( 0, 0, - frTransf.Orig().z) ;
if ( ! vtMove.IsSmall()) {
for ( auto& pLoop : pCopyOth->m_vpLoop)
pLoop->Translate( vtMove) ;
}
// assegno il nuovo riferimento
pCopyOth->m_frF = m_frF ;
// aggiorno puntatore della copia in lavoro
@@ -257,7 +272,7 @@ SurfFlatRegion::MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion&
if ( ! Other.MyGetCurveClassification( *pLoop, ccClass))
return false ;
// creo intervalli validi, tenendo classificazioni ricevute
Intervals inOk1, inOk2 ;
Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ;
for ( auto& ccOne : ccClass) {
if ( nType1 != CRVC_NULL && ccOne.nClass == nType1)
inOk1.Add( ccOne.dParE, ccOne.dParS) ;