Merge branch 'MoreBezier'

This commit is contained in:
Daniele Bariletti
2024-08-05 10:07:42 +02:00
5 changed files with 1425 additions and 985 deletions
+63 -36
View File
@@ -118,9 +118,9 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
return nullptr ;
//// se da fare, metto i tappi sulle estremità
//// se da fare, metto i tappi sulle estremità
//if ( bDoCapEnds) {
// // creo la prima superficie di estremità
// // creo la prima superficie di estremità
// SurfTriMesh STM1 ;
// if ( ! STM1.CreateByFlatContour( PL))
// return nullptr ;
@@ -166,7 +166,7 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
// vPL[i].Invert() ;
// }
// // creo la prima superficie di estremità
// // creo la prima superficie di estremità
// PtrOwner<SurfBezier> pSbz1( CreateBasicSurfBezier()) ;
// if ( IsNull( pSbz1) || ! pSbz1->CreateByRegion( vPL))
// return nullptr ;
@@ -184,7 +184,7 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
// //// salvo tolleranza lineare usata
// //pSTM->SetLinearTolerance( dLinTol) ;
// // restituisco la superficie
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
//}
//-------------------------------------------------------------------------------
@@ -289,7 +289,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
return nullptr ;
//// se richiesti caps /// richiede la SurfCompo
//if ( bCapEnds) {
// // determino se la sezione è chiusa e piatta
// // determino se la sezione è chiusa e piatta
// Plane3d plPlane ; double dArea ;
// bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
// // determino non sia una semplice rivoluzione
@@ -333,7 +333,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
// return nullptr ;
// Vector3d vtNorm = plGuide.GetVersN() ;
// // determino se la guida è chiusa
// // determino se la guida è chiusa
// bool bGuideClosed = pGuide->IsClosed() ;
// // curve di offset
// OffsetCurve OffsCrvR ;
@@ -374,7 +374,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// pSTM->SetSmoothAngle( 20) ;
// // se guida aperta e tappi piatti
// if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
// // verifico che le due estremità siano chiuse e piatte
// // verifico che le due estremità siano chiuse e piatte
// POLYLINEVECTOR vPL ;
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
// return nullptr ;
@@ -453,7 +453,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// Point3d ptCen ;
// pGuide->GetStartPoint( ptCen) ;
// ptCen -= dDimV / 2 * vtNorm ;
// // determino se la guida è chiusa
// // determino se la guida è chiusa
// bool bGuideClosed = pGuide->IsClosed() ;
// // curve di offset
// const int NUM_OFFS = 4 ;
@@ -476,7 +476,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// }
// }
// else {
// // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
// // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
// for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
// bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
// }
@@ -553,7 +553,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// StmFromTriangleSoup stmCapSoup ;
// if ( ! stmCapSoup.Start( nBuckets))
// return nullptr ;
// // verifico che le due estremità siano chiuse e piatte
// // verifico che le due estremità siano chiuse e piatte
// POLYLINEVECTOR vPL ;
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
// return nullptr ;
@@ -654,9 +654,9 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
//static ISurfBezier*
//GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
//{
// // determino se la sezione è chiusa
// // determino se la sezione è chiusa
// bool bSectClosed = pSect->IsClosed() ;
// // determino se la guida è chiusa
// // determino se la guida è chiusa
// bool bGuideClosed = pGuide->IsClosed() ;
//
// // riferimento all'inizio della linea guida
@@ -719,7 +719,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
//
// // se richiesti caps e sezione chiusa e guida aperta
// if ( bCapEnds && bSectClosed && ! bGuideClosed) {
// // verifico che le due estremità siano chiuse e piatte
// // verifico che le due estremità siano chiuse e piatte
// POLYLINEVECTOR vPL ;
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
// return nullptr ;
@@ -763,9 +763,9 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
//static ISurfBezier*
//GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
//{
// // determino se la sezione è chiusa
// // determino se la sezione è chiusa
// bool bSectClosed = pSect->IsClosed() ;
// // determino se la guida è chiusa
// // determino se la guida è chiusa
// bool bGuideClosed = pGuide->IsClosed() ;
// // determino algoritmo da usare per calcolare i riferimenti lungo la curva
// bool bRMF = vtAx.IsSmall() ;
@@ -915,7 +915,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
// bIsLine = true ;
// }
// // se la guida è piana
// // se la guida è piana
// Plane3d plGuide ;
// if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL))
// return GetSurfBezierSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ;
@@ -961,7 +961,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// return nullptr ;
//
// // se rischiesta chiusura...
// // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa
// // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa
// if ( bCapEnds && ! pGuide->IsClosed()) {
// // recupero i loop all'inizio (dalla regione e apportunamente approssimati)
// POLYLINEVECTOR vPLi ;
@@ -972,7 +972,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// return nullptr ;
// }
// }
// // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
// // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
// PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
// if ( ! pSci->CreateByRegion( vPLi))
// return nullptr ;
@@ -1004,7 +1004,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// // verifica parametri
// if ( pSect == nullptr || pGuide == nullptr)
// return nullptr ;
// // determino se la sezione è chiusa
// // determino se la sezione è chiusa
// bool bSectClosed = pSect->IsClosed() ;
// // punto iniziale della sezione e vettore a inizio guida
// Point3d ptStart ;
@@ -1018,7 +1018,7 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
// PolyLine PLG ;
// if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG))
// return nullptr ;
// // determino se la guida è chiusa
// // determino se la guida è chiusa
// bool bGuideClosed = PLG.IsClosed() ;
// // calcolo la superficie
// PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
@@ -1111,21 +1111,8 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
if ( pCurve1 == nullptr || pCurve2 == nullptr)
return nullptr ;
// qui anziché fare le polyline converto le curve in bezier!
// SE NON HO LO STESSO NUMERO DI CURVE COME LO GESTISCO??
//// calcolo la polilinea che approssima la prima curva
//PolyLine PL1 ;
//if ( ! pCurve1->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL1))
// return nullptr ;
//// calcolo la polilinea che approssima la seconda curva
//PolyLine PL2 ;
//if ( ! pCurve2->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL2))
// return nullptr ;
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
// se la curva è già una bezier singola la tengo, sennò la converto // e la compo di bezier???
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
// se la curva è già una bezier singola la tengo, sennò la converto
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
if ( pCurve1->GetType() != CRV_BEZIER)
pCC1->AddCurve( CurveToBezierCurve( pCurve1)) ;
@@ -1134,7 +1121,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
if ( IsNull( pCC1) || ! pCC1->IsValid())
return nullptr ;
// se la curva è già una bezier singola la tengo, sennò la converto
// se la curva è già una bezier singola la tengo, sennò la converto
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
if ( pCurve2->GetType() != CRV_BEZIER)
pCC2->AddCurve( CurveToBezierCurve( pCurve2)) ;
@@ -1151,4 +1138,44 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
//pSbz->SetLinearTolerance( dLinTol) ;
// restituisco la superficie
return Release( pSbz) ;
}
//-------------------------------------------------------------------------------
ISurfBezier*
GetSurfBezierSkinned( const CICURVEPVECTOR& vCrv, double dLinTol)
{
// verifico che le curve siano valide
for ( int i = 0 ; i < int( vCrv.size()) ; ++i) {
if( vCrv[i] == nullptr || ! vCrv[i]->IsValid())
return nullptr ;
}
// se ho solo due curve allora faccio la rigata
if( vCrv.size() == 2)
return GetSurfBezierRuled( vCrv[0], vCrv[1], ISurfBezier::RLT_B_MINDIST_PLUS, dLinTol) ;
//trasformo le curve in curve di bezier, pareggio il numero di sottocurve e il grado
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
// se la curva è già una bezier singola la tengo, sennò la converto
ICURVEPOVECTOR vCrvBez ;
for( int c = 0 ; c < int( vCrv.size()) ; ++c){
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
if ( vCrv[c]->GetType() != CRV_BEZIER )
pCC->AddCurve( CurveToBezierCurve( vCrv[c])) ;
else
pCC->AddCurve( vCrv[c]->Clone()) ;
if ( IsNull( pCC) || ! pCC->IsValid())
return nullptr ;
vCrvBez.emplace_back( Release( pCC)) ;
}
// creo e setto la superficie trimesh
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
if ( IsNull( pSbz) || ! pSbz->CreateBySetOfCurves( vCrvBez))
return nullptr ;
//// salvo tolleranza lineare usata
//pSbz->SetLinearTolerance( dLinTol) ;
// restituisco la superficie
return Release( pSbz) ;
}
+411 -55
View File
@@ -40,6 +40,7 @@
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Extern/Eigen/Dense"
#include "EgtDev/Include/EGkGeoObjSave.h"
using namespace std ;
@@ -47,6 +48,7 @@ using namespace std ;
GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) ;
static bool ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam) ;
//----------------------------------------------------------------------------
SurfBezier::SurfBezier( void)
@@ -87,6 +89,7 @@ SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational
else
m_vWeCtrl.clear() ;
m_nStatus = TO_VERIFY ;
m_nIsPlanar = NOT_CALCULATED ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
@@ -1575,37 +1578,100 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
// prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d
int c = 0 ;
for ( POLYLINEVECTOR vPL : vvPL) {
for ( POLYLINEVECTOR& vPL : vvPL) {
PNTVECTOR vPnt ;
INTVECTOR vTria ;
Triangulate Tri ;
if ( ! Tri.Make( vPL, vPnt, vTria))
if ( ! Tri.Make( vPL, vPnt, vTria)) {
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Triangulation failed in Bezier Surface") ;
return nullptr ;
}
//vedo se la polyline 3d che passo io corrisponde a quella che usavo prima
POLYLINEVECTOR vPL3d = vvPL3d[c] ;
// porto i punti in 3d
PNTVECTOR vPnt3d ;
for( int i = 0 ; i < int( vPL3d.size()) ; ++i) {
PolyLine pl3d = vPL3d[i] ;
PolyLine& pl3d = vPL3d[i] ;
Point3d pt3d ; pl3d.GetFirstPoint( pt3d) ;
//vPnt3d.push_back( pt3d) ;
if( vPL3d.size() > 1)
vPnt3d.push_back( pt3d) ;
while ( pl3d.GetNextPoint( pt3d)) {
vPnt3d.push_back( pt3d) ;
}
}
// controllo per ogni polyline se è stato invertito il vettore dei punti
int nCurrPoint = 0 ;
for( int i = 0 ; i < int( vPL.size()) ; ++i) {
Point3d pt3d ; vPL[i].GetFirstPoint( pt3d) ;
vPL[i].GetNextPoint( pt3d) ;
int nPoints = vPL[i].GetPointNbr() - 2 ;
if ( ! AreSamePointApprox( vPnt[nCurrPoint], pt3d))
reverse( vPnt3d.begin() + nCurrPoint, vPnt3d.begin() + nCurrPoint + nPoints) ;
nCurrPoint += nPoints ;
// se ho ottenuto meno triangoli di quelli che avrei dovuto avere allora potrei aver avuto un problema in prossimità di un polo
// se comunque ho corrispondenza tra vPnt e vPnt3d allora eseguo la trinagolazione in 3d
int nTriaNumber = ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) ;
bool bTriangulationFailedIn2D = nTriaNumber != ( vTria.size()) / 3 ;
//bool bMismatch2D3D = vPnt.size() != vPnt3d.size() ;
bool bTriangulatedIn3D = false ;
if ( bTriangulationFailedIn2D) {
PNTVECTOR vPntBackup = vPnt ;
INTVECTOR vTriaBackup = vTria ;
bool bTriangulationSucceded = true ;
if ( ! Tri.Make( vPL3d, vPnt, vTria))
bTriangulationSucceded = false ;
bTriangulationSucceded = bTriangulationSucceded && ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) == ( vTria.size() ) / 3 ;
if( bTriangulationFailedIn2D) {
if ( bTriangulationSucceded)
LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) RESOLVED")
else
LOG_INFO( GetEGkLogger(), "Info : This problem in MakeByEC23(1) is the same as the previous one")
}
if( bTriangulationSucceded) {
bTriangulatedIn3D = true ;
// calcolo la normale della polyline per flippare eventualmente i triangoli se hanno la normale sbagliata
PolyLine& pl3d = vPL3d[0] ;
Plane3d plPlane ; double dArea = 0 ;
pl3d.IsClosedAndFlat( plPlane, dArea) ;
Vector3d vtN = plPlane.GetVersN() ;
Triangle3d tria ;
tria.Set( vPnt[vTria[0]], vPnt[vTria[1]], vPnt[vTria[2]]) ;
if( tria.GetN() * vtN < 0)
reverse( vTria.begin(), vTria.end()) ;
}
else {
vPnt = vPntBackup ;
vTria = vTriaBackup ;
}
}
// riordino il vettore dei punti su cui non ho fatto la triangolazione
if( int(vPL.size()) == 2) {
//if( vPnt.size() != vPnt3d.size())
// return nullptr ;
PNTVECTOR vPntOrd ;
if( bTriangulatedIn3D) {
ReorderPntVector( vPL3d, true, vPnt, vPL, vPntOrd) ;
vPnt3d = vPnt ;
vPnt = vPntOrd ;
}
else {
ReorderPntVector( vPL, false, vPnt, vPL3d, vPntOrd) ;
vPnt3d = vPntOrd ;
}
}
else if ( bTriangulatedIn3D) {
if( vPL.size() == 1) {
vPnt3d = vPnt ;
PNTVECTOR vPnt2d ;
for( int i = 0 ; i < int( vPL.size()) ; ++i) {
PolyLine& pl = vPL[i] ;
Point3d pt ; pl.GetFirstPoint( pt) ;
//vPnt2D.push_back( pt) ;
while ( pl.GetNextPoint( pt)) {
vPnt2d.push_back( pt) ;
}
}
vPnt = vPnt2d ;
}
else {
PNTVECTOR vPntOrd ;
ReorderPntEnhancedVector( vPL3d, true, vPnt, vPL, vPntOrd) ;
vPnt3d = vPnt ;
vPnt = vPntOrd ;
}
}
//controllo che i due vettori vPnt e vPnt3d abbiano la stessa lunghezza, sennò vuol dire che nel vettore vPnt3d ho avuto dei Rejected e devo ricalcolarli
@@ -1638,6 +1704,129 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
return GetBasicSurfTriMesh( stmSoup.GetSurf()) ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const
{
BOOLVECTOR vbPolyChecked( vPL.size()) ;
fill( vbPolyChecked.begin(), vbPolyChecked.end(), false) ;
for ( int p = 0 ; p < int(vPnt.size()) ; ++p) {
Point3d pt = vPnt[p] ;
int nInd = 0 ;
int nPoly = 0 ;
int nPoints = 0 ;
bool bInverted = false ;
for ( int poly = 0 ; poly < int( vPL.size()) ; ++poly ) {
if( vbPolyChecked[poly])
continue ;
PolyLine pl = vPL[poly] ;
nInd = 0 ;
Point3d ptPoly ; pl.GetFirstPoint( ptPoly) ;
bool bFound = false ;
if( AreSamePointStepExact( pt, ptPoly)){
nPoints = pl.GetPointNbr() ;
nPoly = poly ;
bFound = true ;
pl.GetNextPoint( ptPoly) ;
if( ! AreSamePointStepExact( vPnt[p+1], ptPoly))
bInverted = true ;
break ;
}
while ( pl.GetNextPoint( ptPoly) && ! bFound) {
++ nInd ;
if( AreSamePointStepExact( pt, ptPoly)) {
nPoints = pl.GetPointNbr() ;
nPoly = poly ;
bFound = true ;
pl.GetNextPoint( ptPoly) ;
if( ! AreSamePointStepExact( vPnt[p+1], ptPoly))
bInverted = true ;
break ;
}
}
if( bFound)
break ;
}
if( nInd == 0) {
Point3d ptPoly ;
vPLToOrd[nPoly].GetFirstPoint( ptPoly) ;
vPntOrd.push_back( ptPoly) ;
while ( vPLToOrd[nPoly].GetNextPoint( ptPoly))
vPntOrd.push_back( ptPoly) ;
}
else if ( nInd == nPoints - 1 ) {
Point3d ptPoly ;
vPLToOrd[nPoly].GetLastPoint( ptPoly) ;
vPntOrd.push_back( ptPoly) ;
while ( vPLToOrd[nPoly].GetPrevPoint( ptPoly))
vPntOrd.push_back( ptPoly) ;
}
else {
PNTVECTOR vPntToRotate ;
Point3d ptPoly ;
if( ! bInverted) {
vPLToOrd[nPoly].GetFirstPoint( ptPoly) ;
vPntToRotate.push_back( ptPoly) ;
while ( vPLToOrd[nPoly].GetNextPoint( ptPoly))
vPntToRotate.push_back( ptPoly) ;
}
else {
vPLToOrd[nPoly].GetLastPoint( ptPoly) ;
vPntToRotate.push_back( ptPoly) ;
while ( vPLToOrd[nPoly].GetPrevPoint( ptPoly))
vPntToRotate.push_back( ptPoly) ;
}
vPntToRotate.pop_back() ;
rotate( vPntToRotate.begin(), vPntToRotate.begin() + nInd, vPntToRotate.end()) ;
vPntToRotate.push_back( vPntToRotate[0]) ;
vPntOrd.insert( vPntOrd.end(), vPntToRotate.begin(), vPntToRotate.end()) ;
}
vbPolyChecked[nPoly] = true ;
p += nPoints - 1;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::ReorderPntEnhancedVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const
{
vPntOrd.clear() ;
// costruisco il vettore dei punti da ordinare
PNTVECTOR vPntPolyToOrd ;
for ( int i = 0 ; i < int( vPLToOrd.size()) ; ++i) {
Point3d pt ; vPLToOrd[i].GetFirstPoint( pt) ;
vPntPolyToOrd.push_back( pt) ;
while( vPLToOrd[i].GetNextPoint( pt))
vPntPolyToOrd.push_back( pt) ;
}
// costruisco il vettore con i punti delle polyline in ordine
PNTVECTOR vPntPoly ;
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
Point3d pt ; vPL[i].GetFirstPoint( pt) ;
vPntPoly.push_back( pt) ;
while( vPL[i].GetNextPoint( pt))
vPntPoly.push_back( pt) ;
}
BOOLVECTOR vbPntChecked( vPnt.size()) ;
fill( vbPntChecked.begin(), vbPntChecked.end(), false) ;
// confronto questo vettore con il vettore dei punti in ordine sparso
for ( int p = 0 ; p < int( vPntPoly.size()) ; ++p) {
Point3d pt = vPntPoly[p] ;
for ( int t = 0 ; t < int( vPnt.size()) ; ++t) {
if( vbPntChecked[t])
continue ;
Point3d ptToCheck = vPnt[t] ;
if ( AreSamePointStepExact( pt, ptToCheck)) {
vbPntChecked[t] = true ;
vPntOrd.push_back( vPntPolyToOrd[p]) ;
}
}
}
// applico la stessa trasformazione al vettore dei punti delle polyline vPLToOrd
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
@@ -3196,6 +3385,7 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
else
pCrvBz0->SetControlPoint( p, GetControlPoint( nIndex, nullptr), GetControlWeight( nIndex, nullptr)) ;
}
pCrvBz0->Invert() ;
pCrvCompo->AddCurve( Release( pCrvBz0)) ;
}
}
@@ -3217,6 +3407,7 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
else
pCrvBz1->SetControlPoint( p, GetControlPoint( nIndex, nullptr), GetControlWeight( nIndex, nullptr)) ;
}
pCrvBz1->Invert() ;
pCrvCompo->AddCurve( Release( pCrvBz1)) ;
}
}
@@ -3271,19 +3462,40 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
bool
SurfBezier::IsPlanar( void) const
{
// costruisco il contorno della superficie unendo gli edge e chiedo se la polyline è piana.
PtrOwner<ICurveComposite> pCCEdge( GetSingleEdge3D( false, 0)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 1)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 2)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 3)) ;
if ( m_nIsPlanar != NOT_CALCULATED) {
switch ( m_nIsPlanar ) {
case PLANAR_SURF : return true ; break ;
case NOT_PLANAR_SURF : return false ; break ;
}
}
PolyLine plApprox ;
pCCEdge->ApproxWithLines( 0.01, 15, 0, plApprox) ;
Plane3d plPlane ;
if ( ! plApprox.IsFlat( plPlane, 2 * EPS_SMALL))
return false ;
// in questo caso se è grado 1 in U e V e ho un unica Patch allora sono sicuro sia piana
if ( m_nDegU == 1 && m_nSpanU == 1 && m_nDegV == 1 && m_nSpanV == 1) // questa condizione da sola non è sufficiente ( posso avere superfici torte anche se i lati sono segmenti)
return true ;
if( ! m_bTrimmed) {
// costruisco il contorno della superficie unendo gli edge e chiedo se la polyline è piana.
PtrOwner<ICurveComposite> pCCEdge( GetSingleEdge3D( false, 0)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 1)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 2)) ;
pCCEdge->AddCurve( GetSingleEdge3D( false, 3)) ;
pCCEdge->ApproxWithLines( 0.01, 15, 0, plApprox) ;
if ( ! plApprox.IsFlat( plPlane, 2 * EPS_SMALL)){
m_nIsPlanar = 0 ;
return false ;
}
// in questo caso se è grado 1 in U e V e ho un unica Patch allora sono sicuro sia piana
if ( m_nDegU == 1 && m_nSpanU == 1 && m_nDegV == 1 && m_nSpanV == 1) {
m_nIsPlanar = 1 ;
return true ;
}
}
else {
Point3d ptCtrl ;
bool bOk = true ;
plApprox.AddUPoint( 0, GetControlPoint(0, &bOk)) ;
plApprox.AddUPoint( 1, GetControlPoint(m_nDegU * m_nSpanU, &bOk)) ;
plApprox.AddUPoint( 2, GetControlPoint(( m_nDegU * m_nSpanU + 1) * ( m_nDegV * m_nSpanV + 1), &bOk)) ;
plApprox.AddUPoint( 3, GetControlPoint(( m_nDegU * m_nSpanU + 1) * ( m_nDegV * m_nSpanV), &bOk)) ;
}
double dULast ; plApprox.GetLastU( dULast) ;
++ dULast ;
@@ -3298,10 +3510,13 @@ SurfBezier::IsPlanar( void) const
}
}
plPlane.Reset() ;
if ( plApprox.IsFlat( plPlane, 2 * EPS_SMALL))
if ( plApprox.IsFlat( plPlane, 2 * EPS_SMALL)) {
m_nIsPlanar = 1 ;
return true ;
}
// nel dubbio restituisco false
m_nIsPlanar = 0 ;
return false ;
}
@@ -3931,6 +4146,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
}
// reinizializzo la superficie con il nuovo numero di span in U
nSpanU = nSpanU0 + nRep1 ;
if( nSpanU != nSpanU1 + nRep0)
LOG_DBG_ERR( GetEGkLogger(), "There could be an errore in the creation of a ruled surface in mode RLT_B_MINDIST") ;
if ( nSpanU < max(nSpanU0, nSpanU1))
nSpanU = max(nSpanU0, nSpanU1) ;
nSecondRowInd = nDegU * nSpanU + 1 ;
@@ -4192,7 +4409,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
int nAtEnd1 = 0 ;
Point3d ptP0 ; plU0.GetFirstPoint( ptP0) ;
int c = 0 ;
int nCrvCount = 0 ;
int nRep0 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1
int nRep1 = 0 ;
double dLastParamMatch = 0 ;
@@ -4232,7 +4448,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
nCrvCount = pCrvU1->GetCurveCount() ;
// se sono già troppo vicino ad un split esistente allora non faccio nulla
if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
@@ -4306,7 +4521,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
nCrvCount = pCrvU0->GetCurveCount() ;
//se sono troppo vicino ad uno split esistente allora non faccio nulla
if( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
@@ -4439,6 +4653,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
nSpanU = nSpanU0 + nAtStart0 + nAtEnd0 + nRep1 ;
if( nSpanU != nSpanU1 + nAtStart1 + nAtEnd1 + nRep0)
LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ;
nSecondRowInd = nDegU * nSpanU + 1 ;
// inizializzo la superficie
Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
@@ -4531,32 +4748,29 @@ SurfBezier::FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTO
}
//----------------------------------------------------------------------------
bool
SurfBezier::ParametrizeByLen( const ICurveComposite* pCurve0, const ICurveComposite* pCurve1, DBLVECTOR& vParam0, DBLVECTOR& vParam1) const
static bool
ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam)
{
int nSpanU0 = pCurve0->GetCurveCount() ;
int nSpanU1 = pCurve1->GetCurveCount() ;
DBLVECTOR vLen0 ;
DBLVECTOR vLen1 ;
double dLenTot0 = 0 ;
double dLenTot1 = 0 ;
for( int i = 0 ; i < nSpanU0 ; ++i) {
const ICurve* pSubCrv0 = pCurve0->GetCurve( i) ;
double dLen ; pSubCrv0->GetLength( dLen) ;
dLenTot0 += dLen ;
vLen0.push_back( dLen) ;
}
for( int i = 0 ; i < nSpanU1 ; ++i) {
const ICurve* pSubCrv1 = pCurve1->GetCurve( i) ;
double dLen ; pSubCrv1->GetLength( dLen) ;
dLenTot1 += dLen ;
vLen1.push_back( dLen) ;
int nSpanU = pCurve->GetCurveCount() ;
DBLVECTOR vLen ;
double dLenTot = 0 ;
for( int i = 0 ; i < nSpanU ; ++i) {
const ICurve* pSubCrv = pCurve->GetCurve( i) ;
double dLen ; pSubCrv->GetLength( dLen) ;
dLenTot += dLen ;
vLen.push_back( dLen) ;
}
// determino il parametro di ogni curva rispetto alla lunghezza totale
for ( int i = 0 ; i < nSpanU0 ; ++i)
vParam0.push_back( vLen0[i] / dLenTot0) ;
for ( int i = 0 ; i < nSpanU1 ; ++i)
vParam1.push_back( vLen1[i] / dLenTot1) ;
for ( int i = 0 ; i < nSpanU ; ++i)
vParam.push_back( vLen[i] / dLenTot) ;
return true ;
}
//----------------------------------------------------------------------------
static bool
FindCommonParametrization( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam)
{
return true ;
}
@@ -4589,7 +4803,8 @@ SurfBezier::ParametrizeByLen( const ICurveComposite* pCurve0, const ICurveCompos
// return true ;
//}
static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) {
static bool
ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) {
// se sono chiuse devo controllare che gli start siano il più allineati possibile, se non lo sono cambio gli start
if ( plU0.IsClosed() && plU1.IsClosed()) {
vector<tuple<double,int,Point3d,int,Point3d>> vDistVert ;
@@ -4632,3 +4847,144 @@ static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposit
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez)
{
//uniformo le curve e determino il grado e il numero di span condiviso
//...
//...
int nDegU = 3 ;
int nSpanU = 2 ;
// calcolo i punti di controllo in V
int nDegV = 3 ;
int nSpanV = int( vCrvBez.size()) - 1 ;
PNTMATRIX vPntCrvs ;
for ( int j = 0 ; j < nSpanU ; ++j ) {
PNTVECTOR vPntCtrl0 ;
PNTVECTOR vPntCtrl1 ;
for ( int i = 0 ; i < int( vCrvBez.size()) ; ++i) {
const ICurveComposite* pCC = GetCurveComposite(vCrvBez[i]) ;
const ICurveBezier* pCrvBez = GetCurveBezier(pCC->GetCurve( j)) ;
if ( j == 0)
vPntCtrl0.push_back( pCrvBez->GetControlPoint(0)) ;
vPntCtrl1.push_back( pCrvBez->GetControlPoint(nDegU)) ;
}
if( j==0 )
vPntCrvs.push_back( vPntCtrl0) ;
vPntCrvs.push_back( vPntCtrl1) ;
}
Init( nDegU, nDegV, nSpanU, nSpanV, false) ;
// scorro le span
for ( int s = 0 ; s < int( nSpanU) ; ++s) {
// trovo la direzione media del parametro V
Point3d ptMean = ORIG ;
for ( int i = 1 ; i < int( vPntCrvs[0].size()) ; ++i )
ptMean += vPntCrvs[s][i] ;
ptMean /= int( vPntCrvs[0].size() - 1) ;
Vector3d vtDirXGeneral = ptMean - vPntCrvs[s][0] ;
// prendo le curve a gruppi di 3 per costruire la parabola per trovare la pendenza "intuitiva" della superficie in V
for ( int g = 0 ; g < nSpanV - 1 ; ++g) {
const ICurveComposite* pCC0 = GetCurveComposite( vCrvBez[g]) ;
const ICurveComposite* pCC1 = GetCurveComposite( vCrvBez[g + 1]) ;
const ICurveComposite* pCC2 = GetCurveComposite( vCrvBez[g + 2]) ;
// su ognuna di queste 3 curve prendo un punto per ogni punto di controllo ( semplicemente dividendo uniformemente il parametrico)
for ( int n = s == 0 ? 0 : 1 ; n < nDegU + 1 ; ++n) {
const ICurveBezier* pCrv0 = GetCurveBezier( pCC0->GetCurve( s)) ;
const ICurveBezier* pCrv1 = GetCurveBezier( pCC1->GetCurve( s)) ;
const ICurveBezier* pCrv2 = GetCurveBezier( pCC2->GetCurve( s)) ;
// setto come punti di controllo i punti delle curve
Point3d ptCtrl0 = pCrv0->GetControlPoint( n) ;
Point3d ptCtrl1 = pCrv1->GetControlPoint( n) ;
Point3d ptCtrl2 = pCrv2->GetControlPoint( n) ;
if ( g == 0) {
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * g * 3, ptCtrl0) ;
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 3), ptCtrl1) ;
}
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 6), ptCtrl2) ;
//// trovo i punti di controllo intermedi tra le curve usando la parabola che unisce queste tre curve////
Point3d ptP0 = pCrv0->GetControlPoint( n) ;
Point3d ptP1 = pCrv1->GetControlPoint( n) ;
Point3d ptP2 = pCrv2->GetControlPoint( n) ;
DistPointLine dpl( ptP1, ptP0, ptP2, false) ;
double dDist = INFINITO ; dpl.GetDist( dDist) ;
Point3d ptP3, ptP4, ptP5, ptP6 ;
if ( dDist < EPS_SMALL) {
// i punti sono allineati quindi mi basta prendere dei punti intermedi su questa retta
ptP3 = ptP0 * 2/3 + ptP1 * 1/3 ;
ptP4 = ptP0 * 1/3 + ptP1 * 2/3 ;
ptP5 = ptP1 * 2/3 + ptP2 * 1/3 ;
ptP6 = ptP1 * 1/3 + ptP2 * 2/3 ;
}
else {
// calcolo il piano della parabola e porto i punti in quel riferimento
Plane3d plParab ; plParab.Set( ptP0, ptP1, ptP2) ;
Point3d ptStartV, ptEndV ;
//Vector3d vDirX = ptP2 - ptP0 ;
DistPointLine dpl( ptP1, ptP0, ptP2, true) ;
Point3d ptPerp ; dpl.GetMinDistPoint( ptPerp) ;
Vector3d vtDirY = ptPerp - ptP1 ;
Frame3d frParab ;
Point3d ptStart, ptEnd ;
pCrv1->GetStartPoint( ptStart) ;
pCrv1->GetEndPoint( ptEnd) ;
Vector3d vtDirCrv1 = ptEnd - ptStart ;
Vector3d vtParabNorm = plParab.GetVersN() ;
Vector3d vtDirZ = vtDirCrv1 * vtParabNorm > 0 ? vtParabNorm : - vtParabNorm ;
Vector3d vtDirX = vtDirXGeneral - (vtDirXGeneral * vtDirZ * vtDirZ) ;
if ( ! frParab.Set( ptP0, vtDirX, vtDirY, vtDirZ)) {
vtDirY = vtDirZ ^ vtDirX ;
if ( ! frParab.Set( ptP0, vtDirX, vtDirY, vtDirZ))
return false ;
}
// porto i punti nel piano di riferimento della parabola
Point3d pt0 = ptP0 ; pt0.ToLoc( frParab) ;
Point3d pt1 = ptP1 ; pt1.ToLoc( frParab) ;
Point3d pt2 = ptP2 ; pt2.ToLoc( frParab) ;
Eigen::Matrix3d mA ;
mA.col(0) << pow(pt0.x,2), pow(pt1.x,2) , pow(pt2.x,2) ;
mA.col(1) << pt0.x, pt1.x , pt2.x ;
mA.col(2) << 1, 1, 1 ;
if( abs( mA.determinant()) < EPS_SMALL)
return false ;
Eigen::Vector3d b ( pt0.y, pt1.y, pt2.y) ;
Eigen::Vector3d coeff = mA.fullPivLu().solve(b) ;
// pendenze e termini noti nei punti di contatto
double dm0 = 2 * coeff.x() * pt0.x + coeff.y() ;
double dm1 = 2 * coeff.x() * pt1.x + coeff.y() ;
double dm2 = 2 * coeff.x() * pt2.x + coeff.y() ;
double dq0 = pt0.y - dm0 * pt0.x ;
double dq1 = pt1.y - dm1 * pt1.x ;
double dq2 = pt2.y - dm2 * pt2.x ;
// trovo le intersezioni a coppie tra le tre rette di tangenza
Point3d ptI1 , ptI2;
ptI1.x = (dq1 -dq0) / (dm0 - dm1) ;
ptI1.y = ptI1.x * dm0 + dq0 ;
ptI2.x = ( dq2 - dq1) / ( dm1 - dm2) ;
ptI2.y = ptI2.x * dm1 + dq1 ;
// porto i punti in globale e trovo i punti medi
ptI1.ToGlob( frParab) ;
ptI2.ToGlob( frParab) ;
ptP3 = ( ptP0 + ptI1) / 2 ;
ptP4 = ( ptP1 + ptI1) / 2 ;
ptP5 = ( ptP1 + ptI2) / 2 ;
ptP6 = ( ptP2 + ptI2) / 2 ;
}
if ( g == 0)
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 1), ptP3) ;
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 2), ptP4) ;
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 4), ptP5) ;
SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 5), ptP6) ;
}
}
}
return true ;
}
+4 -1
View File
@@ -143,6 +143,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) override ;
bool CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez) ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
@@ -202,7 +203,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
// funzione che calcola se gli edge sono collassati in poli
bool CalcPoles( void) const ;
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
bool ParametrizeByLen( const ICurveComposite* pCurve0, const ICurveComposite* pCurve1, DBLVECTOR& vParam0, DBLVECTOR& vParam1) const ;
bool ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
bool ReorderPntEnhancedVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
@@ -224,6 +226,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
double m_dTempParam[2] ; // vettore parametri temporanei
mutable vector<ICRVCOMPOPOVECTOR> m_mCCEdge ;// vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
mutable int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
} ;
//-----------------------------------------------------------------------------
+933 -883
View File
File diff suppressed because it is too large Load Diff
+14 -10
View File
@@ -197,7 +197,7 @@ class Cell
{ return c1.m_ptPbl.x < c2.m_ptPbl.x ; }
static bool minorY( const Cell& c1, const Cell& c2)
{ return c1.m_ptPbl.y < c2.m_ptPbl.y ; }
public :
int m_nId ; // Id della cella
int m_nTop ; // cella adiacente al lato top
@@ -218,6 +218,7 @@ class Cell
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 attraversamento della cella
int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo
// contati in senso CCW a partire dal bottom left
private :
Point3d m_ptPbl ; // punto bottom left
@@ -242,10 +243,10 @@ class Tree
bool GetPolygons( POLYLINEMATRIX& vvPolygons) ;
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d) ;
bool GetPolygons( POLYLINEMATRIX& vPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // 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
// se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygons3d) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
// se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells = {}) ;
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
bool GetEdges3D ( POLYLINEMATRIX& mPLEdges) ; // restituisce gli edge 3D come polyline
@@ -278,14 +279,16 @@ class Tree
bool FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
// resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto
bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni.
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, bool bForTriangulation) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, bool bForTriangulation,
const PolyLine& plPolygonsBasic, const PolyLine& plPolygonsBasic3d) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario
bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR.
bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3)
bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2.
bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge
bool CheckIfBefore( int nEdgeA, int nEdgeB) const ; // per due edge uguali per la funzione AreSameEdge chiedo se EdgeA viene prima di EdgeB
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c,
const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool ForTriangulation) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool ForTriangulation, Point3d& ptLast) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag
bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata)
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW)
@@ -303,7 +306,7 @@ class Tree
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
bool m_bTrimmed ; // superficie trimmata
//INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk
std::map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
std::unordered_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
//ICURVEPOVECTOR m_vLoop ; // curve di loop
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
bool m_bBilinear ; // superficie bilineare
@@ -317,9 +320,10 @@ class Tree
int m_nSpanU ; // numero di span lungo il parametro U
int m_nSpanV ; // numero di span lungo il parametro V
POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree
POLYLINEMATRIX m_vPolygonsCorr ; // matrice dei poligoni del tree, corretti per i punti che sono nei poli
POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d 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. I punti sono nell'ordine P00, P10, P11, P01
std::unordered_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
std::unordered_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. I punti sono nell'ordine P00, P10, P11, P01
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