Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel
This commit is contained in:
+38
-22
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
Reference in New Issue
Block a user