Merge branch 'MoreBezier'
This commit is contained in:
+63
-36
@@ -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
@@ -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
@@ -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)
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user