EgtGeomKernel :
- migliorata la robustezza per il calcolo della curvatura - pulizia del codice Da aggiungere : - gestione trim.
This commit is contained in:
@@ -34,9 +34,9 @@ Cell::Cell( void)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Cell::Cell( Point3d ptBL, Point3d ptTR)
|
||||
Cell::Cell( Point3d& ptBL, Point3d& ptTR)
|
||||
: m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0),
|
||||
m_nChild1( -2), m_nChild2( -2), m_ptPbl( ptBL), m_ptPtr(ptTR), m_bProcessed ( false) , m_bSplitVert ( true)
|
||||
m_nChild1( -2), m_nChild2( -2), m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed ( false) , m_bSplitVert ( true)
|
||||
{}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Cell::~Cell( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
Cell::IsSame( Cell cOtherCell) const
|
||||
Cell::IsSame( const Cell& cOtherCell) const
|
||||
{
|
||||
if ( m_nId == cOtherCell.m_nId)
|
||||
return true ;
|
||||
@@ -95,14 +95,17 @@ void Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches)
|
||||
bool bIsRat, bTrimmed ;
|
||||
m_pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ;
|
||||
m_bTrimmed = bTrimmed ;
|
||||
m_nDegU = nDegU ;
|
||||
m_nDegV = nDegV ;
|
||||
if ( nDegU == 1 && nDegV == 1)
|
||||
m_bBilinear = true ;
|
||||
if ( nSpanU * nSpanV != 1)
|
||||
m_bMulti = true ;
|
||||
|
||||
// salvo i vertici 3d della cella root
|
||||
Point3d ptBottom ( 0, 0) ;
|
||||
Point3d ptTop( nSpanU, nSpanV) ;
|
||||
Cell cRoot( ORIG, ptTop) ;
|
||||
Cell cRoot( ptBottom, ptTop) ;
|
||||
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
|
||||
Point3d ptP00, ptP10, ptP11, ptP01 ;
|
||||
bool bOk = false ;
|
||||
@@ -224,7 +227,7 @@ Tree::Split( int nId, double dSplitValue)
|
||||
// controllo che lo split non venga fatto sul lato della cella
|
||||
if ( ( m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().x - EPS_SMALL) ||
|
||||
( ! m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().y - EPS_SMALL)) {
|
||||
// per lo split a parametro libero devo impedire che si facciano split troppo vicini al bordo!!!!!!!!!!!!!!!!!!!
|
||||
// per lo split a parametro libero dovrò impedire che si facciano split troppo vicini al bordo!!!!!!!!!!!!!!!!!!!
|
||||
m_mTree[nId].m_dSplit = dSplitValue ;
|
||||
Cell cChild1, cChild2 ;
|
||||
cChild1.m_nDepth = m_mTree[nId].m_nDepth + 1 ;
|
||||
@@ -330,21 +333,65 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
if ( m_mTree[nCToSplit].IsLeaf()) {
|
||||
// calcolo in quale direzione ho più curvatura
|
||||
// ptP00P10 è un punto tra P00 e P10
|
||||
double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ;
|
||||
double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ;
|
||||
double dULoc = 0.5, dVLoc = 0.5 ;
|
||||
Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00 ;
|
||||
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
|
||||
Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ;
|
||||
Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ;
|
||||
// per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza
|
||||
// misura approssimativa della curvatura in una direzione
|
||||
double dCurvV = Dist( ptV, ptPSrf) ;
|
||||
double dCurvU = Dist( ptU, ptPSrf) ;
|
||||
double dCurvU = 0, dCurvV = 0 ;
|
||||
double dLenParU = m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x ;
|
||||
double dLenParV = m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y ;
|
||||
if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU) {
|
||||
double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ;
|
||||
double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ;
|
||||
double dULoc = 0.5, dVLoc = 0.5 ;
|
||||
Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00 ;
|
||||
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
|
||||
Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ;
|
||||
Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ;
|
||||
dCurvV = Dist( ptV, ptPSrf) ;
|
||||
dCurvU = Dist( ptU, ptPSrf) ;
|
||||
}
|
||||
// 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
|
||||
else{
|
||||
Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00, ptPSrfMid;
|
||||
double dStep = 1. / m_nDegU ;
|
||||
for ( double k = dStep ; k < 1 ; k = k + dStep) {
|
||||
double dU = k * m_mTree[nCToSplit].GetTopRight().x + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().x ;
|
||||
double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ;
|
||||
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
|
||||
if ( k == 0.5)
|
||||
ptPSrfMid = ptPSrf ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ;
|
||||
m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ;
|
||||
CurveLine clV ;
|
||||
clV.Set( ptP00P10, ptP11P01) ;
|
||||
DistPointCurve dpc( ptPSrf, clV) ;
|
||||
double dDist ;
|
||||
dpc.GetDist( dDist) ;
|
||||
dCurvV = max( dCurvV, dDist) ;
|
||||
}
|
||||
dStep = 1. / m_nDegV ;
|
||||
for ( double k = dStep ; k < 1 ; k = k + dStep) {
|
||||
double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ;
|
||||
double dV = k * m_mTree[nCToSplit].GetTopRight().y + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().y ;
|
||||
if ( k == 0.5)
|
||||
ptPSrf = ptPSrfMid ;
|
||||
else
|
||||
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ;
|
||||
m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ;
|
||||
CurveLine clU ;
|
||||
clU.Set( ptP01P00, ptP10P11) ;
|
||||
DistPointCurve dpc( ptPSrf, clU) ;
|
||||
double dDist ;
|
||||
dpc.GetDist( dDist) ;
|
||||
dCurvU = max( 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 ;
|
||||
if ( dCurvV > dCurvU) {
|
||||
// lungo la direzione V ho una curvatura maggiore
|
||||
@@ -383,7 +430,6 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
dSideMaxVal = max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ;
|
||||
|
||||
// se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione
|
||||
double dErr = 0 ;
|
||||
bool bSplit = false ;
|
||||
if ( dSideMinVal / 2 >= dSideMin && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) {
|
||||
CurveLine cl0010, cl0001, cl1011, cl0111 ;
|
||||
@@ -403,8 +449,8 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
int nStepsU = int( 51 * dDimU + 5 * ( 1 - dDimU)) ;
|
||||
int nStepsV = int( 51 * dDimV + 5 * ( 1 - dDimV)) ;
|
||||
for ( int u = 0 ; u < nStepsU && ! bSplit ; ++ u) {
|
||||
dU = double ( u) / double ( nStepsU - 1) ;
|
||||
dULoc = ( 1 - dU) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x ;
|
||||
double dU = double ( u) / double ( nStepsU - 1) ;
|
||||
double dULoc = ( 1 - dU) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x ;
|
||||
if ( ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) ||
|
||||
! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1))
|
||||
return false ;
|
||||
@@ -414,16 +460,14 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
dpc0111.GetMinDistPoint( 0, pt0111, nFlag) ;
|
||||
clV.Set( pt0010, pt0111) ;
|
||||
for ( int v = 0 ; v < nStepsV ; ++ v) {
|
||||
dV = double ( v) / double ( nStepsV - 1) ;
|
||||
dVLoc = ( 1 - dV) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y ;
|
||||
double dV = double ( v) / double ( nStepsV - 1) ;
|
||||
double dVLoc = ( 1 - dV) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y ;
|
||||
if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV))
|
||||
return false ;
|
||||
DistPointCurve dpc( ptBzV, clV) ;
|
||||
// distanza di approssimazione locale
|
||||
double dDist ;
|
||||
dpc.GetDist( dDist) ;
|
||||
//if ( dDist > dErr)
|
||||
// dErr = dDist ;
|
||||
if ( dDist > dLinTol) {
|
||||
bSplit = true ;
|
||||
break ;
|
||||
@@ -432,7 +476,6 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
}
|
||||
}
|
||||
|
||||
//if ( dErr > dLinTol || dSideMaxVal > dSideMax) {
|
||||
if ( bSplit || dSideMaxVal > dSideMax) {
|
||||
m_mTree[nCToSplit].SetSplitDirVert( bVert) ;
|
||||
// effettuo lo split
|
||||
@@ -481,19 +524,12 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
double dLen1 = Dist( ptP10, ptP11) ;
|
||||
double dLen2 = Dist( ptP01, ptP11) ;
|
||||
double dLen3 = Dist( ptP00, ptP01) ;
|
||||
// calcolo se è migliore la divisione in orizzontale o in verticale
|
||||
Point3d ptP00P10, ptP00P01 , ptP01P11, ptP10P11 ;
|
||||
ptP00P10 = ( ptP00 + ptP10) / 2 ;
|
||||
ptP10P11 = ( ptP10 + ptP11) / 2 ;
|
||||
ptP01P11 = ( ptP01 + ptP11) / 2 ;
|
||||
ptP00P01 = ( ptP00 + ptP01) / 2 ;
|
||||
|
||||
bool bVert = false ;
|
||||
// calcolo in quale direzione è meglio dividere in base allo stretch
|
||||
Point3d ptPSrfU, ptPSrfV ;
|
||||
double dU = 0, dV = 0 ;
|
||||
double dDistU = 0, dDistV = 0 ;
|
||||
double dULoc, dVLoc ;
|
||||
PNTVECTOR vPtU, vPtV ;
|
||||
if ( ! m_bMulti) {
|
||||
if ( max(dLen0, dLen2) > max(dLen1, dLen3)) {
|
||||
@@ -507,8 +543,8 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax)
|
||||
for ( double i = 0.25 ; i < 1 ; i = i + 0.25 ) {
|
||||
dU = ( 1 - i) * m_mTree[nCToSplit].GetBottomLeft().x + i * m_mTree[nCToSplit].GetTopRight().x ;
|
||||
dV = ( 1 - i) * m_mTree[nCToSplit].GetBottomLeft().y + i * m_mTree[nCToSplit].GetTopRight().y ;
|
||||
dVLoc = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 ;
|
||||
dULoc = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 ;
|
||||
double dVLoc = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 ;
|
||||
double dULoc = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 ;
|
||||
m_pSrfBz->GetPointD1D2( dU, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrfU) ;
|
||||
m_pSrfBz->GetPointD1D2( dULoc, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrfV) ;
|
||||
vPtU.push_back( ptPSrfU) ;
|
||||
@@ -623,37 +659,37 @@ void Tree::Balance()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs)
|
||||
void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
|
||||
{
|
||||
if ( (int) vTopNeighs.size() == 0) {
|
||||
if ( m_mTree[nId].m_nTop == -2)
|
||||
if ( m_mTree.at(nId).m_nTop == -2)
|
||||
return ;
|
||||
if ( m_mTree[m_mTree[nId].m_nTop].IsLeaf())
|
||||
vTopNeighs.push_back( m_mTree[nId].m_nTop) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nTop).IsLeaf())
|
||||
vTopNeighs.push_back( m_mTree.at(nId).m_nTop) ;
|
||||
else {
|
||||
if ( m_mTree[m_mTree[nId].m_nTop].IsSplitVert()) {
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nTop).IsSplitVert()) {
|
||||
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[m_mTree[nId].m_nTop].GetTopRight().x - m_mTree[m_mTree[nId].m_nTop].GetBottomLeft().x <=
|
||||
m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) {
|
||||
vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nTop).GetTopRight().x - m_mTree.at(m_mTree.at(nId).m_nTop).GetBottomLeft().x <=
|
||||
m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) {
|
||||
vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else{
|
||||
if ( m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x ||
|
||||
m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x )
|
||||
vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x ||
|
||||
m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x )
|
||||
vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ;
|
||||
else
|
||||
vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ;
|
||||
vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ;
|
||||
}
|
||||
}
|
||||
bool bAllLeaves = true ;
|
||||
for ( int i : vTopNeighs ) {
|
||||
if ( ! m_mTree[i].IsLeaf())
|
||||
if ( ! m_mTree.at(i).IsLeaf())
|
||||
bAllLeaves = false ;
|
||||
}
|
||||
if ( ! bAllLeaves )
|
||||
@@ -662,38 +698,38 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs)
|
||||
}
|
||||
else {
|
||||
for ( int j = 0 ; j != (int) vTopNeighs.size() ; ++ j) {
|
||||
int i = vTopNeighs[j] ;
|
||||
if ( m_mTree[i].IsLeaf())
|
||||
int i = vTopNeighs.at(j) ;
|
||||
if ( m_mTree.at(i).IsLeaf())
|
||||
continue;
|
||||
else {
|
||||
// se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child
|
||||
vTopNeighs.erase( remove( vTopNeighs.begin(),vTopNeighs.end(),i)) ;
|
||||
-- j ;
|
||||
if ( m_mTree[i].IsSplitVert() ) {
|
||||
if ( m_mTree.at(i).IsSplitVert() ) {
|
||||
// se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <=
|
||||
m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) {
|
||||
vTopNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(i).GetTopRight().x - m_mTree.at(i).GetBottomLeft().x <=
|
||||
m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) {
|
||||
vTopNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else {
|
||||
if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x ||
|
||||
m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x )
|
||||
vTopNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x ||
|
||||
m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x )
|
||||
vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
else
|
||||
vTopNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vTopNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vTopNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vTopNeighs)
|
||||
vCells.push_back( m_mTree[k]) ;
|
||||
vCells.push_back( m_mTree.at(k)) ;
|
||||
std::sort( vCells.begin(), vCells.end(), Cell::minorX) ;
|
||||
vTopNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -702,37 +738,37 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs)
|
||||
void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
|
||||
{
|
||||
if ( (int) vBottomNeighs.size() == 0) {
|
||||
if ( m_mTree[nId].m_nBottom == -2)
|
||||
if ( m_mTree.at(nId).m_nBottom == -2)
|
||||
return ;
|
||||
if ( m_mTree[m_mTree[nId].m_nBottom].IsLeaf())
|
||||
vBottomNeighs.push_back( m_mTree[nId].m_nBottom) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nBottom).IsLeaf())
|
||||
vBottomNeighs.push_back( m_mTree.at(nId).m_nBottom) ;
|
||||
else {
|
||||
if ( m_mTree[m_mTree[nId].m_nBottom].IsSplitVert()) {
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nBottom).IsSplitVert()) {
|
||||
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[m_mTree[nId].m_nBottom].GetTopRight().x - m_mTree[m_mTree[nId].m_nBottom].GetBottomLeft().x <=
|
||||
m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) {
|
||||
vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nBottom).GetTopRight().x - m_mTree.at(m_mTree.at(nId).m_nBottom).GetBottomLeft().x <=
|
||||
m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) {
|
||||
vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else{
|
||||
if ( m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x ||
|
||||
m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x )
|
||||
vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x ||
|
||||
m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x )
|
||||
vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild2) ;
|
||||
else
|
||||
vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
bool bAllLeaves = true ;
|
||||
for ( int i : vBottomNeighs) {
|
||||
if ( ! m_mTree[i].IsLeaf())
|
||||
if ( ! m_mTree.at(i).IsLeaf())
|
||||
bAllLeaves = false ;
|
||||
}
|
||||
if ( ! bAllLeaves )
|
||||
@@ -741,38 +777,38 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs)
|
||||
}
|
||||
else {
|
||||
for ( int j = 0 ; j != (int) vBottomNeighs.size() ; ++ j) {
|
||||
int i = vBottomNeighs[j] ;
|
||||
if ( m_mTree[i].IsLeaf())
|
||||
int i = vBottomNeighs.at(j) ;
|
||||
if ( m_mTree.at(i).IsLeaf())
|
||||
continue;
|
||||
else {
|
||||
// se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child
|
||||
vBottomNeighs.erase( remove( vBottomNeighs.begin(),vBottomNeighs.end(),i)) ;
|
||||
-- j ;
|
||||
if ( m_mTree[i].IsSplitVert()) {
|
||||
if ( m_mTree.at(i).IsSplitVert()) {
|
||||
// se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <=
|
||||
m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) {
|
||||
vBottomNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(i).GetTopRight().x - m_mTree.at(i).GetBottomLeft().x <=
|
||||
m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) {
|
||||
vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else {
|
||||
if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x ||
|
||||
m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x)
|
||||
vBottomNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x ||
|
||||
m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x)
|
||||
vBottomNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
else
|
||||
vBottomNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vBottomNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vBottomNeighs)
|
||||
vCells.push_back( m_mTree[k]) ;
|
||||
vCells.push_back( m_mTree.at(k)) ;
|
||||
std::sort( vCells.begin(), vCells.end(), Cell::minorX) ;
|
||||
vBottomNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -781,37 +817,37 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs)
|
||||
void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
|
||||
{
|
||||
if ( (int) vLeftNeighs.size() == 0) {
|
||||
if ( m_mTree[nId].m_nLeft == -2)
|
||||
if ( m_mTree.at(nId).m_nLeft == -2)
|
||||
return ;
|
||||
if ( m_mTree[m_mTree[nId].m_nLeft].IsLeaf())
|
||||
vLeftNeighs.push_back( m_mTree[nId].m_nLeft) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nLeft).IsLeaf())
|
||||
vLeftNeighs.push_back( m_mTree.at(nId).m_nLeft) ;
|
||||
else {
|
||||
if ( ! m_mTree[m_mTree[nId].m_nLeft].IsSplitVert()) {
|
||||
if ( ! m_mTree.at(m_mTree.at(nId).m_nLeft).IsSplitVert()) {
|
||||
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[m_mTree[nId].m_nLeft].GetTopRight().y - m_mTree[m_mTree[nId].m_nLeft].GetBottomLeft().y <=
|
||||
m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) {
|
||||
vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nLeft).GetTopRight().y - m_mTree.at(m_mTree.at(nId).m_nLeft).GetBottomLeft().y <=
|
||||
m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) {
|
||||
vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else{
|
||||
if ( m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y ||
|
||||
m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y)
|
||||
vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y ||
|
||||
m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y)
|
||||
vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ;
|
||||
else
|
||||
vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ;
|
||||
}
|
||||
}
|
||||
bool bAllLeaves = true ;
|
||||
for ( int i : vLeftNeighs) {
|
||||
if ( ! m_mTree[i].IsLeaf())
|
||||
if ( ! m_mTree.at(i).IsLeaf())
|
||||
bAllLeaves = false ;
|
||||
}
|
||||
if ( ! bAllLeaves )
|
||||
@@ -820,38 +856,38 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs)
|
||||
}
|
||||
else {
|
||||
for ( int j = 0 ; j != (int) vLeftNeighs.size() ; ++ j) {
|
||||
int i = vLeftNeighs[j] ;
|
||||
if ( m_mTree[i].IsLeaf())
|
||||
int i = vLeftNeighs.at(j) ;
|
||||
if ( m_mTree.at(i).IsLeaf())
|
||||
continue;
|
||||
else {
|
||||
// se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child
|
||||
vLeftNeighs.erase( remove( vLeftNeighs.begin(),vLeftNeighs.end(),i)) ;
|
||||
-- j ;
|
||||
if ( ! m_mTree[i].IsSplitVert()) {
|
||||
if ( ! m_mTree.at(i).IsSplitVert()) {
|
||||
// se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <=
|
||||
m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) {
|
||||
vLeftNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(i).GetTopRight().y - m_mTree.at(i).GetBottomLeft().y <=
|
||||
m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) {
|
||||
vLeftNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else {
|
||||
if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y ||
|
||||
m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y)
|
||||
vLeftNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y ||
|
||||
m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y)
|
||||
vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
else
|
||||
vLeftNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vLeftNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vLeftNeighs)
|
||||
vCells.push_back( m_mTree[k]) ;
|
||||
vCells.push_back( m_mTree.at(k)) ;
|
||||
std::sort( vCells.begin(), vCells.end(), Cell::minorY) ;
|
||||
vLeftNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -859,37 +895,37 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs)
|
||||
void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
|
||||
{
|
||||
if ( (int) vRightNeighs.size() == 0) {
|
||||
if ( m_mTree[nId].m_nRight == -2)
|
||||
if ( m_mTree.at(nId).m_nRight == -2)
|
||||
return ;
|
||||
if ( m_mTree[m_mTree[nId].m_nRight].IsLeaf())
|
||||
vRightNeighs.push_back( m_mTree[nId].m_nRight) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nRight).IsLeaf())
|
||||
vRightNeighs.push_back( m_mTree.at(nId).m_nRight) ;
|
||||
else {
|
||||
if ( ! m_mTree[m_mTree[nId].m_nRight].IsSplitVert()) {
|
||||
if ( ! m_mTree.at(m_mTree.at(nId).m_nRight).IsSplitVert()) {
|
||||
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[m_mTree[nId].m_nRight].GetTopRight().y - m_mTree[m_mTree[nId].m_nRight].GetBottomLeft().y <=
|
||||
m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) {
|
||||
vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(nId).m_nRight).GetTopRight().y - m_mTree.at(m_mTree.at(nId).m_nRight).GetBottomLeft().y <=
|
||||
m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) {
|
||||
vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else{
|
||||
if ( m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y ||
|
||||
m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y)
|
||||
vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y ||
|
||||
m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y)
|
||||
vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild2) ;
|
||||
else
|
||||
vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
bool bAllLeaves = true ;
|
||||
for ( int i : vRightNeighs) {
|
||||
if ( ! m_mTree[i].IsLeaf())
|
||||
if ( ! m_mTree.at(i).IsLeaf())
|
||||
bAllLeaves = false ;
|
||||
}
|
||||
if ( ! bAllLeaves )
|
||||
@@ -898,38 +934,38 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs)
|
||||
}
|
||||
else {
|
||||
for ( int j = 0 ; j != (int) vRightNeighs.size() ; ++ j) {
|
||||
int i = vRightNeighs[j] ;
|
||||
if ( m_mTree[i].IsLeaf())
|
||||
int i = vRightNeighs.at(j) ;
|
||||
if ( m_mTree.at(i).IsLeaf())
|
||||
continue;
|
||||
else {
|
||||
// se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child
|
||||
vRightNeighs.erase( remove( vRightNeighs.begin(),vRightNeighs.end(), i)) ;
|
||||
-- j ;
|
||||
if ( ! m_mTree[i].IsSplitVert()) {
|
||||
if ( ! m_mTree.at(i).IsSplitVert()) {
|
||||
// se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
|
||||
if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <=
|
||||
m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) {
|
||||
vRightNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(i).GetTopRight().y - m_mTree.at(i).GetBottomLeft().y <=
|
||||
m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) {
|
||||
vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
}
|
||||
// altrimenti solo uno dei figli lo sarà
|
||||
else {
|
||||
if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y ||
|
||||
m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y)
|
||||
vRightNeighs.push_back( m_mTree[i].m_nChild2) ;
|
||||
if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y ||
|
||||
m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y)
|
||||
vRightNeighs.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
else
|
||||
vRightNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vRightNeighs.push_back( m_mTree[i].m_nChild1) ;
|
||||
vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vRightNeighs)
|
||||
vCells.push_back( m_mTree[k]) ;
|
||||
vCells.push_back( m_mTree.at(k)) ;
|
||||
std::sort( vCells.begin(), vCells.end(), Cell::minorY) ;
|
||||
vRightNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -937,51 +973,51 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d)
|
||||
int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) const
|
||||
{
|
||||
if ( nId == -1 && m_mTree[-1].IsLeaf()) {
|
||||
if ( nId == -1 && m_mTree.at(-1).IsLeaf()) {
|
||||
vnLeaves.push_back( -1) ;
|
||||
return 0 ;
|
||||
}
|
||||
else {
|
||||
if ( (int) vnLeaves.size() == 0) {
|
||||
if ( m_mTree[nId].IsLeaf())
|
||||
if ( m_mTree.at(nId).IsLeaf())
|
||||
return d ;
|
||||
else {
|
||||
vnLeaves.push_back( m_mTree[nId].m_nChild1) ;
|
||||
vnLeaves.push_back( m_mTree[nId].m_nChild2) ;
|
||||
if ( ! m_mTree[m_mTree[nId].m_nChild1].IsLeaf() || ! m_mTree[m_mTree[nId].m_nChild2].IsLeaf())
|
||||
vnLeaves.push_back( m_mTree.at(nId).m_nChild1) ;
|
||||
vnLeaves.push_back( m_mTree.at(nId).m_nChild2) ;
|
||||
if ( ! m_mTree.at(m_mTree.at(nId).m_nChild1).IsLeaf() || ! m_mTree.at(m_mTree.at(nId).m_nChild2).IsLeaf())
|
||||
// almeno un child non è leaf quindi devo richiamare ricorsivamente questa funzione sui child in questione
|
||||
d = GetHeightLeaves( nId, vnLeaves, m_mTree[m_mTree[nId].m_nChild1].m_nDepth) ;
|
||||
d = GetHeightLeaves( nId, vnLeaves, m_mTree.at(m_mTree.at(nId).m_nChild1).m_nDepth) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( int j = 0 ; j != (int) vnLeaves.size() ; ++ j) {
|
||||
int i = vnLeaves[j] ;
|
||||
if ( m_mTree[i].IsLeaf() ) {
|
||||
int i = vnLeaves.at(j) ;
|
||||
if ( m_mTree.at(i).IsLeaf() ) {
|
||||
continue ;
|
||||
}
|
||||
else {
|
||||
// se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child
|
||||
vnLeaves.erase( remove( vnLeaves.begin(),vnLeaves.end(),i)) ;
|
||||
-- j ;
|
||||
vnLeaves.push_back( m_mTree[i].m_nChild1) ;
|
||||
vnLeaves.push_back( m_mTree[i].m_nChild2) ;
|
||||
d = max ( d, m_mTree[m_mTree[i].m_nChild1].m_nDepth) ;
|
||||
vnLeaves.push_back( m_mTree.at(i).m_nChild1) ;
|
||||
vnLeaves.push_back( m_mTree.at(i).m_nChild2) ;
|
||||
d = max ( d, m_mTree.at(m_mTree.at(i).m_nChild1).m_nDepth) ;
|
||||
}
|
||||
}
|
||||
return d ;
|
||||
}
|
||||
return d - m_mTree[nId].m_nDepth ;
|
||||
return d - m_mTree.at(nId).m_nDepth ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int Tree::GetDepth( int nId, int nRef = -2)
|
||||
int Tree::GetDepth( int nId, int nRef = -2) const
|
||||
{
|
||||
int c = 0 ;
|
||||
while ( m_mTree[nId].m_nParent != nRef) {
|
||||
nId = m_mTree[nId].m_nParent ;
|
||||
while ( m_mTree.at(nId).m_nParent != nRef) {
|
||||
nId = m_mTree.at(nId).m_nParent ;
|
||||
++ c ;
|
||||
}
|
||||
return c ;
|
||||
@@ -998,12 +1034,12 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons)
|
||||
for ( int nId : m_vnLeaves) {
|
||||
vVertices.clear() ;
|
||||
vNeigh.clear() ;
|
||||
vVertices.push_back( m_mTree[nId].GetBottomLeft()) ;
|
||||
vVertices.push_back( m_mTree.at(nId).GetBottomLeft()) ;
|
||||
GetBottomNeigh( nId, vNeigh) ;
|
||||
// aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom
|
||||
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){
|
||||
for ( int j : vNeigh )
|
||||
vVertices.push_back( m_mTree[j].GetTopRight()) ;
|
||||
vVertices.push_back( m_mTree.at(j).GetTopRight()) ;
|
||||
bBottomRight = true ;
|
||||
}
|
||||
else
|
||||
@@ -1013,21 +1049,21 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons)
|
||||
// aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right
|
||||
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){
|
||||
for ( int j : vNeigh )
|
||||
vVertices.push_back( m_mTree[j].GetBottomLeft()) ;
|
||||
vVertices.push_back( m_mTree.at(j).GetBottomLeft()) ;
|
||||
}
|
||||
// se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right
|
||||
else if ( ! bBottomRight ) {
|
||||
Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ;
|
||||
Point3d ptBr( m_mTree.at(nId).GetTopRight().x, m_mTree.at(nId).GetBottomLeft().y) ;
|
||||
vVertices.push_back( ptBr) ;
|
||||
}
|
||||
vNeigh.clear() ;
|
||||
vVertices.push_back( m_mTree[nId].GetTopRight()) ;
|
||||
vVertices.push_back( m_mTree.at(nId).GetTopRight()) ;
|
||||
GetTopNeigh ( nId, vNeigh) ;
|
||||
std::reverse( vNeigh.begin(), vNeigh.end()) ;
|
||||
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
|
||||
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) {
|
||||
for ( int j : vNeigh)
|
||||
vVertices.push_back( m_mTree[j].GetBottomLeft()) ;
|
||||
vVertices.push_back( m_mTree.at(j).GetBottomLeft()) ;
|
||||
bTopLeft = true ;
|
||||
}
|
||||
else
|
||||
@@ -1038,39 +1074,39 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons)
|
||||
// aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left
|
||||
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) {
|
||||
for ( int j : vNeigh)
|
||||
vVertices.push_back( m_mTree[j].GetTopRight()) ;
|
||||
vVertices.push_back( m_mTree.at(j).GetTopRight()) ;
|
||||
}
|
||||
// se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left
|
||||
else if ( ! bTopLeft) {
|
||||
Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ;
|
||||
Point3d ptTl( m_mTree.at(nId).GetBottomLeft().x, m_mTree.at(nId).GetTopRight().y) ;
|
||||
vVertices.push_back( ptTl) ;
|
||||
}
|
||||
vNeigh.clear() ;
|
||||
vVertices.push_back( m_mTree[nId].GetBottomLeft()) ;
|
||||
vVertices.push_back( m_mTree.at(nId).GetBottomLeft()) ;
|
||||
// se ho una cella con vicino dello stesso grado ( quindi il poligono ha solo 5 punti) controllo la curvatura nella cella e
|
||||
// se necessario cambio l'ordine dei vertici per scegliere la diagonale di split migliore
|
||||
if ( vVertices.size() == 5) {
|
||||
Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01;
|
||||
double dU, dV ;
|
||||
dU = ( m_mTree[nId].GetBottomLeft().x + m_mTree[nId].GetTopRight().x) / 2 ;
|
||||
dV = ( m_mTree[nId].GetBottomLeft().y + m_mTree[nId].GetTopRight().y) / 2 ;
|
||||
dU = ( m_mTree.at(nId).GetBottomLeft().x + m_mTree.at(nId).GetTopRight().x) / 2 ;
|
||||
dV = ( m_mTree.at(nId).GetBottomLeft().y + m_mTree.at(nId).GetTopRight().y) / 2 ;
|
||||
m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ;
|
||||
ptP00 = m_mVert[nId][0] ;
|
||||
ptP10 = m_mVert[nId][1] ;
|
||||
ptP11 = m_mVert[nId][2] ;
|
||||
ptP01 = m_mVert[nId][3] ;
|
||||
ptP00 = m_mVert.at(nId).at(0) ;
|
||||
ptP10 = m_mVert.at(nId).at(1) ;
|
||||
ptP11 = m_mVert.at(nId).at(2) ;
|
||||
ptP01 = m_mVert.at(nId).at(3) ;
|
||||
Point3d ptP00P11 = ( ptP00 + ptP11) / 2 ;
|
||||
Point3d ptP10P01 = ( ptP10 + ptP01) / 2 ;
|
||||
// ho la curvatura maggiore sulla diagonale tra P10 e P01, ruoto l'ordine dei vertici, in modo che triangulate prenda la diagonale giusta
|
||||
if ( Dist(ptP00P11, ptPSrf) + EPS_SMALL > Dist(ptP10P01, ptPSrf)) {
|
||||
rotate(vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ;
|
||||
vVertices.back() = vVertices[0] ;
|
||||
vVertices.back() = vVertices.at(0) ;
|
||||
}
|
||||
}
|
||||
|
||||
m_vPolygons.emplace_back() ;
|
||||
for ( int i = 0 ; i < (int) vVertices.size() ; ++i) {
|
||||
m_vPolygons.back().AddUPoint( i, vVertices[i]) ;
|
||||
m_vPolygons.back().AddUPoint( i, vVertices.at(i)) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user