|
|
|
@@ -13,12 +13,14 @@
|
|
|
|
|
|
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "SurfTriMesh.h"
|
|
|
|
|
#include "SurfBezier.h"
|
|
|
|
|
#include "GeoConst.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
|
|
|
|
#include "/EgtDev/Include/EGkProjectCurveSurf.h"
|
|
|
|
|
|
|
|
|
|
using namespace std ;
|
|
|
|
|
|
|
|
|
@@ -26,72 +28,27 @@ using namespace std ;
|
|
|
|
|
// Angolo limite tra normale al triangolo e direzione di proiezione 89°
|
|
|
|
|
const double COS_ANG_LIM = 0.0175 ;
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
static bool
|
|
|
|
|
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
|
|
|
|
{
|
|
|
|
|
for ( int i = nPrec + 1 ; i < nCurr ; ++ i) {
|
|
|
|
|
double dSqDist ;
|
|
|
|
|
if ( ! DistPointLine( vPt5ax[i].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
|
|
|
|
return false ;
|
|
|
|
|
}
|
|
|
|
|
return true ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
static bool
|
|
|
|
|
RemovePointsInExcess( PNT5AXVECTOR& vMyPt5ax, double dLinTol, double dMaxSegmLen)
|
|
|
|
|
{
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
|
|
|
|
double dSqTol = dLinTol * dLinTol ;
|
|
|
|
|
const double LENREF = 100 ;
|
|
|
|
|
double dCosAngLim = 1 - dSqTol / ( 2 * LENREF * LENREF) ;
|
|
|
|
|
int nPrec = 0 ;
|
|
|
|
|
int nCurr = 1 ;
|
|
|
|
|
int nNext = 2 ;
|
|
|
|
|
while ( nNext < int( vMyPt5ax.size())) {
|
|
|
|
|
bool bRemove = false ;
|
|
|
|
|
// lunghezza del segmento che unisce gli adiacenti
|
|
|
|
|
double dSqLen = SqDist( vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
|
|
|
|
// se lunghezza inferiore al massimo, passo agli altri controlli
|
|
|
|
|
if ( dSqLen <= dSqMaxLen) {
|
|
|
|
|
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
|
|
|
|
DistPointLine dPL( vMyPt5ax[nCurr].ptP, vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
|
|
|
|
double dSqDist ;
|
|
|
|
|
// se distanza inferiore a tolleranza lineare
|
|
|
|
|
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vMyPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
|
|
|
|
// verifico se errore angolare inferiore a limite
|
|
|
|
|
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
|
|
|
|
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir, vMyPt5ax[nNext].vtDir, dPar) ;
|
|
|
|
|
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir > dCosAngLim)
|
|
|
|
|
bRemove = true ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// se da eliminare
|
|
|
|
|
if ( bRemove) {
|
|
|
|
|
// dichiaro da eliminare il punto
|
|
|
|
|
vMyPt5ax[nCurr].nFlag = -1 ;
|
|
|
|
|
// avanzo con corrente e successivo
|
|
|
|
|
nCurr = nNext ;
|
|
|
|
|
++ nNext ;
|
|
|
|
|
}
|
|
|
|
|
// altrimenti da tenere
|
|
|
|
|
else {
|
|
|
|
|
// avanzo il terzetto di uno step
|
|
|
|
|
nPrec = nCurr ;
|
|
|
|
|
nCurr = nNext ;
|
|
|
|
|
++ nNext ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vector3d& vtDir, double dLinTol, double dMaxSegmLen,
|
|
|
|
|
PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
ProjectCurveOnSurf( const ICurve& crCrv, const ISurf& sfSurf, const Vector3d& vtDir,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
{
|
|
|
|
|
// sistemazioni per tipo di superficie
|
|
|
|
|
const SurfTriMesh* pSurfTm = nullptr ;
|
|
|
|
|
switch ( sfSurf.GetType()) {
|
|
|
|
|
case SRF_TRIMESH :
|
|
|
|
|
pSurfTm = GetBasicSurfTriMesh( &sfSurf) ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_BEZIER :
|
|
|
|
|
pSurfTm = GetBasicSurfBezier( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_FLATRGN :
|
|
|
|
|
pSurfTm = GetBasicSurfFlatRegion( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
if ( pSurfTm == nullptr)
|
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
|
|
// controllo le tolleranze
|
|
|
|
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
|
|
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
|
|
@@ -107,7 +64,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec
|
|
|
|
|
Frame3d frRefLine ;
|
|
|
|
|
if ( ! frRefLine.Set( ORIG, vtDir))
|
|
|
|
|
return false ;
|
|
|
|
|
IntersParLinesSurfTm intPLSTM( frRefLine, tmSurf) ;
|
|
|
|
|
IntersParLinesSurfTm intPLSTM( frRefLine, *pSurfTm) ;
|
|
|
|
|
|
|
|
|
|
// Vettore locale dei punti risultanti
|
|
|
|
|
PNT5AXVECTOR vMyPt5ax ;
|
|
|
|
@@ -136,21 +93,20 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec
|
|
|
|
|
ptInt = vIntRes[nI].ptI ;
|
|
|
|
|
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
|
|
|
Triangle3dEx trTria ;
|
|
|
|
|
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
if ( ! pSurfTm->GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
return false ;
|
|
|
|
|
Vector3d vtN ;
|
|
|
|
|
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
|
|
|
vtN = trTria.GetN() ;
|
|
|
|
|
// aggiungo al vettore dei proiettati
|
|
|
|
|
vMyPt5ax.emplace_back( ptInt, vtN, dPar, 1) ;
|
|
|
|
|
vMyPt5ax.emplace_back( ptInt, vtN, vtDir, dPar, 1) ;
|
|
|
|
|
}
|
|
|
|
|
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
|
|
|
|
// eventuale rimozione punti in eccesso rispetto alle tolleranze lasciata alla funzione chiamante
|
|
|
|
|
|
|
|
|
|
// copio i punti rimasti nel vettore di ritorno
|
|
|
|
|
// copio i punti nel vettore di ritorno
|
|
|
|
|
vPt5ax.clear() ;
|
|
|
|
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
|
|
|
|
if ( Pt5ax.nFlag != -1)
|
|
|
|
@@ -162,9 +118,25 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGeoPoint3d& gpRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
ProjectCurveOnSurf( const ICurve& crCrv, const ISurf& sfSurf, const IGeoPoint3d& gpRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
{
|
|
|
|
|
// sistemazioni per tipo di superficie
|
|
|
|
|
const SurfTriMesh* pSurfTm = nullptr ;
|
|
|
|
|
switch ( sfSurf.GetType()) {
|
|
|
|
|
case SRF_TRIMESH :
|
|
|
|
|
pSurfTm = GetBasicSurfTriMesh( &sfSurf) ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_BEZIER :
|
|
|
|
|
pSurfTm = GetBasicSurfBezier( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_FLATRGN :
|
|
|
|
|
pSurfTm = GetBasicSurfFlatRegion( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
if ( pSurfTm == nullptr)
|
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
|
|
// controllo le tolleranze
|
|
|
|
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
|
|
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
|
|
@@ -194,7 +166,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGe
|
|
|
|
|
if ( dLineLen > EPS_SMALL) {
|
|
|
|
|
vtLine /= dLineLen ;
|
|
|
|
|
ILSIVECTOR vIntRes ;
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *pSurfTm, vIntRes, false)) {
|
|
|
|
|
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
|
|
|
|
int nI = int( vIntRes.size()) - 1 ;
|
|
|
|
|
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
|
|
|
@@ -209,7 +181,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGe
|
|
|
|
|
ptInt = vIntRes[nI].ptI ;
|
|
|
|
|
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
|
|
|
Triangle3dEx trTria ;
|
|
|
|
|
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
if ( ! pSurfTm->GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
return false ;
|
|
|
|
|
Vector3d vtN ;
|
|
|
|
|
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
|
|
@@ -222,10 +194,9 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGe
|
|
|
|
|
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
|
|
|
|
// eventuale rimozione punti in eccesso rispetto alle tolleranze lasciata alla funzione chiamante
|
|
|
|
|
|
|
|
|
|
// copio i punti rimasti nel vettore di ritorno
|
|
|
|
|
// copio i punti nel vettore di ritorno
|
|
|
|
|
vPt5ax.clear() ;
|
|
|
|
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
|
|
|
|
if ( Pt5ax.nFlag != -1)
|
|
|
|
@@ -237,9 +208,25 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGe
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICurve& crRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
ProjectCurveOnSurf( const ICurve& crCrv, const ISurf& sfSurf, const ICurve& crRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
{
|
|
|
|
|
// sistemazioni per tipo di superficie
|
|
|
|
|
const SurfTriMesh* pSurfTm = nullptr ;
|
|
|
|
|
switch ( sfSurf.GetType()) {
|
|
|
|
|
case SRF_TRIMESH :
|
|
|
|
|
pSurfTm = GetBasicSurfTriMesh( &sfSurf) ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_BEZIER :
|
|
|
|
|
pSurfTm = GetBasicSurfBezier( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_FLATRGN :
|
|
|
|
|
pSurfTm = GetBasicSurfFlatRegion( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
if ( pSurfTm == nullptr)
|
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
|
|
// controllo le tolleranze
|
|
|
|
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
|
|
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
|
|
@@ -272,7 +259,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu
|
|
|
|
|
if ( dLineLen > EPS_SMALL) {
|
|
|
|
|
vtLine /= dLineLen ;
|
|
|
|
|
ILSIVECTOR vIntRes ;
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *pSurfTm, vIntRes, false)) {
|
|
|
|
|
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
|
|
|
|
int nI = int( vIntRes.size()) - 1 ;
|
|
|
|
|
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
|
|
|
@@ -287,7 +274,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu
|
|
|
|
|
ptInt = vIntRes[nI].ptI ;
|
|
|
|
|
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
|
|
|
Triangle3dEx trTria ;
|
|
|
|
|
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
if ( ! pSurfTm->GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
return false ;
|
|
|
|
|
Vector3d vtN ;
|
|
|
|
|
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
|
|
@@ -301,10 +288,9 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu
|
|
|
|
|
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
|
|
|
|
// eventuale rimozione punti in eccesso rispetto alle tolleranze lasciata alla funzione chiamante
|
|
|
|
|
|
|
|
|
|
// copio i punti rimasti nel vettore di ritorno
|
|
|
|
|
// copio i punti nel vettore di ritorno
|
|
|
|
|
vPt5ax.clear() ;
|
|
|
|
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
|
|
|
|
if ( Pt5ax.nFlag != -1)
|
|
|
|
@@ -316,9 +302,41 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICu
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISurfTriMesh& tmRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
ProjectCurveOnSurf( const ICurve& crCrv, const ISurf& sfSurf, const ISurf& sfRef,
|
|
|
|
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
|
|
|
|
{
|
|
|
|
|
// sistemazioni per tipo di superficie
|
|
|
|
|
const SurfTriMesh* pSurfTm = nullptr ;
|
|
|
|
|
switch ( sfSurf.GetType()) {
|
|
|
|
|
case SRF_TRIMESH :
|
|
|
|
|
pSurfTm = GetBasicSurfTriMesh( &sfSurf) ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_BEZIER :
|
|
|
|
|
pSurfTm = GetBasicSurfBezier( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_FLATRGN :
|
|
|
|
|
pSurfTm = GetBasicSurfFlatRegion( &sfSurf)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
if ( pSurfTm == nullptr)
|
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
|
|
// sistemazioni per tipo di superficie di riferimento
|
|
|
|
|
const SurfTriMesh* pRefTm = nullptr ;
|
|
|
|
|
switch ( sfRef.GetType()) {
|
|
|
|
|
case SRF_TRIMESH :
|
|
|
|
|
pRefTm = GetBasicSurfTriMesh( &sfRef) ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_BEZIER :
|
|
|
|
|
pRefTm = GetBasicSurfBezier( &sfRef)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
case SRF_FLATRGN :
|
|
|
|
|
pRefTm = GetBasicSurfFlatRegion( &sfRef)->GetAuxSurf() ;
|
|
|
|
|
break ;
|
|
|
|
|
}
|
|
|
|
|
if ( pRefTm == nullptr)
|
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
|
|
// controllo le tolleranze
|
|
|
|
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
|
|
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
|
|
@@ -341,7 +359,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
|
|
|
|
while ( bFound) {
|
|
|
|
|
// punto sulla superficie guida a minima distanza
|
|
|
|
|
DistPointSurfTm dPS( ptP, tmRef) ;
|
|
|
|
|
DistPointSurfTm dPS( ptP, *pRefTm) ;
|
|
|
|
|
Point3d ptMin ;
|
|
|
|
|
int nTriaMin ;
|
|
|
|
|
if ( dPS.GetMinDistPoint( ptMin) && dPS.GetMinDistTriaIndex ( nTriaMin)) {
|
|
|
|
@@ -353,7 +371,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
else {
|
|
|
|
|
// calcolo la normale della superficie guida
|
|
|
|
|
Triangle3dEx trGuide ;
|
|
|
|
|
if ( ! tmRef.GetTriangle( nTriaMin, trGuide))
|
|
|
|
|
if ( ! pRefTm->GetTriangle( nTriaMin, trGuide))
|
|
|
|
|
return false ;
|
|
|
|
|
if ( ! CalcNormal( ptMin, trGuide, vtLine))
|
|
|
|
|
vtLine = trGuide.GetN() ;
|
|
|
|
@@ -361,7 +379,7 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
}
|
|
|
|
|
// intersezione della retta con la superficie
|
|
|
|
|
ILSIVECTOR vIntRes ;
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
|
|
|
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *pSurfTm, vIntRes, false)) {
|
|
|
|
|
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
|
|
|
|
int nI = int( vIntRes.size()) - 1 ;
|
|
|
|
|
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
|
|
|
@@ -376,14 +394,14 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
ptInt = vIntRes[nI].ptI ;
|
|
|
|
|
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
|
|
|
Triangle3dEx trTria ;
|
|
|
|
|
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
if ( ! pSurfTm->GetTriangle( vIntRes[nI].nT, trTria))
|
|
|
|
|
return false ;
|
|
|
|
|
Vector3d vtN ;
|
|
|
|
|
if ( ! CalcNormal( ptMin, trTria, vtN))
|
|
|
|
|
vtN = trTria.GetN() ;
|
|
|
|
|
// calcolo la normale della superficie guida
|
|
|
|
|
Triangle3dEx trGuide ;
|
|
|
|
|
if ( ! tmRef.GetTriangle( nTriaMin, trGuide))
|
|
|
|
|
if ( ! pRefTm->GetTriangle( nTriaMin, trGuide))
|
|
|
|
|
return false ;
|
|
|
|
|
Vector3d vtN2 ;
|
|
|
|
|
if ( ! CalcNormal( ptMin, trGuide, vtN2))
|
|
|
|
@@ -396,10 +414,9 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
|
|
|
|
// eventuale rimozione punti in eccesso rispetto alle tolleranze lasciata alla funzione chiamante
|
|
|
|
|
|
|
|
|
|
// copio i punti rimasti nel vettore di ritorno
|
|
|
|
|
// copio i punti nel vettore di ritorno
|
|
|
|
|
vPt5ax.clear() ;
|
|
|
|
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
|
|
|
|
if ( Pt5ax.nFlag != -1)
|
|
|
|
@@ -408,3 +425,71 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISu
|
|
|
|
|
|
|
|
|
|
return true ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
static bool
|
|
|
|
|
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
|
|
|
|
{
|
|
|
|
|
for ( int i = nPrec + 1 ; i < nCurr ; ++ i) {
|
|
|
|
|
double dSqDist ;
|
|
|
|
|
if ( ! DistPointLine( vPt5ax[i].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
|
|
|
|
return false ;
|
|
|
|
|
}
|
|
|
|
|
return true ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
bool
|
|
|
|
|
RemovePointsInExcess( PNT5AXVECTOR& vMyPt5ax, double dLinTol, double dMaxSegmLen, bool bTestDir)
|
|
|
|
|
{
|
|
|
|
|
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
|
|
|
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
|
|
|
|
double dSqTol = dLinTol * dLinTol ;
|
|
|
|
|
const double LENREF = 100 ;
|
|
|
|
|
double dCosAngLim = 1 - dSqTol / ( 2 * LENREF * LENREF) ;
|
|
|
|
|
int nPrec = 0 ;
|
|
|
|
|
int nCurr = 1 ;
|
|
|
|
|
int nNext = 2 ;
|
|
|
|
|
while ( nNext < int( vMyPt5ax.size())) {
|
|
|
|
|
bool bRemove = false ;
|
|
|
|
|
// lunghezza del segmento che unisce gli adiacenti
|
|
|
|
|
double dSqLen = SqDist( vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
|
|
|
|
// se lunghezza inferiore al massimo, passo agli altri controlli
|
|
|
|
|
if ( dSqLen <= dSqMaxLen) {
|
|
|
|
|
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
|
|
|
|
DistPointLine dPL( vMyPt5ax[nCurr].ptP, vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
|
|
|
|
double dSqDist ;
|
|
|
|
|
// se distanza inferiore a tolleranza lineare
|
|
|
|
|
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vMyPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
|
|
|
|
// verifico se errore angolare inferiore a limite
|
|
|
|
|
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
|
|
|
|
if ( bTestDir) {
|
|
|
|
|
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir, vMyPt5ax[nNext].vtDir, dPar) ;
|
|
|
|
|
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir > dCosAngLim)
|
|
|
|
|
bRemove = true ;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir2, vMyPt5ax[nNext].vtDir2, dPar) ;
|
|
|
|
|
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir2 > dCosAngLim)
|
|
|
|
|
bRemove = true ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// se da eliminare
|
|
|
|
|
if ( bRemove) {
|
|
|
|
|
// dichiaro da eliminare il punto
|
|
|
|
|
vMyPt5ax[nCurr].nFlag = -1 ;
|
|
|
|
|
// avanzo con corrente e successivo
|
|
|
|
|
nCurr = nNext ;
|
|
|
|
|
++ nNext ;
|
|
|
|
|
}
|
|
|
|
|
// altrimenti da tenere
|
|
|
|
|
else {
|
|
|
|
|
// avanzo il terzetto di uno step
|
|
|
|
|
nPrec = nCurr ;
|
|
|
|
|
nCurr = nNext ;
|
|
|
|
|
++ nNext ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true ;
|
|
|
|
|
}
|