This commit is contained in:
Dario Sassi
2024-01-29 09:17:13 +01:00
4 changed files with 336 additions and 207 deletions
+38 -22
View File
@@ -54,7 +54,7 @@ SurfBezier::~SurfBezier( void)
bool
SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational)
{
// verifico validità grado
// verifico validit grado
if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG || nSpanU < 1 || nSpanV < 1)
return false ;
@@ -86,7 +86,7 @@ SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational
bool
SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
{
// verifico validità indice
// verifico validit indice
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd >= GetDim())
return false ;
@@ -108,7 +108,7 @@ SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
bool
SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
{
// verifico validità, razionalità e indice
// verifico validit, razionalit e indice
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim())
return false ;
@@ -158,7 +158,7 @@ SurfBezier::GetTrimRegion( void) const
bool
SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const
{
// verifico validità superficie
// verifico validit superficie
if ( m_nStatus != OK)
return false ;
// restituisco gradi e flag di razionale
@@ -175,7 +175,7 @@ SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIs
const Point3d&
SurfBezier::GetControlPoint( int nInd, bool* pbOk) const
{
// verifico validità e indice
// verifico validit e indice
if ( m_nStatus != OK || nInd < 0 || nInd >= GetDim()) {
if ( pbOk != NULL)
*pbOk = false ;
@@ -191,7 +191,7 @@ SurfBezier::GetControlPoint( int nInd, bool* pbOk) const
double
SurfBezier::GetControlWeight( int nInd, bool* pbOk) const
{
// verifico validità, razionalità e indice
// verifico validit, razionalit e indice
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) {
if ( pbOk != NULL)
*pbOk = false ;
@@ -503,7 +503,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs,
if ( vtN.Normalize())
return true ;
// se solo una delle due derivate è piccola, mi sposto lungo il relativo parametro e uso le tangenti
// se solo una delle due derivate piccola, mi sposto lungo il relativo parametro e uso le tangenti
if ( pvtDerU->Len() < EPS_SMALL && pvtDerV->Len() > 10 * EPS_SMALL) {
double dCoeff = ( dU - 1000 * EPS_PARAM < 0. ? 1 : -1) ;
double dUm = dU + 1000 * EPS_PARAM * dCoeff ;
@@ -610,7 +610,7 @@ SurfBezier::GetTitle( void) const
bool
SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const
{
// verifico validità superficie
// verifico validit superficie
if ( m_nStatus != OK)
sOut += string( "Status=Invalid") + szNewLine ;
// area
@@ -843,7 +843,7 @@ SurfBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, d
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dell'asse di rotazione
// verifico validit dell'asse di rotazione
if ( vtAx.IsSmall())
return false ;
@@ -899,7 +899,7 @@ SurfBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del piano di specchiatura
// verifico validit del piano di specchiatura
if ( vtNorm.IsSmall())
return false ;
@@ -922,7 +922,7 @@ SurfBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d&
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dei parametri
// verifico validit dei parametri
if ( vtNorm.IsSmall() || vtDir.IsSmall())
return false ;
@@ -944,11 +944,11 @@ SurfBezier::ToGlob( const Frame3d& frRef)
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del frame
// verifico validit del frame
if ( frRef.GetType() == Frame3d::ERR)
return false ;
// se frame identità, non devo fare alcunché
// se frame identit, non devo fare alcunch
if ( IsGlobFrame( frRef))
return true ;
@@ -970,11 +970,11 @@ SurfBezier::ToLoc( const Frame3d& frRef)
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità del frame
// verifico validit del frame
if ( frRef.GetType() == Frame3d::ERR)
return false ;
// se frame identità, non devo fare alcunché
// se frame identit, non devo fare alcunch
if ( IsGlobFrame( frRef))
return true ;
@@ -996,11 +996,11 @@ SurfBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// verifico validità dei frame
// verifico validit dei frame
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
return false ;
// se i due riferimenti coincidono, non devo fare alcunché
// se i due riferimenti coincidono, non devo fare alcunch
if ( AreSameFrame( frOri, frDest))
return true ;
@@ -1263,7 +1263,7 @@ SurfBezier::GetLoop( int nLoop) const
// se loop chiuso lo restituisco, altrimenti errore
return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ;
}
// la superficie è trimmata, quindi devo cercare nei vari chunck il loop corrispondente
// la superficie trimmata, quindi devo cercare nei vari chunck il loop corrispondente
else {
if ( nLoop > m_pTrimReg->GetChunkCount())
return nullptr ;
@@ -1421,7 +1421,7 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
// ResetAuxSurf() ;
// return nullptr ;
// }
// // se già calcolata, la restituisco
// // se gi calcolata, la restituisco
// if ( m_pSTM != nullptr)
// return m_pSTM ;
// // costruttore della superficie
@@ -1497,7 +1497,7 @@ SurfBezier::GetAuxSurf( void) const
ResetAuxSurf() ;
return nullptr ;
}
// se già calcolata, la restituisco
// se gi calcolata, la restituisco
if ( m_pSTM != nullptr)
return m_pSTM ;
@@ -1507,12 +1507,21 @@ SurfBezier::GetAuxSurf( void) const
Tree Tree( this, true) ;
BIPNTVECTOR vTrees ;
Tree.GetIndependentTrees( vTrees) ;
bool bTest = false ; // per debug
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
Point3d ptMin = std::get<0>( vTrees[i]) ;
Point3d ptMax = std::get<1>( vTrees[i]) ;
Tree.SetSurf( this, true, ptMin, ptMax) ;
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
if ( bTest) {
Tree.BuildTree_test() ; // per debug
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
Tree.SetTestMode() ;
}
else {
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
}
Tree.GetPolygons( vvPL) ;
//Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic
}
//// per usare i polygon basic//////////////////////
@@ -1571,7 +1580,14 @@ SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
Point3d ptMin = get<0>( vTrees[i]) ;
Point3d ptMax = get<1>( vTrees[i]) ;
Tree.SetSurf( this, true, ptMin, ptMax) ;
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
bool bTest = false ; // per debug
if ( bTest) {
Tree.BuildTree_test() ; // per debug
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
}
else {
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
}
vector<Cell> vCells ;
Tree.GetLeaves( vCells) ;
for ( int k = 0 ; k < int( vCells.size()) ; ++ k) {
+115 -20
View File
@@ -1272,6 +1272,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ;
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
// non mi basta fare un controllo sulle bbox perché non so come sono orientate le superfici e che potrebbero anche non essere chiuse
bool bRetriangulated = true ;
if ( ! bModif && ( int( AmbiguosA.size()) == 0 || int( AmbiguosB.size()) == 0)) {
bRetriangulated = false ;
@@ -1280,7 +1281,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
int nCurVert = GetFirstVertex( ptFirstV) ;
int nInOutNum = 0 ;
while ( nInOutNum == 0 && nCurVert != SVT_NULL) {
int nTriaNum = - 1 ;
INTVECTOR vnTriaNum ;
double dMinDist = DBL_MAX ;
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) {
// Se il triangolo B non è valido, continuo
@@ -1288,18 +1289,66 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
if ( ! SurfB.GetTriangle( nTB, trTriaB) || ! trTriaB.Validate( true))
continue ;
double dDist ;
if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist) && dDist < dMinDist) {
nTriaNum = nTB ;
dMinDist = dDist ;
// potrei trovare più triangolo equidistanti, li salvo tutti
if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist)) {
if ( abs(dDist - dMinDist) < EPS_SMALL)
vnTriaNum.push_back( nTB) ;
else if ( dDist < dMinDist){
vnTriaNum.clear() ;
vnTriaNum.push_back( nTB) ;
dMinDist = dDist ;
}
}
}
if ( nTriaNum >= 0) {
if ( ! vnTriaNum.empty()) {
Triangle3d trTriaB ;
SurfB.GetTriangle( nTriaNum, trTriaB) ;
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL)
nInOutNum = 1 ;
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL)
nInOutNum = - 1 ;
bool bSame = true ;
// controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro
for ( int nTriaNum : vnTriaNum) {
SurfB.GetTriangle( nTriaNum, trTriaB) ;
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) {
if ( nInOutNum == 0)
nInOutNum = 1 ;
else if (nInOutNum == -1) {
bSame = false ;
break ;
}
}
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) {
if ( nInOutNum == 0)
nInOutNum = -1 ;
else if (nInOutNum == 1) {
bSame = false ;
break ;
}
}
}
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
// e ricalcolo l'informazione che mi dà la sua normale
if ( ! bSame ) {
Point3d ptBar_tot ;
for (int nTriaNum : vnTriaNum) {
SurfB.GetTriangle( nTriaNum, trTriaB) ;
ptBar_tot += trTriaB.GetCentroid();
}
ptBar_tot /= (int)vnTriaNum.size() ;
for (int nTriaNum : vnTriaNum) {
SurfB.GetTriangle( nTriaNum, trTriaB) ;
Point3d ptInters1, ptInters2 ;
int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaB, ptInters1, ptInters2, true) ;
if (nInters == ILTT_NO)
continue ;
else if ( nInters == ILTT_IN ) {
if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL)
nInOutNum = 1 ;
else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL)
nInOutNum = -1 ;
break ;
}
else
nInOutNum = 0 ;
}
}
}
if ( nInOutNum == 0) {
nCurVert = GetNextVertex( nVertNum, ptFirstV) ;
@@ -1313,7 +1362,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
nCurVert = SurfB.GetFirstVertex( ptFirstV) ;
nInOutNum = 0 ;
while ( nInOutNum == 0 && nCurVert != SVT_NULL) {
int nTriaNum = - 1 ;
INTVECTOR vnTriaNum ;
double dMinDist = DBL_MAX ;
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
// Se il triangolo A non è valido, continuo
@@ -1323,19 +1372,65 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
DistPointTriangle DistCalculator( ptFirstV, trTriaA) ;
double dDist ;
DistCalculator.GetDist( dDist) ;
if ( dDist < dMinDist) {
nTriaNum = nTA ;
dMinDist = dDist ;
// potrei trovare più triangolo equidistanti, li salvo tutti
if ( DistPointTriangle( ptFirstV, trTriaA).GetDist( dDist)) {
if ( abs(dDist - dMinDist) < EPS_SMALL)
vnTriaNum.push_back( nTA) ;
else if ( dDist < dMinDist){
vnTriaNum.clear() ;
vnTriaNum.push_back( nTA) ;
dMinDist = dDist ;
}
}
}
if ( nTriaNum >= 0) {
if ( ! vnTriaNum.empty()) {
Triangle3d trTriaA ;
GetTriangle( nTriaNum, trTriaA) ;
if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL) {
nInOutNum = 1 ;
bool bSame = true ;
// controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro
for ( int nTriaNum : vnTriaNum) {
GetTriangle( nTriaNum, trTriaA) ;
if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) {
if ( nInOutNum == 0)
nInOutNum = 1 ;
else if (nInOutNum == -1) {
bSame = false ;
break ;
}
}
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) {
if ( nInOutNum == 0)
nInOutNum = -1 ;
else if (nInOutNum == 1) {
bSame = false ;
break ;
}
}
}
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) {
nInOutNum = - 1 ;
// se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino
// e ricalcolo l'informazione che mi dà la sua normale
if ( ! bSame ) {
Point3d ptBar_tot ;
for (int nTriaNum : vnTriaNum) {
GetTriangle( nTriaNum, trTriaA) ;
ptBar_tot += trTriaA.GetCentroid();
}
ptBar_tot /= (int)vnTriaNum.size() ;
for (int nTriaNum : vnTriaNum) {
GetTriangle( nTriaNum, trTriaA) ;
Point3d ptInters1, ptInters2 ;
int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaA, ptInters1, ptInters2, true) ;
if (nInters == ILTT_NO)
continue ;
else if ( nInters == ILTT_IN ) {
if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL)
nInOutNum = 1 ;
else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL)
nInOutNum = -1 ;
break ;
}
else
nInOutNum = 0 ;
}
}
}
if ( nInOutNum == 0) {
+151 -139
View File
@@ -23,13 +23,19 @@
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "DistPointCrvComposite.h"
///////////per debug
//#include "/EgtDev/Include/EGkStringUtils3d.h"
//#include "/EgtDev/Include/EExDllMain.h"
///////////per debug
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
Tree::Tree( void)
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true)
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false)
{
Point3d ptBl( 0, 0), ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ;
Cell cRoot( ptBl, ptTr) ;
@@ -38,7 +44,7 @@ Tree::Tree( void)
//----------------------------------------------------------------------------
Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true)
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false)
{
SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ;
}
@@ -194,8 +200,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
}
}
vLeaves.clear() ;
GetHeightLeaves( -1, vLeaves) ;
m_vnParents = vLeaves ;
}
// controllo se la superficie è chiusa.
// se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa
@@ -273,6 +277,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
}
}
}
// calcolo i parent che ho creato con le eventuali divisioni preliminari
INTVECTOR vLeaves ;
GetHeightLeaves( -1, vLeaves) ;
m_vnParents = vLeaves ;
// calcolo e salvo la lunghezza reale delle curve di bezier di bordo
PtrOwner<CurveComposite> pCrvV0( m_pSrfBz->GetCurveOnU( 0)) ;
@@ -546,6 +554,8 @@ Tree::BuildTree_test( double dLinTol, double dSideMin, double dSideMax)
Split( 10) ;
m_vnLeaves.push_back( 20) ;
m_vnLeaves.push_back( 21) ;
// riempio anche la lista dei parent delle celle
m_vnParents = m_vnLeaves ;
return true ;
}
@@ -1367,7 +1377,12 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
// scorro sulle celle e costruisco i poligoni
int nCells = int( vPolygonsBasic.size()) ;
for ( int i = 0 ; i < nCells ; ++ i) {
///////////per debug
//std::string sOut = std::to_string( i) ;
//LOG_ERROR( GetEGkLogger(), sOut.c_str()) ;
///////////per debug
//
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
if ( m_mTree[nId].m_nFlag == 4) {
@@ -1483,9 +1498,9 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons)
reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
if ( ! vNeigh.empty() && vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro U e la cella è sul lato top
// se la superficie è chiusa lungo il parametro V e la cella è sul lato top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
if ( m_bClosedU && m_mTree.at( nId).m_bOnTopEdge) {
if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ;
vVertices.push_back( pt) ;
@@ -1577,12 +1592,13 @@ Tree::ResetTree( void)
//----------------------------------------------------------------------------
INTVECTOR
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs) const
{
INTVECTOR nCells ;
int nId = -1 ;
// se fallisce ritorna un vettore vuoto
// verifico che il punto sia all'interno dello spazio parametrico
// allargo i bordi in modo da tenere anche i punti sul bordo dello spazio parametrico
if ( ptToAssign.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssign.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL||
ptToAssign.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssign.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) {
//nCells.push_back( - 2) ;
@@ -1591,15 +1607,19 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
// se ho diviso preliminarmente le patches e in uno dei due parametri ho un numero dispari di patches devo individuare a mano la cella parent
// in cui individuare la foglia giusta
if ( m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) {
if ( (m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) || m_bTestMode) {
INTVECTOR nParents = FindCell( ptToAssign, clTrim, m_vnParents) ;
nId = nParents.back() ;
if ( m_bTestMode ) {
nCells.push_back(nId) ;
return nCells ;
}
}
// individuo la foglia in cui ho lo start del loop
while ( ! m_mTree.at( nId).IsLeaf()) {
if ( m_mTree.at( nId).IsSplitVert()) {
double dMid = ( m_mTree.at( nId).GetBottomLeft().x + m_mTree.at( nId).GetTopRight().x) / 2 ;
if ( ptToAssign.x < dMid + EPS_SMALL) {
if ( ptToAssign.x < dMid) {
nId = m_mTree.at( nId).m_nChild1 ;
}
else {
@@ -1608,7 +1628,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
}
else {
double dMid = ( m_mTree.at( nId).GetBottomLeft().y + m_mTree.at( nId).GetTopRight().y) / 2 ;
if ( ptToAssign.y < dMid + EPS_SMALL) {
if ( ptToAssign.y < dMid) {
nId = m_mTree.at( nId).m_nChild2 ;
}
else {
@@ -1618,26 +1638,37 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const
}
nCells.push_back( nId) ;
// se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta
Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ;
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ;
if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL ||
abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL)
{
Point3d ptToAssignPlus ;
double dParam ;
Vector3d vDir ;
clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vDir) ;
if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) {
vDir.Rotate( Z_AX, -90) ;
ptToAssignPlus = ptToAssignPlus + vDir * 2 * EPS_SMALL ;
}
nCells = FindCell( ptToAssignPlus, clTrim) ;
if ( nCells.empty()) {
ptToAssignPlus = ptToAssignPlus - 4 * vDir * EPS_SMALL ;
nCells = FindCell( ptToAssignPlus, clTrim) ;
if ( ! bRecurs) {
// se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta
Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ;
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ;
if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL ||
abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL)
{
Vector3d vtDir ;
clTrim.GetStartDir( vtDir) ;
// proseguo lungo la curva di trim di EPS_SMALL
Point3d ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ;
// se la curva di trim è praticamente parallela ad un lato allora giro a destra, perché voglio considerare intersecate le celle esterne ( sul bordo) al loop
if ( abs( vtDir.x) > 1 - EPS_SMALL || abs( vtDir.y) > 1 - EPS_SMALL) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, 90) ;
ptToAssignPlus = ptToAssignPlus + vtDir * EPS_SMALL ;
// controllo di non essere uscito dallo spazio parametrico ed eventualmente giro a sinistra
if ( ptToAssignPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssignPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL||
ptToAssignPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssignPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) {
// rispetto al punto di partenza avanzo lungo la curva di trim
ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ;
Vector3d vtDirSX = vtDir ; vtDirSX.Rotate( Z_AX, -90) ;
// e poi giro a sinistra
ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ;
}
}
INTVECTOR nCellsSave = nCells ;
nCells = FindCell( ptToAssignPlus, clTrim, true) ;
if ( nCells.empty()) {
// se nonostante tutto non trovo nulla allora tengo il risultato ottenuto scorrendo l'albero
nCells = nCellsSave ;
}
}
}
return nCells ;
@@ -1650,22 +1681,45 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
// se non trova nulla restituisce un vettore vuoto
// restituisce sempre solo una cella
// la CurveLine è il segmento di trim su cui giace ptToAssign
Point3d ptIntersPlus ;
double dParam ;
Vector3d vDir ;
cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ;
// mi sposto appena più avanti di ptToAssign
cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ;
// questo punto va trovato con precisione, perché se seleziono la cella sbagliata si incasina tutto
INTVECTOR nCells ;
int nId = -1 ;
for ( int nCell : vCells) {
if ( ptIntersPlus.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptIntersPlus.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO &&
ptIntersPlus.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptIntersPlus.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) {
if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x &&
ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y) {
nId = nCell ;
nCells.push_back( nId) ;
}
}
// se non ho trovato nulla vuol dire che sono su un vertice o su un lato
if ( (int)nCells.size() == 0 ) {
for ( int nCell : vCells) {
if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO &&
ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) {
nId = nCell ;
nCells.push_back( nId) ;
}
}
if ( (int)nCells.size() == 1)
return nCells ;
// sono su vertice o un lato, quindi avanzo con il parametro lungo la curva
else if ( (int)nCells.size() >= 1 ) {
// la CurveLine è il segmento di trim su cui giace ptToAssign
Point3d ptIntersPlus ;
Vector3d vtDir ;
cl.GetStartDir( vtDir) ;
// mi sposto appena più avanti di ptToAssign
// se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore prima di spostarmi
if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL)
vtDir.Rotate( Z_AX, -45) ;
ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
nCells = FindCell( ptIntersPlus, cl, vCells) ;
}
// se vuoto allora il punto non è in nessuna delle celle passate in input
else
return nCells ;
}
return nCells ;
}
@@ -1781,10 +1835,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ;
//sistemo l'ingresso della prima cella
int nEdge ;
OnWhichEdge( nFirstCell, ptFirst, nEdge) ;
if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge))
return false ;
m_mTree[nFirstCell].m_vInters[nPass].nIn = nEdge ;
// sistemo l'uscita dell'ultima cella
OnWhichEdge( nId, ptLast, nEdge) ;
if ( ! OnWhichEdge( nId, ptLast, nEdge))
return false ;
m_mTree[nId].m_vInters.back().nOut = nEdge ;
// sistemo il flag dell'ultima cella
if ( m_mTree[nId].m_nFlag == -1)
@@ -1967,7 +2023,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
// -1 se la curva è sempre dentro la cella
bool bIntersFound = false ;
Point3d ptInters ;
int nEdge2 ;
if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) {
@@ -1979,16 +2034,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
nEdge2 = 1 ;
clEdge2.Set( ptTl, ptBL) ;
}
//else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) {
// nEdge = 4 ;
// ptInters = ptTl ;
// bIntersFound = true ;
//}
//else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) {
// nEdge = 7 ;
// ptInters = ptTR ;
// bIntersFound = true ;
//}
}
else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) {
nEdge = 1 ;
@@ -1999,16 +2044,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
nEdge2 = 2 ;
clEdge2.Set( ptBL, ptBr) ;
}
//else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) {
// nEdge = 5 ;
// ptInters = ptBL ;
// bIntersFound = true ;
//}
//else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) {
// nEdge = 4 ;
// ptInters = ptTl ;
// bIntersFound = true ;
//}
}
else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) {
nEdge = 2 ;
@@ -2019,16 +2054,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
nEdge2 = 3 ;
clEdge2.Set( ptBr, ptTR) ;
}
//else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) {
// nEdge = 6 ;
// ptInters = ptBr ;
// bIntersFound = true ;
//}
//else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) {
// nEdge = 5 ;
// ptInters = ptBL ;
// bIntersFound = true ;
//}
}
else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) {
nEdge = 3 ;
@@ -2039,65 +2064,44 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
nEdge2 = 0 ;
clEdge2.Set( ptTR, ptTl) ;
}
//else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) {
// nEdge = 7 ;
// ptInters = ptTR ;
// bIntersFound = true ;
//}
//else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) {
// nEdge = 6 ;
// ptInters = ptBr ;
// bIntersFound = true ;
//}
}
else
return false ;
bool bIntersOn2Found = false ;
if ( ! bIntersFound) {
// intersezione e controlli
IntersLineLine illExit( clTrim, clEdge, true) ;
IntCrvCrvInfo aInfo, aInfo2 ;
bool bIntersOn1Found = true ;
if ( ! illExit.GetIntCrvCrvInfo( aInfo)) {
bIntersOn1Found = false ;
if ( ! clEdge2.IsValid())
return false ;
}
else if ( aInfo.bOverlap && ! bFirstInters) {
ptInters = aInfo.IciA[1].ptI ;
bIntersFound = true ;
}
if ( clEdge2.IsValid() && ! bIntersFound){
IntersLineLine illExit2( clTrim, clEdge2, true) ;
// verifico su quale dei due lati ho l'intersezione
if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)){
if ( bIntersOn1Found) {
// se ho intersezione su Edge1 con sovrapposizione, seleziono o il primo punto o il secondo.
if ( aInfo.bOverlap && ! bFirstInters)
ptInters = aInfo.IciA[1].ptI ;
else
ptInters = aInfo.IciA[0].ptI ;
}
else
return false ;
}
else {
//// solo intersezione sul lato 2
bIntersOn2Found = true ;
if ( aInfo2.bOverlap && ! bFirstInters)
ptInters = aInfo2.IciA[1].ptI ;
else
ptInters = aInfo2.IciA[0].ptI ;
}
}
else
ptInters = aInfo.IciA[0].ptI ; // qui devo mettere il controllo su prima o seconda intersezione?
bool bIntersFound = false ;
// intersezione e controlli
IntersLineLine illExit( clTrim, clEdge, true) ;
IntCrvCrvInfo aInfo, aInfo2 ;
if ( ! illExit.GetIntCrvCrvInfo( aInfo)) {
bIntersFound = false ;
if ( ! clEdge2.IsValid())
return false ;
}
if ( ! bIntersOn2Found)
OnWhichEdge( nId, ptInters, nEdge) ;
else
nEdge = nEdge2 ;
else {
bIntersFound = true ;
if ( aInfo.bOverlap)
ptInters = aInfo.IciA[1].ptI ;
else
ptInters = aInfo.IciA[0].ptI ;
}
if ( clEdge2.IsValid() && ! bIntersFound){
IntersLineLine illExit2( clTrim, clEdge2, true) ;
// verifico su quale dei due lati ho l'intersezione
if ( ! illExit2.GetIntCrvCrvInfo( aInfo2))
bIntersFound = false ;
else {
bIntersFound = true ;
//// solo intersezione sul lato 2
if ( aInfo2.bOverlap)
ptInters = aInfo2.IciA[1].ptI ;
else
ptInters = aInfo2.IciA[0].ptI ;
}
}
if ( ! bIntersFound)
return false ;
// determino il lato/vertice di uscita
OnWhichEdge( nId, ptInters, nEdge) ;
m_mTree[nId].m_vInters.back().nOut = nEdge ;
if ( (int)vptInters.size() == 0 || ! AreSamePointExact( ptInters , vptInters.back()))
vptInters.push_back( ptInters) ;
@@ -2239,11 +2243,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 6 ;
}
else {
else if (! vNeigh1.empty()) {
nId = vNeigh1.back() ;
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 7 ;
}
else
return false ;
}
}
else if ( nEdge == 5) {
@@ -2288,11 +2294,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 7 ;
}
else {
else if (! vNeigh1.empty()) {
nId = vNeigh1[0] ;
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 4 ;
}
else
return false ;
}
}
else if ( nEdge == 6) {
@@ -2337,11 +2345,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 4 ;
}
else {
else if (! vNeigh1.empty()) {
nId = vNeigh1[0] ;
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 5 ;
}
else
return false ;
}
}
else if ( nEdge == 7) {
@@ -2386,11 +2396,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 5 ;
}
else {
else if (! vNeigh1.empty()) {
nId = vNeigh1.back() ;
m_mTree[nId].m_vInters.emplace_back() ;
m_mTree[nId].m_vInters.back().nIn = 6 ;
}
else
return false ;
}
}
// aggiungo l'intersezione al vettore delle intersezioni della prossima cella
@@ -3376,14 +3388,6 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
Point3d ptTl ( ptBL.x, ptTR.y) ;
Point3d ptBr ( ptTR.x, ptBL.y) ;
if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL)
nEdge = 0 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL)
nEdge = 1 ;
else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL)
nEdge = 2 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL)
nEdge = 3 ;
if ( AreSamePointApprox( ptToAssign, ptTR))
nEdge = 7 ;
else if ( AreSamePointApprox( ptToAssign, ptTl))
@@ -3392,6 +3396,14 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
nEdge = 5 ;
else if ( AreSamePointApprox( ptToAssign, ptBr))
nEdge = 6 ;
else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL)
nEdge = 0 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL)
nEdge = 1 ;
else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL)
nEdge = 2 ;
else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL)
nEdge = 3 ;
else
return false ;
return true ;
+32 -26
View File
@@ -26,13 +26,12 @@ struct Inters {
PNTVECTOR vpt ;
int nOut ;
bool bCCW ;
bool bVertex ;
int nChunk ;
// riordino le intersezioni per lato in senso antiorario dal top
// se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
// se ho pi intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
bool operator < ( Inters& b)
{
// trovo in che ordine stanno i due strat, tenendo conto anche della possibilità che siano vertici
// trovo in che ordine stanno i due strat, tenendo conto anche della possibilit che siano vertici
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ;
int nPos1 = std::distance( vEdges.begin(), iter1) ;
@@ -53,7 +52,7 @@ struct Inters {
pl.Close() ;
pl.GetAreaXY( dAreaB) ;
}
// se nIn è un vertice sistemo il valore
// se nIn un vertice sistemo il valore
int nEdgeIn = nIn ;
if ( nIn > 3)
nEdgeIn = nIn - 4 ;
@@ -74,8 +73,8 @@ struct Inters {
}
} ;
// nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
// -1 se la curva è sempre dentro la cella
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da l in senso antiorario
// -1 se la curva sempre dentro la cella
//----------------------------------------------------------------------------
class Cell
@@ -90,11 +89,16 @@ class Cell
// |_________________|
// Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE)
public :
~Cell( void) {}
Cell( void)
: 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_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false),
m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) {}
Cell( const Point3d& ptBL, const Point3d& ptTR)
m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true)
{
Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ;
m_ptPtr = ptTr ;
}
Cell( const Point3d& ptBL, const 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_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false),
m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {}
@@ -114,9 +118,9 @@ class Cell
{ return m_ptPtr ; }
double GetSplitValue( void) const
{ return m_dSplit ; }
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, senn orizzontalmente
{ return m_bSplitVert ; }
bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia
bool IsLeaf( void) const // flag che indica se la cella ha figli o se una foglia
{ return ( m_nChild1 == -2 && m_nChild2 == -2) ; }
bool IsProcessed( void) const // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati
{ return m_bProcessed ; }
@@ -134,24 +138,24 @@ class Cell
int m_nLeft ; // cella adiacente al lato left
int m_nRight ; // cella adiacente al lato right
int m_nParent ; // cella genitore
int m_nDepth ; // profondità della cella rispetto a root
double m_dSplit ; // parametro a cui è stata splittata la cella
int m_nDepth ; // profondit della cella rispetto a root
double m_dSplit ; // parametro a cui stata splittata la cella
int m_nChild1 ; // prima cella figlio
int m_nChild2 ; // seconda cella figlio
int m_nFlag ; // falg che indica la caratterizzazione della cella rispetto ai loop di trim
// 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop
int m_nFlag2 ; // falg che indica se la cella è stata attraversata durante l'ultima fase del labelling
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U)
bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V)
int m_nFlag2 ; // falg che indica se la cella stata attraversata durante l'ultima fase del labelling
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 met e met
bool m_bOnLeftEdge ; // flag che indica se la cella sul lato sinistro ( per superfici chiuse sul parametro U)
bool m_bOnTopEdge ; // flag che indica se la cella sul lato top ( per superfici chiuse sul parametro V)
std::vector<Inters> m_vInters ; // vettore delle intersezioni della cella con i loop di trim
// ogni elemento del vettore è l'insieme dei punti che caratterizza un atrtaversamento della cella
// ogni elemento del vettore l'insieme dei punti che caratterizza un atrtaversamento della cella
private :
Point3d m_ptPbl ; // punto bottom left
Point3d m_ptPtr ; // punto top right
bool m_bProcessed ; // flag che indica se la cella è stata processata
bool m_bSplitVert ; // flag che indica in quale direzione è stata divisa la cella
bool m_bProcessed ; // flag che indica se la cella stata processata
bool m_bSplitVert ; // flag che indica in quale direzione stata divisa la cella
} ;
//----------------------------------------------------------------------------
@@ -163,18 +167,19 @@ class Tree
Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin lunghezza minima del lato di una cella nello spazio reale
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
bool GetPolygons( POLYLINEMATRIX& vPolygons) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
bool GetLeaves ( std::vector<Cell>& vLeaves) const ;
void SetTestMode( void) { m_bTestMode = true ;} ;
private :
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profonditù di +- 1
bool Split( int nId) ; // funzione di split di una cella dell'albero a met nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondit di +- 1
int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
int GetDepth( int nId, int nRef) const ; // livello del nodo nId
void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top
@@ -183,7 +188,7 @@ class Tree
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right
void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario
void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl) const ; // dato un punto, trova la cella foglia a cui appartiene
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
@@ -219,8 +224,9 @@ class Tree
int m_nSpanU ;
int m_nSpanV ;
POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 puntatore Null e -1 root
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id lo stesso che la cella ha in m_mTree
INTVECTOR m_vnLeaves ; // vettore delle foglie
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
bool m_bTestMode ; // bool che indica se la test mode è attiva
} ;