EgtGeomKernel :
- correzioni, migliorie e d estensioni alle superfici di Bezier - in Release cambiate opzioni di ottimizzazione da /Ox a /O2.
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
#pragma once
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+117
-80
@@ -25,6 +25,7 @@
|
||||
#include "NgeReader.h"
|
||||
#include "PolynomialPoint3d.h"
|
||||
#include "Bernstein.h"
|
||||
#include "deCasteljau.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
@@ -57,11 +58,11 @@ CurveBezier::~CurveBezier( void)
|
||||
bool
|
||||
CurveBezier::Init( int nDeg, bool bIsRational)
|
||||
{
|
||||
// verifico validità grado
|
||||
// verifico validità grado
|
||||
if ( nDeg < 1 || nDeg > MAXDEG)
|
||||
return false ;
|
||||
|
||||
// imposto grado, flag di razionale e singolarità non studiata
|
||||
// imposto grado, flag di razionale e singolarità non studiata
|
||||
m_nDeg = nDeg ;
|
||||
m_bRat = bIsRational ;
|
||||
m_dParSing = - 2 ;
|
||||
@@ -84,7 +85,7 @@ CurveBezier::Init( int nDeg, bool bIsRational)
|
||||
bool
|
||||
CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
||||
{
|
||||
// verifico validità indice
|
||||
// verifico validità indice
|
||||
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg)
|
||||
return false ;
|
||||
|
||||
@@ -95,7 +96,7 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
||||
if ( m_bRat)
|
||||
m_vWeCtrl[nInd] = 1 ;
|
||||
|
||||
// annullo analisi presenza singolarità
|
||||
// annullo analisi presenza singolarità
|
||||
m_dParSing = - 2 ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -108,7 +109,7 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
||||
bool
|
||||
CurveBezier::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 > m_nDeg)
|
||||
return false ;
|
||||
|
||||
@@ -120,7 +121,7 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
||||
m_vPtCtrl[nInd] = ptCtrl ;
|
||||
m_vWeCtrl[nInd] = dW ;
|
||||
|
||||
// annullo analisi presenza singolarità
|
||||
// annullo analisi presenza singolarità
|
||||
m_dParSing = - 2 ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -215,7 +216,7 @@ CurveBezier::IsAPoint( void) const
|
||||
const Point3d&
|
||||
CurveBezier::GetControlPoint( int nInd, bool* pbOk) const
|
||||
{
|
||||
// verifico validità e indice
|
||||
// verifico validità e indice
|
||||
if ( m_nStatus != OK || nInd < 0 || nInd > m_nDeg) {
|
||||
if ( pbOk != NULL)
|
||||
*pbOk = false ;
|
||||
@@ -231,7 +232,7 @@ CurveBezier::GetControlPoint( int nInd, bool* pbOk) const
|
||||
double
|
||||
CurveBezier::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 > m_nDeg) {
|
||||
if ( pbOk != NULL)
|
||||
*pbOk = false ;
|
||||
@@ -452,7 +453,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
b3Loc.Add( ptTemp) ;
|
||||
}
|
||||
}
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ;
|
||||
Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ;
|
||||
@@ -470,7 +471,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
// assegno il box nel riferimento
|
||||
@@ -496,7 +497,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
b3Ref.Add( ptTemp) ;
|
||||
}
|
||||
}
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
vtFrExtr.ToGlob( frRef) ;
|
||||
@@ -525,7 +526,7 @@ CurveBezier::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
if ( ! shPL.AddUPoint( dU, GetControlPoint( i)))
|
||||
return false ;
|
||||
}
|
||||
// recupero dati sulla planarità
|
||||
// recupero dati sulla planarità
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
@@ -597,7 +598,7 @@ CurveBezier::GetMidPoint( Point3d& ptMid) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
double dLen, dMid ;
|
||||
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
|
||||
return false ;
|
||||
@@ -634,7 +635,7 @@ CurveBezier::GetMidDir( Vector3d& vtDir) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
double dLen, dMid ;
|
||||
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
|
||||
return false ;
|
||||
@@ -787,7 +788,7 @@ CurveBezier::GetSingularParam( double& dPar) const
|
||||
if ( m_dParSing < -1.5)
|
||||
CalcSingularParam() ;
|
||||
|
||||
// se esiste singolarità
|
||||
// se esiste singolarità
|
||||
if ( m_dParSing > 0 && m_dParSing < 1) {
|
||||
dPar = m_dParSing ;
|
||||
return 1 ;
|
||||
@@ -801,15 +802,15 @@ CurveBezier::GetSingularParam( double& dPar) const
|
||||
bool
|
||||
CurveBezier::CalcSingularParam( void) const
|
||||
{
|
||||
// non si considerano singolarità agli estremi ( non creano problemi)
|
||||
// non si considerano singolarità agli estremi ( non creano problemi)
|
||||
|
||||
// le curve di grado 1 non possono avere singolarità
|
||||
// le curve di grado 1 non possono avere singolarità
|
||||
if ( m_nDeg <= 1) {
|
||||
m_dParSing = -1 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// le curve di grado 2 possono avere singolarità solo se i punti sono allineati con ordine P0 P2 P1
|
||||
// le curve di grado 2 possono avere singolarità solo se i punti sono allineati con ordine P0 P2 P1
|
||||
if ( m_nDeg == 2) {
|
||||
Vector3d vtV1 = m_vPtCtrl[1] - m_vPtCtrl[0] ;
|
||||
Vector3d vtV2 = m_vPtCtrl[2] - m_vPtCtrl[1] ;
|
||||
@@ -849,7 +850,7 @@ CurveBezier::CalcSingularParam( void) const
|
||||
pol3P.AdjustDegree() ;
|
||||
}
|
||||
|
||||
// calcolo gli zeri della componente più importante della derivata
|
||||
// calcolo gli zeri della componente più importante della derivata
|
||||
DBLVECTOR vdRoot ;
|
||||
int nZ = pol3P.FindMainComponentRoots( vdRoot) ;
|
||||
// scarto gli zeri fuori dall'intervallo aperto 0-1 e quelli ripetuti
|
||||
@@ -867,13 +868,13 @@ CurveBezier::CalcSingularParam( void) const
|
||||
}
|
||||
}
|
||||
|
||||
// non ci sono singolarità
|
||||
// non ci sono singolarità
|
||||
m_dParSing = -1 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// i coefficienti sono ordinati dalla potenza più bassa alla più alta
|
||||
// i coefficienti sono ordinati dalla potenza più bassa alla più alta
|
||||
// se razionale, ritorna la sola forma monomiale del numeratore
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
@@ -910,8 +911,8 @@ CurveBezier::ToPowerBase( PolynomialPoint3d& pol3P) const
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// i coefficienti sono ordinati dalla potenza più bassa alla più alta
|
||||
// se polinomiale, la forma monomiale del denominatore è un 1
|
||||
// i coefficienti sono ordinati dalla potenza più bassa alla più alta
|
||||
// se polinomiale, la forma monomiale del denominatore è un 1
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::ToPowerBase( PolynomialPoint3d& pol3Num, Polynomial& polDen) const
|
||||
@@ -976,6 +977,37 @@ CurveBezier::GetControlPolygonLength( double& dLen) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::GetApproxLength( double& dLen) const
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// se ridotta ad un punto
|
||||
if ( IsAPoint()) {
|
||||
dLen = 0 ;
|
||||
return true ;
|
||||
}
|
||||
// se grado 1
|
||||
if ( m_nDeg == 1) {
|
||||
dLen = Dist( m_vPtCtrl[0], m_vPtCtrl[m_nDeg]) ;
|
||||
return true ;
|
||||
}
|
||||
// la divido in due metà
|
||||
CurveBezier crvBez1 = *this ;
|
||||
crvBez1.TrimEndAtParam( 0.5) ;
|
||||
double dCordLen1 = Dist( crvBez1.m_vPtCtrl[0], crvBez1.m_vPtCtrl[m_nDeg]) ;
|
||||
double dCtrlLen1 ; crvBez1.GetControlPolygonLength( dCtrlLen1) ;
|
||||
CurveBezier crvBez2 = *this ;
|
||||
crvBez2.TrimStartAtParam( 0.5) ;
|
||||
double dCordLen2 = Dist( crvBez2.m_vPtCtrl[0], crvBez2.m_vPtCtrl[m_nDeg]) ;
|
||||
double dCtrlLen2 ; crvBez2.GetControlPolygonLength( dCtrlLen2) ;
|
||||
// applico la formula di Gravesen (Graphics Gems V)
|
||||
dLen = ( 2 * ( dCordLen1 + dCordLen2) + ( m_nDeg - 1) * ( dCtrlLen1 + dCtrlLen2)) / ( m_nDeg + 1) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::GetLength( double& dLen) const
|
||||
@@ -1016,18 +1048,18 @@ CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2,
|
||||
double dUMid ;
|
||||
Point3d ptMid ;
|
||||
|
||||
// prima metà
|
||||
// prima metà
|
||||
dUMid = 0.5 * ( dU0 + dU1) ;
|
||||
GetPointD1D2( dUMid, ptMid) ;
|
||||
double dD3 = GetSegmentLength( nLev +1, dU0, dUMid, dU1,
|
||||
ptP0, ptMid, ptP1) ;
|
||||
// seconda metà
|
||||
// seconda metà
|
||||
dUMid = 0.5 * ( dU1 + dU2) ;
|
||||
GetPointD1D2( dUMid, ptMid) ;
|
||||
double dD4 = GetSegmentLength( nLev + 1, dU1, dUMid, dU2,
|
||||
ptP1, ptMid, ptP2) ;
|
||||
|
||||
// la lunghezza è la somma delle due
|
||||
// la lunghezza è la somma delle due
|
||||
return ( dD3 + dD4) ;
|
||||
}
|
||||
|
||||
@@ -1191,6 +1223,31 @@ CurveBezier::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) co
|
||||
return GetLengthAtParam( dU, dLen) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::ApproxWithLines( int nStep, PolyLine& PL) const
|
||||
{
|
||||
// pulisco la polilinea
|
||||
PL.Clear() ;
|
||||
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// calcolo i punti richiesti
|
||||
double dStep = 1.0 / nStep ;
|
||||
for ( int i = 0 ; i <= nStep ; ++ i) {
|
||||
double dU = i * dStep ;
|
||||
Point3d ptPos ;
|
||||
if ( GetPointD1D2( dU, ptPos))
|
||||
PL.AddUPoint( dU, ptPos) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const
|
||||
@@ -1221,7 +1278,7 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly
|
||||
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
|
||||
if ( ! PL.ApproxOnSide( vtExtr, ( nType == APL_LEFT), dLinTol))
|
||||
return false ;
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
|
||||
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
|
||||
return false ;
|
||||
@@ -1237,7 +1294,7 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly
|
||||
if ( ! FlatOrSplit( 0, *this, 0, 1, dLinTol, dAngTolDeg, PL))
|
||||
return false ;
|
||||
|
||||
// se è stato inserito un solo punto, aggiungo il finale
|
||||
// se è stato inserito un solo punto, aggiungo il finale
|
||||
if ( PL.GetPointNbr() == 1)
|
||||
return PL.AddUPoint( 1, m_vPtCtrl[m_nDeg]) ;
|
||||
// altrimenti, se l'ultimo punto non coincide con il finale lo sostituisco (distano al max di dLinTol)
|
||||
@@ -1308,19 +1365,19 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
|
||||
double dParDiv ;
|
||||
double dParMid ;
|
||||
CurveBezier crvBez1 ;
|
||||
// se prima suddivisione e c'è singolarità, divido su questa
|
||||
// se prima suddivisione e c'è singolarità, divido su questa
|
||||
if ( nLev == 0 && GetSingularParam( dParDiv) > 0)
|
||||
;
|
||||
// altrimenti divido a metà
|
||||
// altrimenti divido a metà
|
||||
else
|
||||
dParDiv = 0.5 ;
|
||||
dParMid = dParDiv * ( dParStart + dParEnd) ;
|
||||
// prima metà
|
||||
// prima metà
|
||||
crvBez1 = crvBez ;
|
||||
crvBez1.TrimEndAtParam( dParDiv) ;
|
||||
if ( ! FlatOrSplit( nLev + 1, crvBez1, dParStart, dParMid, dLinTol, dAngTolDeg, PL))
|
||||
return false ;
|
||||
// seconda metà
|
||||
// seconda metà
|
||||
crvBez1 = crvBez ;
|
||||
crvBez1.TrimStartAtParam( dParDiv) ;
|
||||
if ( ! FlatOrSplit( nLev + 1, crvBez1, dParMid, dParEnd, dLinTol, dAngTolDeg, PL))
|
||||
@@ -1351,7 +1408,7 @@ CurveBezier::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) con
|
||||
PA.ToGlob( frExtr) ;
|
||||
return bOk ;
|
||||
}
|
||||
// l'estrusione è secondo Z+, pertanto sono già nel piano XY
|
||||
// l'estrusione è secondo Z+, pertanto sono già nel piano XY
|
||||
else
|
||||
return ApproxWithArcsXY( dLinTol, dAngTolDeg, PA) ;
|
||||
}
|
||||
@@ -1386,7 +1443,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
double dMaxDist ;
|
||||
|
||||
// se la polilinea ha più di 2 punti
|
||||
// se la polilinea ha più di 2 punti
|
||||
if ( PL.GetPointNbr() > 2) {
|
||||
// calcolo punti e direzioni agli estremi della polilinea usando la curva di Bezier
|
||||
double dU ;
|
||||
@@ -1404,7 +1461,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
}
|
||||
// se la polilinea è formata da 2 punti
|
||||
// se la polilinea è formata da 2 punti
|
||||
else if ( PL.GetPointNbr() == 2) {
|
||||
// se molto vicini, esco
|
||||
double dLen ;
|
||||
@@ -1463,10 +1520,10 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
|
||||
// spezzo l'intervallo in due parti
|
||||
double dParMid ;
|
||||
// se prima suddivisione e c'è singolarità, divido su questa
|
||||
// se prima suddivisione e c'è singolarità, divido su questa
|
||||
if ( nLev == 0 && GetSingularParam( dParMid) > 0)
|
||||
;
|
||||
// altrimenti divido a metà
|
||||
// altrimenti divido a metà
|
||||
else {
|
||||
double dParStart, dParEnd ;
|
||||
if ( ! PL.GetFirstU( dParStart) || ! PL.GetLastU( dParEnd))
|
||||
@@ -1476,10 +1533,10 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
PolyLine PL2 ;
|
||||
if ( ! PL.Split( dParMid, PL2))
|
||||
return false ;
|
||||
// prima metà
|
||||
// prima metà
|
||||
if ( ! BiArcOrSplit( nLev + 1, PL, dLinTol, dAngTolDeg, PA))
|
||||
return false ;
|
||||
// seconda metà
|
||||
// seconda metà
|
||||
return BiArcOrSplit( nLev + 1, PL2, dLinTol, dAngTolDeg, PA) ;
|
||||
}
|
||||
|
||||
@@ -1493,7 +1550,7 @@ CurveBezier::CopyParamRange( double dUStart, double dUEnd) const
|
||||
return nullptr ;
|
||||
// se il parametro start supera quello di end
|
||||
if ( dUStart > dUEnd - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunché
|
||||
if ( ! IsClosed())
|
||||
return nullptr ;
|
||||
// se curva chiusa, il trim si avvolge attorno al punto di giunzione
|
||||
@@ -1575,24 +1632,14 @@ CurveBezier::TrimStartAtParam( double dUTrim)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// se devo togliere dall'inizio o prima non tolgo niente
|
||||
if ( dUTrim <= 0)
|
||||
return true ;
|
||||
// se devo togliere a partire dalla fine o dopo non rimane niente
|
||||
if ( dUTrim >= 1)
|
||||
return false ;
|
||||
// eseguo il trim (algoritmo di de Casteljau)
|
||||
for ( int k = 1 ; k <= m_nDeg ; k ++) {
|
||||
for ( int i = 0 ; i <= m_nDeg - k ; i ++) {
|
||||
if ( ! m_bRat) {
|
||||
m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i] + dUTrim * m_vPtCtrl[i+1] ;
|
||||
}
|
||||
else {
|
||||
m_vPtCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i] * m_vPtCtrl[i] + dUTrim * m_vWeCtrl[i+1] * m_vPtCtrl[i+1] ;
|
||||
m_vWeCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i] + dUTrim * m_vWeCtrl[i+1] ;
|
||||
m_vPtCtrl[i] = m_vPtCtrl[i] * ( 1 / m_vWeCtrl[i]) ;
|
||||
}
|
||||
}
|
||||
if ( ! m_bRat) {
|
||||
if ( ! deCastTrimStart( dUTrim, m_nDeg, m_vPtCtrl))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
if ( ! deCastRatTrimStart( dUTrim, m_nDeg, m_vPtCtrl, m_vWeCtrl))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata
|
||||
@@ -1609,24 +1656,14 @@ CurveBezier::TrimEndAtParam( double dUTrim)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// se devo togliere a partire dall'inizio o prima non rimane niente
|
||||
if ( dUTrim < EPS_PARAM)
|
||||
return false ;
|
||||
// se devo togliere dalla fine o dopo non tolgo niente
|
||||
if ( dUTrim > 1 - EPS_PARAM)
|
||||
return true ;
|
||||
// eseguo il trim (algoritmo di de Casteljau)
|
||||
for ( int k = 1 ; k <= m_nDeg ; k ++) {
|
||||
for ( int i = m_nDeg ; i >= k ; i --) {
|
||||
if ( ! m_bRat) {
|
||||
m_vPtCtrl[i] = ( 1 - dUTrim) * m_vPtCtrl[i-1] + dUTrim * m_vPtCtrl[ i] ;
|
||||
}
|
||||
else {
|
||||
m_vPtCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i-1] * m_vPtCtrl[i-1] + dUTrim * m_vWeCtrl[ i] * m_vPtCtrl[ i] ;
|
||||
m_vWeCtrl[i] = ( 1 - dUTrim) * m_vWeCtrl[i-1] + dUTrim * m_vWeCtrl[ i] ;
|
||||
m_vPtCtrl[i] = m_vPtCtrl[i] * ( 1 / m_vWeCtrl[i]) ;
|
||||
}
|
||||
}
|
||||
if ( ! m_bRat) {
|
||||
if ( ! deCastTrimEnd( dUTrim, m_nDeg, m_vPtCtrl))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
if ( ! deCastRatTrimEnd( dUTrim, m_nDeg, m_vPtCtrl, m_vWeCtrl))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata
|
||||
@@ -1808,7 +1845,7 @@ CurveBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng,
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -1879,7 +1916,7 @@ CurveBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -1903,7 +1940,7 @@ CurveBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d&
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei parametri
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -1932,7 +1969,7 @@ CurveBezier::ToGlob( const Frame3d& frRef)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
@@ -1956,7 +1993,7 @@ CurveBezier::ToLoc( const Frame3d& frRef)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
@@ -1980,7 +2017,7 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
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 ;
|
||||
|
||||
|
||||
@@ -155,6 +155,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
{ if ( ! CopyFrom( cbSrc))
|
||||
LOG_ERROR( GetEGkLogger(), "CurveBezier : copy error")
|
||||
return *this ; }
|
||||
bool ApproxWithLines( int nStep, PolyLine& PL) const ;
|
||||
bool GetApproxLength( double& dLen) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveBezier& cbSrc) ;
|
||||
|
||||
@@ -173,7 +173,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>Full</Optimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;I_AM_EGK;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@@ -220,7 +220,7 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>Full</Optimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;I_AM_EGK;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@@ -283,6 +283,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CurveByApprox.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||
<ClInclude Include="deCasteljau.h" />
|
||||
<ClCompile Include="DistPointSurfTm.cpp" />
|
||||
<ClCompile Include="DistPointTria.cpp" />
|
||||
<ClCompile Include="ExtDimension.cpp" />
|
||||
|
||||
@@ -414,6 +414,9 @@
|
||||
<ClCompile Include="SurfBezier.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="deCasteljau.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
|
||||
@@ -74,6 +74,44 @@ StmFromTriangleSoup::AddTriangle( const Triangle3d& Tria)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::AddTriangle( const Point3d& ptP0, const Point3d& ptP1, const Point3d& ptP2)
|
||||
{
|
||||
// verifico inizializzazione
|
||||
if ( m_pSTM == nullptr)
|
||||
return false ;
|
||||
// ciclo sui tre vertici
|
||||
int nIdV[3] ;
|
||||
if ( ( nIdV[0] = AddVertex( ptP0)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[1] = AddVertex( ptP1)) == SVT_NULL)
|
||||
return false ;
|
||||
if ( ( nIdV[2] = AddVertex( ptP2)) == SVT_NULL)
|
||||
return false ;
|
||||
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||
if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) {
|
||||
if ( m_pSTM->AddTriangle( nIdV) == SVT_NULL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
StmFromTriangleSoup::AddVertex( const Point3d& ptP)
|
||||
{
|
||||
// verifico se già presente
|
||||
int nId ;
|
||||
if ( m_VertGrid.Find( ptP, 2 * EPS_SMALL, nId))
|
||||
return nId ;
|
||||
// aggiungo il vertice
|
||||
if ( ( nId = m_pSTM->AddVertex( ptP)) == SVT_NULL)
|
||||
return SVT_NULL ;
|
||||
m_VertGrid.InsertPoint( ptP, nId) ;
|
||||
return nId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
StmFromTriangleSoup::End( void)
|
||||
|
||||
+313
-75
@@ -18,9 +18,13 @@
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "Bernstein.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -29,7 +33,7 @@ GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfBezier::SurfBezier(void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_bRat( false), m_nTempProp( 0)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_bRat( false), m_bTrimmed( false), m_nTempProp( 0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,6 +56,7 @@ SurfBezier::Init( int nDegU, int nDegV, bool bIsRational)
|
||||
m_nDegU = nDegU ;
|
||||
m_nDegV = nDegV ;
|
||||
m_bRat = bIsRational ;
|
||||
m_bTrimmed = false ;
|
||||
|
||||
// dimensiono i vettori dei punti e dei pesi
|
||||
m_vPtCtrl.assign( GetDim(), ORIG) ;
|
||||
@@ -115,7 +120,7 @@ SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat) const
|
||||
SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat, bool& bTrimmed) const
|
||||
{
|
||||
// verifico validità superficie
|
||||
if ( m_nStatus != OK)
|
||||
@@ -124,6 +129,7 @@ SurfBezier::GetInfo( int& nDegU, int& nDegV, bool& bIsRat) const
|
||||
nDegU = m_nDegU ;
|
||||
nDegV = m_nDegV ;
|
||||
bIsRat = m_bRat ;
|
||||
bTrimmed = m_bTrimmed ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -535,6 +541,8 @@ SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
sOut += "Area=" + ToString( GetAreaInUiUnits( dArea, bMM),1) + szNewLine ;
|
||||
// parametri : flag razionale
|
||||
sOut += ( m_bRat ? "Rat " : "Int ") ;
|
||||
// flag trimmata
|
||||
sOut += ( m_bTrimmed ? "Trim " : "Full ") ;
|
||||
// gradi in U e V
|
||||
sOut += "DegU=" + ToString( m_nDegU) + " DegV=" + ToString( m_nDegV) + szNewLine ;
|
||||
// ciclo sui punti di controllo ( con pesi se razionale)
|
||||
@@ -562,6 +570,9 @@ SurfBezier::Save( NgeWriter& ngeOut) const
|
||||
// flag razionale
|
||||
if ( ! ngeOut.WriteBool( m_bRat, ";"))
|
||||
return false ;
|
||||
// flag trimmata
|
||||
if ( ! ngeOut.WriteBool( m_bTrimmed, ";"))
|
||||
return false ;
|
||||
// gradi
|
||||
if ( ! ngeOut.WriteInt( m_nDegU, ",") ||
|
||||
! ngeOut.WriteInt( m_nDegV, ";", true))
|
||||
@@ -593,6 +604,10 @@ SurfBezier::Load( NgeReader& ngeIn)
|
||||
bool bIsRat ;
|
||||
if ( ! ngeIn.ReadBool( bIsRat, ";"))
|
||||
return false ;
|
||||
// recupero il flag trimmata
|
||||
bool bTrimmed ;
|
||||
if ( ! ngeIn.ReadBool( bTrimmed, ";"))
|
||||
return false ;
|
||||
// recupero i gradi
|
||||
int nDegU, nDegV ;
|
||||
if ( ! ngeIn.ReadInt( nDegU, ",") ||
|
||||
@@ -647,20 +662,45 @@ SurfBezier::Validate( void)
|
||||
bool
|
||||
SurfBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
{
|
||||
// assegno il box in locale
|
||||
if ( ! GetAuxSurf())
|
||||
return false ;
|
||||
return m_pSTM->GetLocalBBox( b3Loc, nFlag) ;
|
||||
// basta approssimato
|
||||
if ( ( nFlag & BBF_EXACT) == 0) {
|
||||
for ( int i = 0 ; i < GetDim() ; ++ i) {
|
||||
Point3d ptTemp = m_vPtCtrl[i] ;
|
||||
b3Loc.Add( ptTemp) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// deve essere preciso
|
||||
else {
|
||||
// verifico esistenza trimesh associata
|
||||
if ( ! GetAuxSurf())
|
||||
return false ;
|
||||
// calcolo il box della trimesh
|
||||
return m_pSTM->GetLocalBBox( b3Loc, nFlag) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
{
|
||||
// assegno il box nel riferimento
|
||||
if ( ! GetAuxSurf())
|
||||
return false ;
|
||||
return m_pSTM->GetBBox( frRef, b3Ref, nFlag) ;
|
||||
// basta approssimato
|
||||
if ( ( nFlag & BBF_EXACT) == 0) {
|
||||
for ( int i = 0 ; i < GetDim() ; ++ i) {
|
||||
Point3d ptTemp = m_vPtCtrl[i] ;
|
||||
ptTemp.ToGlob( frRef) ;
|
||||
b3Ref.Add( ptTemp) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// deve essere preciso
|
||||
else {
|
||||
// verifico esistenza trimesh associata
|
||||
if ( ! GetAuxSurf())
|
||||
return false ;
|
||||
// calcolo il box della trimesh
|
||||
return m_pSTM->GetBBox( frRef, b3Ref, nFlag) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -898,6 +938,202 @@ SurfBezier::Invert( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfBezier::GetSteps( int nDeg, double dLen, int nQuality) const
|
||||
{
|
||||
const double dCoeff[] = { 0, 1, 2, 2.4, 2.8, 3, 3, 3, 3, 3, 3, 3} ;
|
||||
nDeg = Clamp( nDeg, 0, MAXDEG) ;
|
||||
nQuality = Clamp( nQuality, 1, 3) ;
|
||||
double dMult = sqrt( max( dLen, 10.)) ;
|
||||
return int( nQuality * dMult * dCoeff[nDeg]) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveBezier*
|
||||
SurfBezier::GetCurveOnU( double dV) const
|
||||
{
|
||||
// controlli
|
||||
if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dV = Clamp( dV, 0., 1.) ;
|
||||
|
||||
// se forma polinomiale (o integrale)
|
||||
if ( ! m_bRat) {
|
||||
// preparazione della curva di Bezier
|
||||
PtrOwner<CurveBezier> pCbz( CreateBasicCurveBezier()) ;
|
||||
if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, false))
|
||||
return nullptr ;
|
||||
// calcolo dei polinomi di Bernstein per V di grado opportuno
|
||||
DBLVECTOR vBernV( m_nDegV + 1) ;
|
||||
GetAllBernstein( dV, m_nDegV, vBernV) ;
|
||||
// calcolo dei punti di controllo della curva
|
||||
for ( int i = 0 ; i <= m_nDegU ; ++ i) {
|
||||
Point3d ptP = ORIG ;
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j)
|
||||
ptP += vBernV[j] * m_vPtCtrl[GetInd( i, j)] ;
|
||||
pCbz->SetControlPoint( i, ptP) ;
|
||||
}
|
||||
return Release( pCbz) ;
|
||||
}
|
||||
// altrimenti forma razionale
|
||||
else {
|
||||
// preparazione della curva di Bezier
|
||||
PtrOwner<CurveBezier> pCbz( CreateBasicCurveBezier()) ;
|
||||
if ( IsNull( pCbz) || ! pCbz->Init( m_nDegU, true))
|
||||
return nullptr ;
|
||||
// calcolo dei polinomi di Bernstein per V di grado opportuno
|
||||
DBLVECTOR vBernV( m_nDegV + 1) ;
|
||||
GetAllBernstein( dV, m_nDegV, vBernV) ;
|
||||
// calcolo dei punti di controllo della curva
|
||||
PNTVECTOR vPtWCtrl( GetDim()) ;
|
||||
for ( int i = 0 ; i < GetDim() ; ++ i)
|
||||
vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ;
|
||||
for ( int i = 0 ; i <= m_nDegU ; ++ i) {
|
||||
Point3d ptP = ORIG ;
|
||||
double dW = 0 ;
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
|
||||
ptP += vBernV[j] * vPtWCtrl[GetInd( i, j)] ;
|
||||
dW += vBernV[j] * m_vWeCtrl[GetInd( i, j)] ;
|
||||
}
|
||||
double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ;
|
||||
pCbz->SetControlPoint( i, ptP * dInvW, dW) ;
|
||||
}
|
||||
return Release( pCbz) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveBezier*
|
||||
SurfBezier::GetCurveOnV( double dU) const
|
||||
{
|
||||
// controlli
|
||||
if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
|
||||
// se forma polinomiale (o integrale)
|
||||
if ( ! m_bRat) {
|
||||
// preparazione della curva di Bezier
|
||||
PtrOwner<CurveBezier> pCbz( CreateBasicCurveBezier()) ;
|
||||
if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, false))
|
||||
return nullptr ;
|
||||
// calcolo dei polinomi di Bernstein per U di grado opportuno
|
||||
DBLVECTOR vBernU( m_nDegU + 1) ;
|
||||
GetAllBernstein( dU, m_nDegU, vBernU) ;
|
||||
// calcolo dei punti di controllo della curva
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
|
||||
Point3d ptP = ORIG ;
|
||||
for ( int i = 0 ; i <= m_nDegU ; ++ i)
|
||||
ptP += vBernU[i] * m_vPtCtrl[GetInd( i, j)] ;
|
||||
pCbz->SetControlPoint( j, ptP) ;
|
||||
}
|
||||
return Release( pCbz) ;
|
||||
}
|
||||
// altrimenti forma razionale
|
||||
else {
|
||||
// preparazione della curva di Bezier
|
||||
PtrOwner<CurveBezier> pCbz( CreateBasicCurveBezier()) ;
|
||||
if ( IsNull( pCbz) || ! pCbz->Init( m_nDegV, true))
|
||||
return nullptr ;
|
||||
// calcolo dei polinomi di Bernstein per U di grado opportuno
|
||||
DBLVECTOR vBernU( m_nDegU + 1) ;
|
||||
GetAllBernstein( dU, m_nDegU, vBernU) ;
|
||||
// calcolo dei punti di controllo della curva
|
||||
PNTVECTOR vPtWCtrl( GetDim()) ;
|
||||
for ( int i = 0 ; i < GetDim() ; ++ i)
|
||||
vPtWCtrl[i] = m_vWeCtrl[i] * m_vPtCtrl[i] ;
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j) {
|
||||
Point3d ptP = ORIG ;
|
||||
double dW = 0 ;
|
||||
for ( int i = 0 ; i <= m_nDegU ; ++ i) {
|
||||
ptP += vBernU[i] * vPtWCtrl[GetInd( i, j)] ;
|
||||
dW += vBernU[i] * m_vWeCtrl[GetInd( i, j)] ;
|
||||
}
|
||||
double dInvW = 1 / ( ( dW > EPS_ZERO) ? dW : EPS_ZERO) ;
|
||||
pCbz->SetControlPoint( j, ptP * dInvW, dW) ;
|
||||
}
|
||||
return Release( pCbz) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
SurfBezier::GetLoop( int nLoop) const
|
||||
{
|
||||
// Se superficie completa, basta concatenare le 4 isoparametriche di bordo
|
||||
if ( ! m_bTrimmed) {
|
||||
// Esiste solo il loop esterno
|
||||
if ( nLoop |= 0)
|
||||
return nullptr ;
|
||||
// Loop
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
// prima curva U=0
|
||||
PtrOwner<CurveBezier> pCbzU0( GetCurveOnU( 0)) ;
|
||||
if ( ! IsNull( pCbzU0) && ! pCbzU0->IsAPoint())
|
||||
pLoop->AddCurve( Release( pCbzU0)) ;
|
||||
// seconda curva V=1
|
||||
PtrOwner<CurveBezier> pCbzV1( GetCurveOnV( 1)) ;
|
||||
if ( ! IsNull( pCbzV1) && ! pCbzV1->IsAPoint())
|
||||
pLoop->AddCurve( Release( pCbzV1)) ;
|
||||
// terza curva U=1 invertita
|
||||
PtrOwner<CurveBezier> pCbzU1( GetCurveOnU( 1)) ;
|
||||
if ( ! IsNull( pCbzU1) && ! pCbzU1->IsAPoint()) {
|
||||
pCbzU1->Invert() ;
|
||||
pLoop->AddCurve( Release( pCbzU1)) ;
|
||||
}
|
||||
// quarta curva V=0 invertita
|
||||
PtrOwner<CurveBezier> pCbzV0( GetCurveOnV( 0)) ;
|
||||
if ( ! IsNull( pCbzV0) && ! pCbzV0->IsAPoint()) {
|
||||
pCbzV0->Invert() ;
|
||||
pLoop->AddCurve( Release( pCbzV0)) ;
|
||||
}
|
||||
// se loop chiuso lo restituisco, altrimenti errore
|
||||
return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ;
|
||||
}
|
||||
// altrimenti trimmata, per ora non gestita
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetCurveOnU( double dV, int nStep, PolyLine& plCrvU) const
|
||||
{
|
||||
plCrvU.Clear() ;
|
||||
if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dV = Clamp( dV, 0., 1.) ;
|
||||
PtrOwner<CurveBezier> pCbz( GetCurveOnU( dV)) ;
|
||||
if ( IsNull( pCbz))
|
||||
return false ;
|
||||
if ( nStep <= 0) {
|
||||
double dLenU = 0 ;
|
||||
pCbz->GetApproxLength( dLenU) ;
|
||||
nStep = GetSteps( m_nDegU, dLenU, 2) ;
|
||||
}
|
||||
return pCbz->ApproxWithLines( nStep, plCrvU) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetCurveOnV( double dU, int nStep, PolyLine& plCrvV) const
|
||||
{
|
||||
plCrvV.Clear() ;
|
||||
if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
PtrOwner<CurveBezier> pCbz( GetCurveOnV( dU)) ;
|
||||
if ( IsNull( pCbz))
|
||||
return false ;
|
||||
if ( nStep <= 0) {
|
||||
double dLenV = 0 ;
|
||||
pCbz->GetApproxLength( dLenV) ;
|
||||
nStep = GetSteps( m_nDegV, dLenV, 2) ;
|
||||
}
|
||||
return pCbz->ApproxWithLines( nStep, plCrvV) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const
|
||||
@@ -918,54 +1154,32 @@ SurfBezier::GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const
|
||||
plCtrlV.Clear() ;
|
||||
if ( nIndU < 0 || nIndU > m_nDegU)
|
||||
return false ;
|
||||
for ( int i = 0 ; i <= m_nDegV ; ++ i)
|
||||
plCtrlV.AddUPoint( double( i) / m_nDegV, m_vPtCtrl[GetInd( nIndU, i)]) ;
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j)
|
||||
plCtrlV.AddUPoint( double( j) / m_nDegV, m_vPtCtrl[GetInd( nIndU, j)]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetCurveOnU( double dV, PolyLine& plCtrlU) const
|
||||
double
|
||||
SurfBezier::GetCurveOnUApproxLen( double dV) const
|
||||
{
|
||||
plCtrlU.Clear() ;
|
||||
if ( dV < - EPS_PARAM || dV > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dV = Clamp( dV, 0., 1.) ;
|
||||
int nStepU = 20 * m_nDegU ;
|
||||
double dStepU = 1.0 / nStepU ;
|
||||
for ( int i = 0 ; i <= nStepU ; ++ i) {
|
||||
double dU = i * dStepU ;
|
||||
Point3d ptPos ;
|
||||
if ( GetPointD1D2( dU, dV, ptPos))
|
||||
plCtrlU.AddUPoint( dU, ptPos) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
PtrOwner<CurveBezier> pCbz( GetCurveOnU( dV)) ;
|
||||
double dLen ;
|
||||
if ( IsNull( pCbz) || ! pCbz->GetApproxLength( dLen))
|
||||
return 0 ;
|
||||
return dLen ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetCurveOnV( double dU, PolyLine& plCtrlV) const
|
||||
double
|
||||
SurfBezier::GetCurveOnVApproxLen( double dU) const
|
||||
{
|
||||
plCtrlV.Clear() ;
|
||||
if ( dU < - EPS_PARAM || dU > 1 + EPS_PARAM)
|
||||
return false ;
|
||||
dU = Clamp( dU, 0., 1.) ;
|
||||
int nStepV = 20 * m_nDegV ;
|
||||
double dStepV = 1.0 / nStepV ;
|
||||
for ( int j = 0 ; j <= nStepV ; ++ j) {
|
||||
double dV = j * dStepV ;
|
||||
Point3d ptPos ;
|
||||
if ( GetPointD1D2( dU, dV, ptPos))
|
||||
plCtrlV.AddUPoint( dV, ptPos) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
PtrOwner<CurveBezier> pCbz( GetCurveOnV( dU)) ;
|
||||
double dLen ;
|
||||
if ( IsNull( pCbz) || ! pCbz->GetApproxLength( dLen))
|
||||
return 0 ;
|
||||
return dLen ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -980,41 +1194,65 @@ SurfBezier::GetAuxSurf( void) const
|
||||
// se già calcolata, la restituisco
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM ;
|
||||
// la creo
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM))
|
||||
return nullptr ;
|
||||
// prima isoparametrica
|
||||
// costruttore della superficie
|
||||
StmFromTriangleSoup stmSoup ;
|
||||
stmSoup.Start() ;
|
||||
// definisco il numero degli step in U e in V
|
||||
double dMaxLenU = 0 ;
|
||||
for ( int j = 0 ; j <= m_nDegV ; ++ j)
|
||||
dMaxLenU = max( dMaxLenU, GetCurveOnUApproxLen( double( j) / m_nDegV)) ;
|
||||
int nStepU = GetSteps( m_nDegU, dMaxLenU, 2) ;
|
||||
double dMaxLenV = 0 ;
|
||||
for ( int i = 0 ; i <= m_nDegU ; ++ i)
|
||||
dMaxLenV = max( dMaxLenV, GetCurveOnVApproxLen( double( i) / m_nDegU)) ;
|
||||
int nStepV = GetSteps( m_nDegV, dMaxLenV, 2) ;
|
||||
// prima curva isoparametrica (potrebbe essere un solo punto)
|
||||
PolyLine PL1 ;
|
||||
GetCurveOnU( 0, PL1) ;
|
||||
GetCurveOnU( 0, nStepU, PL1) ;
|
||||
bool bSingle1 = ( PL1.GetPointNbr() == 1) ;
|
||||
// ciclo sulle isoparametriche
|
||||
int nStrip = 20 * m_nDegV ;
|
||||
for ( int i = 1 ; i <= nStrip ; ++ i) {
|
||||
// altra isoparametrica
|
||||
for ( int i = 1 ; i <= nStepV ; ++ i) {
|
||||
// seconda curva isoparametrica (con tanti punti quanti la prima, oppure uno solo)
|
||||
double dV = double( i) / nStepV ;
|
||||
PolyLine PL2 ;
|
||||
GetCurveOnU( double( i) / nStrip, PL2) ;
|
||||
// creo la trimesh tra le due isoparametriche
|
||||
PtrOwner<SurfTriMesh> pSt12( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSt12))
|
||||
return nullptr ;
|
||||
if ( PL1.GetPointNbr() == 1) {
|
||||
Point3d ptP ; PL1.GetFirstPoint( ptP) ;
|
||||
pSt12->CreateByPointCurve( ptP, PL2) ;
|
||||
pSt12->Invert() ;
|
||||
GetCurveOnU( dV, nStepU, PL2) ;
|
||||
bool bSingle2 = ( PL2.GetPointNbr() == 1) ;
|
||||
// inserisco i triangoli della striscia nel costruttore della TriMesh
|
||||
Point3d ptP1c, ptP2c ;
|
||||
Point3d ptP1n, ptP2n ;
|
||||
bool bNext = PL1.GetFirstPoint( ptP1c) && PL2.GetFirstPoint( ptP2c) ;
|
||||
if ( bNext) {
|
||||
if ( bSingle1 && bSingle2)
|
||||
bNext = false ;
|
||||
if ( bSingle1)
|
||||
ptP1n = ptP1c ;
|
||||
else
|
||||
bNext = bNext && PL1.GetNextPoint( ptP1n) ;
|
||||
if ( bSingle2)
|
||||
ptP2n = ptP2c ;
|
||||
else
|
||||
bNext = bNext && PL2.GetNextPoint( ptP2n) ;
|
||||
}
|
||||
else if ( PL2.GetPointNbr() == 1) {
|
||||
Point3d ptP ; PL2.GetFirstPoint( ptP) ;
|
||||
pSt12->CreateByPointCurve( ptP, PL1) ;
|
||||
while ( bNext) {
|
||||
// eventuale primo triangolo (con base sui correnti e vertice su P2 successivo)
|
||||
if ( ! AreSamePointApprox( ptP1c, ptP2c))
|
||||
stmSoup.AddTriangle( ptP2c, ptP1c, ptP2n) ;
|
||||
// eventuale secondo triangolo (con vertice su P1 corrente e base sui successivi)
|
||||
if ( ! AreSamePointApprox( ptP1n, ptP2n))
|
||||
stmSoup.AddTriangle( ptP1c, ptP1n, ptP2n) ;
|
||||
// passo alla successiva coppia
|
||||
ptP1c = ptP1n ;
|
||||
ptP2c = ptP2n ;
|
||||
bNext = ( bSingle1 || PL1.GetNextPoint( ptP1n)) && ( bSingle2 || PL2.GetNextPoint( ptP2n)) ;
|
||||
}
|
||||
else
|
||||
pSt12->CreateByTwoCurves( PL1, PL2, ISurfTriMesh::RLT_ISOPAR) ;
|
||||
// inserisco questa trimesh in quella complessiva
|
||||
pSTM->DoSewing( *pSt12) ;
|
||||
// salvo isoparametrica PL2 in PL1
|
||||
PL1.GetUPointList().swap( PL2.GetUPointList()) ;
|
||||
bSingle1 = bSingle2 ;
|
||||
}
|
||||
// la salvo
|
||||
m_pSTM = Release( pSTM) ;
|
||||
// la completo
|
||||
stmSoup.End() ;
|
||||
// la salvo
|
||||
m_pSTM = GetBasicSurfTriMesh( stmSoup.GetSurf()) ;
|
||||
return m_pSTM ;
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -16,6 +16,7 @@
|
||||
#include "ObjGraphicsMgr.h"
|
||||
#include "DllMain.h"
|
||||
#include "GeoObjRW.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
@@ -79,7 +80,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
bool SetControlPoint( int nIndU, int nIndV, const Point3d& ptCtrl, double dW) override
|
||||
{ return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl, dW) ; }
|
||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
|
||||
bool GetInfo( int& nDegU, int& nDegV, bool& bIsRat) const override ;
|
||||
bool GetInfo( int& nDegU, int& nDegV, bool& bIsRat, bool& bTrimmed) const override ;
|
||||
const Point3d& GetControlPoint( int nIndU, int nIndV, bool* pbOk) const override
|
||||
{ return GetControlPoint( GetInd( nIndU, nIndV), pbOk) ; }
|
||||
const Point3d& GetControlPoint( int nInd, bool* pbOk) const override ;
|
||||
@@ -93,10 +94,11 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
bool GetPointNrmD1D2( double dU, double dV, Point3d& ptPos, Vector3d& vtN,
|
||||
Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr,
|
||||
Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ;
|
||||
CurveBezier* GetCurveOnU( double dV) const override ;
|
||||
CurveBezier* GetCurveOnV( double dU) const override ;
|
||||
ICurve* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni)
|
||||
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
|
||||
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
||||
bool GetCurveOnU( double dV, PolyLine& plCtrlU) const override ;
|
||||
bool GetCurveOnV( double dU, PolyLine& plCtrlV) const override ;
|
||||
const ISurfTriMesh* GetAuxSurf( void) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
@@ -116,6 +118,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
enum ParDir { ON_U = 1, ON_V = 2} ;
|
||||
static const int MAXDEG = 11 ;
|
||||
|
||||
private :
|
||||
@@ -130,6 +133,11 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
int GetDim( void) const
|
||||
{ return ( m_nDegU + 1) * ( m_nDegV + 1) ; }
|
||||
void ResetAuxSurf( void) const ;
|
||||
int GetSteps( int nDeg, double dLen, int nQuality) const ;
|
||||
bool GetCurveOnU( double dV, int nStep, PolyLine& plCrvU) const ;
|
||||
bool GetCurveOnV( double dU, int nStep, PolyLine& plCrvV) const ;
|
||||
double GetCurveOnUApproxLen( double dV) const ;
|
||||
double GetCurveOnVApproxLen( double dU) const ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
@@ -138,6 +146,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
int m_nDegU ; // grado in U
|
||||
int m_nDegV ; // grado in V
|
||||
bool m_bRat ; // flag di razionale/polinomiale
|
||||
bool m_bTrimmed ; // flag per presenza regione di trim
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : deCasteljau.h Data : 29.03.20 Versione : 2.2c3
|
||||
// Contenuto : Applicazioni dell'algoritmo di de Casteljau.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 29.03.20 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
deCastTrimStart( double dPar, int nDeg, PNTVECTOR& vPtCtrl)
|
||||
{
|
||||
if ( dPar < EPS_PARAM)
|
||||
return true ;
|
||||
if ( dPar > 1 - EPS_PARAM)
|
||||
return false ;
|
||||
for ( int k = 1 ; k <= nDeg ; ++ k) {
|
||||
for ( int i = 0 ; i <= nDeg - k ; ++ i) {
|
||||
vPtCtrl[i] = ( 1 - dPar) * vPtCtrl[i] + dPar * vPtCtrl[i+1] ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
deCastRatTrimStart( double dPar, int nDeg, PNTVECTOR& vPtCtrl, DBLVECTOR& vWeCtrl)
|
||||
{
|
||||
if ( dPar < EPS_PARAM)
|
||||
return true ;
|
||||
if ( dPar > 1 - EPS_PARAM)
|
||||
return false ;
|
||||
for ( int k = 1 ; k <= nDeg ; ++ k) {
|
||||
for ( int i = 0 ; i <= nDeg - k ; ++ i) {
|
||||
vPtCtrl[i] = ( 1 - dPar) * vWeCtrl[i] * vPtCtrl[i] + dPar * vWeCtrl[i+1] * vPtCtrl[i+1] ;
|
||||
vWeCtrl[i] = ( 1 - dPar) * vWeCtrl[i] + dPar * vWeCtrl[i+1] ;
|
||||
vPtCtrl[i] = vPtCtrl[i] * ( 1 / vWeCtrl[i]) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
deCastTrimEnd( double dPar, int nDeg, PNTVECTOR& vPtCtrl)
|
||||
{
|
||||
if ( dPar < EPS_PARAM)
|
||||
return false ;
|
||||
if ( dPar > 1 - EPS_PARAM)
|
||||
return true ;
|
||||
for ( int k = 1 ; k <= nDeg ; ++ k) {
|
||||
for ( int i = nDeg ; i >= k ; -- i) {
|
||||
vPtCtrl[i] = ( 1 - dPar) * vPtCtrl[i-1] + dPar * vPtCtrl[ i] ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
deCastRatTrimEnd( double dPar, int nDeg, PNTVECTOR& vPtCtrl, DBLVECTOR& vWeCtrl)
|
||||
{
|
||||
if ( dPar < EPS_PARAM)
|
||||
return false ;
|
||||
if ( dPar > 1 - EPS_PARAM)
|
||||
return true ;
|
||||
for ( int k = 1 ; k <= nDeg ; ++ k) {
|
||||
for ( int i = nDeg ; i >= k ; -- i) {
|
||||
vPtCtrl[i] = ( 1 - dPar) * vWeCtrl[i-1] * vPtCtrl[i-1] + dPar * vWeCtrl[ i] * vPtCtrl[ i] ;
|
||||
vWeCtrl[i] = ( 1 - dPar) * vWeCtrl[i-1] + dPar * vWeCtrl[ i] ;
|
||||
vPtCtrl[i] = vPtCtrl[i] * ( 1 / vWeCtrl[i]) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
// stdafx.cpp : file di origine che include solo le inclusioni standard
|
||||
// EgtGeometry.pch sarà l'intestazione precompilata
|
||||
// stdafx.obj conterrà le informazioni sui tipi precompilati
|
||||
// EgtGeometry.pch sarà l'intestazione precompilata
|
||||
// stdafx.obj conterrà le informazioni sui tipi precompilati
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user