EgtGeomKernel :
- modifiche e migliorie calcoli per approssimazione di superfici di Bezier con trimesh - aggiunte funzioni globali per impostare tolleranze di approssimazione delle superfici di Bezier - eliminazione dell'uso della funzione pow (inefficiente) dove non necessaria - utilizzo di Pow (efficiente) per potenze con esponente intero.
This commit is contained in:
+156
-133
@@ -42,22 +42,34 @@
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Extern/Eigen/Dense"
|
||||
|
||||
|
||||
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) ;
|
||||
static bool BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) ;
|
||||
//----------------------------------------------------------------------------
|
||||
static unordered_map<INTINT, DBLVECTOR, PairHashIntInt> s_mBernCache ; // mappa dei polinomi di bernstein
|
||||
static double s_dAuxSurfTol = 200 * EPS_SMALL ;
|
||||
static double s_dAuxSurfRefinedTol = 50 * EPS_SMALL ;
|
||||
|
||||
static unordered_map<INTINT, DBLVECTOR, PairHashIntInt> m_mBernCache ; // mappa dei polinomi di bernstein
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
SetSurfBezierAuxSurfTol( double dTol)
|
||||
{
|
||||
s_dAuxSurfTol = max( dTol, EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
SetSurfBezierAuxSurfRefinedTol( double dTol)
|
||||
{
|
||||
s_dAuxSurfRefinedTol = max( dTol, EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfBezier::SurfBezier( void)
|
||||
: m_pSTM( nullptr), m_pSTMRefined( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false),
|
||||
m_bTrimmed( false), m_bClosedU( false), m_bClosedV( false), m_pTrimReg(nullptr), m_nTempProp{0,0}, m_dTempParam{0.0,0.0}
|
||||
m_bTrimmed( false), m_bClosedU( false), m_bClosedV( false), m_pTrimReg( nullptr), m_nTempProp{0,0}, m_dTempParam{0.0,0.0}, m_nIsPlanar( -1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -365,24 +377,26 @@ SurfBezier::GetCentroid( Point3d& ptCen) const
|
||||
return false ;
|
||||
// inizio con centro nell'origine
|
||||
ptCen = ORIG ;
|
||||
// calcolo il baricentro
|
||||
if ( m_pSTM == nullptr)
|
||||
if ( ! GetAuxSurf())
|
||||
return false ;
|
||||
return m_pSTM->GetCentroid( ptCen) ;
|
||||
// calcolo il baricentro della superficie ausiliaria
|
||||
GetAuxSurf() ;
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM->GetCentroid( ptCen) ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const
|
||||
{
|
||||
INTINT key( nDegU, int( dU * pow(2,24))) ;
|
||||
if ( m_mBernCache.find( key) == m_mBernCache.end()) {
|
||||
const int TWO_TO_24 = 16777216 ;
|
||||
INTINT key( nDegU, int( dU * TWO_TO_24)) ;
|
||||
if ( s_mBernCache.find( key) == s_mBernCache.end()) {
|
||||
DBLVECTOR vBern( nDegU + 1) ;
|
||||
GetAllBernstein( dU, nDegU, vBern) ;
|
||||
m_mBernCache[key] = vBern ;
|
||||
s_mBernCache[key] = vBern ;
|
||||
}
|
||||
vBernU = m_mBernCache[key] ;
|
||||
vBernU = s_mBernCache[key] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -741,42 +755,49 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs,
|
||||
if ( vtN.Normalize())
|
||||
return true ;
|
||||
|
||||
// se solo una delle due derivate è piccola, mi sposto lungo il relativo parametro e uso le tangenti
|
||||
// se solo una sola delle due derivate è piccola, mi sposto lungo l'altro parametro
|
||||
if ( pvtDerU->Len() < EPS_SMALL && pvtDerV->Len() > 10 * EPS_SMALL) {
|
||||
double dCoeff = ( dU - 1000 * EPS_PARAM < 0. ? 1 : -1) ;
|
||||
double dUm = dU + 1000 * EPS_PARAM * dCoeff ;
|
||||
double dVm = dV ;
|
||||
if ( nVs == ISurfBezier::FROM_MINUS)
|
||||
dVm = ( dV - 100 * EPS_PARAM < 0 ? dV + 100 * EPS_PARAM : dV - 100 * EPS_PARAM) ;
|
||||
else
|
||||
dVm = ( dV + 100 * EPS_PARAM > m_nSpanV ? dV - 100 * EPS_PARAM : dV + 100 * EPS_PARAM) ;
|
||||
Point3d ptTmp ;
|
||||
Vector3d vtTmpU, vtTmpV ;
|
||||
GetPointD1D2( dUm, dV, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ;
|
||||
vtN = ( *pvtDerV ^ vtTmpV) * dCoeff ;
|
||||
GetPointD1D2( dU, dVm, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ;
|
||||
vtN = vtTmpU ^ vtTmpV ;
|
||||
if ( vtN.Normalize())
|
||||
return true ;
|
||||
}
|
||||
if ( pvtDerU->Len() > 10 * EPS_SMALL && pvtDerV->Len() < EPS_SMALL) {
|
||||
double dCoeff = ( dV - 1000 * EPS_PARAM < 0. ? 1 : -1) ;
|
||||
double dVm = dV + 1000 * EPS_PARAM * dCoeff ;
|
||||
double dUm = dU ;
|
||||
if ( nUs == ISurfBezier::FROM_MINUS)
|
||||
dUm = ( dU - 100 * EPS_PARAM < 0 ? dU + 100 * EPS_PARAM : dU - 100 * EPS_PARAM) ;
|
||||
else
|
||||
dUm = ( dU + 100 * EPS_PARAM > m_nSpanU ? dU - 100 * EPS_PARAM : dU + 100 * EPS_PARAM) ;
|
||||
Point3d ptTmp ;
|
||||
Vector3d vtTmpU, vtTmpV ;
|
||||
GetPointD1D2( dU, dVm, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ;
|
||||
vtN = ( vtTmpU ^ *pvtDerU) * dCoeff ;
|
||||
GetPointD1D2( dUm, dV, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ;
|
||||
vtN = vtTmpU ^ vtTmpV ;
|
||||
if ( vtN.Normalize())
|
||||
return true ;
|
||||
}
|
||||
|
||||
// ricalcolo con una piccola variazione di entrambi i parametri
|
||||
double dUm ;
|
||||
if ( dU - 100 * EPS_PARAM < 0.)
|
||||
dUm = dU + 100 * EPS_PARAM ;
|
||||
double dUm = dU ;
|
||||
if ( nUs == ISurfBezier::FROM_MINUS)
|
||||
dUm = ( dU - 100 * EPS_PARAM < 0 ? dU + 100 * EPS_PARAM : dU - 100 * EPS_PARAM) ;
|
||||
else
|
||||
dUm = dU - 100 * EPS_PARAM ;
|
||||
double dVm ;
|
||||
if ( dV - 100 * EPS_PARAM < 0.)
|
||||
dVm = dV + 100 * EPS_PARAM ;
|
||||
dUm = ( dU + 100 * EPS_PARAM > m_nSpanU ? dU - 100 * EPS_PARAM : dU + 100 * EPS_PARAM) ;
|
||||
double dVm = dV ;
|
||||
if ( nVs == ISurfBezier::FROM_MINUS)
|
||||
dVm = ( dV - 100 * EPS_PARAM < 0 ? dV + 100 * EPS_PARAM : dV - 100 * EPS_PARAM) ;
|
||||
else
|
||||
dVm = dV - 100 * EPS_PARAM ;
|
||||
dVm = ( dV + 100 * EPS_PARAM > m_nSpanV ? dV - 100 * EPS_PARAM : dV + 100 * EPS_PARAM) ;
|
||||
Point3d ptTmp ;
|
||||
GetPointD1D2( dUm, dVm, nUs, nVs, ptTmp, pvtDerU, pvtDerV) ;
|
||||
vtN = *pvtDerU ^ *pvtDerV ;
|
||||
Vector3d vtTmpU, vtTmpV ;
|
||||
GetPointD1D2( dUm, dVm, nUs, nVs, ptTmp, &vtTmpU, &vtTmpV) ;
|
||||
vtN = vtTmpU ^ vtTmpV ;
|
||||
return vtN.Normalize() ;
|
||||
}
|
||||
|
||||
@@ -829,7 +850,7 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc)
|
||||
m_mCCEdge.back().emplace_back( sbSrc.m_mCCEdge[i][j]->Clone()) ;
|
||||
}
|
||||
}
|
||||
if( sbSrc.m_bTrimmed) {
|
||||
if ( sbSrc.m_bTrimmed) {
|
||||
for ( int i = 0 ; i < int( sbSrc.m_vCCLoop.size()) ; ++i)
|
||||
m_vCCLoop.emplace_back( sbSrc.m_vCCLoop[i]->Clone());
|
||||
}
|
||||
@@ -1679,11 +1700,21 @@ SurfBezier::GetAuxSurf( void) const
|
||||
ResetAuxSurf() ;
|
||||
return nullptr ;
|
||||
}
|
||||
// se già calcolata, la restituisco
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM ;
|
||||
// se già calcolata
|
||||
if ( m_pSTM != nullptr) {
|
||||
// se con la stessa tolleranza, la restituisco
|
||||
if ( abs( s_dAuxSurfTol - m_pSTM->GetTempParam()) < EPS_SMALL)
|
||||
return m_pSTM ;
|
||||
// altrimenti la cancello prima di ricalcolarla
|
||||
else {
|
||||
delete( m_pSTM) ;
|
||||
m_pSTM = nullptr ;
|
||||
}
|
||||
}
|
||||
// eseguo calcolo
|
||||
m_pSTM = GetApproxSurf( 1000 * EPS_SMALL, 100 * EPS_SMALL) ;
|
||||
m_pSTM = GetApproxSurf( s_dAuxSurfTol, 100 * EPS_SMALL) ;
|
||||
if ( m_pSTM != nullptr)
|
||||
m_pSTM->SetTempParam( s_dAuxSurfTol) ;
|
||||
return m_pSTM ;
|
||||
}
|
||||
|
||||
@@ -1697,10 +1728,20 @@ SurfBezier::GetAuxSurfRefined( void) const
|
||||
return nullptr ;
|
||||
}
|
||||
// se già calcolata, la restituisco
|
||||
if ( m_pSTMRefined != nullptr)
|
||||
return m_pSTMRefined ;
|
||||
if ( m_pSTMRefined != nullptr) {
|
||||
// se con la stessa tolleranza, la restituisco
|
||||
if ( abs( s_dAuxSurfRefinedTol - m_pSTMRefined->GetTempParam()) < EPS_SMALL)
|
||||
return m_pSTMRefined ;
|
||||
// altrimenti la cancello prima di ricalcolarla
|
||||
else {
|
||||
delete( m_pSTMRefined) ;
|
||||
m_pSTMRefined = nullptr ;
|
||||
}
|
||||
}
|
||||
// eseguo calcolo
|
||||
m_pSTMRefined = GetApproxSurf( 50 * EPS_SMALL, 100 * EPS_SMALL) ;
|
||||
m_pSTMRefined = GetApproxSurf( s_dAuxSurfRefinedTol, 100 * EPS_SMALL) ;
|
||||
if ( m_pSTMRefined != nullptr)
|
||||
m_pSTMRefined->SetTempParam( s_dAuxSurfRefinedTol) ;
|
||||
return m_pSTMRefined ;
|
||||
}
|
||||
|
||||
@@ -1714,11 +1755,11 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
|
||||
// se c'è ausiliaria di visualizzazione con gli stessi parametri, ne restituisco una copia
|
||||
if ( m_pSTM != nullptr &&
|
||||
abs( dTol - 1000 * EPS_SMALL) < EPS_SMALL && abs( dSideMin - 100 * EPS_SMALL) < EPS_SMALL)
|
||||
abs( dTol - s_dAuxSurfTol) < EPS_SMALL && abs( dSideMin - 100 * EPS_SMALL) < EPS_SMALL)
|
||||
return m_pSTM->Clone() ;
|
||||
// se c'è ausiliaria e richiesta con gli stessi parametri, ne restituisco una copia
|
||||
if ( m_pSTMRefined != nullptr &&
|
||||
abs( dTol - 50 * EPS_SMALL) < EPS_SMALL && abs( dSideMin - 100 * EPS_SMALL) < EPS_SMALL)
|
||||
abs( dTol - s_dAuxSurfRefinedTol) < EPS_SMALL && abs( dSideMin - 100 * EPS_SMALL) < EPS_SMALL)
|
||||
return m_pSTMRefined->Clone() ;
|
||||
|
||||
// costruttore della superficie
|
||||
@@ -1726,28 +1767,18 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
POLYLINEMATRIX vvPL3d ;
|
||||
//POLYLINEVECTOR vPL ; // per usare i polygon basic
|
||||
Tree Tree ;
|
||||
if ( ! Tree.SetSurf( this, true))
|
||||
if ( ! Tree.SetSurf( this))
|
||||
return nullptr ;
|
||||
BIPNTVECTOR vTrees ;
|
||||
Tree.GetIndependentTrees( vTrees) ;
|
||||
bool bTest = false ; // per debug
|
||||
// resetto il vettore degli edge
|
||||
m_mCCEdge.clear() ;
|
||||
m_vCCLoop.clear() ;
|
||||
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
|
||||
Point3d ptMin = get<0>( vTrees[i]) ;
|
||||
Point3d ptMax = get<1>( vTrees[i]) ;
|
||||
Tree.SetSurf( this, true, ptMin, ptMax) ;
|
||||
if ( bTest) {
|
||||
Tree.BuildTree_test() ; // per debug
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
|
||||
Tree.SetTestMode() ;
|
||||
}
|
||||
else {
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
|
||||
Tree.BuildTree( dTol, dSideMin) ;
|
||||
//Tree.BuildTree( 1, 5) ; //debug
|
||||
}
|
||||
Tree.SetSurf( this, ptMin, ptMax) ;
|
||||
Tree.BuildTree( dTol, dSideMin) ;
|
||||
if ( ! Tree.GetPolygons( vvPL, vvPL3d, m_mCCEdge, m_vCCLoop))
|
||||
continue ;
|
||||
//Tree.GetPolygonsBasic( vPL, true) ; // per usare i polygon basic
|
||||
@@ -1787,18 +1818,18 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
POLYLINEVECTOR vPL3d = vvPL3d[c] ;
|
||||
|
||||
PNTVECTOR vPnt3d ;
|
||||
for( int i = 0 ; i < int( vPL3d.size()) ; ++i) {
|
||||
for ( int i = 0 ; i < int( vPL3d.size()) ; ++i) {
|
||||
PolyLine& pl3d = vPL3d[i] ;
|
||||
Point3d pt3d ; pl3d.GetFirstPoint( pt3d) ;
|
||||
if( vPL3d.size() > 1)
|
||||
if ( vPL3d.size() > 1)
|
||||
vPnt3d.push_back( pt3d) ;
|
||||
while ( pl3d.GetNextPoint( pt3d)) {
|
||||
vPnt3d.push_back( pt3d) ;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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() ;
|
||||
@@ -1810,13 +1841,13 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
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 ( 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) {
|
||||
if ( bTriangulationSucceded) {
|
||||
bTriangulatedIn3D = true ;
|
||||
// calcolo la normale della polyline per flippare eventualmente i triangoli se hanno la normale sbagliata
|
||||
PolyLine& pl3d = vPL3d[0] ;
|
||||
@@ -1825,7 +1856,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
Vector3d vtN = plPlane.GetVersN() ;
|
||||
Triangle3d tria ;
|
||||
tria.Set( vPnt[vTria[0]], vPnt[vTria[1]], vPnt[vTria[2]]) ;
|
||||
if( tria.GetN() * vtN < 0)
|
||||
if ( tria.GetN() * vtN < 0)
|
||||
reverse( vTria.begin(), vTria.end()) ;
|
||||
}
|
||||
else {
|
||||
@@ -1835,11 +1866,11 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
}
|
||||
|
||||
// riordino il vettore dei punti su cui non ho fatto la triangolazione
|
||||
if( int(vPL.size()) == 2) {
|
||||
if ( vPL.size() == 2) {
|
||||
//if( vPnt.size() != vPnt3d.size())
|
||||
// return nullptr ;
|
||||
PNTVECTOR vPntOrd ;
|
||||
if( bTriangulatedIn3D) {
|
||||
if ( bTriangulatedIn3D) {
|
||||
ReorderPntVector( vPL3d, true, vPnt, vPL, vPntOrd) ;
|
||||
vPnt3d = vPnt ;
|
||||
vPnt = vPntOrd ;
|
||||
@@ -1850,7 +1881,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
}
|
||||
}
|
||||
else if ( bTriangulatedIn3D) {
|
||||
if( vPL.size() == 1) {
|
||||
if ( vPL.size() == 1) {
|
||||
vPnt3d = vPnt ;
|
||||
PNTVECTOR vPnt2d ;
|
||||
for( int i = 0 ; i < int( vPL.size()) ; ++i) {
|
||||
@@ -1871,9 +1902,9 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
// i punti in eccesso verranno poi scartati dalla trimesh
|
||||
if( vPnt.size() != vPnt3d.size()) {
|
||||
// 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
|
||||
// i punti in eccesso verranno poi scartati dalla trimesh
|
||||
if ( vPnt.size() != vPnt3d.size()) {
|
||||
vPnt3d.clear() ;
|
||||
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
|
||||
Point3d pt3d ;
|
||||
@@ -2029,23 +2060,15 @@ bool
|
||||
SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
|
||||
{
|
||||
Tree Tree ;
|
||||
if ( ! Tree.SetSurf( this, true))
|
||||
if ( ! Tree.SetSurf( this))
|
||||
return false ;
|
||||
BIPNTVECTOR vTrees ;
|
||||
Tree.GetIndependentTrees( vTrees) ;
|
||||
for ( int i = 0 ; i < int( vTrees.size()) ; ++ i) {
|
||||
Point3d ptMin = get<0>( vTrees[i]) ;
|
||||
Point3d ptMax = get<1>( vTrees[i]) ;
|
||||
Tree.SetSurf( this, true, ptMin, ptMax) ;
|
||||
bool bTest = false ; // per debug
|
||||
if ( bTest) {
|
||||
Tree.BuildTree_test() ; // per debug
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
|
||||
}
|
||||
else {
|
||||
//Tree.BuildTree( 100 * LIN_TOL_FINE, 0.1) ;
|
||||
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
|
||||
}
|
||||
Tree.SetSurf( this, ptMin, ptMax) ;
|
||||
Tree.BuildTree( s_dAuxSurfTol, 100 * EPS_SMALL) ;
|
||||
vector<Cell> vCells ;
|
||||
Tree.GetLeaves( vCells) ;
|
||||
for ( int k = 0 ; k < int( vCells.size()) ; ++ k) {
|
||||
@@ -2825,7 +2848,7 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
|
||||
for ( int i = 0 ; i < int( m_mCCEdge[c].size()) ; ++i) {
|
||||
if ( ! m_mCCEdge[c][i]->IsValid()) {
|
||||
Point3d pt ;
|
||||
if ( ! m_mCCEdge[c][i]->GetOnlyPoint(pt))
|
||||
if ( ! m_mCCEdge[c][i]->GetOnlyPoint( pt))
|
||||
return false ;
|
||||
vInters[c] = AreSamePointApprox( pt, ptI) ? 1 : 0 ;
|
||||
if ( vInters[c] == 1)
|
||||
@@ -3177,8 +3200,8 @@ SurfBezier::UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d
|
||||
}
|
||||
// calcolo le nuove coordinate
|
||||
Vector3d vtDir ;
|
||||
double dASum = abs(dfdU) + abs(dfdV) ;
|
||||
double dSSum = sqrt( pow(dfdU,2) + pow( dfdV,2)) ;
|
||||
double dASum = abs( dfdU) + abs( dfdV) ;
|
||||
double dSSum = sqrt( dfdU * dfdU + dfdV * dfdV) ;
|
||||
vtDir.Set( - dfdU, - dfdV, 0) ;
|
||||
if ( ! vtDir.Normalize() )
|
||||
vtDir.Set( - dfdU / dSSum, - dfdV / dSSum, 0) ;
|
||||
@@ -4191,8 +4214,8 @@ SurfBezier::CreateByPointCurve( const Point3d& pt, const ICurve* pCurve)
|
||||
return false ;
|
||||
// recupero span e grado nel parametro U
|
||||
int nSpanU = int( CrvU.GetCurveCount()) ;
|
||||
int nDegU = ( GetCurveBezier( CrvU.GetCurve(0)))->GetDegree() ;
|
||||
bool bRat = (GetCurveBezier( CrvU.GetCurve(0)))->IsRational() ;
|
||||
int nDegU = GetCurveBezier( CrvU.GetCurve(0))->GetDegree() ;
|
||||
bool bRat = GetCurveBezier( CrvU.GetCurve(0))->IsRational() ;
|
||||
// in V decido che la funzione è una patch di grado 1
|
||||
int nSpanV = 1 ;
|
||||
int nDegV = 1 ;
|
||||
@@ -4219,6 +4242,52 @@ SurfBezier::CreateByPointCurve( const Point3d& pt, const ICurve* pCurve)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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 ;
|
||||
tuple<double,int,Point3d,int,Point3d> tMatch ;
|
||||
Point3d pt0 ;
|
||||
bool bOk0 = plU0.GetFirstPoint( pt0) ;
|
||||
int c0 = 0 ;
|
||||
double dMinDist = INFINITO ;
|
||||
while ( bOk0) {
|
||||
Point3d pt1 ;
|
||||
bool bOk1 = plU1.GetFirstPoint( pt1) ;
|
||||
int c1 = 0 ;
|
||||
while ( bOk1) {
|
||||
double dDist = Dist( pt0, pt1) ;
|
||||
if ( dDist < dMinDist) {
|
||||
tMatch = make_tuple( dDist, c0, pt0, c1, pt1) ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
++c1 ;
|
||||
bOk1 = plU1.GetNextPoint( pt1) ;
|
||||
}
|
||||
vDistVert.push_back( tMatch) ;
|
||||
dMinDist = INFINITO ;
|
||||
c1 = 0 ;
|
||||
++c0 ;
|
||||
bOk0 = plU0.GetNextPoint( pt0) ;
|
||||
}
|
||||
int nMin = 0 ;
|
||||
dMinDist = INFINITO ;
|
||||
for ( int i = 0 ; i < int( vDistVert.size()) ; ++i) {
|
||||
if( get<0>(vDistVert[i]) < dMinDist) {
|
||||
dMinDist = get<0>(vDistVert[i]) ;
|
||||
nMin = i ;
|
||||
}
|
||||
}
|
||||
ChangePolyLineStart(plU0, get<2>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
ChangePolyLineStart(plU1, get<4>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
pCrvU0->ChangeStartPoint( double( get<1>(vDistVert[nMin]))) ;
|
||||
pCrvU1->ChangeStartPoint( double( get<3>(vDistVert[nMin]))) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int nRuledType)
|
||||
@@ -5098,52 +5167,6 @@ SplitByCommonParam( ICURVEPOVECTOR& vCrvBezUnif, DBLVECTOR& vCommonParam, DBLMAT
|
||||
return true ;
|
||||
}
|
||||
|
||||
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 ;
|
||||
tuple<double,int,Point3d,int,Point3d> tMatch ;
|
||||
Point3d pt0 ;
|
||||
bool bOk0 = plU0.GetFirstPoint( pt0) ;
|
||||
int c0 = 0 ;
|
||||
double dMinDist = INFINITO ;
|
||||
while ( bOk0) {
|
||||
Point3d pt1 ;
|
||||
bool bOk1 = plU1.GetFirstPoint( pt1) ;
|
||||
int c1 = 0 ;
|
||||
while ( bOk1) {
|
||||
double dDist = Dist( pt0, pt1) ;
|
||||
if ( dDist < dMinDist) {
|
||||
tMatch = make_tuple( dDist, c0, pt0, c1, pt1) ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
++c1 ;
|
||||
bOk1 = plU1.GetNextPoint( pt1) ;
|
||||
}
|
||||
vDistVert.push_back( tMatch) ;
|
||||
dMinDist = INFINITO ;
|
||||
c1 = 0 ;
|
||||
++c0 ;
|
||||
bOk0 = plU0.GetNextPoint( pt0) ;
|
||||
}
|
||||
int nMin = 0 ;
|
||||
dMinDist = INFINITO ;
|
||||
for ( int i = 0 ; i < int( vDistVert.size()) ; ++i) {
|
||||
if( get<0>(vDistVert[i]) < dMinDist) {
|
||||
dMinDist = get<0>(vDistVert[i]) ;
|
||||
nMin = i ;
|
||||
}
|
||||
}
|
||||
ChangePolyLineStart(plU0, get<2>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
ChangePolyLineStart(plU1, get<4>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
pCrvU0->ChangeStartPoint( double( get<1>(vDistVert[nMin]))) ;
|
||||
pCrvU1->ChangeStartPoint( double( get<3>(vDistVert[nMin]))) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3)
|
||||
@@ -5311,7 +5334,7 @@ SurfBezier::CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDe
|
||||
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(0) << pt0.x * pt0.x, pt1.x * pt1.x, pt2.x * pt2.x ;
|
||||
mA.col(1) << pt0.x, pt1.x , pt2.x ;
|
||||
mA.col(2) << 1, 1, 1 ;
|
||||
if( abs( mA.determinant()) < EPS_SMALL)
|
||||
|
||||
Reference in New Issue
Block a user