diff --git a/Tree.cpp b/Tree.cpp index 51fb1a0..17183f8 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -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) ;