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:
Dario Sassi
2025-08-22 11:44:56 +02:00
parent 1b9738eace
commit f22ea484db
7 changed files with 479 additions and 637 deletions
+156 -133
View File
@@ -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)