EgtGeomKernel :

- correzione alle superfici di bezier.
This commit is contained in:
Daniele Bariletti
2025-10-24 09:11:21 +02:00
parent 2983454ce2
commit 62e041ed8c
2 changed files with 108 additions and 36 deletions
+95 -30
View File
@@ -755,6 +755,13 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
// sono arrivato ad una cella Leaf, quindi salvo la cella
m_vnLeaves.push_back( nCToSplit) ;
pcToSplit->SetProcessed() ;
if( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11))
pcToSplit->m_nCollapsed = Cell::Collapsed::VERT_EDGES ;
else if( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11))
pcToSplit->m_nCollapsed = Cell::Collapsed::HORIZ_EDGES ;
else
pcToSplit->m_nCollapsed = Cell::Collapsed::NO_COLLAPSE ;
// risalgo i parent finché non trovo il primo Child2 da processare
nCToSplit = pcToSplit->m_nParent ;
pcToSplit = &m_mTree[nCToSplit] ;
@@ -861,6 +868,13 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
// sono arrivato ad una cella Leaf, quindi salvo la cella
m_vnLeaves.push_back( nCToSplit) ;
pcToSplit->SetProcessed() ;
if( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11))
pcToSplit->m_nCollapsed = Cell::Collapsed::VERT_EDGES ;
else if( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11))
pcToSplit->m_nCollapsed = Cell::Collapsed::HORIZ_EDGES ;
else
pcToSplit->m_nCollapsed = Cell::Collapsed::NO_COLLAPSE ;
// risalgo i parent finché non trovo il primo Child2 da processare
nCToSplit = pcToSplit->m_nParent ;
pcToSplit = &m_mTree[nCToSplit] ;
@@ -894,9 +908,16 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
//----------------------------------------------------------------------------
void
Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs, DBLDBL ddInt) const
{
const Cell& cell = m_mTree.at( nId) ;
double dMax = cell.GetTopRight().x ;
double dMin = cell.GetBottomLeft().x ;
if ( ddInt.second > 0) {
dMax = ddInt.second ;
dMin = ddInt.first ;
}
// le celle restituite sono ordinate per x crescente
if ( vTopNeighs.empty()) {
if ( cell.m_nTop == -2)
@@ -907,14 +928,14 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
if ( m_mTree.at( cell.m_nTop).IsSplitVert()) {
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
if ( m_mTree.at( cell.m_nTop).GetTopRight().x - m_mTree.at( cell.m_nTop).GetBottomLeft().x <=
cell.GetTopRight().x - cell.GetBottomLeft().x) {
dMax - dMin) {
vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild1) ;
vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild2) ;
}
// altrimenti solo uno dei figli lo sarà
else {
if ( m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x ||
m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x )
if ( m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetTopRight().x <= dMin ||
m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetBottomLeft().x >= dMax )
vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild2) ;
else
vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild1) ;
@@ -945,14 +966,14 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
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.at( i).GetTopRight().x - m_mTree.at( i).GetBottomLeft().x <=
cell.GetTopRight().x - cell.GetBottomLeft().x) {
dMax - dMin) {
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.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x )
if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= dMin ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= dMax)
vTopNeighs.push_back( m_mTree.at( i).m_nChild2) ;
else
vTopNeighs.push_back( m_mTree.at( i).m_nChild1) ;
@@ -977,9 +998,16 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
//----------------------------------------------------------------------------
void
Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs, DBLDBL ddInt) const
{
const Cell& cell = m_mTree.at( nId) ;
double dMax = cell.GetTopRight().x ;
double dMin = cell.GetBottomLeft().x ;
if ( ddInt.second > 0) {
dMax = ddInt.second ;
dMin = ddInt.first ;
}
// le celle restituite sono ordinate per x crescente
if ( vBottomNeighs.empty()) {
if ( cell.m_nBottom == -2)
@@ -990,14 +1018,14 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
if ( m_mTree.at( cell.m_nBottom).IsSplitVert()) {
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
if ( m_mTree.at( cell.m_nBottom).GetTopRight().x - m_mTree.at( cell.m_nBottom).GetBottomLeft().x <=
cell.GetTopRight().x - cell.GetBottomLeft().x) {
dMax - dMin) {
vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild1) ;
vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild2) ;
}
// altrimenti solo uno dei figli lo sarà
else{
if ( m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x ||
m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x )
if ( m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetTopRight().x <= dMin ||
m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetBottomLeft().x >= dMax )
vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild2) ;
else
vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild1) ;
@@ -1028,14 +1056,14 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
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.at( i).GetTopRight().x - m_mTree.at( i).GetBottomLeft().x <=
cell.GetTopRight().x - cell.GetBottomLeft().x) {
dMax - dMin) {
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.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x)
if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= dMin ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= dMax)
vBottomNeighs.push_back( m_mTree.at( i).m_nChild2) ;
else
vBottomNeighs.push_back( m_mTree.at( i).m_nChild1) ;
@@ -1059,9 +1087,16 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
//----------------------------------------------------------------------------
void
Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs, DBLDBL ddInt) const
{
const Cell& cell = m_mTree.at( nId) ;
double dMax = cell.GetTopRight().y ;
double dMin = cell.GetBottomLeft().y ;
if ( ddInt.second > 0) {
dMax = ddInt.second ;
dMin = ddInt.first ;
}
// le celle restituite sono ordinate per y crescente
if ( vLeftNeighs.empty()) {
if ( cell.m_nLeft == -2)
@@ -1072,14 +1107,14 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
if ( ! m_mTree.at( cell.m_nLeft).IsSplitVert()) {
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
if ( m_mTree.at( cell.m_nLeft).GetTopRight().y - m_mTree.at( cell.m_nLeft).GetBottomLeft().y <=
cell.GetTopRight().y - cell.GetBottomLeft().y) {
dMax - dMin) {
vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild1) ;
vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild2) ;
}
// altrimenti solo uno dei figli lo sarà
else{
if ( m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y ||
m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y)
if ( m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetTopRight().y <= dMin ||
m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetBottomLeft().y >= dMax)
vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild2) ;
else
vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild1) ;
@@ -1110,14 +1145,14 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
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.at( i).GetTopRight().y - m_mTree.at( i).GetBottomLeft().y <=
cell.GetTopRight().y - cell.GetBottomLeft().y) {
dMax - dMin) {
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.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y)
if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= dMin ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= dMax)
vLeftNeighs.push_back( m_mTree.at( i).m_nChild2) ;
else
vLeftNeighs.push_back( m_mTree.at( i).m_nChild1) ;
@@ -1141,9 +1176,16 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
//----------------------------------------------------------------------------
void
Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs, DBLDBL ddInt) const
{
const Cell& cell = m_mTree.at( nId) ;
double dMax = cell.GetTopRight().y ;
double dMin = cell.GetBottomLeft().y ;
if ( ddInt.second > 0) {
dMax = ddInt.second ;
dMin = ddInt.first ;
}
// le celle restituite sono ordinate per y crescente
if ( vRightNeighs.empty()) {
if ( cell.m_nRight == -2)
@@ -1154,14 +1196,14 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
if ( ! m_mTree.at( cell.m_nRight).IsSplitVert()) {
// se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima
if ( m_mTree.at( cell.m_nRight).GetTopRight().y - m_mTree.at( cell.m_nRight).GetBottomLeft().y <=
cell.GetTopRight().y - cell.GetBottomLeft().y) {
dMax - dMin) {
vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild1) ;
vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild2) ;
}
// altrimenti solo uno dei figli lo sarà
else{
if ( m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y ||
m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y)
if ( m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetTopRight().y <= dMin ||
m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetBottomLeft().y >= dMax)
vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild2) ;
else
vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild1) ;
@@ -1192,14 +1234,14 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
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.at( i).GetTopRight().y - m_mTree.at( i).GetBottomLeft().y <=
cell.GetTopRight().y - cell.GetBottomLeft().y) {
dMax - dMin) {
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.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y)
if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= dMin ||
m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= dMax)
vRightNeighs.push_back( m_mTree.at( i).m_nChild2) ;
else
vRightNeighs.push_back( m_mTree.at( i).m_nChild1) ;
@@ -1394,7 +1436,7 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vec
// se richiesto aggiorno gli edge 3d e i loop della superficie
if ( bUpdateEdges || vvCCEdges3D.empty()) {
GetEdges3D( vvCCEdges3D, vPolygonsCorrected) ;
GetEdges3D( vvCCEdges3D, vPolygonsBasic) ;
GetSplitLoops( vCCLoops) ;
}
return true ;
@@ -1431,6 +1473,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
int c = 0 ;
for ( int nId : m_vnLeaves) {
Cell& cell = m_mTree.at( nId) ;
if( cell.m_nCollapsed != Cell::Collapsed::NO_COLLAPSE)
continue ;
vVertices.clear() ;
vVertices3d.clear() ;
vNeigh.clear() ;
@@ -1442,6 +1486,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
std::fill( vbBonusVert.begin(), vbBonusVert.end(), false) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetBottomNeigh( nId, vNeigh) ;
if( ! vNeigh.empty() && m_mTree.at(vNeigh[0]).m_nCollapsed == Cell::Collapsed::VERT_EDGES)
GetBottomNeigh( vNeigh[0], vNeigh, DBLDBL( cell.GetBottomLeft().x, cell.GetTopRight().x)) ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, ptP00) ;
GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, ptP10) ;
@@ -1476,6 +1522,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
bBottomRight = false ;
vNeigh.clear() ;
GetRightNeigh ( nId, vNeigh) ;
if( ! vNeigh.empty() && m_mTree.at(vNeigh[0]).m_nCollapsed == Cell::Collapsed::HORIZ_EDGES)
GetRightNeigh( vNeigh[0], vNeigh, DBLDBL( cell.GetBottomLeft().y, cell.GetTopRight().y)) ;
// aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right
if ( vNeigh.size() > 1){
// se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left
@@ -1516,6 +1564,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetTopNeigh ( nId, vNeigh) ;
if( ! vNeigh.empty() && m_mTree.at(vNeigh[0]).m_nCollapsed == Cell::Collapsed::VERT_EDGES)
GetTopNeigh( vNeigh[0], vNeigh, DBLDBL( cell.GetBottomLeft().x, cell.GetTopRight().x)) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
if ( vNeigh.size() > 1) {
@@ -1546,6 +1596,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
bTopLeft = false ;
vNeigh.clear() ;
GetLeftNeigh ( nId, vNeigh) ;
if( ! vNeigh.empty() && m_mTree.at(vNeigh[0]).m_nCollapsed == Cell::Collapsed::HORIZ_EDGES)
GetLeftNeigh( vNeigh[0], vNeigh, DBLDBL( cell.GetBottomLeft().y, cell.GetTopRight().y)) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left
if ( vNeigh.size() > 1) {
@@ -1595,6 +1647,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
// ora devo controllare se uno dei lati della cella è collassato in un punto.
// se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra
// se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato
bool bAlreadyCropped = false ;
if ( AreSamePointApprox(ptP00, ptP10)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW
@@ -1623,8 +1676,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
bAlreadyCropped = true ;
}
if ( AreSamePointApprox(ptP10, ptP11)) {
if( bAlreadyCropped)
continue ;
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
@@ -1648,8 +1704,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
bAlreadyCropped = true ;
}
if ( AreSamePointApprox(ptP11, ptP01)) {
if( bAlreadyCropped)
continue ;
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
@@ -1673,8 +1732,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
bAlreadyCropped = true ;
}
if ( AreSamePointApprox(ptP01, ptP00)) {
if( bAlreadyCropped)
continue ;
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
@@ -1702,6 +1764,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
bAlreadyCropped = true ;
}
if ( ! m_bTrimmed) {
@@ -2742,7 +2805,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
Point3d ptNextVert ;
switch ( next ) {
case 0 : ptNextVert = ptTR ; break ;
case 1 : ptNextVert = ptTl; break ;
case 1 : ptNextVert = ptTl ; break ;
case 2 : ptNextVert = ptBL ; break ;
case 3 : ptNextVert = ptBr ; break ;
}
@@ -3947,6 +4010,8 @@ Tree::GetEdges3D( vector<ICRVCOMPOPOVECTOR>& mCCEdges, POLYLINEVECTOR& vPolygons
// scorro sui poligoni delle celle di un lato
for ( int c = 0 ; c < int( vEdges[i].size()) ; ++c) {
Cell& cNeigh = m_mTree.at(vEdges[i][c]) ;
if( cNeigh.m_vnPolyId.empty())
continue ;
PolyLine& plCell = vPolygons[cNeigh.m_vnPolyId[0]] ;
Point3d pt ; plCell.GetFirstPoint( pt) ;
Point3d pt3d ;