EgtGeomKernel :

- correzione alla triangolazione di span bilineari in superfici di grado superiore all'uno.
This commit is contained in:
Daniele Bariletti
2024-06-03 17:30:05 +02:00
parent 3b81a6b92e
commit d7d36b670a
+49 -24
View File
@@ -751,24 +751,6 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ;
dCurvV = Dist( ptV, ptPSrf) ;
dCurvU = Dist( ptU, ptPSrf) ;
// devo calcolare anche il twist, in caso di bordi rettilinei ( superficie di grado maggiore di 1, ma che in realtà è una bilineare)
// NON posso guardare la distanza tra il punto medio delle diagonali e il punto centrale della cella ( uLoc = 0.5, vLoc = 0.5)
// posso guardare la distanza tra le due diagonali
Point3d ptP00, ptP10, ptP11, ptP01 ;
// distanza reale tra i vertici della cella
ptP00 = m_mVert[nCToSplit][0] ;
ptP10 = m_mVert[nCToSplit][1] ;
ptP11 = m_mVert[nCToSplit][2] ;
ptP01 = m_mVert[nCToSplit][3] ;
// da implementare!!!!! serve una valutazione più fine, sennò approssimo la superficie in modo troppo grossolano!!!!
DistLineLine dll( ptP00, ptP11, ptP10, ptP01, true, true) ;
double dDist = 0 ; dll.GetDist( dDist) ;
if ( dDist > max(dCurvU, dCurvV) ) {
// devo decidere in quale direzione splittare
// dovrei capire in quale delle due direzioni è più torta la superficie
}
}
// faccio un'analisi più fine della curvatura se almeno il grado di una curva di uno dei due parametri è alto e
// se sto ancora guardando una cella abbastanza grande
@@ -809,6 +791,42 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
}
}
// devo calcolare anche il twist, in caso di bordi rettilinei ( superficie di grado maggiore di 1, ma che in realtà è una bilineare)
// NON posso guardare la distanza tra il punto medio delle diagonali e il punto centrale della cella ( uLoc = 0.5, vLoc = 0.5)
// posso guardare la distanza tra le due diagonali
bool bTwist = false ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
// distanza reale tra i vertici della cella
ptP00 = m_mVert[nCToSplit][0] ;
ptP10 = m_mVert[nCToSplit][1] ;
ptP11 = m_mVert[nCToSplit][2] ;
ptP01 = m_mVert[nCToSplit][3] ;
// serve una valutazione più fine, sennò approssimo la superficie in modo troppo grossolano
DistLineLine dll( ptP00, ptP11, ptP10, ptP01, true, true) ;
double dDist = 0 ; dll.GetDist( dDist) ;
if ( dDist > max(dCurvU, dCurvV) && dDist > EPS_SMALL) {
bTwist = true ;
// devo decidere in quale direzione splittare
// dovrei capire in quale delle due direzioni è più torta la superficie
Vector3d vtU0 = ptP10 - ptP00 ;
Vector3d vtU1 = ptP11 - ptP01 ;
double dAngU ;
bool bDetU = false ;
vtU0.GetRotation( vtU1, vtU0 ^ vtU1, dAngU, bDetU) ;
Vector3d vtV0 = ptP01 - ptP00 ;
Vector3d vtV1 = ptP11 - ptP10 ;
double dAngV ;
bool bDetV = false ;
// faccio la get rotation tra le coppie vettori, usando come asse il loro prodotto vettoriale per ottenere la rotazione tra i due lati
// splitto nella direzione perpendicolare alla coppia di vettori più torti tra loro.
vtV0.GetRotation( vtV1, vtV0 ^ vtV1, dAngV, bDetV) ;
if ( dAngU > dAngV)
dCurvV = dDist ;
else
dCurvU = dDist ;
}
// per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza
// misura approssimativa della curvatura in una direzione
bool bVert ;
@@ -821,12 +839,12 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
bVert = true ;
}
m_mTree[nCToSplit].SetSplitDirVert( bVert) ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
//Point3d ptP00, ptP10, ptP11, ptP01 ;
//ptP00 = m_mVert[nCToSplit][0] ;
//ptP10 = m_mVert[nCToSplit][1] ;
//ptP11 = m_mVert[nCToSplit][2] ;
//ptP01 = m_mVert[nCToSplit][3] ;
// distanza reale tra i vertici della cella
ptP00 = m_mVert[nCToSplit][0] ;
ptP10 = m_mVert[nCToSplit][1] ;
ptP11 = m_mVert[nCToSplit][2] ;
ptP01 = m_mVert[nCToSplit][3] ;
double dLen0 = Dist( ptP00, ptP10) ;
double dLen1 = Dist( ptP10, ptP11) ;
double dLen2 = Dist( ptP01, ptP11) ;
@@ -868,7 +886,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
bool bSplit = false ;
// dSideMinVal potrebbe essere zero se entrambi i lati che dovrei splittare sono collassati in un punto, ma questo non vuol
// dire che non dovrei eseguire lo split
if ( (dSideMinVal / 2 >= dSideMin || dSideMinVal < EPS_SMALL) && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) {
if ( ! bTwist && (dSideMinVal / 2 >= dSideMin || dSideMinVal < EPS_SMALL) && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) {
CurveLine cl0010, cl0001, cl1011, cl0111 ;
// V=0
cl0010.Set( ptP00, ptP10) ;
@@ -938,6 +956,13 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
}
}
}
else if ( bTwist ) {
// se la cella è twistata allora l'errore lo calcolo come nelle bilineari
//double dErr = 1. / 4. * ( ( ptP00 - ptP01) + ( ptP11 - ptP10)).Len() ;
double dErr = ( ( ptP00 - ptP01) + ( ptP11 - ptP10)).Len() / 20 ;
if ( dErr > dLinTol)
bSplit = true ;
}
if ( bSplit || dSideMaxVal > dSideMax) {
m_mTree[nCToSplit].SetSplitDirVert( bVert) ;