Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bc315bd1d |
@@ -317,8 +317,6 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
|
|||||||
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||||
// unisco eventuali tratti allineati
|
// unisco eventuali tratti allineati
|
||||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ;
|
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ;
|
||||||
// richiudo i loop per sicurezza
|
|
||||||
pCrvCo->Close() ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
#include "CurveBezier.h"
|
#include "CurveBezier.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "CreateCurveAux.h"
|
#include "CreateCurveAux.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h"
|
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|||||||
+1
-2
@@ -134,8 +134,7 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd,
|
|||||||
|
|
||||||
// calcolo arco non riuscito, se i punti sono allineati nel giusto verso per essere una retta
|
// calcolo arco non riuscito, se i punti sono allineati nel giusto verso per essere una retta
|
||||||
// verifico se i punti sono allineati nel giusto verso
|
// verifico se i punti sono allineati nel giusto verso
|
||||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO ||
|
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
|
||||||
AreSamePointApprox( ptOther, ptStart) || AreSamePointApprox( ptEnd, ptOther)) {
|
|
||||||
// creo l'oggetto retta
|
// creo l'oggetto retta
|
||||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||||
if ( IsNull( pLine))
|
if ( IsNull( pLine))
|
||||||
|
|||||||
+8
-8
@@ -133,22 +133,22 @@ Attribs::Load( NgeReader& ngeIn)
|
|||||||
unsigned char ucLev ;
|
unsigned char ucLev ;
|
||||||
if ( ! ngeIn.ReadUchar( ucLev, ","))
|
if ( ! ngeIn.ReadUchar( ucLev, ","))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[LEVEL] = Clamp( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
m_Data[LEVEL] = CLIP( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||||
// modo
|
// modo
|
||||||
unsigned char ucMode ;
|
unsigned char ucMode ;
|
||||||
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[MODE] = Clamp( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
m_Data[MODE] = CLIP( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||||
// stato (se SEL è convertito in ON)
|
// stato (se SEL è convertito in ON)
|
||||||
unsigned char ucStat ;
|
unsigned char ucStat ;
|
||||||
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[STATUS] = Clamp( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
m_Data[STATUS] = CLIP( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||||
// marcatura (sempre OFF)
|
// marcatura (sempre OFF)
|
||||||
unsigned char ucMark ;
|
unsigned char ucMark ;
|
||||||
if ( ! ngeIn.ReadUchar( ucMark, ";"))
|
if ( ! ngeIn.ReadUchar( ucMark, ";"))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[MARK] = Clamp( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
m_Data[MARK] = CLIP( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||||
// materiale
|
// materiale
|
||||||
if ( ! ngeIn.ReadInt( m_Material, ";"))
|
if ( ! ngeIn.ReadInt( m_Material, ";"))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -185,22 +185,22 @@ Attribs::DataFromString( const string& sParam)
|
|||||||
int nLev ;
|
int nLev ;
|
||||||
if ( ! FromString( vsParams[0], nLev))
|
if ( ! FromString( vsParams[0], nLev))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||||
// modo
|
// modo
|
||||||
int nMode ;
|
int nMode ;
|
||||||
if ( ! FromString( vsParams[1], nMode))
|
if ( ! FromString( vsParams[1], nMode))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||||
// stato (ammessi solo OFF e ON)
|
// stato (ammessi solo OFF e ON)
|
||||||
int nStat ;
|
int nStat ;
|
||||||
if ( ! FromString( vsParams[2], nStat))
|
if ( ! FromString( vsParams[2], nStat))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||||
// marcatura (ammesso solo OFF)
|
// marcatura (ammesso solo OFF)
|
||||||
int nMark ;
|
int nMark ;
|
||||||
if ( ! FromString( vsParams[3], nMark))
|
if ( ! FromString( vsParams[3], nMark))
|
||||||
return false ;
|
return false ;
|
||||||
m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
m_Data[MARK] = CLIP( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,14 @@
|
|||||||
#include "/EgtDev/Include/EGkGdbConst.h"
|
#include "/EgtDev/Include/EGkGdbConst.h"
|
||||||
#include "/EgtDev/Include/EGkColor.h"
|
#include "/EgtDev/Include/EGkColor.h"
|
||||||
#include "/EgtDev/Include/EgtStringBase.h"
|
#include "/EgtDev/Include/EgtStringBase.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
|
||||||
|
|
||||||
class NgeWriter ;
|
class NgeWriter ;
|
||||||
class NgeReader ;
|
class NgeReader ;
|
||||||
class GeomDB ;
|
class GeomDB ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
#define CLIP( nV, nMIN, nMAX) (( nV < nMIN) ? nMIN : (( nV > nMAX) ? nMAX : nV))
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class Attribs
|
class Attribs
|
||||||
{
|
{
|
||||||
@@ -44,14 +46,14 @@ class Attribs
|
|||||||
bool Load( NgeReader& ngeIn) ;
|
bool Load( NgeReader& ngeIn) ;
|
||||||
void SetLevel( int nLev)
|
void SetLevel( int nLev)
|
||||||
{ m_OldData[LEVEL] = m_Data[LEVEL] ;
|
{ m_OldData[LEVEL] = m_Data[LEVEL] ;
|
||||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
||||||
void RevertLevel( void)
|
void RevertLevel( void)
|
||||||
{ std::swap( m_Data[LEVEL], m_OldData[LEVEL]) ; }
|
{ std::swap( m_Data[LEVEL], m_OldData[LEVEL]) ; }
|
||||||
int GetLevel( void) const
|
int GetLevel( void) const
|
||||||
{ return m_Data[LEVEL] ; }
|
{ return m_Data[LEVEL] ; }
|
||||||
void SetMode( int nMode)
|
void SetMode( int nMode)
|
||||||
{ m_OldData[MODE] = m_Data[MODE] ;
|
{ m_OldData[MODE] = m_Data[MODE] ;
|
||||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
||||||
void RevertMode( void)
|
void RevertMode( void)
|
||||||
{ std::swap( m_Data[MODE], m_OldData[MODE]) ; }
|
{ std::swap( m_Data[MODE], m_OldData[MODE]) ; }
|
||||||
int GetMode( void) const
|
int GetMode( void) const
|
||||||
@@ -59,13 +61,13 @@ class Attribs
|
|||||||
void SetStatus( int nStat)
|
void SetStatus( int nStat)
|
||||||
{ if ( m_Data[STATUS] != GDB_ST_SEL)
|
{ if ( m_Data[STATUS] != GDB_ST_SEL)
|
||||||
m_OldData[STATUS] = m_Data[STATUS] ;
|
m_OldData[STATUS] = m_Data[STATUS] ;
|
||||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
||||||
void RevertStatus( void)
|
void RevertStatus( void)
|
||||||
{ SetStatus( m_OldData[STATUS]) ; }
|
{ SetStatus( m_OldData[STATUS]) ; }
|
||||||
int GetStatus( void) const
|
int GetStatus( void) const
|
||||||
{ return m_Data[STATUS] ; }
|
{ return m_Data[STATUS] ; }
|
||||||
void SetMark( int nMark)
|
void SetMark( void)
|
||||||
{ m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_ON_2) ; }
|
{ m_Data[MARK] = GDB_MK_ON ; }
|
||||||
void ResetMark( void)
|
void ResetMark( void)
|
||||||
{ m_Data[MARK] = GDB_MK_OFF ; }
|
{ m_Data[MARK] = GDB_MK_OFF ; }
|
||||||
int GetMark( void) const
|
int GetMark( void) const
|
||||||
|
|||||||
+6
-9
@@ -83,7 +83,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ICurve*
|
ICurve*
|
||||||
GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||||
const PolyLine& PL, double& dDist, double dTol)
|
const PolyLine& PL, double& dDist)
|
||||||
{
|
{
|
||||||
// calcolo la curva dove giacciono i punti di giunzione tra i due archi del biarco
|
// calcolo la curva dove giacciono i punti di giunzione tra i due archi del biarco
|
||||||
PtrOwner<ICurve> pJCrv( CalcJCurve( ptP0, dDir0Deg, ptP1, dDir1Deg)) ;
|
PtrOwner<ICurve> pJCrv( CalcJCurve( ptP0, dDir0Deg, ptP1, dDir1Deg)) ;
|
||||||
@@ -122,7 +122,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// non c'è intersezione, assegno valore medio
|
// non c'è intersezione, assegno valore medio
|
||||||
if ( dU < -0.5)
|
if ( dU < -0.5)
|
||||||
dU = 0.5 ;
|
dU = 0.5 ;
|
||||||
// elimino casi vicino agli estremi, danno solo problemi
|
// elimino casi vicino agli estremi, danno solo problemi
|
||||||
@@ -142,10 +142,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
|||||||
Point3d ptPrev = ptCurr ;
|
Point3d ptPrev = ptCurr ;
|
||||||
while ( bPnt) {
|
while ( bPnt) {
|
||||||
double dLen = Dist( ptCurr, ptPrev) ;
|
double dLen = Dist( ptCurr, ptPrev) ;
|
||||||
int nStep = int( dLen / STEP) + 1 ;
|
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ;
|
||||||
int nMinStep = ( dLen > 50 * dTol ? 3 : ( dLen > 10 * dTol ? 2 : 1)) ;
|
|
||||||
int nMaxStep = 10 ;
|
|
||||||
nStep = Clamp( nStep, nMinStep, nMaxStep) ;
|
|
||||||
for ( int i = 1 ; i <= nStep ; ++ i) {
|
for ( int i = 1 ; i <= nStep ; ++ i) {
|
||||||
double dCoeff = double( i) / nStep ;
|
double dCoeff = double( i) / nStep ;
|
||||||
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
|
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
|
||||||
@@ -166,7 +163,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
|||||||
static ICurve*
|
static ICurve*
|
||||||
CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg)
|
CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg)
|
||||||
{
|
{
|
||||||
// se i due punti coincidono, non si può fare alcunché
|
// se i due punti coincidono, non si può fare alcunché
|
||||||
if ( AreSamePointApprox( ptP0, ptP1))
|
if ( AreSamePointApprox( ptP0, ptP1))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
@@ -208,14 +205,14 @@ CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dD
|
|||||||
double dDir0RelDeg = DiffAngle( dDir0Deg, dDirDiffDeg) ;
|
double dDir0RelDeg = DiffAngle( dDir0Deg, dDirDiffDeg) ;
|
||||||
// direzione iniziale secondo arco limite rispetto a direzione P0->P1 (dalla finale simmetrico e invert)
|
// direzione iniziale secondo arco limite rispetto a direzione P0->P1 (dalla finale simmetrico e invert)
|
||||||
double dDir1RelDeg = - DiffAngle( dDir1Deg, dDirDiffDeg) ;
|
double dDir1RelDeg = - DiffAngle( dDir1Deg, dDirDiffDeg) ;
|
||||||
// nel caso di direzioni a 180deg si sceglie la più compatta
|
// nel caso di direzioni a 180deg si sceglie la più compatta
|
||||||
if ( abs( abs( dDir1RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
if ( abs( abs( dDir1RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
||||||
dDir1RelDeg = ( dDir0RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
dDir1RelDeg = ( dDir0RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||||
else if ( abs( abs( dDir0RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
else if ( abs( abs( dDir0RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
||||||
dDir0RelDeg = ( dDir1RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
dDir0RelDeg = ( dDir1RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||||
// intervallo angolare ammissibile a partire da direzione iniziale primo arco ammissibile ( == Dir0)
|
// intervallo angolare ammissibile a partire da direzione iniziale primo arco ammissibile ( == Dir0)
|
||||||
double dDeltaAngDeg = - dDir0RelDeg + dDir1RelDeg ;
|
double dDeltaAngDeg = - dDir0RelDeg + dDir1RelDeg ;
|
||||||
// se non è nella regione, prendo l'altra parte di arco
|
// se non è nella regione, prendo l'altra parte di arco
|
||||||
if ( ! AngleInSpan( dDirStartRelDeg, dDir0RelDeg, dDeltaAngDeg))
|
if ( ! AngleInSpan( dDirStartRelDeg, dDir0RelDeg, dDeltaAngDeg))
|
||||||
pArc->ToExplementary() ;
|
pArc->ToExplementary() ;
|
||||||
// inverto per avere parametrizzazione crescente allontanandosi da Dir0 e avvicinandosi a Dir1
|
// inverto per avere parametrizzazione crescente allontanandosi da Dir0 e avvicinandosi a Dir1
|
||||||
|
|||||||
@@ -17,5 +17,5 @@
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||||
const PolyLine& PL, double& dDist, double dTol) ;
|
const PolyLine& PL, double& dDist) ;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
|||||||
//----------------------------------------------------------------------------
|
|
||||||
// EgalTech 2024-2024
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// File : CAvSilhouetteSurfTm.h Data : 16.06.24 Versione : 2.6f2
|
|
||||||
// Contenuto : Dichiarazione della classe calcolo multi-silhouette.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Modifiche : 10.06.24 DS Creazione modulo.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CAvToolSurfTm.h"
|
|
||||||
#include "SurfFlatRegion.h"
|
|
||||||
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
|
|
||||||
{
|
|
||||||
public :
|
|
||||||
// generica
|
|
||||||
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol) override ;
|
|
||||||
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol,
|
|
||||||
double dSideAng, double dDiam, double dCornRad, double dMaxMat, double dOffsR,
|
|
||||||
double dMaxDepth) override ;
|
|
||||||
bool GetSilhouette( double dLevel, POLYLINEVECTOR& vPL) override ;
|
|
||||||
|
|
||||||
public :
|
|
||||||
CAvParSilhouettesSurfTm( void) ;
|
|
||||||
|
|
||||||
private :
|
|
||||||
bool Prepare( void) ;
|
|
||||||
|
|
||||||
private :
|
|
||||||
CISURFTMPVECTOR m_vpStm ;
|
|
||||||
CAvToolSurfTm m_cavTstm ;
|
|
||||||
Frame3d m_frGrid ;
|
|
||||||
double m_dTol ;
|
|
||||||
double m_dSharpedTol ;
|
|
||||||
int m_nStepX ;
|
|
||||||
int m_nStepY ;
|
|
||||||
double m_dRad ;
|
|
||||||
double m_dCornRad ;
|
|
||||||
double m_dMaxMat ;
|
|
||||||
double m_dSideAng ;
|
|
||||||
double m_dOffsR ;
|
|
||||||
double m_dDimZ ;
|
|
||||||
double m_dLevelOffs ;
|
|
||||||
double m_dMaxDepth ;
|
|
||||||
bool m_bGridOk ;
|
|
||||||
bool m_bTool ;
|
|
||||||
DBLVECTOR m_vdGrid ;
|
|
||||||
} ;
|
|
||||||
+54
-525
@@ -1,21 +1,21 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2018-2024
|
// EgalTech 2018-2018
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : CAvToolSurfTm.cpp Data : 07.06.24 Versione : 2.6f2
|
// File : CAvToolSurfTm.cpp Data : 08.05.18 Versione : 1.9e2
|
||||||
// Contenuto : Implementazione della classe CAvToolSurfTm.
|
// Contenuto : Implementazione della classe CAvToolSurfTm.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Modifiche : 27.04.18 DS Creazione modulo.
|
// Modifiche : 27.04.18 DS Creazione modulo.
|
||||||
// 07.06.24 DS Con tolleranza lineare negativa non si controlla il punto medio.
|
//
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CAvToolTriangle.h"
|
#include "CAvToolTriangle.h"
|
||||||
#include "CAvToolSurfTm.h"
|
#include "CAvToolSurfTm.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "DllMain.h"
|
#include "DllMain.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
@@ -24,7 +24,6 @@ using namespace std ;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const int STEP_PE = 50 ;
|
const int STEP_PE = 50 ;
|
||||||
const double MAX_MOVE = 20000 ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ICAvToolSurfTm*
|
ICAvToolSurfTm*
|
||||||
@@ -38,29 +37,10 @@ CreateCAvToolSurfTm( void)
|
|||||||
// CAvToolSurfTm
|
// CAvToolSurfTm
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
CAvToolSurfTm::CAvToolSurfTm( void)
|
CAvToolSurfTm::CAvToolSurfTm( void)
|
||||||
: m_frMove( false), m_Tool( false)
|
: m_Tool( false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::Clear( void)
|
|
||||||
{
|
|
||||||
// pulisco la lista dei puntatori a Stm
|
|
||||||
m_vSTM.clear() ;
|
|
||||||
// pulisco e inizializzo la prima posizione della lista delle basi per gli indici dei triangoli
|
|
||||||
m_vBaseInd.clear() ;
|
|
||||||
m_vBaseInd.emplace_back( 0) ;
|
|
||||||
// pulisco HashGrid 2d
|
|
||||||
m_HGrids.Clear() ;
|
|
||||||
// reset utensile
|
|
||||||
m_Tool.Clear() ;
|
|
||||||
// reset riferimento
|
|
||||||
m_frMove.Reset( false) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||||
@@ -70,9 +50,6 @@ CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
|||||||
// pulisco e inizializzo la prima posizione della lista delle basi per gli indici dei triangoli
|
// pulisco e inizializzo la prima posizione della lista delle basi per gli indici dei triangoli
|
||||||
m_vBaseInd.clear() ;
|
m_vBaseInd.clear() ;
|
||||||
m_vBaseInd.emplace_back( 0) ;
|
m_vBaseInd.emplace_back( 0) ;
|
||||||
// pulisco HashGrid 2d
|
|
||||||
m_HGrids.Clear() ;
|
|
||||||
// non tocco l'utensile
|
|
||||||
// aggiungo la superficie
|
// aggiungo la superficie
|
||||||
return AddSurfTm( Stm) ;
|
return AddSurfTm( Stm) ;
|
||||||
}
|
}
|
||||||
@@ -81,7 +58,7 @@ CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
|||||||
bool
|
bool
|
||||||
CAvToolSurfTm::AddSurfTm( const ISurfTriMesh& Stm)
|
CAvToolSurfTm::AddSurfTm( const ISurfTriMesh& Stm)
|
||||||
{
|
{
|
||||||
// verifico validità superficie
|
// verifico validità superficie
|
||||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &Stm) ;
|
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &Stm) ;
|
||||||
if ( pStm == nullptr || ! pStm->IsValid())
|
if ( pStm == nullptr || ! pStm->IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
@@ -122,227 +99,40 @@ CAvToolSurfTm::SetGenTool( const ICurveComposite* pToolOutline)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist)
|
||||||
double& dTotDist, Vector3d* pvtTriaN) const
|
|
||||||
{
|
{
|
||||||
// Se utensile non definito, errore
|
// Se utensile non definito, errore
|
||||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||||
return false ;
|
return false ;
|
||||||
// Se direzioni non definite, errore
|
// Imposto il riferimento di movimento
|
||||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
|
||||||
return false ;
|
|
||||||
// Se riferimento di movimento già presente
|
|
||||||
if ( m_frMove.IsValid()) {
|
|
||||||
// Calcolo nuovo riferimento di movimento
|
|
||||||
Frame3d frMove ;
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
|
||||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
|
||||||
else
|
|
||||||
frMove.Set( ORIG, vtMove) ;
|
|
||||||
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d
|
|
||||||
if ( AreSameFrame( frMove, m_frMove)) {
|
|
||||||
// Eseguo controllo
|
|
||||||
Point3d ptCurr = ptT ;
|
|
||||||
Vector3d vtTriaN ;
|
|
||||||
dTotDist = MyTestPositionHG( ptCurr, vtDir, vtTriaN) ;
|
|
||||||
if ( pvtTriaN != nullptr)
|
|
||||||
*pvtTriaN = vtTriaN ;
|
|
||||||
return ( dTotDist > - EPS_SMALL) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Altrimenti eseguo controllo diretto
|
|
||||||
Point3d ptCurr = ptT ;
|
|
||||||
Vector3d vtTriaN ;
|
|
||||||
dTotDist = MyTestPosition( ptCurr, vtDir, vtMove, vtTriaN) ;
|
|
||||||
if ( pvtTriaN != nullptr)
|
|
||||||
*pvtTriaN = vtTriaN ;
|
|
||||||
return ( dTotDist > - EPS_SMALL) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
|
||||||
double& dTotDist, VCT3DVECTOR& vVtN) const
|
|
||||||
{
|
|
||||||
// Funzione per calcolo collisione tra utensile e superfici ;
|
|
||||||
// dToTDist è la distanza di traslazione del punto ptT lungo vtDir per evitare la collisione,
|
|
||||||
// vVtN è la normale del triangolo che genera collsione ( NB. Nel caso di più triangoli concorrenti,
|
|
||||||
// vengono restituite tutte le normali trovate)
|
|
||||||
|
|
||||||
// Inizializzazione parametri
|
|
||||||
dTotDist = 0 ;
|
|
||||||
vVtN.clear() ;
|
|
||||||
// Se utensile non definito, errore
|
|
||||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
|
||||||
return false ;
|
|
||||||
// Se direzioni non definite, errore
|
|
||||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
|
||||||
return false ;
|
|
||||||
// Se riferimento di movimento già presente
|
|
||||||
if ( m_frMove.IsValid()) {
|
|
||||||
// Calcolo nuovo riferimento di movimento
|
|
||||||
Frame3d frMove ;
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
|
||||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
|
||||||
else
|
|
||||||
frMove.Set( ORIG, vtMove) ;
|
|
||||||
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d
|
|
||||||
if ( AreSameFrame( frMove, m_frMove)) {
|
|
||||||
// Eseguo controllo
|
|
||||||
Point3d ptCurr = ptT ;
|
|
||||||
dTotDist = MyTestPositionHGAdv( ptCurr, vtDir, vVtN) ;
|
|
||||||
return ( dTotDist > - EPS_SMALL) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Altrimenti eseguo controllo diretto
|
|
||||||
Point3d ptCurr = ptT ;
|
|
||||||
dTotDist = MyTestPositionAdv( ptCurr, vtDir, vtMove, vVtN) ;
|
|
||||||
return ( dTotDist > - EPS_SMALL) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff)
|
|
||||||
{
|
|
||||||
// Se utensile non definito, errore
|
|
||||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
|
||||||
return false ;
|
|
||||||
// Se direzioni non definite, errore
|
|
||||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
|
||||||
return false ;
|
|
||||||
// Se vettore vuoto, non devo fare alcunché
|
|
||||||
if ( vPntM.empty())
|
|
||||||
return true ;
|
|
||||||
// Calcolo nuovo riferimento di movimento
|
|
||||||
Frame3d frMove ;
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||||
else
|
else
|
||||||
frMove.Set( ORIG, vtMove) ;
|
m_frMove.Set( ORIG, vtMove) ;
|
||||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
// Eseguo controllo
|
||||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
Point3d ptCurr = ptT ;
|
||||||
// Salvo nuovo riferimento
|
dTotDist = MyTestPosition( ptCurr, vtDir) ;
|
||||||
m_frMove = frMove ;
|
return ( dTotDist > - EPS_SMALL) ;
|
||||||
// Ricalcolo HashGrid
|
|
||||||
if ( ! PrepareHashGrid())
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
// Determino il numero di punti dell'insieme
|
|
||||||
m_nTotPnt = int( vPntM.size()) ;
|
|
||||||
// Recupero il numero massimo di thread concorrenti
|
|
||||||
int nThreadMax = thread::hardware_concurrency() ;
|
|
||||||
bool bOk = true ;
|
|
||||||
// Se un solo thread o pochi punti
|
|
||||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
|
||||||
m_nCurrPnt = 0 ;
|
|
||||||
bOk = TestSubSeries( -1, vPntM, vtDir, 0, m_nTotPnt - 1, dProgCoeff) ;
|
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
const int MAX_PARTS = 32 ;
|
|
||||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
|
||||||
// calcolo le parti del vettore
|
|
||||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
|
||||||
int nPartDim = m_nTotPnt / nPartCnt + 1 ;
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
|
||||||
vFstLst[i].first = i * nPartDim ;
|
|
||||||
vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
|
|
||||||
}
|
|
||||||
// processo le parti
|
|
||||||
m_nCurrPnt = 0 ;
|
|
||||||
m_bBreak = false ;
|
|
||||||
future<bool> vRes[MAX_PARTS] ;
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
|
||||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubSeries, this, i, ref( vPntM), cref( vtDir), vFstLst[i].first, vFstLst[i].second, dProgCoeff) ;
|
|
||||||
// attendo i risultati
|
|
||||||
int nFin = 0 ;
|
|
||||||
int nNextPE = 0 ;
|
|
||||||
while ( nFin < nPartCnt) {
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
|
||||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
|
||||||
bOk = vRes[i].get() && bOk ;
|
|
||||||
++ nFin ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( m_nCurrPnt > nNextPE) {
|
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
|
||||||
nNextPE += STEP_PE ;
|
|
||||||
if ( nRes == 1)
|
|
||||||
m_bBreak = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
|
||||||
}
|
|
||||||
return bOk ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CAvToolSurfTm::TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff)
|
CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol)
|
||||||
{
|
|
||||||
// Se vettore vuoto, non devo fare alcunché
|
|
||||||
if ( vPntM.empty())
|
|
||||||
return true ;
|
|
||||||
// Ciclo sui punti da verificare
|
|
||||||
for ( int i = nFirst ; i <= nLast ; ++ i) {
|
|
||||||
// verifico il punto
|
|
||||||
Vector3d vtTriaN ;
|
|
||||||
double dMove = MyTestPositionHG( vPntM[i].first, vtDir, vtTriaN) ;
|
|
||||||
vPntM[i].second = dMove ;
|
|
||||||
if ( dMove < - EPS_SMALL)
|
|
||||||
return false ;
|
|
||||||
++ m_nCurrPnt ;
|
|
||||||
// se singolo thread
|
|
||||||
if ( nId == -1) {
|
|
||||||
// gestione eventi (ogni STEP_PE punti)
|
|
||||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
|
||||||
if ( nRes == 1)
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti multithread
|
|
||||||
else {
|
|
||||||
if ( m_bBreak)
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff)
|
|
||||||
{
|
{
|
||||||
// Se utensile non definito, errore
|
// Se utensile non definito, errore
|
||||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||||
return false ;
|
return false ;
|
||||||
// Se direzioni non definite, errore
|
// Se lista vuota, non devo fare alcunché
|
||||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
|
||||||
return false ;
|
|
||||||
// Se lista vuota, non devo fare alcunché
|
|
||||||
if ( lPntM.empty())
|
if ( lPntM.empty())
|
||||||
return true ;
|
return true ;
|
||||||
// Controllo la tolleranza lineare (se negativa non vanno fatti controlli sui punti medi)
|
// Imposto il riferimento di movimento
|
||||||
if ( dLinTol > -EPS_ZERO)
|
|
||||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
||||||
else
|
|
||||||
dLinTol = -1 ;
|
|
||||||
// Calcolo nuovo riferimento di movimento
|
|
||||||
Frame3d frMove ;
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||||
else
|
else
|
||||||
frMove.Set( ORIG, vtMove) ;
|
m_frMove.Set( ORIG, vtMove) ;
|
||||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
// Predispongo Hash Grid
|
||||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
if ( ! PrepareHashGrid())
|
||||||
// Salvo nuovo riferimento
|
return false ;
|
||||||
m_frMove = frMove ;
|
|
||||||
// Ricalcolo HashGrid
|
|
||||||
if ( ! PrepareHashGrid())
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
// Determino il numero di punti del path
|
// Determino il numero di punti del path
|
||||||
m_nTotPnt = int( lPntM.size()) ;
|
m_nTotPnt = int( lPntM.size()) ;
|
||||||
// Recupero il numero massimo di thread concorrenti
|
// Recupero il numero massimo di thread concorrenti
|
||||||
@@ -350,9 +140,8 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
|||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
// Se un solo thread o pochi punti
|
// Se un solo thread o pochi punti
|
||||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||||
m_nCurrPnt = 0 ;
|
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol) ;
|
||||||
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol, dProgCoeff) ;
|
ProcessEvents( 100, 0) ;
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
|
||||||
}
|
}
|
||||||
// altrimenti
|
// altrimenti
|
||||||
else {
|
else {
|
||||||
@@ -372,7 +161,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
|||||||
m_bBreak = false ;
|
m_bBreak = false ;
|
||||||
future<bool> vRes[MAX_PARTS] ;
|
future<bool> vRes[MAX_PARTS] ;
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol, dProgCoeff) ;
|
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol) ;
|
||||||
// attendo i risultati
|
// attendo i risultati
|
||||||
int nFin = 0 ;
|
int nFin = 0 ;
|
||||||
int nNextPE = 0 ;
|
int nNextPE = 0 ;
|
||||||
@@ -384,7 +173,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( m_nCurrPnt > nNextPE) {
|
if ( m_nCurrPnt > nNextPE) {
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 10) ;
|
||||||
nNextPE += STEP_PE ;
|
nNextPE += STEP_PE ;
|
||||||
if ( nRes == 1)
|
if ( nRes == 1)
|
||||||
m_bBreak = true ;
|
m_bBreak = true ;
|
||||||
@@ -396,98 +185,18 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
|||||||
lPntM.pop_back() ;
|
lPntM.pop_back() ;
|
||||||
lPntM.splice( lPntM.end(), vlPntM[i]) ;
|
lPntM.splice( lPntM.end(), vlPntM[i]) ;
|
||||||
}
|
}
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
ProcessEvents( 100, 0) ;
|
||||||
}
|
}
|
||||||
|
// pulisco HashGrid 2d
|
||||||
|
m_HGrids.Clear() ;
|
||||||
return bOk ;
|
return bOk ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CAvToolSurfTm::TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff)
|
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
|
||||||
{
|
{
|
||||||
// NB. la posizione del punto non viene modificata :
|
// Se lista vuota, non devo fare alcunché
|
||||||
// get<0> vPntM[i] è il punto su cui viene posizionata la testa dell'utensile ( const)
|
|
||||||
// get<1> vPntM[i] è il parametro di traslazione del punto lungo vtDir per evitare collisioni con i triangoli
|
|
||||||
// get<2> vPntM[i] è un vettore di Vector3d contenente tutte le normali di tangenza ( a meno di 10 * EPS_SMALL)
|
|
||||||
|
|
||||||
// Se utensile non definito, errore
|
|
||||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
|
||||||
return false ;
|
|
||||||
// Se direzioni non definite, errore
|
|
||||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
|
||||||
return false ;
|
|
||||||
// Se vettore vuoto, non devo fare alcunché
|
|
||||||
if ( vPntM.empty())
|
|
||||||
return true ;
|
|
||||||
// Calcolo nuovo riferimento di movimento
|
|
||||||
Frame3d frMove ;
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
|
||||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
|
||||||
else
|
|
||||||
frMove.Set( ORIG, vtMove) ;
|
|
||||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
|
||||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
|
||||||
// Salvo nuovo riferimento
|
|
||||||
m_frMove = frMove ;
|
|
||||||
// Ricalcolo HashGrid
|
|
||||||
if ( ! PrepareHashGrid())
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
// Determino il numero di punti del path
|
|
||||||
m_nTotPnt = int( vPntM.size()) ;
|
|
||||||
// Recupero il numero massimo di thread concorrenti
|
|
||||||
int nThreadMax = thread::hardware_concurrency() ;
|
|
||||||
bool bOk = true ;
|
|
||||||
// Se un solo thread o pochi punti
|
|
||||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
|
||||||
m_nCurrPnt = 0 ;
|
|
||||||
bOk = TestSubSeriesAdv( -1, vPntM, vtDir, 0, m_nTotPnt - 1, dProgCoeff) ;
|
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
const int MAX_PARTS = 32 ;
|
|
||||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
|
||||||
// calcolo le parti del vettore
|
|
||||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
|
||||||
int nPartDim = m_nTotPnt / nPartCnt + 1 ;
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
|
||||||
vFstLst[i].first = i * nPartDim ;
|
|
||||||
vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
|
|
||||||
}
|
|
||||||
// processo le parti
|
|
||||||
m_nCurrPnt = 0 ;
|
|
||||||
m_bBreak = false ;
|
|
||||||
future<bool> vRes[MAX_PARTS] ;
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
|
||||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubSeriesAdv, this, i, ref( vPntM), cref( vtDir), vFstLst[i].first, vFstLst[i].second, dProgCoeff) ;
|
|
||||||
// attendo i risultati
|
|
||||||
int nFin = 0 ;
|
|
||||||
int nNextPE = 0 ;
|
|
||||||
while ( nFin < nPartCnt) {
|
|
||||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
|
||||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
|
||||||
bOk = vRes[i].get() && bOk ;
|
|
||||||
++ nFin ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( m_nCurrPnt > nNextPE) {
|
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
|
||||||
nNextPE += STEP_PE ;
|
|
||||||
if ( nRes == 1)
|
|
||||||
m_bBreak = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
|
||||||
}
|
|
||||||
return bOk ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff)
|
|
||||||
{
|
|
||||||
// Se lista vuota, non devo fare alcunché
|
|
||||||
if ( lPntM.empty())
|
if ( lPntM.empty())
|
||||||
return true ;
|
return true ;
|
||||||
// Ciclo sui punti
|
// Ciclo sui punti
|
||||||
@@ -497,13 +206,11 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
|||||||
while ( itPntMCurr != lPntM.end()) {
|
while ( itPntMCurr != lPntM.end()) {
|
||||||
// verifico il punto
|
// verifico il punto
|
||||||
ptCurr = itPntMCurr->first ;
|
ptCurr = itPntMCurr->first ;
|
||||||
Vector3d vtTriaN ;
|
itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ;
|
||||||
double dMove = MyTestPositionHG( itPntMCurr->first, vtDir, vtTriaN) ;
|
if ( itPntMCurr->second < - EPS_SMALL)
|
||||||
itPntMCurr->second = dMove ;
|
|
||||||
if ( dMove < - EPS_SMALL)
|
|
||||||
return false ;
|
return false ;
|
||||||
// se esiste il punto precedente e richiesto devo verificare il medio
|
// se esiste il punto precedente devo verificare il medio
|
||||||
if ( itPntMPrev != lPntM.end() && dLinTol > 0) {
|
if ( itPntMPrev != lPntM.end()) {
|
||||||
MyTestMidPointHG( lPntM, itPntMPrev, itPntMCurr, ptPrev, ptCurr, vtDir, dLinTol, 1) ;
|
MyTestMidPointHG( lPntM, itPntMPrev, itPntMCurr, ptPrev, ptCurr, vtDir, dLinTol, 1) ;
|
||||||
}
|
}
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
@@ -515,7 +222,7 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
|||||||
if ( nId == -1) {
|
if ( nId == -1) {
|
||||||
// gestione eventi (ogni STEP_PE punti)
|
// gestione eventi (ogni STEP_PE punti)
|
||||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
if (( m_nCurrPnt % STEP_PE) == 0) {
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 0) ;
|
||||||
if ( nRes == 1)
|
if ( nRes == 1)
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -529,44 +236,10 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CAvToolSurfTm::TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff)
|
|
||||||
{
|
|
||||||
// Se vettore vuoto, non devo fare alcunché
|
|
||||||
if ( vPntM.empty())
|
|
||||||
return true ;
|
|
||||||
// Ciclo sui punti da verificare
|
|
||||||
for ( int i = nFirst ; i <= nLast ; ++ i) {
|
|
||||||
// verifico il punto
|
|
||||||
Point3d ptCurr = get<0>( vPntM[i]) ;
|
|
||||||
get<1>( vPntM[i]) = MyTestPositionHGAdv( ptCurr, vtDir, get<2>( vPntM[i])) ;
|
|
||||||
if ( get<1>( vPntM[i]) < - EPS_SMALL)
|
|
||||||
return false ;
|
|
||||||
++ m_nCurrPnt ;
|
|
||||||
// se singolo thread
|
|
||||||
if ( nId == -1) {
|
|
||||||
// gestione eventi (ogni STEP_PE punti)
|
|
||||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
|
||||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
|
||||||
if ( nRes == 1)
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti multithread
|
|
||||||
else {
|
|
||||||
if ( m_bBreak)
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
||||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const
|
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev)
|
||||||
{
|
{
|
||||||
// se superato limite di ricursione, esco
|
// se superato limite di ricursione, esco
|
||||||
const int MAX_LEV = 10 ;
|
const int MAX_LEV = 10 ;
|
||||||
@@ -576,8 +249,7 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
|||||||
Point3d ptMid = Media( ptPrev, ptCurr, 0.5) ;
|
Point3d ptMid = Media( ptPrev, ptCurr, 0.5) ;
|
||||||
// ne effettuo la correzione per evitare la collisione
|
// ne effettuo la correzione per evitare la collisione
|
||||||
Point3d ptNewMid = ptMid ;
|
Point3d ptNewMid = ptMid ;
|
||||||
Vector3d vtTriaN ;
|
double dMidMove = MyTestPositionHG( ptNewMid, vtDir) ;
|
||||||
double dMidMove = MyTestPositionHG( ptNewMid, vtDir, vtTriaN) ;
|
|
||||||
if ( dMidMove < - EPS_SMALL)
|
if ( dMidMove < - EPS_SMALL)
|
||||||
return false ;
|
return false ;
|
||||||
// massima distanza ammissibile
|
// massima distanza ammissibile
|
||||||
@@ -586,7 +258,7 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
|||||||
if ( abs(( Media( itPntMPrev->first, itPntMCurr->first, 0.5) - ptNewMid) * m_frMove.VersZ()) > 0.5 * dLinTol ||
|
if ( abs(( Media( itPntMPrev->first, itPntMCurr->first, 0.5) - ptNewMid) * m_frMove.VersZ()) > 0.5 * dLinTol ||
|
||||||
SqDist( itPntMPrev->first, itPntMCurr->first) > dMaxSqDist) {
|
SqDist( itPntMPrev->first, itPntMCurr->first) > dMaxSqDist) {
|
||||||
// aggiungo
|
// aggiungo
|
||||||
lPntM.emplace( itPntMCurr, ptNewMid, dMidMove) ;
|
lPntM.emplace( itPntMCurr, ptNewMid, - dMidMove) ;
|
||||||
auto itPntMMid = itPntMCurr ;
|
auto itPntMMid = itPntMCurr ;
|
||||||
-- itPntMMid ;
|
-- itPntMMid ;
|
||||||
// verifico intervallo precedente
|
// verifico intervallo precedente
|
||||||
@@ -599,48 +271,20 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
double
|
double
|
||||||
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const
|
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
|
||||||
{
|
{
|
||||||
// box dell'utensile con suo movimento
|
|
||||||
BBox3d b3Tool ;
|
|
||||||
// utensile
|
|
||||||
b3Tool.Add( ptT) ;
|
|
||||||
b3Tool.Add( ptT - vtDir * m_Tool.GetHeigth()) ;
|
|
||||||
if ( vtDir.IsX())
|
|
||||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDir.IsY())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDir.IsZ())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
|
||||||
else {
|
|
||||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDir.x * vtDir.x) ;
|
|
||||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDir.y * vtDir.y) ;
|
|
||||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDir.z * vtDir.z) ;
|
|
||||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
|
||||||
}
|
|
||||||
// aggiungo movimento
|
|
||||||
BBox3d b3Moved = b3Tool ;
|
|
||||||
b3Moved.Translate( MAX_MOVE * vtMove) ;
|
|
||||||
b3Tool.Add( b3Moved) ;
|
|
||||||
|
|
||||||
// determino movimento minimo per evitare collisione con superfici
|
|
||||||
double dTotDist = 0 ;
|
double dTotDist = 0 ;
|
||||||
vtTriaN = V_NULL ;
|
|
||||||
for ( auto pStm : m_vSTM) {
|
for ( auto pStm : m_vSTM) {
|
||||||
INTVECTOR vTria ;
|
Triangle3d Tria ;
|
||||||
if ( pStm->GetAllTriaOverlapBox( b3Tool, vTria)) {
|
for ( int nTria = pStm->GetFirstTriangle( Tria) ;
|
||||||
for ( int nTria : vTria) {
|
nTria != SVT_NULL ;
|
||||||
Triangle3d Tria ;
|
nTria = pStm->GetNextTriangle( nTria, Tria)) {
|
||||||
if ( pStm->GetTriangle( nTria, Tria)) {
|
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
|
||||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
|
if ( dDist < - EPS_SMALL)
|
||||||
if ( dDist < - EPS_SMALL)
|
return -1 ;
|
||||||
return -1 ;
|
if ( dDist > EPS_SMALL) {
|
||||||
if ( dDist > EPS_SMALL) {
|
dTotDist += dDist ;
|
||||||
dTotDist += dDist ;
|
ptT += dDist * m_frMove.VersZ() ;
|
||||||
ptT += dDist * vtMove ;
|
|
||||||
vtTriaN = Tria.GetN() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,61 +293,7 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
double
|
double
|
||||||
CAvToolSurfTm::MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const
|
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||||
{
|
|
||||||
// box dell'utensile con suo movimento
|
|
||||||
BBox3d b3Tool ;
|
|
||||||
// utensile
|
|
||||||
b3Tool.Add( ptT) ;
|
|
||||||
b3Tool.Add( ptT - vtDir * m_Tool.GetHeigth()) ;
|
|
||||||
if ( vtDir.IsX())
|
|
||||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDir.IsY())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDir.IsZ())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
|
||||||
else {
|
|
||||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDir.x * vtDir.x) ;
|
|
||||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDir.y * vtDir.y) ;
|
|
||||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDir.z * vtDir.z) ;
|
|
||||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
|
||||||
}
|
|
||||||
// aggiungo movimento
|
|
||||||
BBox3d b3Moved = b3Tool ;
|
|
||||||
b3Moved.Translate( MAX_MOVE * vtMove) ;
|
|
||||||
b3Tool.Add( b3Moved) ;
|
|
||||||
|
|
||||||
// determino movimento minimo per evitare collisione con superfici
|
|
||||||
double dTotDist = 0 ;
|
|
||||||
vVtTriaN.clear() ;
|
|
||||||
for ( auto pStm : m_vSTM) {
|
|
||||||
INTVECTOR vTria ;
|
|
||||||
if ( pStm->GetAllTriaOverlapBox( b3Tool, vTria)) {
|
|
||||||
for ( int nTria : vTria) {
|
|
||||||
Triangle3d Tria ;
|
|
||||||
if ( pStm->GetTriangle( nTria, Tria)) {
|
|
||||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
|
|
||||||
if ( dDist < - EPS_SMALL)
|
|
||||||
return -1 ;
|
|
||||||
// se devo traslare il punto, c'è collisione
|
|
||||||
if ( dDist > EPS_SMALL) {
|
|
||||||
if ( dDist > 10 * EPS_SMALL) {
|
|
||||||
vVtTriaN.clear() ;
|
|
||||||
dTotDist += dDist ;
|
|
||||||
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
|
|
||||||
}
|
|
||||||
vVtTriaN.push_back( Tria.GetN()) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dTotDist ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
double
|
|
||||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const
|
|
||||||
{
|
{
|
||||||
// calcolo box utensile nel riferimento di movimento
|
// calcolo box utensile nel riferimento di movimento
|
||||||
BBox3d b3Tool ;
|
BBox3d b3Tool ;
|
||||||
@@ -723,10 +313,8 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d&
|
|||||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
|
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
|
||||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
||||||
}
|
}
|
||||||
|
// ciclo sui triangoli che intersecano box in 2d
|
||||||
// ciclo sui triangoli che intersecano box in 2d
|
|
||||||
double dTotDist = 0 ;
|
double dTotDist = 0 ;
|
||||||
vtTriaN = V_NULL ;
|
|
||||||
INTVECTOR vnIds ;
|
INTVECTOR vnIds ;
|
||||||
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
||||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||||
@@ -742,70 +330,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d&
|
|||||||
if ( dDist > EPS_SMALL) {
|
if ( dDist > EPS_SMALL) {
|
||||||
dTotDist += dDist ;
|
dTotDist += dDist ;
|
||||||
ptT += dDist * m_frMove.VersZ() ;
|
ptT += dDist * m_frMove.VersZ() ;
|
||||||
vtTriaN = Tria.GetN() ;
|
|
||||||
}
|
}
|
||||||
else if ( dDist < -EPS_SMALL)
|
else if ( dDist < -EPS_SMALL)
|
||||||
return -1 ;
|
return -1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dTotDist ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
double
|
|
||||||
CAvToolSurfTm::MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const
|
|
||||||
{
|
|
||||||
// calcolo box utensile nel riferimento di movimento
|
|
||||||
BBox3d b3Tool ;
|
|
||||||
Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ;
|
|
||||||
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
|
|
||||||
b3Tool.Add( ptTL) ;
|
|
||||||
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
|
|
||||||
if ( vtDirL.IsX())
|
|
||||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDirL.IsY())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
|
||||||
else if ( vtDirL.IsZ())
|
|
||||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
|
||||||
else {
|
|
||||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
|
|
||||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDirL.y * vtDirL.y) ;
|
|
||||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
|
|
||||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ciclo sui triangoli che intersecano box in 2d
|
|
||||||
double dTotDist = 0. ;
|
|
||||||
INTVECTOR vnIds ;
|
|
||||||
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
|
||||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
|
||||||
// recupero la superficie
|
|
||||||
int nInd = vnIds[i] ;
|
|
||||||
int nSurf = GetSurfInd( nInd) ;
|
|
||||||
if ( nSurf == -1)
|
|
||||||
return -1 ;
|
|
||||||
// recupero il triangolo
|
|
||||||
int nT = nInd - m_vBaseInd[nSurf] ;
|
|
||||||
Triangle3d Tria ;
|
|
||||||
if ( ! m_vSTM[nSurf]->GetTriangle( nT, Tria))
|
|
||||||
return -1 ;
|
|
||||||
// calcolo della collisione
|
|
||||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
|
|
||||||
if ( dDist < - EPS_SMALL)
|
|
||||||
return -1 ;
|
|
||||||
// se devo traslare il punto, c'è collisione
|
|
||||||
if ( dDist > EPS_SMALL) {
|
|
||||||
if ( dDist > 10 * EPS_SMALL) {
|
|
||||||
vVtTriaN.clear() ;
|
|
||||||
dTotDist += dDist ;
|
|
||||||
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
|
|
||||||
}
|
|
||||||
vVtTriaN.push_back( Tria.GetN()) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dTotDist ;
|
return dTotDist ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,7 +345,7 @@ CAvToolSurfTm::PrepareHashGrid( void)
|
|||||||
// pulisco HashGrid 2d
|
// pulisco HashGrid 2d
|
||||||
m_HGrids.Clear() ;
|
m_HGrids.Clear() ;
|
||||||
// verifico esistenza superfici
|
// verifico esistenza superfici
|
||||||
if ( m_vSTM.empty() || m_vBaseInd.size() < m_vSTM.size() + 1)
|
if ( m_vSTM.size() == 0 || m_vBaseInd.size() < m_vSTM.size() + 1)
|
||||||
return false ;
|
return false ;
|
||||||
// creo HashGrid 2d
|
// creo HashGrid 2d
|
||||||
const int LIM_HG_TRIA = 256 ;
|
const int LIM_HG_TRIA = 256 ;
|
||||||
@@ -843,7 +372,7 @@ CAvToolSurfTm::PrepareHashGrid( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
CAvToolSurfTm::GetSurfInd( int nT) const
|
CAvToolSurfTm::GetSurfInd( int nT)
|
||||||
{
|
{
|
||||||
// verifico la presenza di almeno un intervallo
|
// verifico la presenza di almeno un intervallo
|
||||||
if ( m_vBaseInd.size() < 2)
|
if ( m_vBaseInd.size() < 2)
|
||||||
|
|||||||
+7
-32
@@ -34,47 +34,22 @@ class CAvToolSurfTm : public ICAvToolSurfTm
|
|||||||
{ return m_Tool.GetRadius() ; }
|
{ return m_Tool.GetRadius() ; }
|
||||||
double GetToolHeight( void) const override
|
double GetToolHeight( void) const override
|
||||||
{ return m_Tool.GetHeigth() ; }
|
{ return m_Tool.GetHeigth() ; }
|
||||||
double GetToolTipHeight( void) const override
|
|
||||||
{ return m_Tool.GetTipHeigth() ; } ;
|
|
||||||
double GetToolTipRadius( void) const override
|
|
||||||
{ return m_Tool.GetTipRadius() ; } ;
|
|
||||||
double GetToolCornRadius( void) const override
|
|
||||||
{ return m_Tool.GetCornRadius() ; } ;
|
|
||||||
CISURFTMPVECTOR GetvStm( void) const {
|
|
||||||
CISURFTMPVECTOR vcStm ;
|
|
||||||
for ( int i = 0 ; i < int( m_vSTM.size()) ; ++ i)
|
|
||||||
vcStm.emplace_back( CloneSurfTriMesh( m_vSTM[i])) ;
|
|
||||||
return vcStm ;
|
|
||||||
}
|
|
||||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
||||||
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
||||||
|
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist) override ;
|
||||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol) override ;
|
||||||
double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ;
|
|
||||||
bool TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
|
||||||
double& dTotDist, VCT3DVECTOR& vVtN) const override ;
|
|
||||||
|
|
||||||
bool TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
|
|
||||||
bool TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
|
|
||||||
|
|
||||||
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff = 1) override ;
|
|
||||||
|
|
||||||
public :
|
public :
|
||||||
CAvToolSurfTm( void) ;
|
CAvToolSurfTm( void) ;
|
||||||
bool Clear( void) ;
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
|
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol) ;
|
||||||
bool TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
|
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir) ;
|
||||||
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff) ;
|
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir) ;
|
||||||
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const ;
|
|
||||||
double MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const ;
|
|
||||||
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const ;
|
|
||||||
double MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const ;
|
|
||||||
bool MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
bool MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
||||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ;
|
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) ;
|
||||||
bool PrepareHashGrid( void) ;
|
bool PrepareHashGrid( void) ;
|
||||||
int GetSurfInd( int nT) const ;
|
int GetSurfInd( int nT) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
typedef std::vector<const SurfTriMesh*> CSURFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
typedef std::vector<const SurfTriMesh*> CSURFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@
|
|||||||
#include "CAvToolTriangle.h"
|
#include "CAvToolTriangle.h"
|
||||||
#include "IntersLineSurfStd.h"
|
#include "IntersLineSurfStd.h"
|
||||||
#include "IntersLineTria.h"
|
#include "IntersLineTria.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "CDeUtility.h"
|
#include "CDeUtility.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntervals.h"
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
@@ -2503,7 +2503,7 @@ DiskSegmentEscapeDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
|
|||||||
double dSegDist = 0. ;
|
double dSegDist = 0. ;
|
||||||
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
|
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
|
||||||
// Soluzione interna al segmento
|
// Soluzione interna al segmento
|
||||||
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen + EPS_ZERO) {
|
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen) {
|
||||||
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
|
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
|
||||||
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
|
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
|
||||||
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
|
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
|
||||||
|
|||||||
+1
-1
@@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "CDeCylTria.h"
|
#include "CDeCylTria.h"
|
||||||
#include "CDeConvexTorusTria.h"
|
#include "CDeConvexTorusTria.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|||||||
+2
-1
@@ -12,10 +12,11 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "DistLineLine.h"
|
||||||
#include "CDeTriaTria.h"
|
#include "CDeTriaTria.h"
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
|
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CDeUtility.h"
|
#include "CDeUtility.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|||||||
+1789
-7893
File diff suppressed because it is too large
Load Diff
+23
-26
@@ -2,7 +2,7 @@
|
|||||||
// EgalTech 2013-2014
|
// EgalTech 2013-2014
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : ChainCurves.cpp Data : 20.07.14 Versione : 1.5g3
|
// File : ChainCurves.cpp Data : 20.07.14 Versione : 1.5g3
|
||||||
// Contenuto : Implementazione della funzione ChainCurves, per creare una o più
|
// Contenuto : Implementazione della funzione ChainCurves, per creare una o più
|
||||||
// curve composite a partire dalle curve date.
|
// curve composite a partire dalle curve date.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -43,10 +43,10 @@ bool
|
|||||||
ChainCurves::AddCurve( int nId, const Point3d& ptStart, const Vector3d& vtStart,
|
ChainCurves::AddCurve( int nId, const Point3d& ptStart, const Vector3d& vtStart,
|
||||||
const Point3d& ptEnd, const Vector3d& vtEnd)
|
const Point3d& ptEnd, const Vector3d& vtEnd)
|
||||||
{
|
{
|
||||||
// verifico validità Id
|
// verifico validità Id
|
||||||
if ( nId <= 0)
|
if ( nId <= 0)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico non sia già stata aggiunta la stessa entità
|
// verifico non sia già stata aggiunta la stessa entità
|
||||||
if ( ! m_sCrvId.insert( nId).second)
|
if ( ! m_sCrvId.insert( nId).second)
|
||||||
return true ;
|
return true ;
|
||||||
// inserisco i dati della curva nel vettore
|
// inserisco i dati della curva nel vettore
|
||||||
@@ -68,7 +68,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
|||||||
m_bIsFork = false ;
|
m_bIsFork = false ;
|
||||||
m_vFork.clear() ;
|
m_vFork.clear() ;
|
||||||
|
|
||||||
// recupero l'entità più vicina al punto di start
|
// recupero l'entità più vicina al punto di start
|
||||||
int nStart ;
|
int nStart ;
|
||||||
INTVECTOR vStart ;
|
INTVECTOR vStart ;
|
||||||
if ( ! m_PointGrid.FindNearest( ptStart, vStart) ||
|
if ( ! m_PointGrid.FindNearest( ptStart, vStart) ||
|
||||||
@@ -82,7 +82,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
|||||||
// tolgo dal grid
|
// tolgo dal grid
|
||||||
RemoveEntityFromGrid( nId) ;
|
RemoveEntityFromGrid( nId) ;
|
||||||
|
|
||||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||||
bool bSkip = false ;
|
bool bSkip = false ;
|
||||||
if ( bHaltOnFork) {
|
if ( bHaltOnFork) {
|
||||||
auto iIter = GetForkPoint( m_vCrvData[nId].ptEnd) ;
|
auto iIter = GetForkPoint( m_vCrvData[nId].ptEnd) ;
|
||||||
@@ -93,7 +93,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// concateno dopo la fine dell'entità di partenza
|
// concateno dopo la fine dell'entità di partenza
|
||||||
INTVECTOR vIdsAfter ;
|
INTVECTOR vIdsAfter ;
|
||||||
bool bClosed = false ;
|
bool bClosed = false ;
|
||||||
if ( ! bSkip && ! GetChainFromPoint( m_vCrvData[nId].ptEnd, m_vCrvData[nId].vtEnd,
|
if ( ! bSkip && ! GetChainFromPoint( m_vCrvData[nId].ptEnd, m_vCrvData[nId].vtEnd,
|
||||||
@@ -102,7 +102,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||||
bool bRevSkip = false ;
|
bool bRevSkip = false ;
|
||||||
if ( bHaltOnFork) {
|
if ( bHaltOnFork) {
|
||||||
auto iIter = GetForkPoint( m_vCrvData[nId].ptStart) ;
|
auto iIter = GetForkPoint( m_vCrvData[nId].ptStart) ;
|
||||||
@@ -113,7 +113,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se non ho già chiuso l'anello, concateno prima dell'inizio dell'entità di partenza
|
// se non ho già chiuso l'anello, concateno prima dell'inizio dell'entità di partenza
|
||||||
INTVECTOR vIdsBefore ;
|
INTVECTOR vIdsBefore ;
|
||||||
if ( ! bClosed) {
|
if ( ! bClosed) {
|
||||||
bool bRevClosed ;
|
bool bRevClosed ;
|
||||||
@@ -258,7 +258,7 @@ ChainCurves::RemoveEntityFromGrid( int nId)
|
|||||||
bool
|
bool
|
||||||
ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int& nStart)
|
ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int& nStart)
|
||||||
{
|
{
|
||||||
// numero di entità candidate
|
// numero di entità candidate
|
||||||
int nSize = int( vStart.size()) ;
|
int nSize = int( vStart.size()) ;
|
||||||
|
|
||||||
// se nessuna, errore
|
// se nessuna, errore
|
||||||
@@ -273,7 +273,7 @@ ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int&
|
|||||||
|
|
||||||
// altrimenti, cerco la migliore
|
// altrimenti, cerco la migliore
|
||||||
int nI = - 1 ;
|
int nI = - 1 ;
|
||||||
double dDistMin = INFINITO ;
|
double dSqDistMin = SQ_INFINITO ;
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||||
// recupero indice e verso
|
// recupero indice e verso
|
||||||
int nId = abs( vStart[i]) - 1 ;
|
int nId = abs( vStart[i]) - 1 ;
|
||||||
@@ -281,12 +281,9 @@ ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int&
|
|||||||
// calcolo un punto vicino all'estremo lungo la tangente
|
// calcolo un punto vicino all'estremo lungo la tangente
|
||||||
Point3d ptNear = ( bEquiv ? m_vCrvData[nId].ptStart + m_vCrvData[nId].vtStart :
|
Point3d ptNear = ( bEquiv ? m_vCrvData[nId].ptStart + m_vCrvData[nId].vtStart :
|
||||||
m_vCrvData[nId].ptEnd - m_vCrvData[nId].vtEnd) ;
|
m_vCrvData[nId].ptEnd - m_vCrvData[nId].vtEnd) ;
|
||||||
double dDist = Dist( ptStart, ptNear) ;
|
double dSqDist = SqDist( ptStart, ptNear) ;
|
||||||
// tengo il segmento più vicino al punto
|
if ( dSqDist < dSqDistMin) {
|
||||||
// favorendo eventualmente quello equiverso se entro EPS da un concorrente
|
dSqDistMin = dSqDist ;
|
||||||
if ( dDist < dDistMin - EPS_SMALL ||
|
|
||||||
((dDist < dDistMin + EPS_SMALL) && bEquiv && vStart[nI] < 0)) {
|
|
||||||
dDistMin = dDist ;
|
|
||||||
nI = i ;
|
nI = i ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +302,7 @@ bool
|
|||||||
ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vNext, bool bHaltOnFork, int& nNext)
|
ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vNext, bool bHaltOnFork, int& nNext)
|
||||||
{
|
{
|
||||||
INTVECTOR vMyNext = vNext ;
|
INTVECTOR vMyNext = vNext ;
|
||||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||||
int nM = -1 ;
|
int nM = -1 ;
|
||||||
Point3d ptRef ;
|
Point3d ptRef ;
|
||||||
double dSqMinDist = m_dToler * m_dToler ;
|
double dSqMinDist = m_dToler * m_dToler ;
|
||||||
@@ -322,19 +319,19 @@ ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
|
||||||
// salto l'entità più vicina
|
// salto l'entità più vicina
|
||||||
if ( i == nM)
|
if ( i == nM)
|
||||||
continue ;
|
continue ;
|
||||||
// recupero indice e verso
|
// recupero indice e verso
|
||||||
int nId = abs( vMyNext[i]) - 1 ;
|
int nId = abs( vMyNext[i]) - 1 ;
|
||||||
bool bEquiv = ( vMyNext[i] > 0) ;
|
bool bEquiv = ( vMyNext[i] > 0) ;
|
||||||
// verifico se più vicino al più vicino
|
// verifico se più vicino al più vicino
|
||||||
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
||||||
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
||||||
if ( dRefSqDist < dCurrSqDist)
|
if ( dRefSqDist < dCurrSqDist)
|
||||||
vMyNext[i] = 0 ;
|
vMyNext[i] = 0 ;
|
||||||
}
|
}
|
||||||
// cerco la direzione più vicina
|
// cerco la direzione più vicina
|
||||||
int nI = -1 ;
|
int nI = -1 ;
|
||||||
int nF = 0 ;
|
int nF = 0 ;
|
||||||
INTVECTOR vFork ;
|
INTVECTOR vFork ;
|
||||||
@@ -346,7 +343,7 @@ ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
|||||||
// recupero indice e verso
|
// recupero indice e verso
|
||||||
int nId = abs( vMyNext[i]) - 1 ;
|
int nId = abs( vMyNext[i]) - 1 ;
|
||||||
bool bEquiv = ( vMyNext[i] > 0) ;
|
bool bEquiv = ( vMyNext[i] > 0) ;
|
||||||
// incremento contatore indice entità tra cui scegliere
|
// incremento contatore indice entità tra cui scegliere
|
||||||
++ nF ;
|
++ nF ;
|
||||||
vFork.push_back( vMyNext[i]) ;
|
vFork.push_back( vMyNext[i]) ;
|
||||||
// se vietata inversione, salto se controverso
|
// se vietata inversione, salto se controverso
|
||||||
@@ -390,7 +387,7 @@ bool
|
|||||||
ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bHaltOnFork, int& nPrev)
|
ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bHaltOnFork, int& nPrev)
|
||||||
{
|
{
|
||||||
INTVECTOR vMyPrev = vPrev ;
|
INTVECTOR vMyPrev = vPrev ;
|
||||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||||
int nM = -1 ;
|
int nM = -1 ;
|
||||||
Point3d ptRef ;
|
Point3d ptRef ;
|
||||||
double dSqMinDist = m_dToler * m_dToler ;
|
double dSqMinDist = m_dToler * m_dToler ;
|
||||||
@@ -407,19 +404,19 @@ ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
|
||||||
// salto l'entità più vicina
|
// salto l'entità più vicina
|
||||||
if ( i == nM)
|
if ( i == nM)
|
||||||
continue ;
|
continue ;
|
||||||
// recupero indice e verso
|
// recupero indice e verso
|
||||||
int nId = abs( vMyPrev[i]) - 1 ;
|
int nId = abs( vMyPrev[i]) - 1 ;
|
||||||
bool bEquiv = ( vMyPrev[i] < 0) ;
|
bool bEquiv = ( vMyPrev[i] < 0) ;
|
||||||
// verifico se più vicino al più vicino
|
// verifico se più vicino al più vicino
|
||||||
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
||||||
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
||||||
if ( dRefSqDist < dCurrSqDist)
|
if ( dRefSqDist < dCurrSqDist)
|
||||||
vMyPrev[i] = 0 ;
|
vMyPrev[i] = 0 ;
|
||||||
}
|
}
|
||||||
// cerco la direzione più vicina
|
// cerco la direzione più vicina
|
||||||
int nI = - 1 ;
|
int nI = - 1 ;
|
||||||
int nF = 0 ;
|
int nF = 0 ;
|
||||||
double dProScaMax = - 1.1 ;
|
double dProScaMax = - 1.1 ;
|
||||||
@@ -431,7 +428,7 @@ ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
|||||||
// recupero indice e verso
|
// recupero indice e verso
|
||||||
int nId = abs( vMyPrev[i]) - 1 ;
|
int nId = abs( vMyPrev[i]) - 1 ;
|
||||||
bool bEquiv = ( vMyPrev[i] < 0) ;
|
bool bEquiv = ( vMyPrev[i] < 0) ;
|
||||||
// incremento contatore indice entità tra cui scegliere
|
// incremento contatore indice entità tra cui scegliere
|
||||||
++ nF ;
|
++ nF ;
|
||||||
vFork.push_back( vMyPrev[i]) ;
|
vFork.push_back( vMyPrev[i]) ;
|
||||||
// se vietata inversione, salto se controverso
|
// se vietata inversione, salto se controverso
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
#include "CurveBezier.h"
|
#include "CurveBezier.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "CreateCurveAux.h"
|
#include "CreateCurveAux.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|||||||
+1
-2
@@ -398,7 +398,7 @@ CurveArc::Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bo
|
|||||||
if ( dLenA > ( dRad - EPS_ZERO))
|
if ( dLenA > ( dRad - EPS_ZERO))
|
||||||
dLenH = 0 ;
|
dLenH = 0 ;
|
||||||
else
|
else
|
||||||
dLenH = sqrt( dRad * dRad - dLenA * dLenA) ;
|
dLenH= sqrt( dRad * dRad - dLenA * dLenA) ;
|
||||||
// versore dal punto medio della corda al centro
|
// versore dal punto medio della corda al centro
|
||||||
Vector3d vtH = vtA / dLenA ;
|
Vector3d vtH = vtA / dLenA ;
|
||||||
vtH.Rotate( Z_AX, 0, ( bCCW ? 1 : -1)) ;
|
vtH.Rotate( Z_AX, 0, ( bCCW ? 1 : -1)) ;
|
||||||
@@ -410,7 +410,6 @@ CurveArc::Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bo
|
|||||||
m_dRad = dRad ;
|
m_dRad = dRad ;
|
||||||
// calcolo il versore di start
|
// calcolo il versore di start
|
||||||
m_VtS = ( ptStart - m_PtCen) / m_dRad ;
|
m_VtS = ( ptStart - m_PtCen) / m_dRad ;
|
||||||
m_VtS.Normalize() ;
|
|
||||||
// calcolo l'angolo al centro
|
// calcolo l'angolo al centro
|
||||||
bool bDet ;
|
bool bDet ;
|
||||||
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, m_dAngCenDeg, bDet) || ! bDet)
|
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, m_dAngCenDeg, bDet) || ! bDet)
|
||||||
|
|||||||
+49
-1105
File diff suppressed because it is too large
Load Diff
@@ -33,5 +33,4 @@ bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
|||||||
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||||
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||||
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||||
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
|
|
||||||
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
||||||
|
|||||||
+6
-246
@@ -13,13 +13,13 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveAux.h"
|
|
||||||
#include "CurveBezier.h"
|
#include "CurveBezier.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "DistPointCrvBezier.h"
|
#include "DistPointCrvBezier.h"
|
||||||
#include "BiArcs.h"
|
#include "BiArcs.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "PolygonPlane.h"
|
#include "PolygonPlane.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "GeoObjFactory.h"
|
#include "GeoObjFactory.h"
|
||||||
#include "NgeWriter.h"
|
#include "NgeWriter.h"
|
||||||
#include "NgeReader.h"
|
#include "NgeReader.h"
|
||||||
@@ -27,16 +27,12 @@
|
|||||||
#include "Bernstein.h"
|
#include "Bernstein.h"
|
||||||
#include "deCasteljau.h"
|
#include "deCasteljau.h"
|
||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
#include "IntersLineLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||||
#include "/EgtDev/Include/ENkPolynomial.h"
|
#include "/EgtDev/Include/ENkPolynomial.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
||||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
@@ -142,32 +138,6 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::SetControlWeight( int nInd, double dW)
|
|
||||||
{
|
|
||||||
// verifico validità, razionalità e indice
|
|
||||||
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd > m_nDeg)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// verifico che il peso non sia nullo o negativo
|
|
||||||
if ( dW < EPS_SMALL)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// assegno il valore e il peso
|
|
||||||
m_vWeCtrl[nInd] = dW ;
|
|
||||||
|
|
||||||
// annullo analisi presenza singolarità
|
|
||||||
m_dParSing = - 2 ;
|
|
||||||
|
|
||||||
// imposto ricalcolo Voronoi
|
|
||||||
ResetVoronoiObject() ;
|
|
||||||
// imposto ricalcolo della grafica
|
|
||||||
m_OGrMgr.Reset() ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveBezier::FromArc( const ICurveArc& crArc)
|
CurveBezier::FromArc( const ICurveArc& crArc)
|
||||||
@@ -225,35 +195,6 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
|||||||
SetControlPoint( 1, ptNew1, dW) ;
|
SetControlPoint( 1, ptNew1, dW) ;
|
||||||
SetControlPoint( 2, ptNew2, dW) ;
|
SetControlPoint( 2, ptNew2, dW) ;
|
||||||
SetControlPoint( 3, ptEnd, 1) ;
|
SetControlPoint( 3, ptEnd, 1) ;
|
||||||
|
|
||||||
//// anziché usare una bezier cubica approssimo le eliche con più bezier quadratiche razionali.
|
|
||||||
//// più è grande l'angolo al centro dell'arco e maggiore sarà l'errore di approssimazione
|
|
||||||
//
|
|
||||||
// // quadratica razionale
|
|
||||||
// // peso del punto di controllo intermedio
|
|
||||||
// double dW = dCosAhalf ;
|
|
||||||
// // calcolo dei punti di controllo
|
|
||||||
// Point3d ptStart ;
|
|
||||||
// crArc.GetStartPoint( ptStart) ;
|
|
||||||
// Point3d ptEnd ;
|
|
||||||
// crArc.GetEndPoint( ptEnd) ;
|
|
||||||
// // Point3d ptMed = Media( ptStart, ptEnd, 0.5) ;
|
|
||||||
// //Vector3d vtDir = ptMed - crArc.GetCenter() ;
|
|
||||||
// // Point3d ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ;
|
|
||||||
// Vector3d vtStart ; crArc.GetStartDir( vtStart) ;
|
|
||||||
// Vector3d vtEnd ; crArc.GetEndDir( vtEnd) ;
|
|
||||||
// PtrOwner<CurveLine> pCrvLine1( CreateBasicCurveLine()) ;
|
|
||||||
// pCrvLine1->SetPVL( ptStart, vtStart, 10) ;
|
|
||||||
// PtrOwner<CurveLine> pCrvLine2( CreateBasicCurveLine()) ;
|
|
||||||
// pCrvLine2->SetPVL( ptEnd, vtEnd, 10) ;
|
|
||||||
// IntersLineLine ill( *pCrvLine1, *pCrvLine2, false) ;
|
|
||||||
// IntCrvCrvInfo iccInfo ; ill.GetIntCrvCrvInfo( iccInfo) ;
|
|
||||||
// Point3d ptNew = 0.5 * (iccInfo.IciA->ptI + iccInfo.IciB->ptI) ;
|
|
||||||
// // inserimento nella curva dei punti di controllo con i pesi
|
|
||||||
// Init( 2, true) ;
|
|
||||||
// SetControlPoint( 0, ptStart, 1) ;
|
|
||||||
// SetControlPoint( 1, ptNew, dW) ;
|
|
||||||
// SetControlPoint( 2, ptEnd, 1) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copio estrusione e spessore
|
// copio estrusione e spessore
|
||||||
@@ -263,30 +204,6 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::FromLine( const ICurveLine& crLine)
|
|
||||||
{
|
|
||||||
if ( ! crLine.IsValid())
|
|
||||||
return false ;
|
|
||||||
double dWeight = 1 ;
|
|
||||||
int nCount = 0 ;
|
|
||||||
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
|
|
||||||
SetControlPoint( nCount, ptStart, dWeight) ;
|
|
||||||
++nCount ;
|
|
||||||
double dPart = 1. / m_nDeg ;
|
|
||||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
|
||||||
double dU = i * dPart ;
|
|
||||||
Point3d ptMid ; crLine.GetPointD1D2( dU, ICurve::FROM_MINUS, ptMid) ;
|
|
||||||
SetControlPoint( nCount, ptMid, dWeight) ;
|
|
||||||
++nCount ;
|
|
||||||
}
|
|
||||||
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
|
|
||||||
SetControlPoint( nCount, ptEnd, dWeight) ;
|
|
||||||
++nCount ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveBezier::IsAPoint( void) const
|
CurveBezier::IsAPoint( void) const
|
||||||
@@ -369,7 +286,6 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
|||||||
return true ;
|
return true ;
|
||||||
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
|
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
|
||||||
return false ;
|
return false ;
|
||||||
m_dParSing = cbSrc.m_dParSing ;
|
|
||||||
m_vPtCtrl = cbSrc.m_vPtCtrl ;
|
m_vPtCtrl = cbSrc.m_vPtCtrl ;
|
||||||
if ( cbSrc.m_bRat)
|
if ( cbSrc.m_bRat)
|
||||||
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
||||||
@@ -1570,7 +1486,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
|||||||
return false ;
|
return false ;
|
||||||
vtDir.ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
vtDir.ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||||
if ( IsNull( pCrv))
|
if ( IsNull( pCrv))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -1807,24 +1723,12 @@ CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
|||||||
// verifico che i trim non cancellino interamente la curva
|
// verifico che i trim non cancellino interamente la curva
|
||||||
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
|
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
|
||||||
return false ;
|
return false ;
|
||||||
// se razionale devo trovare il punto di trim iniziale per ricalcolare il parametro di trim
|
|
||||||
Point3d ptStart ;
|
|
||||||
if( m_bRat)
|
|
||||||
GetPointD1D2( dUStartTrim, ptStart) ;
|
|
||||||
// trim finale
|
// trim finale
|
||||||
if ( ! TrimEndAtParam( dUEndTrim))
|
if ( ! TrimEndAtParam( dUEndTrim))
|
||||||
return false ;
|
return false ;
|
||||||
// trim iniziale con il parametro opportunamente ricalcolato
|
// trim iniziale con il parametro opportunamente ricalcolato
|
||||||
double dNewUStartTrim ;
|
double dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||||
if( m_bRat)
|
return TrimStartAtParam( dNewUStartTrim) ;
|
||||||
GetParamAtPoint( ptStart, dNewUStartTrim) ;
|
|
||||||
else
|
|
||||||
dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
|
||||||
//trim iniziale
|
|
||||||
if( ! TrimStartAtParam( dNewUStartTrim))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1840,10 +1744,7 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// utilizzo il trim sui parametri
|
// utilizzo il trim sui parametri
|
||||||
if( ! TrimStartAtParam( dUTrim))
|
return TrimStartAtParam( dUTrim) ;
|
||||||
return false ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1859,10 +1760,7 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// utilizzo il trim sui parametri
|
// utilizzo il trim sui parametri
|
||||||
if( ! TrimEndAtParam( dUTrim))
|
return TrimEndAtParam( dUTrim) ;
|
||||||
return false ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -2254,141 +2152,3 @@ CurveBezier::ResetVoronoiObject() const
|
|||||||
delete m_pVoronoiObj ;
|
delete m_pVoronoiObj ;
|
||||||
m_pVoronoiObj = nullptr ;
|
m_pVoronoiObj = nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::MakeRational( void)
|
|
||||||
{
|
|
||||||
if ( m_bRat)
|
|
||||||
return true ;
|
|
||||||
// creo il vettore dei pesi e li setto tutti a 1
|
|
||||||
m_vWeCtrl.assign( m_nDeg + 1, 1) ;
|
|
||||||
// aggiorno il flag rational
|
|
||||||
m_bRat = true ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::MakeRationalStandardForm( void)
|
|
||||||
{
|
|
||||||
if ( ! m_bRat)
|
|
||||||
return false ;
|
|
||||||
double dW0 = m_vWeCtrl.front() ;
|
|
||||||
double dWn = m_vWeCtrl.back() ;
|
|
||||||
if ( dW0 > 1 - EPS_ZERO && dWn > 1 - EPS_ZERO)
|
|
||||||
return true ;
|
|
||||||
if ( dW0 < EPS_ZERO || dWn < EPS_ZERO)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// formula del Farin
|
|
||||||
double dCoeff = pow( dW0 / dWn, 1. / m_nDeg) ;
|
|
||||||
for ( int i = 0 ; i < m_nDeg + 1 ; ++i)
|
|
||||||
m_vWeCtrl[i] *= Pow( dCoeff, i) / dW0 ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::MakeNonRational( double dTol)
|
|
||||||
{
|
|
||||||
if ( ! m_bRat)
|
|
||||||
return true ;
|
|
||||||
|
|
||||||
// controllo se i pesi sono tutti == 1 allora è una finta razionale e mi basta fare una copia dei punti di controllo
|
|
||||||
bool bIsActualRat = false ;
|
|
||||||
for ( int i = 0 ; i < m_nDeg ; ++i) {
|
|
||||||
if ( abs( m_vWeCtrl[i] - 1) > EPS_SMALL) {
|
|
||||||
bIsActualRat = true ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bOk = true ;
|
|
||||||
if ( ! bIsActualRat) {
|
|
||||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
|
||||||
for ( int p = 0 ; p < m_nDeg ; ++p) {
|
|
||||||
Point3d pt = GetControlPoint( p) ;
|
|
||||||
pNewBez->SetControlPoint( p, pt) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// provo ad approssimare la curva di bezier con una controparte non razionale
|
|
||||||
int nDeg = m_nDeg ;
|
|
||||||
// punto di rientro in caso fallisca il primo tentativo
|
|
||||||
retry :
|
|
||||||
nDeg += 2 ;
|
|
||||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
|
||||||
pNewBez->Init( nDeg, false) ;
|
|
||||||
PNTVECTOR vPntCtrl ;
|
|
||||||
PNTVECTOR vPntSampling ;
|
|
||||||
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
|
||||||
Point3d pt ; GetPointD1D2( double( p) / nDeg, pt) ;
|
|
||||||
pNewBez->SetControlPoint( p, pt) ;
|
|
||||||
vPntCtrl.push_back( pt) ;
|
|
||||||
}
|
|
||||||
vPntSampling = vPntCtrl ;
|
|
||||||
int c = 0 ;
|
|
||||||
double dErr = INFINITO ;
|
|
||||||
while ( dErr > dTol && c < 100) {
|
|
||||||
double dErrMax = 0 ;
|
|
||||||
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
|
||||||
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
|
||||||
Point3d pt ; pNewBez->GetPointD1D2( double( p) / nDeg, pt) ;
|
|
||||||
Vector3d vDiff = vPntSampling[p] - pt ;
|
|
||||||
double dErrLoc = vDiff.Len() ;
|
|
||||||
if( dErrLoc > dErrMax)
|
|
||||||
dErrMax = dErrLoc ;
|
|
||||||
// aggiorno il vettore dei punti di controllo della nuova curva
|
|
||||||
vPntCtrl[p] += vDiff ;
|
|
||||||
}
|
|
||||||
dErr = dErrMax ;
|
|
||||||
// aggiorno i punti di controllo della nuova curva
|
|
||||||
for ( int i = 0 ; i < nDeg + 1 ; ++i)
|
|
||||||
pNewBez->SetControlPoint( i, vPntCtrl[i]) ;
|
|
||||||
++c ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcolo l'errore di approssimazione sulla curva
|
|
||||||
CalcBezierApproxError( this, pNewBez, dErr) ;
|
|
||||||
bOk = dErr < dTol ;
|
|
||||||
if ( bOk) {
|
|
||||||
// aggiorno la curva di bezier originale con quella approssimata
|
|
||||||
Init( nDeg, false) ;
|
|
||||||
for ( int i = 0 ; i < nDeg + 1 ; ++i) {
|
|
||||||
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
|
||||||
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( nDeg < m_nDeg + 4)
|
|
||||||
goto retry ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bOk ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CurveBezier::IsALine( void) const
|
|
||||||
{
|
|
||||||
Point3d ptStart ; GetStartPoint( ptStart) ;
|
|
||||||
Point3d ptEnd ; GetEndPoint( ptEnd) ;
|
|
||||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
|
||||||
Point3d ptCtrl = GetControlPoint( i) ;
|
|
||||||
DistPointLine dpl( ptCtrl, ptStart, ptEnd) ;
|
|
||||||
double dDist = 0 ; dpl.GetDist( dDist) ;
|
|
||||||
if( dDist > EPS_SMALL)
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
PNTVECTOR
|
|
||||||
CurveBezier::GetAllControlPoints( void) const
|
|
||||||
{
|
|
||||||
PNTVECTOR vPntCtrl = m_vPtCtrl ;
|
|
||||||
return vPntCtrl ;
|
|
||||||
}
|
|
||||||
+1
-8
@@ -137,9 +137,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
|||||||
bool Init( int nDeg, bool bIsRational) override ;
|
bool Init( int nDeg, bool bIsRational) override ;
|
||||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ;
|
bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ;
|
||||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
|
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
|
||||||
bool SetControlWeight( int nInd, double dW) override ;
|
|
||||||
bool FromArc( const ICurveArc& crArc) override ;
|
bool FromArc( const ICurveArc& crArc) override ;
|
||||||
bool FromLine( const ICurveLine& crLine) override ;
|
|
||||||
int GetDegree( void) const override
|
int GetDegree( void) const override
|
||||||
{ return m_nDeg ; }
|
{ return m_nDeg ; }
|
||||||
bool IsRational( void) const override
|
bool IsRational( void) const override
|
||||||
@@ -149,11 +147,6 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
|||||||
double GetControlWeight( int nInd, bool* pbOk = NULL) const override ;
|
double GetControlWeight( int nInd, bool* pbOk = NULL) const override ;
|
||||||
bool GetControlPolygonLength( double& dLen) const override ;
|
bool GetControlPolygonLength( double& dLen) const override ;
|
||||||
int GetSingularParam( double& dPar) const override ;
|
int GetSingularParam( double& dPar) const override ;
|
||||||
bool MakeRational( void) override ;
|
|
||||||
bool MakeRationalStandardForm( void) override ;
|
|
||||||
bool MakeNonRational( double dTol) override ;
|
|
||||||
bool IsALine( void) const override ;
|
|
||||||
PNTVECTOR GetAllControlPoints( void) const ; // non aggiunta in interfaccia
|
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -197,7 +190,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
|||||||
|
|
||||||
private :
|
private :
|
||||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||||
static const int MAXDEG = 21 ;
|
static const int MAXDEG = 11 ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
|
|||||||
+11
-14
@@ -16,8 +16,8 @@
|
|||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
#include "CalcDerivate.h"
|
#include "CalcDerivate.h"
|
||||||
#include "BiArcs.h"
|
#include "BiArcs.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "RemoveCurveDefects.h"
|
#include "RemoveCurveDefects.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||||
@@ -439,12 +439,12 @@ CurveByApprox::CalcSplitPoints( double dLinTol, double dAngTolDeg, double dLinFe
|
|||||||
m_vSplits.push_back(i) ;
|
m_vSplits.push_back(i) ;
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
// verifico linearità del tratto precedente
|
// verifico linearità del tratto precedente
|
||||||
bool bPrevLin = vtPrev.SqLen() > dSqLinFea &&
|
bool bPrevLin = vtPrev.SqLen() > dSqLinFea &&
|
||||||
( m_vNextDer[i-1] * m_vPrevDer[i]) > dAngTolCos &&
|
( m_vNextDer[i-1] * m_vPrevDer[i]) > dAngTolCos &&
|
||||||
( vtPrev ^ m_vNextDer[i-1]).SqLen() < dSqLinTol &&
|
( vtPrev ^ m_vNextDer[i-1]).SqLen() < dSqLinTol &&
|
||||||
( vtPrev ^ m_vPrevDer[i]).SqLen() < dSqLinTol ;
|
( vtPrev ^ m_vPrevDer[i]).SqLen() < dSqLinTol ;
|
||||||
// verifico linearità del tratto successivo
|
// verifico linearità del tratto successivo
|
||||||
bool bNextLin = vtNext.SqLen() > dSqLinFea &&
|
bool bNextLin = vtNext.SqLen() > dSqLinFea &&
|
||||||
( m_vNextDer[i] * m_vPrevDer[i+1]) > dAngTolCos &&
|
( m_vNextDer[i] * m_vPrevDer[i+1]) > dAngTolCos &&
|
||||||
( vtNext ^ m_vNextDer[i]).SqLen() < dSqLinTol &&
|
( vtNext ^ m_vNextDer[i]).SqLen() < dSqLinTol &&
|
||||||
@@ -483,7 +483,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
PtrOwner<ICurve> pCrv ;
|
PtrOwner<ICurve> pCrv ;
|
||||||
double dMaxDist ;
|
double dMaxDist ;
|
||||||
|
|
||||||
// se la polilinea ha più di 2 punti
|
// se la polilinea ha più di 2 punti
|
||||||
if ( PL.GetPointNbr() > 2) {
|
if ( PL.GetPointNbr() > 2) {
|
||||||
// calcolo punti e direzioni agli estremi della polilinea usando la curva di Bezier
|
// calcolo punti e direzioni agli estremi della polilinea usando la curva di Bezier
|
||||||
int nI ;
|
int nI ;
|
||||||
@@ -501,12 +501,11 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
ptP1 = m_vPnt[nI] ;
|
ptP1 = m_vPnt[nI] ;
|
||||||
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||||
// forzo la spezzatura della curva
|
|
||||||
if ( IsNull( pCrv))
|
if ( IsNull( pCrv))
|
||||||
dMaxDist = 2 * dLinTol ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se la polilinea è formata da 2 punti
|
// se la polilinea è formata da 2 punti
|
||||||
else if ( PL.GetPointNbr() == 2) {
|
else if ( PL.GetPointNbr() == 2) {
|
||||||
// se molto vicini, esco
|
// se molto vicini, esco
|
||||||
double dLen ;
|
double dLen ;
|
||||||
@@ -525,15 +524,13 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
|
|
||||||
// se raggiunto il massimo livello di recursione, forzo l'accettazione del biarco
|
// se raggiunto il massimo livello di recursione, forzo l'accettazione del biarco
|
||||||
if ( nLev >= MAX_LEV) {
|
if ( nLev >= MAX_LEV) {
|
||||||
if ( IsNull( pCrv))
|
|
||||||
return false ;
|
|
||||||
dMaxDist = 0 ;
|
dMaxDist = 0 ;
|
||||||
// segnalo situazione per debug
|
// segnalo situazione per debug
|
||||||
if ( GetEGkDebugLev() >= 5)
|
if ( GetEGkDebugLev() >= 5)
|
||||||
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions")
|
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions")
|
||||||
}
|
}
|
||||||
|
|
||||||
// se lunghezza abbastanza piccola, forzo l'accettazione della curva
|
// se lunghezza abbastanza picccola, forzo l'accettazione della curva
|
||||||
double dLen ;
|
double dLen ;
|
||||||
if ( PL.GetApproxLength( dLen) && dLen < 10 * EPS_SMALL)
|
if ( PL.GetApproxLength( dLen) && dLen < 10 * EPS_SMALL)
|
||||||
dMaxDist = 0 ;
|
dMaxDist = 0 ;
|
||||||
@@ -564,7 +561,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// spezzo l'intervallo in due parti a metà
|
// spezzo l'intervallo in due parti a metà
|
||||||
double dParStart, dParEnd ;
|
double dParStart, dParEnd ;
|
||||||
if ( ! PL.GetFirstU( dParStart) || ! PL.GetLastU( dParEnd))
|
if ( ! PL.GetFirstU( dParStart) || ! PL.GetLastU( dParEnd))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -572,9 +569,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
PolyLine PL2 ;
|
PolyLine PL2 ;
|
||||||
if ( ! PL.Split( dParMid, PL2))
|
if ( ! PL.Split( dParMid, PL2))
|
||||||
return false ;
|
return false ;
|
||||||
// prima metà
|
// prima metà
|
||||||
if ( ! BiArcOrSplit( nLev + 1, PL, dLinTol, dAngTolDeg, PA))
|
if ( ! BiArcOrSplit( nLev + 1, PL, dLinTol, dAngTolDeg, PA))
|
||||||
return false ;
|
return false ;
|
||||||
// seconda metà
|
// seconda metà
|
||||||
return BiArcOrSplit( nLev + 1, PL2, dLinTol, dAngTolDeg, PA) ;
|
return BiArcOrSplit( nLev + 1, PL2, dLinTol, dAngTolDeg, PA) ;
|
||||||
}
|
}
|
||||||
|
|||||||
+92
-145
@@ -14,6 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "DistPointCrvComposite.h"
|
#include "DistPointCrvComposite.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "CurveArc.h"
|
#include "CurveArc.h"
|
||||||
@@ -26,7 +27,6 @@
|
|||||||
#include "NgeWriter.h"
|
#include "NgeWriter.h"
|
||||||
#include "NgeReader.h"
|
#include "NgeReader.h"
|
||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||||
@@ -192,7 +192,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK && ! ( m_CrvSmplS.empty() && ( m_nStatus == TO_VERIFY || m_nStatus == IS_A_POINT)))
|
if ( m_nStatus != OK && ! ( m_CrvSmplS.empty() && m_nStatus == TO_VERIFY))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// controllo la tolleranza
|
// controllo la tolleranza
|
||||||
@@ -224,11 +224,8 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
// lunghezza della curva originale
|
// lunghezza della curva originale
|
||||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||||
// eseguo modifica
|
// eseguo modifica
|
||||||
if ( ! pCrv->ModifyStart( ptEnd)) {
|
if ( ! pCrv->ModifyStart( ptEnd))
|
||||||
CurveLine crvLine ;
|
return false ;
|
||||||
if ( ! crvLine.Set( ptEnd, ptCrvEnd) || ! pCrv.Set( crvLine.Clone()))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
// verifico che la lunghezza non sia variata troppo
|
// verifico che la lunghezza non sia variata troppo
|
||||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||||
@@ -249,11 +246,8 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
// lunghezza della curva originale
|
// lunghezza della curva originale
|
||||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||||
// eseguo modifica
|
// eseguo modifica
|
||||||
if ( ! pCrv->ModifyEnd( ptStart)) {
|
if ( ! pCrv->ModifyEnd( ptStart))
|
||||||
CurveLine crvLine ;
|
return false ;
|
||||||
if ( ! crvLine.Set( ptCrvStart, ptStart) || ! pCrv.Set( crvLine.Clone()))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
// verifico che la lunghezza non sia variata troppo
|
// verifico che la lunghezza non sia variata troppo
|
||||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||||
@@ -297,15 +291,9 @@ CurveComposite::Close( void)
|
|||||||
return true ;
|
return true ;
|
||||||
// se molto vicini li modifico
|
// se molto vicini li modifico
|
||||||
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||||
// se un solo arco
|
|
||||||
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_ARC) {
|
|
||||||
CurveArc* pArc = GetBasicCurveArc( m_CrvSmplS.front()) ;
|
|
||||||
return pArc->ChangeAngCenter( pArc->GetAngCenter() > 0 ? ANG_FULL : -ANG_FULL) ;
|
|
||||||
}
|
|
||||||
// caso generale
|
|
||||||
Point3d ptMid = Media( ptStart, ptEnd) ;
|
Point3d ptMid = Media( ptStart, ptEnd) ;
|
||||||
if ( ! m_CrvSmplS.front()->ModifyStart( ptMid) ||
|
if ( ! ModifyStart( ptMid) ||
|
||||||
! m_CrvSmplS.back()->ModifyEnd( ptMid))
|
! ModifyEnd( ptMid))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// altrimenti aggiungo la linea di chiusura
|
// altrimenti aggiungo la linea di chiusura
|
||||||
@@ -381,10 +369,9 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// ciclo di inserimento dei segmenti che uniscono i punti
|
// ciclo di inserimento dei segmenti che uniscono i punti
|
||||||
double dParIni, dParFin ;
|
|
||||||
Point3d ptIni, ptFin ;
|
Point3d ptIni, ptFin ;
|
||||||
PL.GetFirstUPoint( &dParIni, &ptIni) ;
|
PL.GetFirstPoint( ptIni) ;
|
||||||
while ( PL.GetNextUPoint( &dParFin, &ptFin)) {
|
while ( PL.GetNextPoint( ptFin)) {
|
||||||
// se i punti della coppia coincidono, passo alla coppia successiva
|
// se i punti della coppia coincidono, passo alla coppia successiva
|
||||||
if ( AreSamePointApprox( ptIni, ptFin))
|
if ( AreSamePointApprox( ptIni, ptFin))
|
||||||
continue ;
|
continue ;
|
||||||
@@ -395,14 +382,10 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
|||||||
// assegno i punti estremi
|
// assegno i punti estremi
|
||||||
if ( ! pCrvLine->Set( ptIni, ptFin))
|
if ( ! pCrvLine->Set( ptIni, ptFin))
|
||||||
return false ;
|
return false ;
|
||||||
// assegno i parametri degli estremi
|
|
||||||
pCrvLine->SetTempParam( dParIni, 0) ;
|
|
||||||
pCrvLine->SetTempParam( dParFin, 1) ;
|
|
||||||
// aggiungo la retta alla curva composita
|
// aggiungo la retta alla curva composita
|
||||||
if ( ! AddSimpleCurve( Release( pCrvLine)))
|
if ( ! AddSimpleCurve( Release( pCrvLine)))
|
||||||
return false ;
|
return false ;
|
||||||
// aggiorno dati prossimo punto iniziale
|
// aggiorno dati prossimo punto iniziale
|
||||||
dParIni = dParFin ;
|
|
||||||
ptIni = ptFin ;
|
ptIni = ptFin ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,10 +598,6 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
|
|||||||
if ( ! AddCurve( *pCrv))
|
if ( ! AddCurve( *pCrv))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
if ( ccSrc.m_nStatus == IS_A_POINT) {
|
|
||||||
m_ptStart = ccSrc.m_ptStart ;
|
|
||||||
m_nStatus = IS_A_POINT ;
|
|
||||||
}
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +656,7 @@ CurveComposite::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
|||||||
while ( pCrvSmpl != nullptr && i < MAX_CRV) {
|
while ( pCrvSmpl != nullptr && i < MAX_CRV) {
|
||||||
// assegno ed emetto nome e tipo della curva semplice
|
// assegno ed emetto nome e tipo della curva semplice
|
||||||
sOut += "#" + ToString( i) + " " + pCrvSmpl->GetTitle() + szNewLine ;
|
sOut += "#" + ToString( i) + " " + pCrvSmpl->GetTitle() + szNewLine ;
|
||||||
// dati della curva semplice
|
// salvataggio della curva semplice
|
||||||
if ( ! pCrvSmpl->Dump( sOut, bMM, szNewLine))
|
if ( ! pCrvSmpl->Dump( sOut, bMM, szNewLine))
|
||||||
return false ;
|
return false ;
|
||||||
// passo alla successiva
|
// passo alla successiva
|
||||||
@@ -766,7 +745,7 @@ CurveComposite::Load( NgeReader& ngeIn)
|
|||||||
ICurve* pCrv = ::GetCurve( pGeoO) ;
|
ICurve* pCrv = ::GetCurve( pGeoO) ;
|
||||||
bOk = bOk && ( pCrv != nullptr && pCrv->IsSimple()) ;
|
bOk = bOk && ( pCrv != nullptr && pCrv->IsSimple()) ;
|
||||||
// aggiungo questa curva (sicuramente semplice)
|
// aggiungo questa curva (sicuramente semplice)
|
||||||
bOk = bOk && AddSimpleCurve( pCrv, true, 10 * EPS_SMALL) ;
|
bOk = bOk && AddSimpleCurve( pCrv) ;
|
||||||
// se errore
|
// se errore
|
||||||
if ( ! bOk)
|
if ( ! bOk)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -899,15 +878,10 @@ CurveComposite::TestClosure( void)
|
|||||||
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
|
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
|
||||||
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
||||||
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
|
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
|
||||||
// se un solo arco
|
|
||||||
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_ARC) {
|
|
||||||
CurveArc* pArc = GetBasicCurveArc( m_CrvSmplS.front()) ;
|
|
||||||
return pArc->ChangeAngCenter( pArc->GetAngCenter() > 0 ? ANG_FULL : -ANG_FULL) ;
|
|
||||||
}
|
|
||||||
// caso generale
|
|
||||||
Point3d ptM = Media( ptStart, ptEnd) ;
|
Point3d ptM = Media( ptStart, ptEnd) ;
|
||||||
return ( m_CrvSmplS.front()->ModifyStart( ptM) &&
|
if ( ! m_CrvSmplS.front()->ModifyStart( ptM) ||
|
||||||
m_CrvSmplS.back()->ModifyEnd( ptM)) ;
|
! m_CrvSmplS.back()->ModifyEnd( ptM))
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -963,8 +937,6 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
} break ;
|
} break ;
|
||||||
default :
|
|
||||||
return false ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// recupero dati sulla planarità della polilinea
|
// recupero dati sulla planarità della polilinea
|
||||||
@@ -1789,11 +1761,10 @@ bool
|
|||||||
CurveComposite::AddPoint( const Point3d& ptStart)
|
CurveComposite::AddPoint( const Point3d& ptStart)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != TO_VERIFY && m_nStatus != IS_A_POINT)
|
if ( m_nStatus != TO_VERIFY)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno il punto e setto lo stato
|
// assegno il punto
|
||||||
m_ptStart = ptStart ;
|
m_ptStart = ptStart ;
|
||||||
m_nStatus = IS_A_POINT ;
|
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -1837,7 +1808,7 @@ bool
|
|||||||
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK && m_nStatus != IS_A_POINT)
|
if ( m_nStatus != OK && m_nStatus != TO_VERIFY)
|
||||||
return false ;
|
return false ;
|
||||||
// costruisco la linea
|
// costruisco la linea
|
||||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||||
@@ -3001,7 +2972,7 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast)
|
|||||||
m_CrvSmplS.pop_front() ;
|
m_CrvSmplS.pop_front() ;
|
||||||
}
|
}
|
||||||
// eseguo mini verifica
|
// eseguo mini verifica
|
||||||
m_nStatus = ( ! m_CrvSmplS.empty() ? OK : TO_VERIFY) ;
|
m_nStatus = ( m_CrvSmplS.size() > 0 ? OK : TO_VERIFY) ;
|
||||||
// assegno estrusione e spessore della curva composita
|
// assegno estrusione e spessore della curva composita
|
||||||
pCrv->SetExtrusion( m_VtExtr) ;
|
pCrv->SetExtrusion( m_VtExtr) ;
|
||||||
pCrv->SetThickness( m_dThick) ;
|
pCrv->SetThickness( m_dThick) ;
|
||||||
@@ -3046,7 +3017,7 @@ CurveComposite::ArcsToBezierCurves( void)
|
|||||||
// se arco, devo trasformare in una o più curve di Bezier
|
// se arco, devo trasformare in una o più curve di Bezier
|
||||||
if ( (*Iter)->GetType() == CRV_ARC) {
|
if ( (*Iter)->GetType() == CRV_ARC) {
|
||||||
// eseguo trasformazione
|
// eseguo trasformazione
|
||||||
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( GetCurveArc( *Iter))) ;
|
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( (*Iter))) ;
|
||||||
if ( IsNull( pNewCrv))
|
if ( IsNull( pNewCrv))
|
||||||
return false ;
|
return false ;
|
||||||
// se risultato è singola curva
|
// se risultato è singola curva
|
||||||
@@ -3180,26 +3151,11 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// se precedente molto corta
|
// se precedente molto corta
|
||||||
double dLenP ;
|
double dLenP ;
|
||||||
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
|
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
|
||||||
// se abbastanza allineata alla successiva
|
// se abbastanza allineata alla successiva
|
||||||
Vector3d vtDirP, vtDirC ;
|
Vector3d vtDirP, vtDirC ;
|
||||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||||
bool bModifStart = ( pCrvC->GetType() != CRV_ARC) ;
|
Point3d ptStart ;
|
||||||
if ( ! bModifStart) {
|
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
||||||
/* nel caso in cui la curva corrente sia un arco, bisogna controllare che la somma tra
|
|
||||||
l'angolo al centro e l'angolo sotteso dalla curva precedente non superi l'angolo giro; in
|
|
||||||
caso positivo, la modifica del punto inziale dell'arco ( curva corrente) rimoverebbe
|
|
||||||
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
|
||||||
Point3d ptS ; pCrvP->GetStartPoint( ptS) ;
|
|
||||||
Point3d ptE ; pCrvC->GetStartPoint( ptE) ;
|
|
||||||
const ICurveArc* pArcC = GetBasicCurveArc( pCrvC) ;
|
|
||||||
double dAngRef = ( Dist( ptS, ptE) / pArcC->GetRadius()) * RADTODEG ;
|
|
||||||
bModifStart = ( abs( pArcC->GetAngCenter()) + dAngRef < ANG_FULL - 10 * EPS_ANG_SMALL) ;
|
|
||||||
|
|
||||||
}
|
|
||||||
if ( bModifStart) {
|
|
||||||
Point3d ptStart ;
|
|
||||||
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// se corrente molto corta
|
// se corrente molto corta
|
||||||
@@ -3208,24 +3164,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// se abbastanza allineata alla precedente
|
// se abbastanza allineata alla precedente
|
||||||
Vector3d vtDirP, vtDirC ;
|
Vector3d vtDirP, vtDirC ;
|
||||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||||
bool bModifEnd = ( pCrvP->GetType() != CRV_ARC) ;
|
Point3d ptEnd ;
|
||||||
if ( ! bModifEnd) {
|
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
||||||
/* nel caso in cui la curva predecente sia un arco, bisogna controllare che la somma tra
|
|
||||||
l'angolo al centro e l'angolo sotteso dalla curva corrente non superi l'angolo giro; in
|
|
||||||
caso positivo, la modifica del punto finale dell'arco ( curva precedente) rimoverebbe
|
|
||||||
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
|
||||||
Point3d ptS ; pCrvP->GetEndPoint( ptS) ;
|
|
||||||
Point3d ptE ; pCrvC->GetEndPoint( ptE) ;
|
|
||||||
const CurveArc* pArcP = GetBasicCurveArc( pCrvP) ;
|
|
||||||
double dAngRef = ( Dist( ptS, ptE) / pArcP->GetRadius()) * RADTODEG ;
|
|
||||||
bModifEnd = ( abs( pArcP->GetAngCenter()) + dAngRef < ANG_FULL - 10. * EPS_ANG_SMALL) ;
|
|
||||||
}
|
|
||||||
if ( bModifEnd) {
|
|
||||||
Point3d ptEnd ;
|
|
||||||
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// coefficiente deduzione tolleranza
|
// coefficiente deduzione tolleranza
|
||||||
const double COEFF_TOL = 0.7 ;
|
const double COEFF_TOL = 0.7 ;
|
||||||
// se entrambe rette
|
// se entrambe rette
|
||||||
@@ -3280,69 +3222,61 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// verifico di non superare l'angolo giro al centro
|
// verifico di non superare l'angolo giro al centro
|
||||||
if ( abs( pArcP->GetAngCenter() + pArcC->GetAngCenter()) > ANG_FULL + EPS_ANG_SMALL)
|
if ( abs( pArcP->GetAngCenter() + pArcC->GetAngCenter()) > ANG_FULL + EPS_ANG_SMALL)
|
||||||
return 0 ;
|
return 0 ;
|
||||||
// verifico se archi piatti
|
// se archi piatti
|
||||||
bool bPlaneArcs = pArcP->IsPlane() && pArcC->IsPlane() ;
|
if ( pArcP->IsPlane() && pArcC->IsPlane()) {
|
||||||
// se archi non piatti verifico coincidenza pendenza sulla normale
|
// se calcolo nuovo arco ok, procedo con l'unione
|
||||||
if ( ! bPlaneArcs) {
|
Point3d ptP1 ;
|
||||||
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
pArcP->GetStartPoint( ptP1) ;
|
||||||
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
Point3d ptP2 ;
|
||||||
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) > dCurrLinTol)
|
pArcP->GetEndPoint( ptP2) ;
|
||||||
return 0 ;
|
Point3d ptP3 ;
|
||||||
}
|
pArcC->GetEndPoint( ptP3) ;
|
||||||
|
// verifico se circonferenza completa
|
||||||
// se calcolo nuovo arco ok, procedo con l'unione
|
bool bCirc = ( AreSamePointApprox( ptP1, ptP3)) ;
|
||||||
Point3d ptP1 ;
|
if ( bCirc)
|
||||||
pArcP->GetStartPoint( ptP1) ;
|
pArcC->GetMidPoint( ptP3) ;
|
||||||
Point3d ptP2 ;
|
CurveArc NewArc ;
|
||||||
pArcP->GetEndPoint( ptP2) ;
|
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
||||||
Point3d ptP3 ;
|
// verifico normale al piano dell'arco
|
||||||
pArcC->GetEndPoint( ptP3) ;
|
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||||
|
NewArc.InvertN() ;
|
||||||
// se archi non piani costruisco arco sul piano definito dalla normale e dal punto di partenza del primo arco
|
// se curve originali con la stessa proprietà, la riporto
|
||||||
Frame3d frRef ;
|
if ( nTpr0P == nTpr0C)
|
||||||
if ( ! frRef.Set( ptP1, pArcP->GetNormVersor()))
|
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||||
return 0 ;
|
if ( nTpr1P == nTpr1C)
|
||||||
if ( ! bPlaneArcs) {
|
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||||
ptP1.Scale( frRef, 1, 1, 0) ;
|
// aggiorno l'arco corrente e torno flag modifica
|
||||||
ptP2.Scale( frRef, 1, 1, 0) ;
|
*pArcC = NewArc ;
|
||||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
return -1 ;
|
||||||
ptC1Fin.Scale( frRef, 1, 1, 0) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifico se circonferenza completa
|
|
||||||
bool bCirc = ( AreSamePointEpsilon( ptP1, ptP3, dCurrLinTol)) ;
|
|
||||||
if ( bCirc) {
|
|
||||||
pArcC->GetMidPoint( ptP3) ;
|
|
||||||
if ( ! bPlaneArcs)
|
|
||||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurveArc NewArc ;
|
|
||||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
|
||||||
// se vicino a circonferenza arco per 3 punti potrebbe non dare il risultato desiderato quindi faccio controllo su raggio e centro
|
|
||||||
if ( Dist( NewArc.GetCenter(), ptC1Fin) > 2 * dCurrLinTol || abs( NewArc.GetRadius() - pArcP->GetRadius()) > 2 * dCurrLinTol)
|
|
||||||
return 0 ;
|
|
||||||
|
|
||||||
// verifico normale al piano dell'arco
|
|
||||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
|
||||||
NewArc.InvertN() ;
|
|
||||||
// se archi non piani ripristino il deltaN
|
|
||||||
if ( ! bPlaneArcs) {
|
|
||||||
double dDeltaN1 = pArcP->GetDeltaN() ;
|
|
||||||
double dDeltaN2 = pArcC->GetDeltaN() ;
|
|
||||||
NewArc.ChangeDeltaN( dDeltaN1 + dDeltaN2) ;
|
|
||||||
}
|
}
|
||||||
// se curve originali con la stessa proprietà, la riporto
|
else
|
||||||
if ( nTpr0P == nTpr0C)
|
return 0 ;
|
||||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
}
|
||||||
if ( nTpr1P == nTpr1C)
|
// verifico coincidenza pendenza sulla normale
|
||||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
||||||
// aggiorno l'arco corrente e torno flag modifica
|
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
||||||
*pArcC = NewArc ;
|
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) < dCurrLinTol) {
|
||||||
return -1 ;
|
// se calcolo nuovo arco ok, procedo con l'unione
|
||||||
|
Point3d ptP1 ;
|
||||||
|
pArcP->GetStartPoint( ptP1) ;
|
||||||
|
Vector3d vtDir1 ;
|
||||||
|
pArcP->GetStartDir( vtDir1) ;
|
||||||
|
Point3d ptP3 ;
|
||||||
|
pArcC->GetEndPoint( ptP3) ;
|
||||||
|
CurveArc NewArc ;
|
||||||
|
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
|
||||||
|
// se curve originali con la stessa proprietà, la riporto
|
||||||
|
if ( nTpr0P == nTpr0C)
|
||||||
|
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||||
|
if ( nTpr1P == nTpr1C)
|
||||||
|
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||||
|
// aggiorno l'arco corrente e torno flag modifica
|
||||||
|
*pArcC = NewArc ;
|
||||||
|
return -1 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0 ;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return 0 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nessuna fusione
|
// nessuna fusione
|
||||||
@@ -3840,6 +3774,19 @@ CurveComposite::ResetVoronoiObject() const
|
|||||||
m_pVoronoiObj = nullptr ;
|
m_pVoronoiObj = nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CurveComposite::FromPoint(Point3d& ptStart)
|
||||||
|
{
|
||||||
|
// verifico lo stato
|
||||||
|
if ( m_nStatus != TO_VERIFY)
|
||||||
|
return false ;
|
||||||
|
// assegno il punto e setto lo stato
|
||||||
|
m_ptStart = ptStart ;
|
||||||
|
m_nStatus = IS_A_POINT ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
||||||
|
|||||||
+2
-1
@@ -177,7 +177,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
|||||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
||||||
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
||||||
bool GetCurveTempParam( int nCrv, double& dParam, int nParamInd = 0) const override ;
|
bool GetCurveTempParam( int nCrv, double& dParam, int nParamInd = 0) const override ;
|
||||||
bool GetOnlyPoint( Point3d& ptStart) const override ;
|
bool FromPoint( Point3d& ptStart) override ; // funzione per settare la curva ad un unico punto
|
||||||
|
bool GetOnlyPoint( Point3d& ptStart) const override ; // funzione per recuperare l'unico punto da cui è composta la curva ( degenere)
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
|
|||||||
+1
-1
@@ -14,11 +14,11 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "GeoObjFactory.h"
|
#include "GeoObjFactory.h"
|
||||||
#include "NgeWriter.h"
|
#include "NgeWriter.h"
|
||||||
#include "NgeReader.h"
|
#include "NgeReader.h"
|
||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|||||||
+4
-3
@@ -1,7 +1,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2020-2024
|
// EgalTech 2020-2022
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : DistLineLine.cpp Data : 10.05.24 Versione : 2.6e3
|
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1
|
||||||
// Contenuto : Implementazione della classe distanza fra elementi lineari.
|
// Contenuto : Implementazione della classe distanza fra elementi lineari.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -12,10 +12,11 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
#include "DistLineLine.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
#include "/EgtDev/Include/EGkGeoConst.h"
|
#include "/EgtDev/Include/EGkGeoConst.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2020-2020
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : DistLineLine.h Data : 06.11.20 Versione : 2.2k1
|
||||||
|
// Contenuto : Dichiarazione della classe distanza fra elementi lineari.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 06.11.20 LM Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "/EgtDev/Include/EGkVector3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class DistLineLine
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1,
|
||||||
|
const Point3d& ptSt2, const Point3d& ptEn2,
|
||||||
|
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
|
||||||
|
DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||||
|
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||||
|
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
bool GetSqDist( double& dSqDist) const ;
|
||||||
|
bool GetDist( double& dDist) const ;
|
||||||
|
bool IsEpsilon( double dTol) const
|
||||||
|
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
|
||||||
|
bool IsSmall( void) const
|
||||||
|
{ return IsEpsilon( EPS_SMALL) ; }
|
||||||
|
bool IsZero( void) const
|
||||||
|
{ return IsEpsilon( EPS_ZERO) ; }
|
||||||
|
bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) const ;
|
||||||
|
bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) const ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||||
|
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||||
|
bool bIsSegment1, bool bIsSegment2) ;
|
||||||
|
private:
|
||||||
|
double m_dSqDist ;
|
||||||
|
mutable double m_dDist ;
|
||||||
|
double m_dPos1 ;
|
||||||
|
double m_dPos2 ;
|
||||||
|
Point3d m_ptMinDist1 ;
|
||||||
|
Point3d m_ptMinDist2 ;
|
||||||
|
} ;
|
||||||
+2
-2
@@ -14,9 +14,9 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "DllMain.h"
|
#include "DllMain.h"
|
||||||
#include "GeoConst.h"
|
|
||||||
#include "DistPointCrvAux.h"
|
#include "DistPointCrvAux.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
|||||||
}
|
}
|
||||||
// altrimenti, per curve successive
|
// altrimenti, per curve successive
|
||||||
else {
|
else {
|
||||||
// verifico se la distanza minima dal box è superiore al minimo già trovato
|
// verifico se la distanza minima dal box è superiore al minimo già trovato
|
||||||
BBox3d b3B ;
|
BBox3d b3B ;
|
||||||
if ( pCrvSmpl->GetLocalBBox( b3B) &&
|
if ( pCrvSmpl->GetLocalBBox( b3B) &&
|
||||||
b3B.SqDistFromPoint( ptP) <= m_dDist * m_dDist) {
|
b3B.SqDistFromPoint( ptP) <= m_dDist * m_dDist) {
|
||||||
@@ -105,7 +105,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
|||||||
++ i ;
|
++ i ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// con minima distanza più bassa
|
// con minima distanza più bassa
|
||||||
else if ( dCurrDist < m_dDist) {
|
else if ( dCurrDist < m_dDist) {
|
||||||
// aggiorno i minimi
|
// aggiorno i minimi
|
||||||
m_dDist = dCurrDist ;
|
m_dDist = dCurrDist ;
|
||||||
|
|||||||
+7
-20
@@ -13,10 +13,10 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "DistPointArc.h"
|
#include "DistPointArc.h"
|
||||||
#include "DistPointCrvBezier.h"
|
#include "DistPointCrvBezier.h"
|
||||||
#include "DistPointCrvComposite.h"
|
#include "DistPointCrvComposite.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -47,8 +47,6 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bI
|
|||||||
case CRV_COMPO :
|
case CRV_COMPO :
|
||||||
CrvCompositeCalculate( ptP, Curve) ;
|
CrvCompositeCalculate( ptP, Curve) ;
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
// salvo il punto
|
// salvo il punto
|
||||||
m_ptP = ptP ;
|
m_ptP = ptP ;
|
||||||
@@ -152,7 +150,7 @@ DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||||
double dParam ;
|
double dParam ;
|
||||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
if ( i == 0 ||
|
if ( i == 0 ||
|
||||||
@@ -197,7 +195,7 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
if ( i == 0 ||
|
if ( i == 0 ||
|
||||||
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
||||||
@@ -232,20 +230,9 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
|||||||
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||||
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
||||||
if ( ! vtTg.Normalize()) {
|
if ( ! vtTg.Normalize()) {
|
||||||
double dDeltaU = 1000 * EPS_PARAM ;
|
double dDeltaU = 1000 * EPS_PARAM ;
|
||||||
double dParPre = m_Info[nInd].dPar - dDeltaU ;
|
if ( ! m_pCurve->GetPointTang( m_Info[nInd].dPar - dDeltaU, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
||||||
double dParPost = m_Info[nInd].dPar + dDeltaU ;
|
! m_pCurve->GetPointTang( m_Info[nInd].dPar + dDeltaU, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
||||||
// verifico se il parametro deve essere modificato per adattarsi a curva chiusa
|
|
||||||
if ( m_pCurve->IsClosed()) {
|
|
||||||
double dParS, dParE ;
|
|
||||||
m_pCurve->GetDomain( dParS, dParE) ;
|
|
||||||
if ( dParPre < dParS)
|
|
||||||
dParPre = dParE - dDeltaU ;
|
|
||||||
if ( dParPost > dParE)
|
|
||||||
dParPost = dParS + dDeltaU ;
|
|
||||||
}
|
|
||||||
if ( ! m_pCurve->GetPointTang( dParPre, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
|
||||||
! m_pCurve->GetPointTang( dParPost, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
|
||||||
return false ;
|
return false ;
|
||||||
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||||
if ( ! vtTg.Normalize( EPS_ZERO))
|
if ( ! vtTg.Normalize( EPS_ZERO))
|
||||||
@@ -275,7 +262,7 @@ DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, i
|
|||||||
if ( m_dDist < 0 || m_Info.empty())
|
if ( m_dDist < 0 || m_Info.empty())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||||
int nInd ;
|
int nInd ;
|
||||||
double dParam ;
|
double dParam ;
|
||||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
|
|||||||
+4
-4
@@ -1,19 +1,19 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2013-2024
|
// EgalTech 2013-2013
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : DistPointLine.cpp Data : 20.05.24 Versione : 2.6e5
|
// File : DistPointLine.cpp Data : 17.12.13 Versione : 1.4l1
|
||||||
// Contenuto : Implementazione della classe distanza punto da linea/segmento.
|
// Contenuto : Implementazione della classe distanza punto da linea/segmento.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Modifiche : 17.12.13 DS Creazione modulo.
|
// Modifiche : 17.12.13 DS Creazione modulo.
|
||||||
// 20.05.24 DS Reso pubblico in Include.
|
//
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2013-2014
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : DistPointLine.h Data : 02.01.14 Versione : 1.5a1
|
||||||
|
// Contenuto : Dichiarazione della classe distanza punto da linea/segmento.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 30.12.12 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class DistPointLine
|
||||||
|
{
|
||||||
|
friend class DistPointCurve ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
DistPointLine( const Point3d& ptP,
|
||||||
|
const ICurveLine& crvLine, bool bIsSegment = true) ;
|
||||||
|
DistPointLine( const Point3d& ptP,
|
||||||
|
const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment = true) ;
|
||||||
|
DistPointLine( const Point3d& ptP,
|
||||||
|
const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment = true) ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
bool GetSqDist( double& dSqDist) const ;
|
||||||
|
bool GetDist( double& dDist) const ;
|
||||||
|
bool IsEpsilon( double dTol) const
|
||||||
|
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
|
||||||
|
bool IsSmall( void) const
|
||||||
|
{ return IsEpsilon( EPS_SMALL) ; }
|
||||||
|
bool IsZero( void) const
|
||||||
|
{ return IsEpsilon( EPS_ZERO) ; }
|
||||||
|
int GetNbrMinDist( void) const
|
||||||
|
{ return (( m_dSqDist < 0) ? 0 : 1) ; }
|
||||||
|
bool GetMinDistPoint( Point3d& ptMinDist) const ;
|
||||||
|
bool GetParamAtMinDistPoint( double& dParam) const ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
DistPointLine( void) ;
|
||||||
|
void Calculate( const Point3d& ptP,
|
||||||
|
const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment) ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
double m_dSqDist ;
|
||||||
|
mutable double m_dDist ;
|
||||||
|
double m_dParam ;
|
||||||
|
Point3d m_ptMinDist ;
|
||||||
|
} ;
|
||||||
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
//----------------------------------------------------------------------------
|
|
||||||
// EgalTech 2018-2020
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// File : DistPointSurfTm.cpp Data : 19.12.20 Versione : 2.2l3
|
|
||||||
// Contenuto : Implementazione della classe distanza Punto da Trimesh.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Modifiche : 07.12.18 LM Creazione modulo.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "SurfFlatRegion.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
|
||||||
|
|
||||||
using namespace std ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
DistPointSurfFr::DistPointSurfFr( const Point3d& ptP, const ISurfFlatRegion& frSurf)
|
|
||||||
: m_dDist( -1)
|
|
||||||
{
|
|
||||||
// FlatRegion non valida
|
|
||||||
if ( &frSurf == nullptr || ! frSurf.IsValid())
|
|
||||||
return ;
|
|
||||||
// Calcolo la distanza
|
|
||||||
Calculate( ptP, frSurf) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
DistPointSurfFr::Calculate( const Point3d& ptP, const ISurfFlatRegion& frSurf)
|
|
||||||
{
|
|
||||||
// Inizializzo distanza non calcolata
|
|
||||||
m_dDist = -1 ;
|
|
||||||
|
|
||||||
// Converto regione in classe base
|
|
||||||
const SurfFlatRegion* pSfr = GetBasicSurfFlatRegion( &frSurf) ;
|
|
||||||
if ( pSfr == nullptr)
|
|
||||||
return ;
|
|
||||||
|
|
||||||
// ciclo sulle parti della regione
|
|
||||||
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; nC ++) {
|
|
||||||
// ciclo sui loop della parte di regione
|
|
||||||
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; nL ++) {
|
|
||||||
PtrOwner<ICurve> pLoop( pSfr->GetLoop( nC, nL)) ;
|
|
||||||
if ( IsNull( pLoop)) {
|
|
||||||
m_dDist = -1 ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
DistPointCurve DPL( ptP, *pLoop) ;
|
|
||||||
double dDist ;
|
|
||||||
if ( DPL.GetDist( dDist) && ( m_dDist < -EPS_SMALL || dDist < m_dDist)) {
|
|
||||||
m_dDist = dDist ;
|
|
||||||
int nFlag ;
|
|
||||||
m_nMinChunk = nC ;
|
|
||||||
m_nMinLoop = nL ;
|
|
||||||
DPL.GetParamAtMinDistPoint( 0, m_dMinPar, nFlag) ;
|
|
||||||
DPL.GetMinDistPoint( 0, m_ptMinDistPoint, nFlag) ;
|
|
||||||
DPL.GetSideAtMinDistPoint( 0, pSfr->GetNormVersor(), m_nSide) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se trovata, aggiorno minima distanza sul piano
|
|
||||||
if ( m_dDist > - EPS_SMALL) {
|
|
||||||
Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ;
|
|
||||||
m_dDistOnPlane = min( Dist( ptOn, m_ptMinDistPoint), m_dDist) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfFr::GetDist( double& dDist) const
|
|
||||||
{
|
|
||||||
if ( m_dDist < 0)
|
|
||||||
return false ;
|
|
||||||
dDist = m_dDist ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfFr::GetDistOnRegionPlane( double& dDist) const
|
|
||||||
{
|
|
||||||
if ( m_dDist < 0)
|
|
||||||
return false ;
|
|
||||||
dDist = m_dDistOnPlane ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfFr::GetPointAtMinDist( Point3d& ptMinDist) const
|
|
||||||
{
|
|
||||||
if ( m_dDist < 0)
|
|
||||||
return false ;
|
|
||||||
ptMinDist = m_ptMinDistPoint ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfFr::GetParamAtMinDist( int& nMinChunk, int& nMinLoop, double& dMinPar) const
|
|
||||||
{
|
|
||||||
if ( m_dDist < 0)
|
|
||||||
return false ;
|
|
||||||
nMinChunk = m_nMinChunk ;
|
|
||||||
nMinLoop = m_nMinLoop ;
|
|
||||||
dMinPar = m_dMinPar ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfFr::GetSideAtMinDist( int& nSide) const
|
|
||||||
{
|
|
||||||
if ( m_dDist < 0)
|
|
||||||
return false ;
|
|
||||||
nSide = m_nSide ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
IsPointInsideSurfFr( const Point3d& ptP, const ISurfFlatRegion* pSfr, double dMinDist, bool& bInside, int& nChunk)
|
|
||||||
{
|
|
||||||
// default non include
|
|
||||||
bInside = false ;
|
|
||||||
nChunk = -1 ;
|
|
||||||
// verifica regione
|
|
||||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
|
||||||
return false ;
|
|
||||||
// verifico se la proiezione del punto sul piano della regione sta nel suo box
|
|
||||||
Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ;
|
|
||||||
BBox3d b3Box ;
|
|
||||||
pSfr->GetLocalBBox( b3Box) ;
|
|
||||||
b3Box.Expand( dMinDist) ;
|
|
||||||
if ( ! b3Box.Encloses( ptOn))
|
|
||||||
return true ;
|
|
||||||
// determino dove sta il punto
|
|
||||||
DistPointSurfFr DPR( ptP, *pSfr) ;
|
|
||||||
double dDist ; int nMinCh, nMinL; double dMinPar ; int nSide ;
|
|
||||||
if ( DPR.GetDistOnRegionPlane( dDist) && DPR.GetParamAtMinDist( nMinCh, nMinL, dMinPar) && DPR.GetSideAtMinDist( nSide)) {
|
|
||||||
if ( abs( dMinDist) < EPS_SMALL)
|
|
||||||
bInside = ( nSide != PRS_OUT) ;
|
|
||||||
else if ( dMinDist < 0)
|
|
||||||
bInside = ( nSide == PRS_IN && dDist > abs( dMinDist) - EPS_SMALL) ;
|
|
||||||
else
|
|
||||||
bInside = ( nSide != PRS_OUT || dDist < dMinDist + EPS_SMALL) ;
|
|
||||||
if ( bInside)
|
|
||||||
nChunk = nMinCh ;
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
+30
-117
@@ -15,16 +15,15 @@
|
|||||||
#include "SurfTriMesh.h"
|
#include "SurfTriMesh.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Calcola la differenza fra i bounding-box A e B.
|
// Calcola la differenza fra i bounding-box A e B.
|
||||||
// L'insieme differenza non è un bounding-box, ma è esprimibile come unione di al più sei bounding-box.
|
// L'insieme differenza non è un bounding-box, ma è esprimibile come unione di al più sei bounding-box.
|
||||||
// Se l'insieme differenza fra i box non ha misura nulla viene restituito true, false altrimenti.
|
// Se l'insieme differenza fra i box non ha misura nulla viene restituito true, false altrimenti.
|
||||||
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
|
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
|
||||||
// nel box B; uno di questi si verifica se il box A è vuoto.
|
// nel box B; uno di questi si verifica se il box A è vuoto.
|
||||||
// Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
// Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
||||||
static bool
|
static bool
|
||||||
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||||
@@ -34,7 +33,7 @@ BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDi
|
|||||||
// Se box A vuoto, risultato vuoto
|
// Se box A vuoto, risultato vuoto
|
||||||
if ( boxA.IsEmpty())
|
if ( boxA.IsEmpty())
|
||||||
return false ;
|
return false ;
|
||||||
// Se box B vuoto o i box non si intersecano, risultato è ancora A
|
// Se box B vuoto o i box non si intersecano, risultato è ancora A
|
||||||
BBox3d boxInt ;
|
BBox3d boxInt ;
|
||||||
if ( boxB.IsSmall() || ! boxA.FindIntersection( boxB, boxInt)) {
|
if ( boxB.IsSmall() || ! boxA.FindIntersection( boxB, boxInt)) {
|
||||||
vBoxDiff.emplace_back( boxA) ;
|
vBoxDiff.emplace_back( boxA) ;
|
||||||
@@ -94,10 +93,6 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
{
|
{
|
||||||
// Inizializzo distanza non calcolata
|
// Inizializzo distanza non calcolata
|
||||||
m_dDist = - 1. ;
|
m_dDist = - 1. ;
|
||||||
// Vettore di indici dei triangoli più vicini inizialmente vuoto
|
|
||||||
m_vnMinDistTriaIndex.clear() ;
|
|
||||||
// Controllo se la superficie è chiusa
|
|
||||||
m_bIsSurfClosed = tmSurf.IsClosed() ;
|
|
||||||
|
|
||||||
// Lavoro con l'oggetto superficie trimesh di base
|
// Lavoro con l'oggetto superficie trimesh di base
|
||||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
||||||
@@ -109,8 +104,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
if ( b3Stm.IsEmpty())
|
if ( b3Stm.IsEmpty())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||||
@@ -120,17 +115,14 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
BBox3d boxPPrev( ptP) ;
|
BBox3d boxPPrev( ptP) ;
|
||||||
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||||
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
||||||
double dMinDist = DBL_MAX ;
|
double dMinSqDist = DBL_MAX ;
|
||||||
int nMinDistTriaIndex = SVT_NULL ;
|
int nMinDistTriaIndex = SVT_NULL ;
|
||||||
Point3d ptMinDistPoint ;
|
Point3d ptMinDistPoint ;
|
||||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||||
pStm->ResetTempInts() ;
|
pStm->ResetTempInts() ;
|
||||||
bool bContinue = true ;
|
bool bContinue = true ;
|
||||||
|
|
||||||
// creazione del vettore dei triangoli più vicini a ptP
|
|
||||||
vector<pair<int, Triangle3d>> vTria ; // <indice triangolo, Triangolo>
|
|
||||||
while ( bContinue) {
|
while ( bContinue) {
|
||||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||||
BOXVECTOR vBox ;
|
BOXVECTOR vBox ;
|
||||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||||
// Ciclo sui box differenza
|
// Ciclo sui box differenza
|
||||||
@@ -138,12 +130,12 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
for ( const auto& b3Box : vBox) {
|
for ( const auto& b3Box : vBox) {
|
||||||
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
|
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
|
||||||
BBox3d b3Int ;
|
BBox3d b3Int ;
|
||||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.DistFromPoint( ptP) > dMinDist)
|
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.SqDistFromPoint( ptP) > dMinSqDist)
|
||||||
continue ;
|
continue ;
|
||||||
// ricerca sui triangoli nel box
|
// ricerca sui triangoli nel box
|
||||||
bCollide = true ;
|
bCollide = true ;
|
||||||
INTVECTOR vnIds ;
|
INTVECTOR vnIds ;
|
||||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||||
// Ciclo sui triangoli del sotto-box corrente
|
// Ciclo sui triangoli del sotto-box corrente
|
||||||
for ( auto nT : vnIds) {
|
for ( auto nT : vnIds) {
|
||||||
int nTriaTemp ;
|
int nTriaTemp ;
|
||||||
@@ -151,30 +143,19 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
||||||
pStm->SetTempInt( nT, 1) ;
|
pStm->SetTempInt( nT, 1) ;
|
||||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||||
double dCurrDist ;
|
double dCurSqDist ;
|
||||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||||
if ( distPT.GetDist( dCurrDist)) {
|
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||||
// se distanze uguali...
|
dMinSqDist = dCurSqDist ;
|
||||||
if ( abs( dCurrDist - dMinDist) < EPS_SMALL)
|
nMinDistTriaIndex = nT ;
|
||||||
// aggiungo il triangolo
|
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||||
vTria.emplace_back( make_pair( nT, trCurTria)) ;
|
|
||||||
// se minore...
|
|
||||||
else if ( dCurrDist < dMinDist) {
|
|
||||||
// pulisco il vettore
|
|
||||||
vTria.clear() ;
|
|
||||||
dMinDist = dCurrDist ;
|
|
||||||
nMinDistTriaIndex = nT ;
|
|
||||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
|
||||||
// aggiungo il triangolo
|
|
||||||
vTria.emplace_back( make_pair( nT, trCurTria)) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Se si verifica la condizione di terminazione arresto il ciclo altrimenti aggiorno i box
|
// Se si verifica la condizione di terminazione arresto il ciclo altrimenti aggiorno i box
|
||||||
if ( ! bCollide || dMinDist < EPS_SMALL)
|
if ( ! bCollide || dMinSqDist < EPS_SMALL * EPS_SMALL)
|
||||||
bContinue = false ;
|
bContinue = false ;
|
||||||
else {
|
else {
|
||||||
boxPPrev = boxP ;
|
boxPPrev = boxP ;
|
||||||
@@ -182,71 +163,15 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se non ho trovato nessun triangolo, esco
|
if ( nMinDistTriaIndex != SVT_NULL) {
|
||||||
if ( nMinDistTriaIndex == SVT_NULL)
|
m_dDist = sqrt( max( dMinSqDist, 0.)) ;
|
||||||
return ;
|
|
||||||
|
|
||||||
// Inizializzo il vettore dei triangoli a minima distanza
|
|
||||||
for ( auto& Tria : vTria)
|
|
||||||
m_vnMinDistTriaIndex.emplace_back( Tria.first) ;
|
|
||||||
|
|
||||||
// salvo la distanza minima
|
|
||||||
m_dDist = dMinDist ;
|
|
||||||
// salvo il punto a distanza minima
|
|
||||||
m_ptMinDistPoint = ptMinDistPoint ;
|
|
||||||
// se il punto è sulla TriMesh...
|
|
||||||
if ( m_dDist < EPS_SMALL) {
|
|
||||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
||||||
m_bIsInside = false ;
|
m_ptMinDistPoint = ptMinDistPoint ;
|
||||||
return ;
|
Triangle3d trMinDistTria ;
|
||||||
|
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||||
|
trMinDistTria.Validate() ;
|
||||||
|
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ;
|
||||||
}
|
}
|
||||||
// se ho un solo triangolo, allora deduco le informazioni da lui
|
|
||||||
else if ( int( vTria.size()) == 1) {
|
|
||||||
m_nMinDistTriaIndex = vTria.back().first ;
|
|
||||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * vTria.back().second.GetN() < - EPS_SMALL) ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// controllo se tutti i triangoli a minima distanza forniscono la stessa informazione
|
|
||||||
// ( il punto potrebbe essere esterno a tutti, interno a tutti o indefinito )
|
|
||||||
bool bInside = false ;
|
|
||||||
bool bOutside = false ;
|
|
||||||
for ( int i = 0 ; i < int( vTria.size()) ; ++ i) { // scorro i triangoli a minima distanza
|
|
||||||
if ( ( ptP - vTria[i].second.GetP( 0)) * vTria[i].second.GetN() < - EPS_SMALL)
|
|
||||||
bInside = true ;
|
|
||||||
else
|
|
||||||
bOutside = true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// inizializzo le variabili membro
|
|
||||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
|
||||||
m_bIsInside = false ;
|
|
||||||
|
|
||||||
// se le informazioni non sono coerenti, allora :
|
|
||||||
// 1) calcolo i centroidi dei triangoli in questione
|
|
||||||
// 2) ottengo il punto medio di questi centroidi
|
|
||||||
// 3) controllo quale triangolo interseca il segmento che parte da ptP e arriva a tale punto
|
|
||||||
// 4) userò questo triangolo per classificare ptP
|
|
||||||
if ( bOutside == bInside) {
|
|
||||||
// calcolo il baricentro complessivo
|
|
||||||
Point3d ptBar_tot ;
|
|
||||||
for ( auto& Tria : vTria)
|
|
||||||
ptBar_tot += Tria.second.GetCentroid() ;
|
|
||||||
ptBar_tot /= int( vTria.size()) ;
|
|
||||||
// per ogni triangolo, cerco quello che interseca il segmento
|
|
||||||
for ( auto& Tria : vTria) {
|
|
||||||
Point3d ptInters1, ptInters2 ;
|
|
||||||
int nType = IntersLineTria( ptP, ptBar_tot, Tria.second, ptInters1, ptInters2) ;
|
|
||||||
if ( nType == ILTT_IN) { // se intersezione ho finito
|
|
||||||
DistPointTriangle( ptP, Tria.second).GetMinDistPoint( m_ptMinDistPoint) ;
|
|
||||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * Tria.second.GetN() < - EPS_SMALL) ;
|
|
||||||
m_nMinDistTriaIndex = Tria.first ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // se informazioni coerenti
|
|
||||||
m_bIsInside = bInside ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -285,18 +210,6 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) const
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DistPointSurfTm::GetMinDistTriaIndices( INTVECTOR& vMinDistTriaIndex) const
|
|
||||||
{
|
|
||||||
// Distanza non valida
|
|
||||||
if ( m_dDist < - EPS_ZERO)
|
|
||||||
return false ;
|
|
||||||
// Distanza valida
|
|
||||||
vMinDistTriaIndex = m_vnMinDistTriaIndex ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||||
@@ -311,8 +224,8 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
if ( b3Stm.IsEmpty())
|
if ( b3Stm.IsEmpty())
|
||||||
return SVT_NULL ;
|
return SVT_NULL ;
|
||||||
|
|
||||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||||
@@ -324,11 +237,11 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
// Variabili distanza minima
|
// Variabili distanza minima
|
||||||
int nVert = SVT_NULL ;
|
int nVert = SVT_NULL ;
|
||||||
double dMinSqDist = DBL_MAX ;
|
double dMinSqDist = DBL_MAX ;
|
||||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||||
pStm->ResetTempInts() ;
|
pStm->ResetTempInts() ;
|
||||||
bool bContinue = true ;
|
bool bContinue = true ;
|
||||||
while ( bContinue) {
|
while ( bContinue) {
|
||||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||||
BOXVECTOR vBox ;
|
BOXVECTOR vBox ;
|
||||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||||
// Ciclo sui box differenza
|
// Ciclo sui box differenza
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ProjPlane.h"
|
#include "ProjPlane.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -159,20 +159,11 @@ InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
|
|||||||
{
|
{
|
||||||
// recupero il font manager
|
// recupero il font manager
|
||||||
FontManager& fntMgr = FontManager::GetFontManager() ;
|
FontManager& fntMgr = FontManager::GetFontManager() ;
|
||||||
|
|
||||||
// lo inizializzo
|
// lo inizializzo
|
||||||
fntMgr.Init( sNfeFontDir, sDefaultFont) ;
|
fntMgr.Init( sNfeFontDir, sDefaultFont) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
SetDefaultFont( const string& sDefaultFont)
|
|
||||||
{
|
|
||||||
// recupero il font manager
|
|
||||||
FontManager& fntMgr = FontManager::GetFontManager() ;
|
|
||||||
// imposto il dato
|
|
||||||
fntMgr.SetDefaultFont( sDefaultFont) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
const string&
|
const string&
|
||||||
GetNfeFontDir( void)
|
GetNfeFontDir( void)
|
||||||
|
|||||||
Binary file not shown.
+6
-14
@@ -22,7 +22,7 @@
|
|||||||
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
|
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
|
||||||
<RootNamespace>EgtGeomKernel</RootNamespace>
|
<RootNamespace>EgtGeomKernel</RootNamespace>
|
||||||
<Keyword>MFCDLLProj</Keyword>
|
<Keyword>MFCDLLProj</Keyword>
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v141_xp</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
@@ -117,7 +117,6 @@
|
|||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<AdditionalIncludeDirectories>C:\EgtDev\Extern\abseil\Include</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -282,7 +281,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="BBox3d.cpp" />
|
<ClCompile Include="BBox3d.cpp" />
|
||||||
<ClCompile Include="BiArcs.cpp" />
|
<ClCompile Include="BiArcs.cpp" />
|
||||||
<ClCompile Include="CalcPocketing.cpp" />
|
<ClCompile Include="CalcPocketing.cpp" />
|
||||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
|
||||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||||
@@ -311,7 +309,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="CurveByApprox.cpp" />
|
<ClCompile Include="CurveByApprox.cpp" />
|
||||||
<ClCompile Include="CurveByInterp.cpp" />
|
<ClCompile Include="CurveByInterp.cpp" />
|
||||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||||
<ClCompile Include="DistPointSurfFr.cpp" />
|
|
||||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
@@ -321,21 +318,16 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||||
<ClCompile Include="IntersLineSurfBez.cpp" />
|
<ClCompile Include="IntersLineSurfBez.cpp" />
|
||||||
<ClCompile Include="SurfTriMeshOffset.cpp" />
|
|
||||||
<ClCompile Include="VolZmapOffset.cpp" />
|
|
||||||
<ClCompile Include="PolygonElevation.cpp" />
|
<ClCompile Include="PolygonElevation.cpp" />
|
||||||
<ClCompile Include="Quaternion.cpp" />
|
<ClCompile Include="Quaternion.cpp" />
|
||||||
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
||||||
<ClCompile Include="RotationXplaneFrame.cpp" />
|
<ClCompile Include="RotationXplaneFrame.cpp" />
|
||||||
<ClCompile Include="SbzFromCurves.cpp" />
|
|
||||||
<ClCompile Include="SbzStandard.cpp" />
|
<ClCompile Include="SbzStandard.cpp" />
|
||||||
<ClCompile Include="Voronoi.cpp" />
|
<ClCompile Include="Voronoi.cpp" />
|
||||||
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkDistLineLine.h" />
|
|
||||||
<ClInclude Include="..\Include\EGkDistPointLine.h" />
|
|
||||||
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
|
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||||
@@ -346,8 +338,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
||||||
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
||||||
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
||||||
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h" />
|
|
||||||
<ClInclude Include="CAvSilhouetteSurfTm.h" />
|
|
||||||
<ClInclude Include="CDeBoxTria.h" />
|
<ClInclude Include="CDeBoxTria.h" />
|
||||||
<ClInclude Include="CDeCapsTria.h" />
|
<ClInclude Include="CDeCapsTria.h" />
|
||||||
<ClInclude Include="CDeConeFrustumTria.h" />
|
<ClInclude Include="CDeConeFrustumTria.h" />
|
||||||
@@ -433,7 +423,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="OffsetCurveOnX.cpp" />
|
<ClCompile Include="OffsetCurveOnX.cpp" />
|
||||||
<ClCompile Include="Polygon3d.cpp" />
|
<ClCompile Include="Polygon3d.cpp" />
|
||||||
<ClCompile Include="AdjustLoops.cpp" />
|
<ClCompile Include="AdjustLoops.cpp" />
|
||||||
<ClCompile Include="ProjectCurveSurf.cpp" />
|
<ClCompile Include="ProjectCurveSurfTm.cpp" />
|
||||||
<ClCompile Include="RemoveCurveDefects.cpp" />
|
<ClCompile Include="RemoveCurveDefects.cpp" />
|
||||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||||
<ClCompile Include="SfrCreate.cpp" />
|
<ClCompile Include="SfrCreate.cpp" />
|
||||||
@@ -605,10 +595,12 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClInclude Include="CAvSimpleSurfFrMove.h" />
|
<ClInclude Include="CAvSimpleSurfFrMove.h" />
|
||||||
<ClInclude Include="CAvToolSurfTm.h" />
|
<ClInclude Include="CAvToolSurfTm.h" />
|
||||||
<ClInclude Include="CreateCurveAux.h" />
|
<ClInclude Include="CreateCurveAux.h" />
|
||||||
|
<ClInclude Include="DistLineLine.h" />
|
||||||
<ClInclude Include="DistPointArc.h" />
|
<ClInclude Include="DistPointArc.h" />
|
||||||
<ClInclude Include="DistPointCrvAux.h" />
|
<ClInclude Include="DistPointCrvAux.h" />
|
||||||
<ClInclude Include="DistPointCrvBezier.h" />
|
<ClInclude Include="DistPointCrvBezier.h" />
|
||||||
<ClInclude Include="DistPointCrvComposite.h" />
|
<ClInclude Include="DistPointCrvComposite.h" />
|
||||||
|
<ClInclude Include="DistPointLine.h" />
|
||||||
<ClInclude Include="DllMain.h" />
|
<ClInclude Include="DllMain.h" />
|
||||||
<ClInclude Include="earcut.hpp" />
|
<ClInclude Include="earcut.hpp" />
|
||||||
<ClInclude Include="ExtDimension.h" />
|
<ClInclude Include="ExtDimension.h" />
|
||||||
|
|||||||
@@ -486,7 +486,7 @@
|
|||||||
<ClCompile Include="IntersLineCaps.cpp">
|
<ClCompile Include="IntersLineCaps.cpp">
|
||||||
<Filter>File di origine\GeoInters</Filter>
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ProjectCurveSurf.cpp">
|
<ClCompile Include="ProjectCurveSurfTm.cpp">
|
||||||
<Filter>File di origine\GeoProject</Filter>
|
<Filter>File di origine\GeoProject</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SubtractProjectedFacesOnStmFace.cpp">
|
<ClCompile Include="SubtractProjectedFacesOnStmFace.cpp">
|
||||||
@@ -537,21 +537,6 @@
|
|||||||
<ClCompile Include="Quaternion.cpp">
|
<ClCompile Include="Quaternion.cpp">
|
||||||
<Filter>File di origine\Base</Filter>
|
<Filter>File di origine\Base</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp">
|
|
||||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SbzFromCurves.cpp">
|
|
||||||
<Filter>File di origine\GeoCreate</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="DistPointSurfFr.cpp">
|
|
||||||
<Filter>File di origine\GeoDist</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="VolZmapOffset.cpp">
|
|
||||||
<Filter>File di origine\Geo</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SurfTriMeshOffset.cpp">
|
|
||||||
<Filter>File di origine\GeoOffset</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
@@ -608,6 +593,9 @@
|
|||||||
<ClInclude Include="DistPointArc.h">
|
<ClInclude Include="DistPointArc.h">
|
||||||
<Filter>File di intestazione</Filter>
|
<Filter>File di intestazione</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="DistPointLine.h">
|
||||||
|
<Filter>File di intestazione</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="DistPointCrvBezier.h">
|
<ClInclude Include="DistPointCrvBezier.h">
|
||||||
<Filter>File di intestazione</Filter>
|
<Filter>File di intestazione</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1130,6 +1118,9 @@
|
|||||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
|
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
|
||||||
<Filter>File di intestazione\Include</Filter>
|
<Filter>File di intestazione\Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="DistLineLine.h">
|
||||||
|
<Filter>File di intestazione</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="CDeUtility.h">
|
<ClInclude Include="CDeUtility.h">
|
||||||
<Filter>File di intestazione</Filter>
|
<Filter>File di intestazione</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1223,18 +1214,6 @@
|
|||||||
<ClInclude Include="..\Include\EGkQuaternion.h">
|
<ClInclude Include="..\Include\EGkQuaternion.h">
|
||||||
<Filter>File di intestazione\Include</Filter>
|
<Filter>File di intestazione\Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\Include\EGkDistLineLine.h">
|
|
||||||
<Filter>File di intestazione\Include</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\Include\EGkDistPointLine.h">
|
|
||||||
<Filter>File di intestazione\Include</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="CAvSilhouetteSurfTm.h">
|
|
||||||
<Filter>File di intestazione</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h">
|
|
||||||
<Filter>File di intestazione\Include</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||||
|
|||||||
@@ -147,10 +147,6 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
|||||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// verifico il minimo raggio
|
|
||||||
if ( dRadius < 10 * EPS_SMALL)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// eseguo calcoli
|
// eseguo calcoli
|
||||||
Point3d ptCen, ptTg1, ptTg2 ;
|
Point3d ptCen, ptTg1, ptTg2 ;
|
||||||
int nSide1, nSide2 ;
|
int nSide1, nSide2 ;
|
||||||
@@ -169,11 +165,6 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico dimensione minima
|
|
||||||
double dLen = Dist( ptTg1, ptTg2) ;
|
|
||||||
if ( dLen < 2 * EPS_SMALL)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// orientamento tra le curve
|
// orientamento tra le curve
|
||||||
bool bCCW = ( dSinA > 0) ;
|
bool bCCW = ( dSinA > 0) ;
|
||||||
|
|
||||||
@@ -216,10 +207,6 @@ CreateChamfer( const ICurve& cCrv1, const Point3d& ptNear1,
|
|||||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// verifico lo smusso minimo
|
|
||||||
if ( dDist < 10 * EPS_SMALL)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// calcolo un riferimento sul piano perpendicolare alla normale
|
// calcolo un riferimento sul piano perpendicolare alla normale
|
||||||
Frame3d frIntr ;
|
Frame3d frIntr ;
|
||||||
if ( ! frIntr.Set( ORIG, vtNorm))
|
if ( ! frIntr.Set( ORIG, vtNorm))
|
||||||
|
|||||||
+1
-3
@@ -29,8 +29,6 @@ class FontManager
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
bool Init( const std::string& sNfeFontDir, const std::string& sDefaultFont) ;
|
bool Init( const std::string& sNfeFontDir, const std::string& sDefaultFont) ;
|
||||||
bool SetDefaultFont( const std::string& sDefaultFont)
|
|
||||||
{ m_sDefaultFont = sDefaultFont ; return true ; }
|
|
||||||
bool SetCurrFont( const std::string& sFont, int nWeight, bool bItalic,
|
bool SetCurrFont( const std::string& sFont, int nWeight, bool bItalic,
|
||||||
double dHeight, double dRatio, double dAddAdvance) ;
|
double dHeight, double dRatio, double dAddAdvance) ;
|
||||||
const std::string& GetNfeFontDir( void) const
|
const std::string& GetNfeFontDir( void) const
|
||||||
@@ -56,7 +54,7 @@ class FontManager
|
|||||||
OsFont m_OsFont ;
|
OsFont m_OsFont ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
FontManager( void) : m_bCurrNfeFont( false) {}
|
FontManager( void) {}
|
||||||
FontManager( FontManager const& copy) = delete ;
|
FontManager( FontManager const& copy) = delete ;
|
||||||
FontManager& operator=( FontManager const& copy) = delete ;
|
FontManager& operator=( FontManager const& copy) = delete ;
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
+2
-2
@@ -493,7 +493,7 @@ NfeFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECT
|
|||||||
int nLbLen ;
|
int nLbLen ;
|
||||||
if ( IsLineBreak( vCode, i, nLbLen)) {
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
||||||
// salvo la linea, se contiene qualcosa
|
// salvo la linea, se contiene qualcosa
|
||||||
if ( ! vTmpCode.empty()) {
|
if ( vTmpCode.size() > 0) {
|
||||||
string sLine ;
|
string sLine ;
|
||||||
SetCodePoints( vTmpCode, sLine) ;
|
SetCodePoints( vTmpCode, sLine) ;
|
||||||
vLine.push_back( sLine) ;
|
vLine.push_back( sLine) ;
|
||||||
@@ -523,7 +523,7 @@ NfeFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECT
|
|||||||
dMaxW = vtMove.x ;
|
dMaxW = vtMove.x ;
|
||||||
}
|
}
|
||||||
// salvo eventuale ultima linea
|
// salvo eventuale ultima linea
|
||||||
if ( ! vTmpCode.empty()) {
|
if ( vTmpCode.size() > 0) {
|
||||||
string sLine ;
|
string sLine ;
|
||||||
SetCodePoints( vTmpCode, sLine) ;
|
SetCodePoints( vTmpCode, sLine) ;
|
||||||
vLine.push_back( sLine) ;
|
vLine.push_back( sLine) ;
|
||||||
|
|||||||
+2
-2
@@ -619,7 +619,7 @@ OsFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTO
|
|||||||
int nLbLen ;
|
int nLbLen ;
|
||||||
if ( IsLineBreak( vCode, i, nLbLen)) {
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
||||||
// salvo la linea, se contiene qualcosa
|
// salvo la linea, se contiene qualcosa
|
||||||
if ( ! vTmpCode.empty()) {
|
if ( vTmpCode.size() > 0) {
|
||||||
string sLine ;
|
string sLine ;
|
||||||
SetCodePoints( vTmpCode, sLine) ;
|
SetCodePoints( vTmpCode, sLine) ;
|
||||||
vLine.push_back( sLine) ;
|
vLine.push_back( sLine) ;
|
||||||
@@ -646,7 +646,7 @@ OsFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTO
|
|||||||
dMaxW = vtMove.x ;
|
dMaxW = vtMove.x ;
|
||||||
}
|
}
|
||||||
// salvo eventuale ultima linea
|
// salvo eventuale ultima linea
|
||||||
if ( ! vTmpCode.empty()) {
|
if ( vTmpCode.size() > 0) {
|
||||||
string sLine ;
|
string sLine ;
|
||||||
SetCodePoints( vTmpCode, sLine) ;
|
SetCodePoints( vTmpCode, sLine) ;
|
||||||
vLine.push_back( sLine) ;
|
vLine.push_back( sLine) ;
|
||||||
|
|||||||
-17
@@ -37,23 +37,6 @@ Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX,
|
|||||||
! m_vtVersZ.Normalize())
|
! m_vtVersZ.Normalize())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// se ci sono errori molto piccoli di ortogonalità, li correggo
|
|
||||||
double dOrtXZ = m_vtVersX * m_vtVersZ ;
|
|
||||||
if ( dOrtXZ > EPS_ZERO && dOrtXZ < 10 * EPS_ZERO) {
|
|
||||||
m_vtVersX = OrthoCompo( m_vtVersX, m_vtVersZ) ;
|
|
||||||
m_vtVersX.Normalize() ;
|
|
||||||
}
|
|
||||||
double dOrtYX = m_vtVersY * m_vtVersX ;
|
|
||||||
if ( dOrtYX > EPS_ZERO && dOrtYX < 10 * EPS_ZERO) {
|
|
||||||
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersX) ;
|
|
||||||
m_vtVersY.Normalize() ;
|
|
||||||
}
|
|
||||||
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
|
||||||
if ( dOrtYZ > EPS_ZERO && dOrtYZ < 10 * EPS_ZERO) {
|
|
||||||
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersZ) ;
|
|
||||||
m_vtVersY.Normalize() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifica della ortogonalità dei versori e del senso destrorso
|
// verifica della ortogonalità dei versori e del senso destrorso
|
||||||
if ( ! Verify())
|
if ( ! Verify())
|
||||||
return false ;
|
return false ;
|
||||||
|
|||||||
+5
-5
@@ -2267,7 +2267,7 @@ bool
|
|||||||
GdbExecutor::SurfTriMeshEnd( const STRVECTOR& vsParams)
|
GdbExecutor::SurfTriMeshEnd( const STRVECTOR& vsParams)
|
||||||
{
|
{
|
||||||
// nessun parametro
|
// nessun parametro
|
||||||
if ( ! vsParams.empty())
|
if ( vsParams.size() != 0)
|
||||||
return false ;
|
return false ;
|
||||||
// recupero la superficie
|
// recupero la superficie
|
||||||
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
|
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
|
||||||
@@ -6632,7 +6632,7 @@ GdbExecutor::ExecuteDeselect( const string& sCmd2, const STRVECTOR& vsParams)
|
|||||||
// deselezione di tutto
|
// deselezione di tutto
|
||||||
else if ( sCmd2 == "ALL") {
|
else if ( sCmd2 == "ALL") {
|
||||||
// nessun parametro
|
// nessun parametro
|
||||||
if ( ! vsParams.empty())
|
if ( vsParams.size() != 0)
|
||||||
return false ;
|
return false ;
|
||||||
// cancello selezione oggetti
|
// cancello selezione oggetti
|
||||||
if ( ! m_pGDB->ClearSelection())
|
if ( ! m_pGDB->ClearSelection())
|
||||||
@@ -7773,7 +7773,7 @@ bool
|
|||||||
GdbExecutor::ExecuteNew( const string& sCmd2, const STRVECTOR& vsParams)
|
GdbExecutor::ExecuteNew( const string& sCmd2, const STRVECTOR& vsParams)
|
||||||
{
|
{
|
||||||
// nessun parametro
|
// nessun parametro
|
||||||
if ( ! vsParams.empty())
|
if ( vsParams.size() != 0)
|
||||||
return false ;
|
return false ;
|
||||||
// pulizia e reinizializzazione del DB geometrico
|
// pulizia e reinizializzazione del DB geometrico
|
||||||
m_pGDB->Clear() ;
|
m_pGDB->Clear() ;
|
||||||
@@ -7946,7 +7946,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams)
|
|||||||
// chiudo il file di uscita Tsc
|
// chiudo il file di uscita Tsc
|
||||||
else if ( sCmd2 == "CLOSE") {
|
else if ( sCmd2 == "CLOSE") {
|
||||||
// nessun parametro
|
// nessun parametro
|
||||||
if ( ! vsParams.empty())
|
if ( vsParams.size() != 0)
|
||||||
return false ;
|
return false ;
|
||||||
// scrivo terminazioni e chiudo il file
|
// scrivo terminazioni e chiudo il file
|
||||||
return m_OutTsc.Close() ;
|
return m_OutTsc.Close() ;
|
||||||
@@ -7969,7 +7969,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams)
|
|||||||
else if ( sCmd2 == "SETGR") {
|
else if ( sCmd2 == "SETGR") {
|
||||||
Frame3d frF ;
|
Frame3d frF ;
|
||||||
// nessun parametro
|
// nessun parametro
|
||||||
if ( vsParams.empty())
|
if ( vsParams.size() == 0)
|
||||||
frF.Reset() ;
|
frF.Reset() ;
|
||||||
// un parametro ( Id del gruppo)
|
// un parametro ( Id del gruppo)
|
||||||
else if ( vsParams.size() == 1) {
|
else if ( vsParams.size() == 1) {
|
||||||
|
|||||||
+2
-2
@@ -336,7 +336,7 @@ GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe
|
|||||||
// curva originale
|
// curva originale
|
||||||
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
||||||
// trasformo in curva di Bezier (semplice o composta)
|
// trasformo in curva di Bezier (semplice o composta)
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( pCrv)) ;
|
ICurve* pCrvNew = ArcToBezierCurve( pCrv) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
// assegno alla nuova curva estrusione e spessore di quella originale
|
||||||
@@ -389,7 +389,7 @@ GdbGeo::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDi
|
|||||||
if ( ! pArc->IsPlane() ||
|
if ( ! pArc->IsPlane() ||
|
||||||
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
||||||
// trasformo in curva di Bezier (semplice o composta)
|
// trasformo in curva di Bezier (semplice o composta)
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( m_pGeoObj)) ;
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
// assegno alla nuova curva estrusione e spessore di quella originale
|
||||||
|
|||||||
+2
-2
@@ -1254,13 +1254,13 @@ GdbIterator::GetCalcStatus( int& nStat) const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
GdbIterator::SetMark( int nMark)
|
GdbIterator::SetMark( void)
|
||||||
{
|
{
|
||||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// imposto la marcatura
|
// imposto la marcatura
|
||||||
return m_pCurrObj->SetMark( nMark) ;
|
return m_pCurrObj->SetMark() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ class GdbIterator : public IGdbIterator
|
|||||||
bool RevertStatus( void) override ;
|
bool RevertStatus( void) override ;
|
||||||
bool GetStatus( int& nStat) const override ;
|
bool GetStatus( int& nStat) const override ;
|
||||||
bool GetCalcStatus( int& nStat) const override ;
|
bool GetCalcStatus( int& nStat) const override ;
|
||||||
bool SetMark( int nMark = GDB_MK_ON) override ;
|
bool SetMark( void) override ;
|
||||||
bool ResetMark( void) override ;
|
bool ResetMark( void) override ;
|
||||||
bool GetMark( int& nMark) const override ;
|
bool GetMark( int& nMark) const override ;
|
||||||
bool GetCalcMark( int& nMark) const override ;
|
bool GetCalcMark( int& nMark) const override ;
|
||||||
|
|||||||
+4
-4
@@ -612,14 +612,14 @@ GdbObj::GetCalcStatus( int& nStat, int nLev) const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
GdbObj::SetMark( int nMark)
|
GdbObj::SetMark( void)
|
||||||
{
|
{
|
||||||
// verifico esistenza (con eventuale creazione) degli attributi
|
// verifico esistenza (con eventuale creazione) degli attributi
|
||||||
if ( GetSafeAttribs() == nullptr)
|
if ( GetSafeAttribs() == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// assegno la marcatura
|
// assegno la marcatura
|
||||||
m_pAttribs->SetMark( nMark) ;
|
m_pAttribs->SetMark() ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,8 +659,8 @@ GdbObj::GetCalcMark( int& nMark) const
|
|||||||
nObjMark = m_pAttribs->GetMark() ;
|
nObjMark = m_pAttribs->GetMark() ;
|
||||||
|
|
||||||
// se la marcatura è ON, non ho bisogno di sapere altro
|
// se la marcatura è ON, non ho bisogno di sapere altro
|
||||||
if ( nObjMark == GDB_MK_ON || nObjMark == GDB_MK_ON_2) {
|
if ( nObjMark == GDB_MK_ON) {
|
||||||
nMark = nObjMark ;
|
nMark = GDB_MK_ON ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class GdbObj
|
|||||||
bool IsSelected( void) const ;
|
bool IsSelected( void) const ;
|
||||||
bool GetStatus( int& nStat) const ;
|
bool GetStatus( int& nStat) const ;
|
||||||
bool GetCalcStatus( int& nStat, int nLev = 0) const ;
|
bool GetCalcStatus( int& nStat, int nLev = 0) const ;
|
||||||
bool SetMark( int nMark) ;
|
bool SetMark( void) ;
|
||||||
bool ResetMark( void) ;
|
bool ResetMark( void) ;
|
||||||
bool GetMark( int& nMark) const ;
|
bool GetMark( int& nMark) const ;
|
||||||
bool GetCalcMark( int& nMark) const ;
|
bool GetCalcMark( int& nMark) const ;
|
||||||
|
|||||||
+6
-6
@@ -877,7 +877,7 @@ GeomDB::GetFirstNameInGroup( int nGroupId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbO->GetName( sObjName) &&
|
if ( pGdbO->GetName( sObjName) &&
|
||||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||||
return ( pGdbO->m_nId) ;
|
return ( pGdbO->m_nId) ;
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
pGdbO = pGdbO->GetNext() ;
|
pGdbO = pGdbO->GetNext() ;
|
||||||
@@ -905,7 +905,7 @@ GeomDB::GetNextName( int nId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbNext->GetName( sObjName) &&
|
if ( pGdbNext->GetName( sObjName) &&
|
||||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||||
return ( pGdbNext->m_nId) ;
|
return ( pGdbNext->m_nId) ;
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
pGdbNext = pGdbNext->GetNext() ;
|
pGdbNext = pGdbNext->GetNext() ;
|
||||||
@@ -933,7 +933,7 @@ GeomDB::GetLastNameInGroup( int nGroupId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbO->GetName( sObjName) &&
|
if ( pGdbO->GetName( sObjName) &&
|
||||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||||
return ( pGdbO->m_nId) ;
|
return ( pGdbO->m_nId) ;
|
||||||
// passo al precedente
|
// passo al precedente
|
||||||
pGdbO = pGdbO->GetPrev() ;
|
pGdbO = pGdbO->GetPrev() ;
|
||||||
@@ -961,7 +961,7 @@ GeomDB::GetPrevName( int nId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbPrev->GetName( sObjName) &&
|
if ( pGdbPrev->GetName( sObjName) &&
|
||||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||||
return ( pGdbPrev->m_nId) ;
|
return ( pGdbPrev->m_nId) ;
|
||||||
// passo al precedente
|
// passo al precedente
|
||||||
pGdbPrev = pGdbPrev->GetPrev() ;
|
pGdbPrev = pGdbPrev->GetPrev() ;
|
||||||
@@ -2310,7 +2310,7 @@ GeomDB::GetCalcStatus( int nId, int& nStat) const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
GeomDB::SetMark( int nId, int nMark)
|
GeomDB::SetMark( int nId)
|
||||||
{
|
{
|
||||||
// recupero l'oggetto
|
// recupero l'oggetto
|
||||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||||
@@ -2318,7 +2318,7 @@ GeomDB::SetMark( int nId, int nMark)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// imposto la marcatura
|
// imposto la marcatura
|
||||||
return pGdbObj->SetMark( nMark) ;
|
return pGdbObj->SetMark() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class GeomDB : public IGeomDB
|
|||||||
bool RevertStatus( int nId) override ;
|
bool RevertStatus( int nId) override ;
|
||||||
bool GetStatus( int nId, int& nStat) const override ;
|
bool GetStatus( int nId, int& nStat) const override ;
|
||||||
bool GetCalcStatus( int nId, int& nStat) const override ;
|
bool GetCalcStatus( int nId, int& nStat) const override ;
|
||||||
bool SetMark( int nId, int nMark = GDB_MK_ON) override ;
|
bool SetMark( int nId) override ;
|
||||||
bool ResetMark( int nId) override ;
|
bool ResetMark( int nId) override ;
|
||||||
bool GetMark( int nId, int& nMark) const override ;
|
bool GetMark( int nId, int& nMark) const override ;
|
||||||
bool GetCalcMark( int nId, int& nMark) const override ;
|
bool GetCalcMark( int nId, int& nMark) const override ;
|
||||||
|
|||||||
+11
-11
@@ -116,7 +116,7 @@ HashGrid1d::~HashGrid1d( void)
|
|||||||
{
|
{
|
||||||
Clear() ;
|
Clear() ;
|
||||||
|
|
||||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_CellCount ; ++ pCell) {
|
for ( Cell* pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
}
|
}
|
||||||
@@ -396,10 +396,8 @@ HashGrid1d::Enlarge( void)
|
|||||||
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
pCell->m_neighborOffset = nullptr ;
|
|
||||||
}
|
}
|
||||||
delete[] m_cell ;
|
delete[] m_cell ;
|
||||||
m_cell = nullptr ;
|
|
||||||
|
|
||||||
// ... the number of cells is doubled in each coordinate direction, ...
|
// ... the number of cells is doubled in each coordinate direction, ...
|
||||||
m_CellCount *= 2 ;
|
m_CellCount *= 2 ;
|
||||||
@@ -571,7 +569,7 @@ HashGrids1d::Update( void)
|
|||||||
// Salvo stato di precedente attivazione delle griglie
|
// Salvo stato di precedente attivazione delle griglie
|
||||||
bool bGridActivePrev = m_bGridActive ;
|
bool bGridActivePrev = m_bGridActive ;
|
||||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||||
if ( ! m_objsToAdd.empty()) {
|
if ( m_objsToAdd.size() > 0 ) {
|
||||||
for ( auto pObj : m_objsToAdd) {
|
for ( auto pObj : m_objsToAdd) {
|
||||||
if ( m_bGridActive)
|
if ( m_bGridActive)
|
||||||
addGrid( *pObj) ;
|
addGrid( *pObj) ;
|
||||||
@@ -636,22 +634,24 @@ HashGrids1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
|||||||
sort( vnIds.begin(), vnIds.end()) ;
|
sort( vnIds.begin(), vnIds.end()) ;
|
||||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||||
|
|
||||||
return ( ! vnIds.empty()) ;
|
return ( vnIds.size() > 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
HashGrids1d::Clear( void)
|
HashGrids1d::Clear( void)
|
||||||
{
|
{
|
||||||
m_ObjsList.clear() ;
|
for ( auto pGrid : m_GridList) {
|
||||||
m_ObjsMap.clear() ;
|
|
||||||
m_objsToAdd.clear() ;
|
|
||||||
m_nonGridObjs.clear() ;
|
|
||||||
for ( auto pGrid : m_GridList)
|
|
||||||
delete pGrid ;
|
delete pGrid ;
|
||||||
|
}
|
||||||
m_GridList.clear() ;
|
m_GridList.clear() ;
|
||||||
m_bActivate = true ;
|
|
||||||
m_bGridActive = false ;
|
m_bGridActive = false ;
|
||||||
|
|
||||||
|
m_nonGridObjs.clear() ;
|
||||||
|
|
||||||
|
m_objsToAdd.clear() ;
|
||||||
|
|
||||||
m_b3Objs.Reset() ;
|
m_b3Objs.Reset() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -125,7 +125,7 @@ HashGrid2d::~HashGrid2d( void)
|
|||||||
{
|
{
|
||||||
Clear() ;
|
Clear() ;
|
||||||
|
|
||||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
}
|
}
|
||||||
@@ -445,10 +445,8 @@ HashGrid2d::Enlarge( void)
|
|||||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
for ( auto pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
pCell->m_neighborOffset = nullptr ;
|
|
||||||
}
|
}
|
||||||
delete[] m_cell ;
|
delete[] m_cell ;
|
||||||
m_cell = nullptr ;
|
|
||||||
|
|
||||||
// ... the number of cells is doubled in each coordinate direction, ...
|
// ... the number of cells is doubled in each coordinate direction, ...
|
||||||
m_xCellCount *= 2 ;
|
m_xCellCount *= 2 ;
|
||||||
@@ -625,7 +623,7 @@ HashGrids2d::Update( void)
|
|||||||
// Salvo stato di precedente attivazione delle griglie
|
// Salvo stato di precedente attivazione delle griglie
|
||||||
bool bGridActivePrev = m_bGridActive ;
|
bool bGridActivePrev = m_bGridActive ;
|
||||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||||
if ( ! m_objsToAdd.empty()) {
|
if ( m_objsToAdd.size() > 0 ) {
|
||||||
for ( auto pObj : m_objsToAdd) {
|
for ( auto pObj : m_objsToAdd) {
|
||||||
if ( m_bGridActive)
|
if ( m_bGridActive)
|
||||||
addGrid( *pObj) ;
|
addGrid( *pObj) ;
|
||||||
@@ -690,22 +688,24 @@ HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
|||||||
sort( vnIds.begin(), vnIds.end()) ;
|
sort( vnIds.begin(), vnIds.end()) ;
|
||||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||||
|
|
||||||
return ( ! vnIds.empty()) ;
|
return ( vnIds.size() > 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
HashGrids2d::Clear( void)
|
HashGrids2d::Clear( void)
|
||||||
{
|
{
|
||||||
m_ObjsList.clear() ;
|
for ( auto pGrid : m_GridList) {
|
||||||
m_ObjsMap.clear() ;
|
|
||||||
m_objsToAdd.clear() ;
|
|
||||||
m_nonGridObjs.clear() ;
|
|
||||||
for ( auto pGrid : m_GridList)
|
|
||||||
delete pGrid ;
|
delete pGrid ;
|
||||||
|
}
|
||||||
m_GridList.clear() ;
|
m_GridList.clear() ;
|
||||||
m_bActivate = true ;
|
|
||||||
m_bGridActive = false ;
|
m_bGridActive = false ;
|
||||||
|
|
||||||
|
m_nonGridObjs.clear() ;
|
||||||
|
|
||||||
|
m_objsToAdd.clear() ;
|
||||||
|
|
||||||
m_b3Objs.Reset() ;
|
m_b3Objs.Reset() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -132,7 +132,7 @@ HashGrid3d::~HashGrid3d( void)
|
|||||||
{
|
{
|
||||||
Clear() ;
|
Clear() ;
|
||||||
|
|
||||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
}
|
}
|
||||||
@@ -486,10 +486,8 @@ HashGrid3d::Enlarge( void)
|
|||||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
for ( auto pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||||
delete[] pCell->m_neighborOffset ;
|
delete[] pCell->m_neighborOffset ;
|
||||||
pCell->m_neighborOffset = nullptr ;
|
|
||||||
}
|
}
|
||||||
delete[] m_cell ;
|
delete[] m_cell ;
|
||||||
m_cell = nullptr ;
|
|
||||||
|
|
||||||
// ... the number of cells is doubled in each coordinate direction, ...
|
// ... the number of cells is doubled in each coordinate direction, ...
|
||||||
m_xCellCount *= 2 ;
|
m_xCellCount *= 2 ;
|
||||||
@@ -669,7 +667,7 @@ HashGrids3d::Update( void)
|
|||||||
// Salvo stato di precedente attivazione delle griglie
|
// Salvo stato di precedente attivazione delle griglie
|
||||||
bool bGridActivePrev = m_bGridActive ;
|
bool bGridActivePrev = m_bGridActive ;
|
||||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||||
if ( ! m_objsToAdd.empty()) {
|
if ( m_objsToAdd.size() > 0 ) {
|
||||||
for ( auto pObj : m_objsToAdd) {
|
for ( auto pObj : m_objsToAdd) {
|
||||||
if ( m_bGridActive)
|
if ( m_bGridActive)
|
||||||
addGrid( *pObj) ;
|
addGrid( *pObj) ;
|
||||||
@@ -733,7 +731,7 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
|||||||
sort( vnIds.begin(), vnIds.end()) ;
|
sort( vnIds.begin(), vnIds.end()) ;
|
||||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||||
|
|
||||||
return ( ! vnIds.empty()) ;
|
return ( vnIds.size() > 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -741,15 +739,17 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
|||||||
void
|
void
|
||||||
HashGrids3d::Clear( void)
|
HashGrids3d::Clear( void)
|
||||||
{
|
{
|
||||||
m_ObjsList.clear() ;
|
for ( auto pGrid : m_GridList) {
|
||||||
m_ObjsMap.clear() ;
|
|
||||||
m_objsToAdd.clear() ;
|
|
||||||
m_nonGridObjs.clear() ;
|
|
||||||
for ( auto pGrid : m_GridList)
|
|
||||||
delete pGrid ;
|
delete pGrid ;
|
||||||
|
}
|
||||||
m_GridList.clear() ;
|
m_GridList.clear() ;
|
||||||
m_bActivate = true ;
|
|
||||||
m_bGridActive = false ;
|
m_bGridActive = false ;
|
||||||
|
|
||||||
|
m_nonGridObjs.clear() ;
|
||||||
|
|
||||||
|
m_objsToAdd.clear() ;
|
||||||
|
|
||||||
m_b3Objs.Reset() ;
|
m_b3Objs.Reset() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-8
@@ -17,9 +17,6 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static const double EPS_INTER_ARC = 0.1 * EPS_SMALL ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||||
{
|
{
|
||||||
@@ -63,15 +60,15 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
|||||||
vtDir /= dDist ;
|
vtDir /= dDist ;
|
||||||
|
|
||||||
// cerchi esterni -> nessuna intersezione
|
// cerchi esterni -> nessuna intersezione
|
||||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_INTER_ARC)
|
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_SMALL)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// cerchi interni -> nessuna intersezione
|
// cerchi interni -> nessuna intersezione
|
||||||
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_INTER_ARC)
|
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_SMALL)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// cerchi coincidenti -> sovrapposizioni e/o intersezioni agli estremi
|
// cerchi coincidenti -> sovrapposizioni e/o intersezioni agli estremi
|
||||||
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_INTER_ARC) {
|
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_SMALL) {
|
||||||
// coefficiente da parametro dell'arco 1 a lunghezza
|
// coefficiente da parametro dell'arco 1 a lunghezza
|
||||||
double dU2L = abs( m_Arc1.GetAngCenter()) * DEGTORAD * m_Arc1.GetRadius() ;
|
double dU2L = abs( m_Arc1.GetAngCenter()) * DEGTORAD * m_Arc1.GetRadius() ;
|
||||||
// determino se sono equiversi o controversi
|
// determino se sono equiversi o controversi
|
||||||
@@ -239,7 +236,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
|||||||
double dSqH = m_Arc1.GetRadius() * m_Arc1.GetRadius() - dA * dA ;
|
double dSqH = m_Arc1.GetRadius() * m_Arc1.GetRadius() - dA * dA ;
|
||||||
|
|
||||||
// cerchi tangenti esterni -> una intersezione
|
// cerchi tangenti esterni -> una intersezione
|
||||||
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||||
// tolleranza tangenziale sull'intersezione
|
// tolleranza tangenziale sull'intersezione
|
||||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||||
// calcolo il punto di intersezione
|
// calcolo il punto di intersezione
|
||||||
@@ -361,7 +358,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cerchi tangenti interni -> una intersezione
|
// cerchi tangenti interni -> una intersezione
|
||||||
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||||
// tolleranza tangenziale sull'intersezione
|
// tolleranza tangenziale sull'intersezione
|
||||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||||
// determino quale dei due contiene l'altro
|
// determino quale dei due contiene l'altro
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
|||||||
case CRV_COMPO :
|
case CRV_COMPO :
|
||||||
LineCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
LineCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
case CRV_ARC :
|
case CRV_ARC :
|
||||||
@@ -93,8 +91,6 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
|||||||
case CRV_COMPO :
|
case CRV_COMPO :
|
||||||
ArcCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
ArcCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
case CRV_COMPO :
|
case CRV_COMPO :
|
||||||
@@ -108,12 +104,8 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
|||||||
case CRV_COMPO :
|
case CRV_COMPO :
|
||||||
CrvCompoCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
CrvCompoCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
// per curve approssimate, sistemo...
|
// per curve approssimate, sistemo...
|
||||||
AdjustIntersParams( ( pCalcCrv[0] != m_pCurve[0]), ( pCalcCrv[1] != m_pCurve[1])) ;
|
AdjustIntersParams( ( pCalcCrv[0] != m_pCurve[0]), ( pCalcCrv[1] != m_pCurve[1])) ;
|
||||||
@@ -253,7 +245,7 @@ bool
|
|||||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
||||||
{
|
{
|
||||||
// se non ci sono intersezioni, non va fatto alcunché
|
// se non ci sono intersezioni, non va fatto alcunché
|
||||||
if ( m_Info.empty())
|
if ( m_Info.size() == 0)
|
||||||
return true ;
|
return true ;
|
||||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||||
if ( ! bAdjCrvA && ! bAdjCrvB)
|
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static void
|
|||||||
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
|
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
// se non trovati, esco
|
// se non trovati, esco
|
||||||
if ( vInfo.empty())
|
if ( vInfo.size() == 0)
|
||||||
return ;
|
return ;
|
||||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||||
sort( vInfo.begin(), vInfo.end(),
|
sort( vInfo.begin(), vInfo.end(),
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "IntersLineCaps.h"
|
#include "IntersLineCaps.h"
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
#include "DistLineLine.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|||||||
+24
-29
@@ -19,18 +19,20 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Posizione del punto rispetto alla linea (+1=a destra, 0=nella banda di tolleranza, -1=a sinistra)
|
// Il punto è esterno al FatSegment se dista da questo più di Tol e la sua proiezione sta sul segmento
|
||||||
static int
|
bool
|
||||||
GetPointToLineSide( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol)
|
IsPointOutFatSegment( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol)
|
||||||
{
|
{
|
||||||
double dCross = CrossXY( ( ptP - ptS), vtDir) ;
|
// distanza del punto dalla linea del segmento (con compensazione piccolissimi errori)
|
||||||
double dFat = ( dTol + EPS_ZERO) * dLenXY ;
|
if ( abs( CrossXY( ( ptP - ptS), vtDir)) < ( dTol + EPS_ZERO) * dLenXY)
|
||||||
if ( dCross > dFat)
|
return false ;
|
||||||
return +1 ;
|
// distanza con segno della proiezione del punto sul segmento dall'inizio per lunghezza segmento
|
||||||
else if ( dCross < - dFat)
|
double dDistXY = ScalarXY( ( ptP - ptS), vtDir) ;
|
||||||
return -1 ;
|
// se il punto non si proietta sul segmento entro la tolleranza
|
||||||
else
|
if ( dDistXY < - dTol * dLenXY || dDistXY > ( dLenXY + dTol) * dLenXY)
|
||||||
return 0 ;
|
return false ;
|
||||||
|
// altrimenti
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -42,7 +44,7 @@ IntersLineLine::IntersLineLine( const CurveLine& Line1, const CurveLine& Line2,
|
|||||||
m_bOverlaps = false ;
|
m_bOverlaps = false ;
|
||||||
m_nNumInters = 0 ;
|
m_nNumInters = 0 ;
|
||||||
|
|
||||||
// verifico validità linee
|
// verifico validità linee
|
||||||
if ( ! Line1.IsValid() || ! Line2.IsValid())
|
if ( ! Line1.IsValid() || ! Line2.IsValid())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
@@ -128,36 +130,30 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
if ( ! boxL1.OverlapsXY( boxL2))
|
if ( ! boxL1.OverlapsXY( boxL2))
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// segmento 1 : Start, End, Direzione e Lunghezza
|
// linea 1 : Start, End, Direzione e Lunghezza
|
||||||
Point3d ptS1 = Line1.GetStart() ;
|
Point3d ptS1 = Line1.GetStart() ;
|
||||||
Point3d ptE1 = Line1.GetEnd() ;
|
Point3d ptE1 = Line1.GetEnd() ;
|
||||||
Vector3d vtDir1 = ptE1 - ptS1 ;
|
Vector3d vtDir1 = ptE1 - ptS1 ;
|
||||||
double dLen1XY = vtDir1.LenXY() ;
|
double dLen1XY = vtDir1.LenXY() ;
|
||||||
if ( dLen1XY < EPS_SMALL)
|
if ( dLen1XY < EPS_SMALL)
|
||||||
return ;
|
return ;
|
||||||
// segmento 2 : Start, Direzione e Lunghezza
|
// linea 2 : Start, Direzione e Lunghezza
|
||||||
Point3d ptS2 = Line2.GetStart() ;
|
Point3d ptS2 = Line2.GetStart() ;
|
||||||
Point3d ptE2 = Line2.GetEnd() ;
|
Point3d ptE2 = Line2.GetEnd() ;
|
||||||
Vector3d vtDir2 = ptE2 - ptS2 ;
|
Vector3d vtDir2 = ptE2 - ptS2 ;
|
||||||
double dLen2XY = vtDir2.LenXY() ;
|
double dLen2XY = vtDir2.LenXY() ;
|
||||||
if ( dLen2XY < EPS_SMALL)
|
if ( dLen2XY < EPS_SMALL)
|
||||||
return ;
|
return ;
|
||||||
// posizioni estremi segmento 1 rispetto a linea 2
|
|
||||||
int nS1Side = GetPointToLineSide( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ;
|
|
||||||
int nE1Side = GetPointToLineSide( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ;
|
|
||||||
if ( ( nS1Side == 1 && nE1Side == 1) || ( nS1Side == -1 && nE1Side == -1))
|
|
||||||
return ;
|
|
||||||
// posizioni estremi segmento 2 rispetto a linea 1
|
|
||||||
int nS2Side = GetPointToLineSide( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ;
|
|
||||||
int nE2Side = GetPointToLineSide( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ;
|
|
||||||
if ( ( nS2Side == 1 && nE2Side == 1) || ( nS2Side == -1 && nE2Side == -1))
|
|
||||||
return ;
|
|
||||||
// prodotto vettoriale nel piano XY tra le direzioni delle linee
|
// prodotto vettoriale nel piano XY tra le direzioni delle linee
|
||||||
double dCrossXY = CrossXY( vtDir1, vtDir2) ;
|
double dCrossXY = CrossXY( vtDir1, vtDir2) ;
|
||||||
// flag per linee parallele
|
// flag per linee parallele
|
||||||
bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ;
|
bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ;
|
||||||
// flag per segmenti che si allontanano significativamente
|
// flag per segmenti che si allontanano significativamente
|
||||||
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
bool bFarEnds = ( /*( abs( dCrossXY) > SIN_EPS_ANG_SMALL * ( dLen1XY * dLen2XY)) ||*/
|
||||||
|
IsPointOutFatSegment( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ||
|
||||||
|
IsPointOutFatSegment( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ||
|
||||||
|
IsPointOutFatSegment( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ||
|
||||||
|
IsPointOutFatSegment( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL)) ;
|
||||||
|
|
||||||
// se non sono paralleli e si allontanano tra loro abbastanza
|
// se non sono paralleli e si allontanano tra loro abbastanza
|
||||||
if ( ! bParallel && bFarEnds) {
|
if ( ! bParallel && bFarEnds) {
|
||||||
@@ -172,8 +168,6 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
nPos1 = ICurve::PP_END ; // vicino a fine
|
nPos1 = ICurve::PP_END ; // vicino a fine
|
||||||
else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1)
|
else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1)
|
||||||
nPos1 = ICurve::PP_MID ; // nell'interno
|
nPos1 = ICurve::PP_MID ; // nell'interno
|
||||||
else
|
|
||||||
return ;
|
|
||||||
// verifica posizione intersezione su seconda linea
|
// verifica posizione intersezione su seconda linea
|
||||||
int nPos2 = ICurve::PP_NULL ; // fuori
|
int nPos2 = ICurve::PP_NULL ; // fuori
|
||||||
if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL)
|
if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL)
|
||||||
@@ -182,7 +176,8 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
nPos2 = ICurve::PP_END ; // vicino a fine
|
nPos2 = ICurve::PP_END ; // vicino a fine
|
||||||
else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1)
|
else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1)
|
||||||
nPos2 = ICurve::PP_MID ; // nell'interno
|
nPos2 = ICurve::PP_MID ; // nell'interno
|
||||||
else
|
// se soluzione non accettata, esco
|
||||||
|
if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL)
|
||||||
return ;
|
return ;
|
||||||
// limito i parametri a stare sui segmenti (0...1)
|
// limito i parametri a stare sui segmenti (0...1)
|
||||||
m_Info.IciA[0].dU = min( max( m_Info.IciA[0].dU, 0.), 1.) ;
|
m_Info.IciA[0].dU = min( max( m_Info.IciA[0].dU, 0.), 1.) ;
|
||||||
@@ -195,7 +190,7 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
m_Info.IciA[0].nNextTy = ICCT_NULL ;
|
m_Info.IciA[0].nNextTy = ICCT_NULL ;
|
||||||
m_Info.IciB[0].nPrevTy = ICCT_NULL ;
|
m_Info.IciB[0].nPrevTy = ICCT_NULL ;
|
||||||
m_Info.IciB[0].nNextTy = ICCT_NULL ;
|
m_Info.IciB[0].nNextTy = ICCT_NULL ;
|
||||||
// si incontrano alle estremità, non si può dire alcunché
|
// si incontrano alle estremità, non si può dire alcunché
|
||||||
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
||||||
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
||||||
; // rimangono tutti NULL
|
; // rimangono tutti NULL
|
||||||
|
|||||||
+10
-268
@@ -13,18 +13,12 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveLine.h"
|
|
||||||
#include "CurveBezier.h"
|
|
||||||
#include "CurveComposite.h"
|
|
||||||
#include "SurfFlatRegion.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
||||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
#include "DistPointLine.h"
|
||||||
|
#include "CurveLine.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -73,11 +67,11 @@ static void
|
|||||||
UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos,
|
UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos,
|
||||||
const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo)
|
const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
if ( nILT == ILTA_IN || nILT == ILTA_EDGE || nILT == ILTA_VERT || nILT == ILTA_NO_TRIA) {
|
if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) {
|
||||||
double dU = ( ptIBz - ptL) * vtDir ;
|
double dU = ( ptIBz - ptL) * vtDir ;
|
||||||
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
|
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
|
||||||
}
|
}
|
||||||
else if ( nILT == ILTA_SEGM || nILT == ILTA_SEGM_ON_EDGE) {
|
else if ( nILT == ILTT_SEGM || nILT == ILTT_SEGM_ON_EDGE) {
|
||||||
double dU = ( ptIBz - ptL) * vtDir ;
|
double dU = ( ptIBz - ptL) * vtDir ;
|
||||||
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
||||||
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
|
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
|
||||||
@@ -89,13 +83,13 @@ static void
|
|||||||
OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
|
OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
// se non trovati, esco
|
// se non trovati, esco
|
||||||
if ( vInfo.empty())
|
if ( vInfo.size() == 0)
|
||||||
return ;
|
return ;
|
||||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||||
sort( vInfo.begin(), vInfo.end(),
|
sort( vInfo.begin(), vInfo.end(),
|
||||||
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
|
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
|
||||||
{ double dUa = ( ( a.nILTA == ILTA_SEGM || a.nILTA == ILTA_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||||
double dUb = ( ( b.nILTA == ILTA_SEGM || b.nILTA == ILTA_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||||
return ( dUa < dUb) ; }) ;
|
return ( dUa < dUb) ; }) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +146,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
double dCos = vtN * vtL ;
|
double dCos = vtN * vtL ;
|
||||||
double dCos2 = 0 ;
|
double dCos2 = 0 ;
|
||||||
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
|
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
|
||||||
if ( InfoTm.nILTT == ILTA_SEGM || InfoTm.nILTT == ILTA_SEGM_ON_EDGE ) {
|
if ( InfoTm.nILTT == ILTT_SEGM || InfoTm.nILTT == ILTT_SEGM_ON_EDGE ) {
|
||||||
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
|
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
|
||||||
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
||||||
int nVert[3] ;
|
int nVert[3] ;
|
||||||
@@ -182,7 +176,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
// ciclo sulle intersezioni
|
// ciclo sulle intersezioni
|
||||||
for ( const auto& Info : vInfo) {
|
for ( const auto& Info : vInfo) {
|
||||||
// se intersezione puntuale
|
// se intersezione puntuale
|
||||||
if ( Info.nILTA == ILTA_VERT || Info.nILTA == ILTA_EDGE || Info.nILTA == ILTA_IN) {
|
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||||
int nFlag = LSBT_TOUCH ;
|
int nFlag = LSBT_TOUCH ;
|
||||||
if ( Info.dCosDN > EPS_ZERO)
|
if ( Info.dCosDN > EPS_ZERO)
|
||||||
nFlag = LSBT_OUT ;
|
nFlag = LSBT_OUT ;
|
||||||
@@ -191,7 +185,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
vInters.emplace_back( nFlag, Info.dU) ;
|
vInters.emplace_back( nFlag, Info.dU) ;
|
||||||
}
|
}
|
||||||
// se altrimenti intersezione con coincidenza
|
// se altrimenti intersezione con coincidenza
|
||||||
else if ( Info.nILTA == ILTA_SEGM || Info.nILTA == ILTA_SEGM_ON_EDGE) {
|
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||||
vInters.emplace_back( LSBT_TG_INI, Info.dU) ;
|
vInters.emplace_back( LSBT_TG_INI, Info.dU) ;
|
||||||
vInters.emplace_back( LSBT_TG_FIN, Info.dU2) ;
|
vInters.emplace_back( LSBT_TG_FIN, Info.dU2) ;
|
||||||
}
|
}
|
||||||
@@ -238,255 +232,3 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Intersezione di una linea con una superficie di Bezier
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
IntersLineSurfBzBilinear( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz,
|
|
||||||
ILSBIVECTOR& vInfo, bool bFinite)
|
|
||||||
{
|
|
||||||
int nDegU, nDegV, nSpanU, nSpanV ;
|
|
||||||
bool bRat, bTrimmed ;
|
|
||||||
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
|
||||||
|
|
||||||
// funzione pensata per funzionare solo con una monopatch bilineare
|
|
||||||
if( nDegU > 1 || nDegV > 1 || nSpanU > 1 || nSpanV > 1 || bRat)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
int nInters = int( vInfo.size()) ;
|
|
||||||
|
|
||||||
PNTVECTOR vPntCtrl ;
|
|
||||||
for( int p = 0 ; p < 4 ; ++p) {
|
|
||||||
bool bOk = false ;
|
|
||||||
vPntCtrl.push_back( pSurfBz->GetControlPoint( p, &bOk)) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3d a = vPntCtrl[3] - vPntCtrl[1] + ( vPntCtrl[0] - vPntCtrl[2]) ;
|
|
||||||
Vector3d b = vPntCtrl[1] - vPntCtrl[0] ;
|
|
||||||
Vector3d c = vPntCtrl[2] - vPntCtrl[0] ;
|
|
||||||
Vector3d d = vPntCtrl[0] - ORIG ;
|
|
||||||
|
|
||||||
double A1 = a.x * vtL.z - a.z * vtL.x ;
|
|
||||||
double B1 = b.x * vtL.z - b.z * vtL.x ;
|
|
||||||
double C1 = c.x * vtL.z - c.z * vtL.x ;
|
|
||||||
double A2 = a.y * vtL.z - a.z * vtL.y ;
|
|
||||||
double B2 = b.y * vtL.z - b.z * vtL.y ;
|
|
||||||
double C2 = c.y * vtL.z - c.z * vtL.y ;
|
|
||||||
|
|
||||||
double D1 = ( d.x - ptL.x) * vtL.z - ( d.z - ptL.z) * vtL.x ;
|
|
||||||
double D2 = ( d.y - ptL.y) * vtL.z - ( d.z - ptL.z) * vtL.y ;
|
|
||||||
|
|
||||||
DBLVECTOR vdCoeff, vdRoots ;
|
|
||||||
vdCoeff = { (B2 * D1 - B1 * D2), ( A2 * D1 - A1 * D2 + B2 * C1 - B1 * C2), ( A2 * C1 - A1 * C2)} ;
|
|
||||||
int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
|
||||||
bool bFound = false ;
|
|
||||||
for( int w = 0 ; w < nRoots ; ++w) {
|
|
||||||
if ( vdRoots[w] > 0 - EPS_ZERO && vdRoots[w] < 1 + EPS_ZERO ) {
|
|
||||||
double dU = 0, dV = vdRoots[w] ;
|
|
||||||
// verifico che non sia una soluzione con molteplicità > 1
|
|
||||||
bool bAlreadyFound = false ;
|
|
||||||
for ( int k = w - 1 ; k >= 0 && ! bAlreadyFound ; --k)
|
|
||||||
bAlreadyFound = abs( dV - vdRoots[k]) < EPS_PARAM ;
|
|
||||||
if( ! bAlreadyFound) {
|
|
||||||
dU = (dV * (C1 - C2) + ( D1 - D2)) / ( dV * ( A2 - A1) + ( B2 - B1)) ;
|
|
||||||
if ( dU > - EPS_ZERO && dU < 1 + EPS_ZERO) {
|
|
||||||
Point3d ptIBez, ptIBez2 ;
|
|
||||||
Vector3d vtN ;
|
|
||||||
pSurfBz->GetPointNrmD1D2(dU, dV, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez, vtN) ;
|
|
||||||
Point3d ptSP( dU, dV, 0), ptSP2 ;
|
|
||||||
double dCos = vtN * vtL, dCos2 = 0 ;
|
|
||||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP, ptIBez, dCos, ptSP2, ptIBez2, dCos2, vInfo) ;
|
|
||||||
bFound = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// se tutti i coefficienti sono zero allora potrei avere una linea che giace sulla superficie
|
|
||||||
// per trovare i punti di inizio e fine sovrapposizione trovo i punti a minima distanza tra la linea e gli edge della superficie
|
|
||||||
if( ! bFound && abs( vdCoeff[0]) < EPS_ZERO && abs( vdCoeff[1]) < EPS_ZERO && abs( vdCoeff[2]) < EPS_ZERO) {
|
|
||||||
ICRVCOMPOPOVECTOR vCrvEdge( 4) ;
|
|
||||||
vCrvEdge[0].Set(pSurfBz->GetCurveOnU( 0)) ;
|
|
||||||
vCrvEdge[1].Set(pSurfBz->GetCurveOnV( 1)) ;
|
|
||||||
vCrvEdge[2].Set(pSurfBz->GetCurveOnU( 1)) ;
|
|
||||||
vCrvEdge[3].Set(pSurfBz->GetCurveOnV( 0)) ;
|
|
||||||
double dAngTolDeg = 5 ;
|
|
||||||
for( int i = 0 ; i < 4 ; ++i) {
|
|
||||||
PolyLine plApprox ; vCrvEdge[0]->ApproxWithLines( EPS_SMALL, dAngTolDeg, ICurve::ApprLineType::APL_STD, plApprox) ;
|
|
||||||
//CurveComposite cCC ;
|
|
||||||
//cCC.FromPolyLine( plApprox) ;
|
|
||||||
int nClosestLine = -1 ;
|
|
||||||
double dMinDist = INFINITO ;
|
|
||||||
Point3d pt ; plApprox.GetFirstPoint( pt) ;
|
|
||||||
Point3d ptClosest ;
|
|
||||||
int c = 0 ;
|
|
||||||
int nTot = plApprox.GetPointNbr() ;
|
|
||||||
for( int j = 0 ; j < nTot ; ++j) {
|
|
||||||
DistPointLine dpl( pt, ptL, vtL, dLen, bFinite) ;
|
|
||||||
double dDist = INFINITO ;
|
|
||||||
dpl.GetDist( dDist) ;
|
|
||||||
if ( dDist < dMinDist) {
|
|
||||||
nClosestLine = c ;
|
|
||||||
dMinDist = dDist ;
|
|
||||||
}
|
|
||||||
plApprox.GetNextPoint( pt) ;
|
|
||||||
++ c ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point3d ptInt1, ptInt2 ;
|
|
||||||
if ( nClosestLine < nTot - 1 && nClosestLine > 0) {
|
|
||||||
// tra i due tratti dell'approssimazione che arrivano al punto selezionato come più vicino, devo trovare quale si avvicina di più
|
|
||||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
|
||||||
Point3d ptEnd ;
|
|
||||||
for( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
|
||||||
plApprox.GetNextPoint( ptStart) ;
|
|
||||||
plApprox.GetNextPoint( ptEnd) ;
|
|
||||||
// linea precedente al punto
|
|
||||||
Vector3d vtLinePre = ptEnd - ptStart ;
|
|
||||||
double dLenPre = vtLinePre.Len() ;
|
|
||||||
DistLineLine dllPre( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
|
||||||
double dDistPre = INFINITO ;
|
|
||||||
dllPre.GetDist( dDistPre) ;
|
|
||||||
// linea che inzia con quel punto
|
|
||||||
ptStart = ptEnd ;
|
|
||||||
plApprox.GetNextPoint( ptEnd) ;
|
|
||||||
Vector3d vtLineCurr = ptEnd - ptStart ;
|
|
||||||
double dLenCurr = vtLineCurr.Len() ;
|
|
||||||
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
|
||||||
double dDistCurr = INFINITO ;
|
|
||||||
dllCurr.GetDist( dDistCurr) ;
|
|
||||||
|
|
||||||
if( dDistPre < dDistCurr)
|
|
||||||
dllPre.GetMinDistPoints( ptInt1, ptInt2) ;
|
|
||||||
else
|
|
||||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
|
||||||
}
|
|
||||||
else if ( nClosestLine == 0){
|
|
||||||
// il punto più vicino è sulla prima linea
|
|
||||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
|
||||||
Point3d ptEnd ; plApprox.GetNextPoint( ptEnd) ;
|
|
||||||
Vector3d vtLineCurr = ptEnd - ptStart ;
|
|
||||||
double dLenCurr = vtLineCurr.Len() ;
|
|
||||||
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
|
||||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
|
||||||
}
|
|
||||||
else if ( nClosestLine == nTot- 1) {
|
|
||||||
// il punto più vicino è sull'ultima linea
|
|
||||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
|
||||||
Point3d ptEnd ;
|
|
||||||
for( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
|
||||||
plApprox.GetNextPoint( ptStart) ;
|
|
||||||
plApprox.GetNextPoint( ptEnd) ;
|
|
||||||
Vector3d vtLinePre = ptEnd - ptStart ;
|
|
||||||
double dLenPre = vtLinePre.Len() ;
|
|
||||||
DistLineLine dllCurr( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
|
||||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
double dU1 = 0, dV1 = 0, dU2 = 0, dV2 = 0 ;
|
|
||||||
// se ho trovato due punti vuol dire che la linea coincide con un edge e ho trovato tutto quello che serve
|
|
||||||
if( ! AreSamePointExact( ptInt2, ORIG)) {
|
|
||||||
if( i == 0) {
|
|
||||||
//dV1 = 0 ; dV2 = 0 ;
|
|
||||||
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
|
||||||
vCrvEdge[0]->GetParamAtPoint( ptInt2, dU2) ;
|
|
||||||
}
|
|
||||||
else if( i == 1) {
|
|
||||||
//dU1 = 1 ; dU2 = 1 ;
|
|
||||||
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
|
||||||
vCrvEdge[1]->GetParamAtPoint( ptInt2, dV2) ;
|
|
||||||
}
|
|
||||||
else if( i == 2){
|
|
||||||
//dV1 = 1 ; dV2 = 1 ;
|
|
||||||
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
|
||||||
vCrvEdge[2]->GetParamAtPoint( ptInt2, dU2) ;
|
|
||||||
}
|
|
||||||
else if( i == 3){
|
|
||||||
//dU1 = 0 ; dU2 = 0 ;
|
|
||||||
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
|
||||||
vCrvEdge[3]->GetParamAtPoint( ptInt2, dV2) ;
|
|
||||||
}
|
|
||||||
Point3d ptIBez1, ptIBez2 ;
|
|
||||||
Vector3d vtN1, vtN2 ;
|
|
||||||
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
|
||||||
pSurfBz->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez2, vtN2) ;
|
|
||||||
Point3d ptSP1( dU1, dV1, 0) ;
|
|
||||||
double dCos1 = vtN1 * vtL ;
|
|
||||||
Point3d ptSP2( dU2, dV2, 0) ;
|
|
||||||
double dCos2 = vtN2 * vtL ;
|
|
||||||
// se avevo già trovato un punto singolo che coincide col primo punto di questa intersezione sovrapposta, allora cancello l'intersezione singola che
|
|
||||||
// avevo salvato e aggiungo quella sovrapposto che ho trovato ora
|
|
||||||
if( bFound) {
|
|
||||||
int nNewTot = int(vInfo.size()) ;
|
|
||||||
int nNewInters = nNewTot - nInters ;
|
|
||||||
bool bAlreadyFound = false ;
|
|
||||||
for( int i = 0 ; i < nNewInters ; ++i) {
|
|
||||||
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) || AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP2) ;
|
|
||||||
if ( bAlreadyFound) {
|
|
||||||
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
|
||||||
bFound = true ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
// se ho trovato un punto a distanza zero dalla linea allora ho trovato l'intersezione
|
|
||||||
else if( dMinDist < EPS_SMALL) {
|
|
||||||
if( i == 0) {
|
|
||||||
//dV1 = 0 ;
|
|
||||||
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
|
||||||
}
|
|
||||||
else if( i == 1) {
|
|
||||||
//dU1 = 1 ;
|
|
||||||
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
|
||||||
}
|
|
||||||
else if( i == 2){
|
|
||||||
//dV1 = 1 ;
|
|
||||||
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
|
||||||
}
|
|
||||||
else if( i == 3){
|
|
||||||
//dU1 = 0 ;
|
|
||||||
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
|
||||||
}
|
|
||||||
Point3d ptSP1( dU1, dV1, 0), ptSP2 ;
|
|
||||||
// se avevo trovato già altri punti controllo di non essere esattamente su una diagonale ( e quindi avere un'intersezione con ogni edge, ma due sono doppie)
|
|
||||||
if( bFound) {
|
|
||||||
int nNewTot = int(vInfo.size()) ;
|
|
||||||
int nNewInters = nNewTot - nInters ;
|
|
||||||
bool bAlreadyFound = false ;
|
|
||||||
for( int i = 0 ; i < nNewInters ; ++i)
|
|
||||||
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) ;
|
|
||||||
if( bAlreadyFound)
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point3d ptIBez1, ptIBez2 ;
|
|
||||||
Vector3d vtN1, vtN2 ;
|
|
||||||
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
|
||||||
double dCos1 = vtN1 * vtL, dCos2 = 0 ;
|
|
||||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
|
||||||
bFound = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// se la superficie è trimmed verifico che i punti trovati siano all'interno del parametrico trimmato
|
|
||||||
if( bTrimmed && bFound) {
|
|
||||||
int nNewTot = int(vInfo.size()) ;
|
|
||||||
int nNewInters = nNewTot - nInters ;
|
|
||||||
const ISurfFlatRegion* pFRTrim = pSurfBz->GetTrimRegion() ;
|
|
||||||
for( int i = 0 ; i < nNewInters ; ++i) {
|
|
||||||
Point3d ptTest = vInfo[nNewTot - i].ptUV * SBZ_TREG_COEFF ;
|
|
||||||
bool bInside = false ;
|
|
||||||
double dDist = INFINITO ;
|
|
||||||
IsPointInsideSurfFr( ptTest, pFRTrim, dDist, bInside) ;
|
|
||||||
if( ! bInside)
|
|
||||||
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1670,7 +1670,7 @@ LineTorus( const Point3d& ptLine, const Vector3d& vtLine,
|
|||||||
|
|
||||||
// Studio le soluzioni
|
// Studio le soluzioni
|
||||||
int nIntType = T_ERROR ;
|
int nIntType = T_ERROR ;
|
||||||
if ( vdPar.empty())
|
if ( vdPar.size() == 0)
|
||||||
nIntType = T_NO_INT ;
|
nIntType = T_NO_INT ;
|
||||||
else if ( vdPar.size() == 1) {
|
else if ( vdPar.size() == 1) {
|
||||||
nIntType = T_ONE_TAN ;
|
nIntType = T_ONE_TAN ;
|
||||||
|
|||||||
+21
-108
@@ -23,20 +23,20 @@ using namespace std ;
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
||||||
int nStm, int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
||||||
{
|
{
|
||||||
Point3d ptInt, ptInt2 ;
|
Point3d ptInt, ptInt2 ;
|
||||||
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
||||||
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
||||||
double dU = ( ptInt - ptL) * vtDir ;
|
double dU = ( ptInt - ptL) * vtDir ;
|
||||||
double dCosDN = vtDir * Tria.GetN() ;
|
double dCosDN = vtDir * Tria.GetN() ;
|
||||||
vInfo.emplace_back( nRes, dU, nStm, nT, dCosDN, ptInt) ;
|
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
|
||||||
}
|
}
|
||||||
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
||||||
double dU = ( ptInt - ptL) * vtDir ;
|
double dU = ( ptInt - ptL) * vtDir ;
|
||||||
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
||||||
double dCosDN = vtDir * Tria.GetN() ;
|
double dCosDN = vtDir * Tria.GetN() ;
|
||||||
vInfo.emplace_back( nRes, dU, dU2, nStm, nT, dCosDN, ptInt, ptInt2) ;
|
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,15 +45,13 @@ static void
|
|||||||
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
// se non trovati, esco
|
// se non trovati, esco
|
||||||
if ( vInfo.empty())
|
if ( vInfo.size() == 0)
|
||||||
return ;
|
return ;
|
||||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||||
sort( vInfo.begin(), vInfo.end(),
|
sort( vInfo.begin(), vInfo.end(),
|
||||||
[]( const IntLinStmInfo& a, const IntLinStmInfo& b)
|
[]( const IntLinStmInfo& a, const IntLinStmInfo& b)
|
||||||
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||||
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||||
if ( abs( dUa - dUb) < EPS_SMALL)
|
|
||||||
return ( a.dCosDN < b.dCosDN) ;
|
|
||||||
return ( dUa < dUb) ; }) ;
|
return ( dUa < dUb) ; }) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
Stm.GetTriangle( nT, Tria) ;
|
Stm.GetTriangle( nT, Tria) ;
|
||||||
// aggiorno info con intersezione
|
// aggiorno info con intersezione
|
||||||
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, 0, nT, Tria, vInfo, bFinite) ;
|
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,23 +122,19 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
// Intersezione di molte linee parallele con una superficie TriMesh
|
// Intersezione di molte linee parallele con una superficie TriMesh
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm)
|
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm)
|
||||||
: m_bOk( false), m_frLines( frLines), m_vpSTm( {&Stm})
|
: m_bOk( false), m_frLines( frLines), m_pSTm( &Stm)
|
||||||
{
|
{
|
||||||
// verifico esistenza superficie
|
// verifico esistenza superficie
|
||||||
if ( m_vpSTm[0] == nullptr || ! m_vpSTm[0]->IsValid())
|
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// aggiorno il vettore degli indici di base per mappare i triangoli con le rispettivi superfici
|
// creo HashGrid 2d
|
||||||
// ( in questo caso la superficie è unica, quindi ho solo due elementi)
|
|
||||||
m_vBaseInd = { 0, m_vpSTm[0]->GetTriangleCount()} ;
|
|
||||||
|
|
||||||
// creo HashGrid 2d ed eventualmente attivo la griglia
|
|
||||||
const int LIM_HG_TRIA = 127 ;
|
const int LIM_HG_TRIA = 127 ;
|
||||||
m_HGrids.SetActivationGrid( m_vBaseInd.back() > LIM_HG_TRIA) ;
|
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
||||||
|
|
||||||
// riempio HashGrid
|
// riempio HashGrid
|
||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
int nT = m_vpSTm[0]->GetFirstTriangle( Tria) ;
|
int nT = Stm.GetFirstTriangle( Tria) ;
|
||||||
while ( nT != SVT_NULL) {
|
while ( nT != SVT_NULL) {
|
||||||
// calcolo il BBox del triangolo nel riferimento scelto
|
// calcolo il BBox del triangolo nel riferimento scelto
|
||||||
Tria.ToLoc( m_frLines) ;
|
Tria.ToLoc( m_frLines) ;
|
||||||
@@ -149,55 +143,10 @@ IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfT
|
|||||||
b3Tria.Add( Tria.GetP( 1)) ;
|
b3Tria.Add( Tria.GetP( 1)) ;
|
||||||
b3Tria.Add( Tria.GetP( 2)) ;
|
b3Tria.Add( Tria.GetP( 2)) ;
|
||||||
// inserisco nella griglia
|
// inserisco nella griglia
|
||||||
if ( ! m_HGrids.Add( nT, b3Tria)) // ( 0 + nT, Tria)
|
if ( ! m_HGrids.Add( nT, b3Tria))
|
||||||
return ;
|
return ;
|
||||||
// passo al prossimo triangolo
|
// passo al prossimo triangolo
|
||||||
nT = m_vpSTm[0]->GetNextTriangle( nT, Tria) ;
|
nT = Stm.GetNextTriangle( nT, Tria) ;
|
||||||
}
|
|
||||||
// aggiorno
|
|
||||||
m_bOk = m_HGrids.Update() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Intersezione di molte linee parallele con un vettore di superfici TriMesh
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const CISURFTMPVECTOR& vStm)
|
|
||||||
: m_bOk( false), m_frLines( frLines), m_vpSTm( vStm), m_vBaseInd( {0})
|
|
||||||
{
|
|
||||||
// verifico esistenza superfici
|
|
||||||
if ( m_vpSTm.empty())
|
|
||||||
return ;
|
|
||||||
for ( const ISurfTriMesh* pStm : m_vpSTm) {
|
|
||||||
if ( pStm == nullptr || ! pStm->IsValid())
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// aggiorno il vettore degli indici di base per mappare i triangoli con le rispettivi superfici
|
|
||||||
// NB. dal costruttore è già inizializzato a {0}
|
|
||||||
for ( int i = 0 ; i < int( m_vpSTm.size()) ; ++ i)
|
|
||||||
m_vBaseInd.emplace_back( m_vBaseInd.back() + m_vpSTm[i]->GetTriangleCount()) ;
|
|
||||||
|
|
||||||
// creo HashGrid 2d ed eventualmente attivo la griglia
|
|
||||||
const int LIM_HG_TRIA = 256 ;
|
|
||||||
m_HGrids.SetActivationGrid( m_vBaseInd.back() > LIM_HG_TRIA) ;
|
|
||||||
|
|
||||||
// riempio HashGrid
|
|
||||||
for ( int i = 0 ; i < int( m_vpSTm.size()) ; ++ i) {
|
|
||||||
Triangle3d Tria ;
|
|
||||||
int nT = m_vpSTm[i]->GetFirstTriangle( Tria) ;
|
|
||||||
while ( nT != SVT_NULL) {
|
|
||||||
// calcolo il BBox del triangolo nel riferimento scelto
|
|
||||||
Tria.ToLoc( m_frLines) ;
|
|
||||||
BBox3d b3Tria ;
|
|
||||||
b3Tria.Add( Tria.GetP( 0)) ;
|
|
||||||
b3Tria.Add( Tria.GetP( 1)) ;
|
|
||||||
b3Tria.Add( Tria.GetP( 2)) ;
|
|
||||||
// inserisco nella griglia ( aggiungo shift per indice del triangolo)
|
|
||||||
if ( ! m_HGrids.Add( m_vBaseInd[i] + nT, b3Tria))
|
|
||||||
return ;
|
|
||||||
// passo al prossimo triangolo
|
|
||||||
nT = m_vpSTm[i]->GetNextTriangle( nT, Tria) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// aggiorno
|
// aggiorno
|
||||||
m_bOk = m_HGrids.Update() ;
|
m_bOk = m_HGrids.Update() ;
|
||||||
@@ -211,7 +160,7 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
if ( &vInfo == nullptr)
|
if ( &vInfo == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
vInfo.clear() ;
|
vInfo.clear() ;
|
||||||
// verifico validità
|
// verifico validità
|
||||||
if ( ! m_bOk)
|
if ( ! m_bOk)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -223,22 +172,15 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
Point3d ptLL = ptL ;
|
Point3d ptLL = ptL ;
|
||||||
ptLL.ToGlob( m_frLines) ;
|
ptLL.ToGlob( m_frLines) ;
|
||||||
|
|
||||||
// recupero indici triangoli che intersecano box in 2d
|
// recupero indici triangoli che intersecano box in 2d
|
||||||
INTVECTOR vnIds ;
|
INTVECTOR vnIds ;
|
||||||
if ( m_HGrids.Find( b3Line, vnIds)) {
|
if ( m_HGrids.Find( b3Line, vnIds)) {
|
||||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||||
// recupero la superficie
|
int nT = vnIds[i] ;
|
||||||
int nInd = vnIds[i] ;
|
|
||||||
int nSurf = GetSurfInd( nInd) ;
|
|
||||||
if ( nSurf == -1)
|
|
||||||
return false ;
|
|
||||||
// recupero il triangolo
|
|
||||||
int nT = nInd - m_vBaseInd[nSurf] ;
|
|
||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
if ( ! m_vpSTm[nSurf]->GetTriangle( nT, Tria))
|
m_pSTm->GetTriangle( nT, Tria) ;
|
||||||
return false ;
|
|
||||||
// aggiorno info con intersezione
|
// aggiorno info con intersezione
|
||||||
UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nSurf, nT, Tria, vInfo, bFinite) ;
|
UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nT, Tria, vInfo, bFinite) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,35 +190,6 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
int
|
|
||||||
IntersParLinesSurfTm::GetSurfInd( int nT) const
|
|
||||||
{
|
|
||||||
// verifico la presenza di almeno un intervallo
|
|
||||||
if ( m_vBaseInd.size() < 2)
|
|
||||||
return -1 ;
|
|
||||||
// se la superficie è unica, allora non devo cercarla
|
|
||||||
if ( int( m_vBaseInd.size()) == 2)
|
|
||||||
return 0 ;
|
|
||||||
// ricerca binaria dell'intervallo contenente la posizione del triangolo
|
|
||||||
int nS = 0 ;
|
|
||||||
int nE = int( m_vBaseInd.size()) - 1 ;
|
|
||||||
while ( true) {
|
|
||||||
if ( nT < m_vBaseInd[nS] || nT >= m_vBaseInd[nE])
|
|
||||||
return -1 ;
|
|
||||||
if ( nE - nS == 1)
|
|
||||||
return nS ;
|
|
||||||
int nM = ( nS + nE) / 2 ;
|
|
||||||
if ( nT == m_vBaseInd[nM])
|
|
||||||
return nM ;
|
|
||||||
if ( nT < m_vBaseInd[nM])
|
|
||||||
nE = nM ;
|
|
||||||
else
|
|
||||||
nS = nM ;
|
|
||||||
}
|
|
||||||
return -1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||||
@@ -302,7 +215,7 @@ FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||||
// intersezione precedente
|
// intersezione precedente
|
||||||
size_t i = j - 1 ;
|
size_t i = j - 1 ;
|
||||||
// se hanno lo stesso parametro
|
// se hanno lo stesso parametro
|
||||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||||
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@
|
|||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "IntersLineLine.h"
|
#include "IntersLineLine.h"
|
||||||
#include "IntersLineTria.h"
|
#include "IntersLineTria.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
#include "DistLineLine.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|||||||
@@ -42,5 +42,5 @@ Inters3Planes( const Plane3d& plPlane1, const Plane3d& plPlane2, const Plane3d&
|
|||||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptL, vtL) != IPPT_YES)
|
if ( IntersPlanePlane( plPlane1, plPlane2, ptL, vtL) != IPPT_YES)
|
||||||
return IPPT_NO ;
|
return IPPT_NO ;
|
||||||
// intersezione della linea con il terzo piano
|
// intersezione della linea con il terzo piano
|
||||||
return ( IntersLinePlane( ptL, vtL, 1, plPlane3, ptInt, false) == ILPT_YES ? IPPT_YES : IPPT_NO) ;
|
return ( IntersLinePlane( ptL, vtL, 1, plPlane3, ptInt) == ILPT_YES ? IPPT_YES : IPPT_NO) ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ProjPlane.h"
|
#include "ProjPlane.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "IntersLineTria.h"
|
#include "IntersLineTria.h"
|
||||||
#include "DllMain.h"
|
#include "DllMain.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkIntersTriaTria.h"
|
#include "/EgtDev/Include/EGkIntersTriaTria.h"
|
||||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CreateCurveAux.h"
|
#include "CreateCurveAux.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkLineTgCurvePerpCurve.h"
|
#include "/EgtDev/Include/EGkLineTgCurvePerpCurve.h"
|
||||||
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
|
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CreateCurveAux.h"
|
#include "CreateCurveAux.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "DistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkLineTgTwoCurves.h"
|
#include "/EgtDev/Include/EGkLineTgTwoCurves.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
|
|||||||
+32
-154
@@ -2,7 +2,7 @@
|
|||||||
// EgalTech 2013-2013
|
// EgalTech 2013-2013
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : OffsetAux.cpp Data : 23.11.23 Versione : 2.5k5
|
// File : OffsetAux.cpp Data : 23.11.23 Versione : 2.5k5
|
||||||
// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve.
|
// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -16,24 +16,20 @@
|
|||||||
#include "CurveArc.h"
|
#include "CurveArc.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "/EgtDev/Include/EGkIntervals.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
|
||||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static bool IsFillet( const ICurve* pCrv, double dDist) ;
|
|
||||||
static bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
|
||||||
static bool AdjustIntersections( ICRVCOMPOPVECTOR& CrvList) ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||||
{
|
{
|
||||||
// identifico le sottocurve di tipo fillet e assegno loro temp param 1.0 per riconoscerle nella funzione AdjustCurveFillets
|
// identifico le sottocurve di tipo fillet e assegno loro temp param 1.0 per riconoscerle nella funzione AdjustCurveFillets
|
||||||
for ( int i = 0 ; i < pCrvCo->GetCurveCount() ; i ++) {
|
for ( int i = 0 ; i < pCrvCo->GetCurveCount() ; i ++) {
|
||||||
if ( IsFillet( pCrvCo->GetCurve( i), dDist))
|
// recupero la curva
|
||||||
|
PtrOwner<ICurve> pCrv( pCrvCo->GetCurve(i)->Clone()) ;
|
||||||
|
if ( IsNull( pCrv))
|
||||||
|
return false ;
|
||||||
|
if ( IsFillet( pCrv, dDist))
|
||||||
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
||||||
else
|
else
|
||||||
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
||||||
@@ -43,14 +39,12 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IsFillet( const ICurve* pCrv, double dDist)
|
IsFillet( ICurve* pCrv, double dDist)
|
||||||
{
|
{
|
||||||
if ( pCrv == nullptr)
|
|
||||||
return false ;
|
|
||||||
// deve essere un arco
|
// deve essere un arco
|
||||||
if ( pCrv->GetType() != CRV_ARC)
|
if ( pCrv->GetType() != CRV_ARC)
|
||||||
return false ;
|
return false ;
|
||||||
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||||
// deve avere raggio uguale alla distanza di offset
|
// deve avere raggio uguale alla distanza di offset
|
||||||
if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL)
|
if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -60,76 +54,36 @@ IsFillet( const ICurve* pCrv, double dDist)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
AdjustCurveFillets( ICURVEPOVECTOR& vOffset, double dDist, int nType)
|
AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType)
|
||||||
{
|
{
|
||||||
if ( vOffset.empty())
|
ICURVEPLIST CrvLst ;
|
||||||
return true ;
|
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
||||||
|
while ( ! IsNull( pCrv)) {
|
||||||
// suddivido le curve di offset individuando i fillet e isolandoli dagli altri tratti
|
// se identificato come fillet lo trasformo in smusso o estensione
|
||||||
ICRVCOMPOPVECTOR vCrvs ;
|
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
||||||
for ( int i = 0 ; i < int( vOffset.size()) ; i ++) {
|
CurveComposite ccTemp ;
|
||||||
CurveComposite* pCompo = GetBasicCurveComposite( vOffset[i]) ;
|
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
||||||
if ( pCompo == nullptr)
|
// metto in lista le curve risultanti
|
||||||
return false ;
|
if ( ccTemp.GetCurveCount() > 0) {
|
||||||
bool bNewCrv = true ;
|
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
||||||
PtrOwner<ICurve> pCrv( pCompo->RemoveFirstOrLastCurve(false)) ;
|
while ( ! IsNull( pCrv2)) {
|
||||||
while ( ! IsNull( pCrv)) {
|
CrvLst.push_back( Release( pCrv2)) ;
|
||||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
||||||
// se fillet calcolo il nuovo raccordo
|
|
||||||
CurveComposite* ccTemp = CreateBasicCurveComposite() ;
|
|
||||||
ModifyFillet( pCrv, dDist, nType, *ccTemp) ;
|
|
||||||
// assegno temp param per identificarlo nei conti successivi
|
|
||||||
ccTemp->SetTempParam( 1) ;
|
|
||||||
vCrvs.push_back( ccTemp) ;
|
|
||||||
bNewCrv = true ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// aggiungo la curva
|
|
||||||
if ( bNewCrv) {
|
|
||||||
bNewCrv = false ;
|
|
||||||
CurveComposite* pCompo = ConvertCurveToBasicComposite( Release( pCrv)) ;
|
|
||||||
if ( pCompo == nullptr)
|
|
||||||
return false ;
|
|
||||||
vCrvs.push_back( pCompo) ;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
vCrvs.back()->AddCurve( Release( pCrv)) ;
|
|
||||||
}
|
}
|
||||||
// passo alla curva successiva
|
|
||||||
pCrv.Set( pCompo->RemoveFirstOrLastCurve( false)) ;
|
|
||||||
}
|
}
|
||||||
|
// altrimenti salvo in lista
|
||||||
|
else
|
||||||
|
CrvLst.push_back( Release( pCrv)) ;
|
||||||
|
// passo alla curva successiva
|
||||||
|
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
||||||
}
|
}
|
||||||
vOffset.clear() ;
|
// rimetto le curve nella composita
|
||||||
|
for ( auto pCrv : CrvLst) {
|
||||||
// gestione delle intersezioni
|
pCrvCo->AddCurve( pCrv) ;
|
||||||
if ( ! AdjustIntersections( vCrvs))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// concateno i tratti ottenuti
|
|
||||||
ChainCurves ChainCrv ;
|
|
||||||
ChainCrv.Init( false, 2 * EPS_SMALL, vCrvs.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vCrvs.size()); ++ i) {
|
|
||||||
Point3d ptS, ptE ;
|
|
||||||
Vector3d vtS, vtE ;
|
|
||||||
vCrvs[i]->GetStartPoint( ptS) ;
|
|
||||||
vCrvs[i]->GetEndPoint( ptE) ;
|
|
||||||
vCrvs[i]->GetStartDir( vtS) ;
|
|
||||||
vCrvs[i]->GetEndDir( vtE) ;
|
|
||||||
ChainCrv.AddCurve( i + 1, ptS, vtS, ptE, vtE) ;
|
|
||||||
}
|
|
||||||
// recupero i concatenamenti
|
|
||||||
Point3d ptRef ; vCrvs[0]->GetStartPoint( ptRef) ;
|
|
||||||
INTVECTOR vIds ;
|
|
||||||
while ( ChainCrv.GetChainFromNear( ptRef, false, vIds)) {
|
|
||||||
PtrOwner<CurveComposite> pCompo( CreateBasicCurveComposite()) ;
|
|
||||||
if ( IsNull( pCompo))
|
|
||||||
return false ;
|
|
||||||
for ( auto i : vIds)
|
|
||||||
pCompo->AddCurve( vCrvs[i-1]) ;
|
|
||||||
pCompo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
|
||||||
pCompo->GetEndPoint( ptRef) ;
|
|
||||||
vOffset.emplace_back( Release( pCompo)) ;
|
|
||||||
}
|
}
|
||||||
|
// unisco tratti allineati
|
||||||
|
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -223,79 +177,3 @@ ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux)
|
|||||||
}
|
}
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
AdjustIntersections( ICRVCOMPOPVECTOR& vCrvs)
|
|
||||||
{
|
|
||||||
// sistema le curve nel vettore vCrvs eliminando le parti coinvolte nelle intersezioni
|
|
||||||
|
|
||||||
vector<Intervals> vIntervals( vCrvs.size()) ;
|
|
||||||
INTVECTOR vFillets ;
|
|
||||||
for ( int i = 0 ; i < int( vCrvs.size()) ; i ++) {
|
|
||||||
// salvo i parametri della curva
|
|
||||||
double dParS, dParE ;
|
|
||||||
vCrvs[i]->GetDomain( dParS, dParE) ;
|
|
||||||
vIntervals[i].Set( dParS, dParE) ;
|
|
||||||
// verifico se raccordo
|
|
||||||
if ( vCrvs[i]->GetTempParam() > EPS_SMALL)
|
|
||||||
vFillets.emplace_back( i) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifico se i raccordi intersecano le altre curve
|
|
||||||
bool bInters = false ;
|
|
||||||
for ( int i = 0 ; i < int( vFillets.size()) ; i ++) {
|
|
||||||
int nIdx = vFillets[i] ;
|
|
||||||
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++) {
|
|
||||||
if ( j == nIdx)
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
IntersCurveCurve intCC( *vCrvs[nIdx], *vCrvs[j]) ;
|
|
||||||
int nCnt = intCC.GetIntersCount() ;
|
|
||||||
if ( nCnt > 1) {
|
|
||||||
// aggiorno gli intervalli della curva sottraendo la parte coinvolta dall'intersezione
|
|
||||||
for ( int k = 0 ; k < nCnt - 1 ; k = k+2) {
|
|
||||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
|
||||||
intCC.GetIntCrvCrvInfo( k, iccInfo1) ;
|
|
||||||
// verifico non sia intersezione nell'estremo iniziale o sovrapposizione
|
|
||||||
if ( iccInfo1.IciA[0].dU < EPS_SMALL || iccInfo1.bOverlap) {
|
|
||||||
k-- ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
intCC.GetIntCrvCrvInfo( k+1, iccInfo2) ;
|
|
||||||
|
|
||||||
vIntervals[nIdx].Subtract( iccInfo1.IciA[0].dU, iccInfo2.IciA[0].dU) ;
|
|
||||||
vIntervals[j].Subtract( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
|
||||||
bInters = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! bInters)
|
|
||||||
return true ;
|
|
||||||
|
|
||||||
// aggiorno le curve eliminando i tratti coinvolti nelle intersezioni
|
|
||||||
for ( int i = 0 ; i < int( vIntervals.size()) ; i++) {
|
|
||||||
if ( vIntervals[i].GetCount() > 1) {
|
|
||||||
PtrOwner<CurveComposite> pCompo( CloneBasicCurveComposite( vCrvs[i])) ;
|
|
||||||
if ( IsNull( pCompo))
|
|
||||||
return false ;
|
|
||||||
double dParS, dParE ;
|
|
||||||
vIntervals[i].GetFirst( dParS, dParE) ;
|
|
||||||
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
|
||||||
while ( vIntervals[i].GetNext( dParS, dParE)) {
|
|
||||||
CurveComposite* pCrv = ConvertCurveToBasicComposite( pCompo->CopyParamRange( dParS, dParE)) ;
|
|
||||||
if ( pCrv == nullptr)
|
|
||||||
return false ;
|
|
||||||
vCrvs.emplace_back( pCrv) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double dParS, dParE ;
|
|
||||||
vIntervals[i].GetFirst( dParS, dParE) ;
|
|
||||||
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|||||||
+4
-2
@@ -2,7 +2,7 @@
|
|||||||
// EgalTech 2013-2013
|
// EgalTech 2013-2013
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : OffsetAux.h Data : 23.11.23 Versione : 2.5k5
|
// File : OffsetAux.h Data : 23.11.23 Versione : 2.5k5
|
||||||
// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve.
|
// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -16,4 +16,6 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
||||||
bool AdjustCurveFillets( ICURVEPOVECTOR& vCrvs, double dDist, int nType) ;
|
bool IsFillet( ICurve* pCrv, double dDist) ;
|
||||||
|
bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ;
|
||||||
|
bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
||||||
|
|||||||
+28
-84
@@ -60,8 +60,6 @@ OffsetCurve::Reset( void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_CrvLst.clear() ;
|
m_CrvLst.clear() ;
|
||||||
m_ptOffs = P_INVALID ;
|
|
||||||
m_vtOut = V_INVALID ;
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +74,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
// verifico che la curva esista
|
// verifico che la curva esista
|
||||||
if ( pCrv == nullptr)
|
if ( pCrv == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico se la curva è un segmento di retta
|
// verifico se la curva è un segmento di retta
|
||||||
bool bIsLine = false ;
|
bool bIsLine = false ;
|
||||||
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||||
if ( pLine != nullptr)
|
if ( pLine != nullptr)
|
||||||
@@ -87,7 +85,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
if ( pCompo != nullptr && pCompo->IsALine( m_dLinTol, ptStart, ptEnd))
|
if ( pCompo != nullptr && pCompo->IsALine( m_dLinTol, ptStart, ptEnd))
|
||||||
bIsLine = true ;
|
bIsLine = true ;
|
||||||
}
|
}
|
||||||
// verifico che la curva sia piana (per le linee è comunque sempre vero)
|
// verifico che la curva sia piana (per le linee è comunque sempre vero)
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL) && ! bIsLine)
|
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL) && ! bIsLine)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -169,7 +167,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
// -------------------- OFFSET STANDARD ---------------------------------
|
// -------------------- OFFSET STANDARD ---------------------------------
|
||||||
if ( ! USE_VORONOI) {
|
if ( ! USE_VORONOI) {
|
||||||
|
|
||||||
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
||||||
if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, ANG_TOL_STD_DEG))
|
if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, ANG_TOL_STD_DEG))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -189,11 +187,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
if ( ! ccCopy.MergeCurves( m_dLinTol, ANG_TOL_STD_DEG, bClosed, true))
|
if ( ! ccCopy.MergeCurves( m_dLinTol, ANG_TOL_STD_DEG, bClosed, true))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico se il punto iniziale è stato modificato
|
// verifico se il punto iniziale è stato modificato
|
||||||
Point3d ptNewStart ; ccCopy.GetStartPoint( ptNewStart) ;
|
Point3d ptNewStart ; ccCopy.GetStartPoint( ptNewStart) ;
|
||||||
bChangeStart = ( ! AreSamePointApprox( ptNewStart, ptStart)) ;
|
bChangeStart = ( ! AreSamePointApprox( ptNewStart, ptStart)) ;
|
||||||
|
|
||||||
// calcolo le lunghezze delle diverse entità
|
// calcolo le lunghezze delle diverse entità
|
||||||
DBLVECTOR vLens ;
|
DBLVECTOR vLens ;
|
||||||
{
|
{
|
||||||
const ICurve* pCrv1 = ccCopy.GetFirstCurve() ;
|
const ICurve* pCrv1 = ccCopy.GetFirstCurve() ;
|
||||||
@@ -205,7 +203,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
pCrv1 = ccCopy.GetNextCurve() ;
|
pCrv1 = ccCopy.GetNextCurve() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// calcolo gli angoli tra le diverse entità
|
// calcolo gli angoli tra le diverse entità
|
||||||
DBLVECTOR vAngs ;
|
DBLVECTOR vAngs ;
|
||||||
{
|
{
|
||||||
vAngs.push_back( 0) ;
|
vAngs.push_back( 0) ;
|
||||||
@@ -232,7 +230,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
vAngs.push_back( 0) ;
|
vAngs.push_back( 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
|
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
|
||||||
CurveComposite ccCopy2 ;
|
CurveComposite ccCopy2 ;
|
||||||
if ( ! ccCopy2.CopyFrom( &ccCopy))
|
if ( ! ccCopy2.CopyFrom( &ccCopy))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -287,9 +285,9 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
|
|
||||||
// se originale chiuso, devo confrontare anche ultima e prima curva
|
// se originale chiuso, devo confrontare anche ultima e prima curva
|
||||||
if ( bClosed && m_CrvLst.size() >= 2) {
|
if ( bClosed && m_CrvLst.size() >= 2) {
|
||||||
// la curva precedente è l'ultima dell'offset
|
// la curva precedente è l'ultima dell'offset
|
||||||
ICurve* pCrv1 = m_CrvLst.back() ;
|
ICurve* pCrv1 = m_CrvLst.back() ;
|
||||||
// la curva successiva ora è la prima dell'offset
|
// la curva successiva ora è la prima dell'offset
|
||||||
ICurve* pCrv2 = m_CrvLst.front() ;
|
ICurve* pCrv2 = m_CrvLst.front() ;
|
||||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||||
CurveComposite ccTemp ;
|
CurveComposite ccTemp ;
|
||||||
@@ -336,7 +334,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
bool bNextInt = NextIsLine( iIter, m_CrvLst, bClosed) &&
|
bool bNextInt = NextIsLine( iIter, m_CrvLst, bClosed) &&
|
||||||
NextIsLonger( nInd1, vLens, bClosed) &&
|
NextIsLonger( nInd1, vLens, bClosed) &&
|
||||||
( ( dDist < 0 && vAngs[nInd1] > 0) || ( dDist > 0 && vAngs[nInd1] < 0)) ;
|
( ( dDist < 0 && vAngs[nInd1] > 0) || ( dDist > 0 && vAngs[nInd1] < 0)) ;
|
||||||
// calcolo la massima estensione di offset (Voronoi con entità adiacenti)
|
// calcolo la massima estensione di offset (Voronoi con entità adiacenti)
|
||||||
double dMaxDist = INFINITO ;
|
double dMaxDist = INFINITO ;
|
||||||
if ( bPrevInt && bNextInt) {
|
if ( bPrevInt && bNextInt) {
|
||||||
double dTgA = tan( 0.5 * ( ANG_STRAIGHT - abs( vAngs[nInd1-1])) * DEGTORAD) ;
|
double dTgA = tan( 0.5 * ( ANG_STRAIGHT - abs( vAngs[nInd1-1])) * DEGTORAD) ;
|
||||||
@@ -504,7 +502,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
|
|
||||||
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
||||||
if ( ! bClosed) {
|
if ( ! bClosed) {
|
||||||
// ciconferenza sull'estremità iniziale
|
// ciconferenza sull'estremità iniziale
|
||||||
Point3d ptStart ; ccCopy.GetStartPoint( ptStart) ;
|
Point3d ptStart ; ccCopy.GetStartPoint( ptStart) ;
|
||||||
PtrOwner<CurveArc> pCircS( CreateBasicCurveArc()) ;
|
PtrOwner<CurveArc> pCircS( CreateBasicCurveArc()) ;
|
||||||
if ( IsNull( pCircS) || ! pCircS->Set( ptStart, Z_AX, abs( dDist)))
|
if ( IsNull( pCircS) || ! pCircS->Set( ptStart, Z_AX, abs( dDist)))
|
||||||
@@ -553,7 +551,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
// passo alla successiva
|
// passo alla successiva
|
||||||
++ iIter ;
|
++ iIter ;
|
||||||
}
|
}
|
||||||
// circonferenza sull'estremità finale
|
// circonferenza sull'estremità finale
|
||||||
Point3d ptEnd ; ccCopy.GetEndPoint( ptEnd) ;
|
Point3d ptEnd ; ccCopy.GetEndPoint( ptEnd) ;
|
||||||
PtrOwner<CurveArc> pCircE( CreateBasicCurveArc()) ;
|
PtrOwner<CurveArc> pCircE( CreateBasicCurveArc()) ;
|
||||||
if ( IsNull( pCircE) || ! pCircE->Set( ptEnd, Z_AX, abs( dDist)))
|
if ( IsNull( pCircE) || ! pCircE->Set( ptEnd, Z_AX, abs( dDist)))
|
||||||
@@ -674,20 +672,12 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
||||||
// NB questa parte non è gestita in modo efficiente perchè dovrebbe essere sempre disabilitata.
|
|
||||||
// Le funzioni sono state ottimizzate per lavorare con voronoi
|
|
||||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
||||||
ICURVEPOVECTOR vCrvs ;
|
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
|
||||||
vCrvs.reserve( m_CrvLst.size()) ;
|
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||||
for ( auto pCrv : m_CrvLst) {
|
IdentifyFillets( pCrvCo, dDist) ;
|
||||||
IdentifyFillets( GetCurveComposite( pCrv), dDist) ;
|
AdjustCurveFillets( pCrvCo, dDist, nType) ;
|
||||||
vCrvs.emplace_back( pCrv) ;
|
}
|
||||||
}
|
|
||||||
if ( ! AdjustCurveFillets( vCrvs, dDist, nType))
|
|
||||||
return false ;
|
|
||||||
m_CrvLst.clear() ;
|
|
||||||
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++)
|
|
||||||
m_CrvLst.emplace_back( Release( vCrvs[j])) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,27 +697,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
// calcolo offset con Voronoi
|
// calcolo offset con Voronoi
|
||||||
ICURVEPOVECTOR vOffs ;
|
ICURVEPOVECTOR vOffs ;
|
||||||
voronoiObj->CalcOffset( vOffs, dDist, nType) ;
|
voronoiObj->CalcOffset( vOffs, dDist, nType) ;
|
||||||
if ( vOffs.empty()) {
|
|
||||||
// se non ho ottenuto offset e sono circa al valore limite ritento con valore leggermente diverso per le tolleranze di vroni
|
|
||||||
double dMaxOffs ;
|
|
||||||
if ( ! pCrv->IsClosed() || ( voronoiObj->CalcLimitOffset( 0, dDist < 0, dMaxOffs) && abs( dMaxOffs - abs( dDist)) < EPS_SMALL)) {
|
|
||||||
double dCorr = ( dDist > 0 ? - VRONI_OFFS_TOL : VRONI_OFFS_TOL) ;
|
|
||||||
voronoiObj->CalcOffset( vOffs, dDist + dCorr, nType) ;
|
|
||||||
}
|
|
||||||
// se ancora vuoto calcolo i punti speciali di offset ( punti e direzioni sui bisettore alla distanza richiesta)
|
|
||||||
if ( vOffs.empty()) {
|
|
||||||
PNTVECTVECTOR vPntOffs ;
|
|
||||||
voronoiObj->CalcSpecialPointOffset( vPntOffs, dDist) ;
|
|
||||||
// NB al momento vengono gestiti solo i casi in cui vi è un unico punto di offset. Se si ottengono più punti di offset
|
|
||||||
// ( e.g. alcune curve aperte) non se ne restiusce nessuno. Da estendere, se necessario, individuando i punti dal lato
|
|
||||||
// di offset richiesto
|
|
||||||
if ( vPntOffs.size() == 1) {
|
|
||||||
m_ptOffs = vPntOffs[0].first ;
|
|
||||||
m_vtOut = vPntOffs[0].second ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
|
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
|
||||||
m_CrvLst.emplace_back( Release( vOffs[i])) ;
|
m_CrvLst.emplace_back( Release( vOffs[i])) ;
|
||||||
|
|
||||||
@@ -755,21 +724,10 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
||||||
pCrv->ToGlob( frCopy) ;
|
pCrv->ToGlob( frCopy) ;
|
||||||
}
|
}
|
||||||
if ( m_ptOffs.IsValid()) {
|
|
||||||
m_ptOffs.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
|
||||||
m_ptOffs.ToGlob( frCopy) ;
|
|
||||||
m_vtOut.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
|
||||||
m_vtOut.ToGlob( frCopy) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ( bNeedRef) {
|
else if ( bNeedRef) {
|
||||||
for ( auto pCrv : m_CrvLst)
|
for ( auto pCrv : m_CrvLst)
|
||||||
pCrv->ToGlob( frCopy) ;
|
pCrv->ToGlob( frCopy) ;
|
||||||
if ( m_ptOffs.IsValid()) {
|
|
||||||
m_ptOffs.ToGlob( frCopy) ;
|
|
||||||
m_vtOut.ToGlob( frCopy) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// assegno estrusione e spessore come curva originale e unisco parti allineate
|
// assegno estrusione e spessore come curva originale e unisco parti allineate
|
||||||
@@ -847,20 +805,6 @@ OffsetCurve::GetShorterCurve( void)
|
|||||||
return pCrv ;
|
return pCrv ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
OffsetCurve::GetPointOffset( Point3d& ptOffs, Vector3d& vtOut)
|
|
||||||
{
|
|
||||||
// verifico se valori validi da restituire
|
|
||||||
if ( ! m_ptOffs.IsValid() || ! m_vtOut.IsValid())
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
ptOffs = m_ptOffs ;
|
|
||||||
vtOut = m_vtOut ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool bClosed)
|
PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool bClosed)
|
||||||
@@ -873,7 +817,7 @@ PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bo
|
|||||||
// se non esiste e curva chiusa prendo l'ultimo
|
// se non esiste e curva chiusa prendo l'ultimo
|
||||||
if ( iPrev == CrvLst.end() && bClosed)
|
if ( iPrev == CrvLst.end() && bClosed)
|
||||||
-- iPrev ;
|
-- iPrev ;
|
||||||
// se non esiste o non è una linea, test fallito
|
// se non esiste o non è una linea, test fallito
|
||||||
if ( iPrev == CrvLst.end() || (*iPrev)->GetType() != CRV_LINE )
|
if ( iPrev == CrvLst.end() || (*iPrev)->GetType() != CRV_LINE )
|
||||||
return false ;
|
return false ;
|
||||||
// test superato
|
// test superato
|
||||||
@@ -886,7 +830,7 @@ PreviousIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
|||||||
{
|
{
|
||||||
// massimo indice nel vettore
|
// massimo indice nel vettore
|
||||||
int nMax = int( vLens.size()) - 1 ;
|
int nMax = int( vLens.size()) - 1 ;
|
||||||
// verifico validità indice (questo indice è incrementato di 1)
|
// verifico validità indice (questo indice è incrementato di 1)
|
||||||
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
||||||
return false ;
|
return false ;
|
||||||
// indice del precedente nel vettore di lunghezze
|
// indice del precedente nel vettore di lunghezze
|
||||||
@@ -910,7 +854,7 @@ NextIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool b
|
|||||||
// se non esiste e curva chiusa prendo il primo
|
// se non esiste e curva chiusa prendo il primo
|
||||||
if ( iNext == CrvLst.end() && bClosed)
|
if ( iNext == CrvLst.end() && bClosed)
|
||||||
iNext = CrvLst.begin() ;
|
iNext = CrvLst.begin() ;
|
||||||
// se non esiste o non è una linea, test fallito
|
// se non esiste o non è una linea, test fallito
|
||||||
if ( iNext == CrvLst.end() || (*iNext)->GetType() != CRV_LINE )
|
if ( iNext == CrvLst.end() || (*iNext)->GetType() != CRV_LINE )
|
||||||
return false ;
|
return false ;
|
||||||
// test superato
|
// test superato
|
||||||
@@ -923,7 +867,7 @@ NextIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
|||||||
{
|
{
|
||||||
// massimo indice nel vettore
|
// massimo indice nel vettore
|
||||||
int nMax = int( vLens.size()) - 1 ;
|
int nMax = int( vLens.size()) - 1 ;
|
||||||
// verifico validità indice (questo indice è incrementato di 1)
|
// verifico validità indice (questo indice è incrementato di 1)
|
||||||
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
||||||
return false ;
|
return false ;
|
||||||
// indice del successivo nel vettore di lunghezze
|
// indice del successivo nel vettore di lunghezze
|
||||||
@@ -1002,7 +946,7 @@ VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
|||||||
nRes = 4 ;
|
nRes = 4 ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
// se coincidono esattamente, va bene così
|
// se coincidono esattamente, va bene così
|
||||||
if ( AreSamePointExact( ptP1, ptP2)) {
|
if ( AreSamePointExact( ptP1, ptP2)) {
|
||||||
nRes = 0 ;
|
nRes = 0 ;
|
||||||
return true ;
|
return true ;
|
||||||
@@ -1032,7 +976,7 @@ VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
|||||||
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
|
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
|
||||||
if ( intCC.GetIntersCount() == 0)
|
if ( intCC.GetIntersCount() == 0)
|
||||||
return false ;
|
return false ;
|
||||||
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
|
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
|
||||||
Point3d ptP1, ptP2 ;
|
Point3d ptP1, ptP2 ;
|
||||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -1080,7 +1024,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
|||||||
vtDir2.Invert() ;
|
vtDir2.Invert() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico sia angolo esterno (accetto se entità quasi esattamente sovrapposte)
|
// verifico sia angolo esterno (accetto se entità quasi esattamente sovrapposte)
|
||||||
if ( abs( dAngDeg) < ( ANG_STRAIGHT - 10 * EPS_ANG_ZERO) &&
|
if ( abs( dAngDeg) < ( ANG_STRAIGHT - 10 * EPS_ANG_ZERO) &&
|
||||||
( ( dDist < 0 && dAngDeg > 0) ||
|
( ( dDist < 0 && dAngDeg > 0) ||
|
||||||
( dDist > 0 && dAngDeg < 0)))
|
( dDist > 0 && dAngDeg < 0)))
|
||||||
@@ -1122,7 +1066,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
|||||||
return false ;
|
return false ;
|
||||||
ptP1a = ptP1 + vtDir1 * dLen ;
|
ptP1a = ptP1 + vtDir1 * dLen ;
|
||||||
ptP2a = ptP2 - vtDir2 * dLen ;
|
ptP2a = ptP2 - vtDir2 * dLen ;
|
||||||
// se prima c'è linea posso allungarla
|
// se prima c'è linea posso allungarla
|
||||||
if ( pCrv1->GetType() == CRV_LINE)
|
if ( pCrv1->GetType() == CRV_LINE)
|
||||||
pCrv1->ModifyEnd( ptP1a) ;
|
pCrv1->ModifyEnd( ptP1a) ;
|
||||||
// altrimenti, devo aggiungere una nuova linea
|
// altrimenti, devo aggiungere una nuova linea
|
||||||
@@ -1141,7 +1085,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
|||||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se dopo c'è linea posso allungarla
|
// se dopo c'è linea posso allungarla
|
||||||
if ( pCrv2->GetType() == CRV_LINE)
|
if ( pCrv2->GetType() == CRV_LINE)
|
||||||
pCrv2->ModifyStart( ptP2a) ;
|
pCrv2->ModifyStart( ptP2a) ;
|
||||||
// altrimenti, devo aggiungere una nuova linea
|
// altrimenti, devo aggiungere una nuova linea
|
||||||
@@ -1164,7 +1108,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
|||||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||||
return false ;
|
return false ;
|
||||||
ptPc = ptP1 + vtDir1 * dLen ;
|
ptPc = ptP1 + vtDir1 * dLen ;
|
||||||
// se prima c'è linea o angolo molto piccolo posso allungarla
|
// se prima c'è linea o angolo molto piccolo posso allungarla
|
||||||
if ( ( pCrv1->GetType() == CRV_LINE) || bAngSmall)
|
if ( ( pCrv1->GetType() == CRV_LINE) || bAngSmall)
|
||||||
pCrv1->ModifyEnd( ptPc) ;
|
pCrv1->ModifyEnd( ptPc) ;
|
||||||
// altrimenti, devo aggiungere una nuova linea
|
// altrimenti, devo aggiungere una nuova linea
|
||||||
@@ -1175,7 +1119,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
|||||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se dopo c'è linea o angolo molto piccolo posso allungarla
|
// se dopo c'è linea o angolo molto piccolo posso allungarla
|
||||||
if ( ( pCrv2->GetType() == CRV_LINE) || bAngSmall)
|
if ( ( pCrv2->GetType() == CRV_LINE) || bAngSmall)
|
||||||
pCrv2->ModifyStart( ptPc) ;
|
pCrv2->ModifyStart( ptPc) ;
|
||||||
// altrimenti, devo aggiungere una nuova linea
|
// altrimenti, devo aggiungere una nuova linea
|
||||||
|
|||||||
+2
-2
@@ -195,7 +195,7 @@ PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( ! vnIds.empty()) ;
|
return ( vnIds.size() > 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -221,7 +221,7 @@ PointGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( ! vnIds.empty()) ;
|
return ( vnIds.size() > 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+31
-41
@@ -14,28 +14,36 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "PointsPCA.h"
|
#include "PointsPCA.h"
|
||||||
#include "/EgtDev/Extern/Eigen/Dense"
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
PointsPCA::PointsPCA( void)
|
PointsPCA::PointsPCA( void)
|
||||||
{
|
{
|
||||||
|
// azzero numero punti
|
||||||
|
m_dTotW = 0 ;
|
||||||
|
// azzero il baricentro
|
||||||
|
m_ptCen.Set( 0, 0, 0) ;
|
||||||
|
// azzero matrice di covarianza
|
||||||
|
m_CovMat.setZero() ;
|
||||||
// inizializzo il rank ad un valore assurdo
|
// inizializzo il rank ad un valore assurdo
|
||||||
m_nRank = - 1 ;
|
m_nRank = - 1 ;
|
||||||
// inizializzo baricentro
|
|
||||||
m_ptCen.Set( 0, 0, 0) ;
|
|
||||||
// inizializzo il peso totale
|
|
||||||
m_dTotW = 0 ;
|
|
||||||
// riservo memoria per la matrice di punti e pesi
|
|
||||||
m_vPntW.reserve( 128) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
PointsPCA::AddPoint( const Point3d& ptP, double dW)
|
PointsPCA::AddPoint( const Point3d& ptP, double dW)
|
||||||
{
|
{
|
||||||
// salvo i dati
|
// incremento numero punti
|
||||||
m_vPntW.emplace_back( ptP, dW) ;
|
m_dTotW += dW ;
|
||||||
|
// aggiorno il baricentro
|
||||||
|
m_ptCen += dW * ptP ;
|
||||||
|
// aggiorno la matrice di covarianza (solo triangolo superiore perchè simmetrica)
|
||||||
|
m_CovMat(0,0) += dW * ( ptP.x * ptP.x) ;
|
||||||
|
m_CovMat(1,1) += dW * ( ptP.y * ptP.y) ;
|
||||||
|
m_CovMat(2,2) += dW * ( ptP.z * ptP.z) ;
|
||||||
|
m_CovMat(0,1) += dW * ( ptP.x * ptP.y) ;
|
||||||
|
m_CovMat(0,2) += dW * ( ptP.x * ptP.z) ;
|
||||||
|
m_CovMat(1,2) += dW * ( ptP.y * ptP.z) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -50,47 +58,29 @@ PointsPCA::Finalize( void)
|
|||||||
m_nRank = 0 ;
|
m_nRank = 0 ;
|
||||||
|
|
||||||
// se non sono stati assegnati punti, esco
|
// se non sono stati assegnati punti, esco
|
||||||
if ( m_vPntW.empty())
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo del peso totale
|
|
||||||
for ( const auto& PntW : m_vPntW)
|
|
||||||
m_dTotW += PntW.second ;
|
|
||||||
if ( m_dTotW < EPS_ZERO)
|
if ( m_dTotW < EPS_ZERO)
|
||||||
return false ;
|
return false ;
|
||||||
// fattore di scala
|
|
||||||
|
// fattore di scala per numero di punti
|
||||||
double dScale = 1 / m_dTotW ;
|
double dScale = 1 / m_dTotW ;
|
||||||
|
|
||||||
// calcolo del baricentro
|
// calcolo del baricentro
|
||||||
for ( const auto& PntW : m_vPntW)
|
|
||||||
m_ptCen += PntW.second * PntW.first ;
|
|
||||||
m_ptCen *= dScale ;
|
m_ptCen *= dScale ;
|
||||||
|
|
||||||
// matrice di covarianza
|
// completo la matrice di covarianza
|
||||||
Eigen::Matrix3d CovMat ;
|
m_CovMat(0,0) = m_CovMat(0,0) * dScale - m_ptCen.x * m_ptCen.x ;
|
||||||
CovMat.setZero() ;
|
m_CovMat(1,1) = m_CovMat(1,1) * dScale - m_ptCen.y * m_ptCen.y ;
|
||||||
for ( const auto& PntW : m_vPntW) {
|
m_CovMat(2,2) = m_CovMat(2,2) * dScale - m_ptCen.z * m_ptCen.z ;
|
||||||
Point3d ptP( PntW.first.x - m_ptCen.x, PntW.first.y - m_ptCen.y, PntW.first.z - m_ptCen.z) ;
|
m_CovMat(0,1) = m_CovMat(0,1) * dScale - m_ptCen.x * m_ptCen.y ;
|
||||||
CovMat(0,0) += PntW.second * ( ptP.x * ptP.x) ;
|
m_CovMat(0,2) = m_CovMat(0,2) * dScale - m_ptCen.x * m_ptCen.z ;
|
||||||
CovMat(1,1) += PntW.second * ( ptP.y * ptP.y) ;
|
m_CovMat(1,2) = m_CovMat(1,2) * dScale - m_ptCen.y * m_ptCen.z ;
|
||||||
CovMat(2,2) += PntW.second * ( ptP.z * ptP.z) ;
|
m_CovMat(1,0) = m_CovMat(0,1) ;
|
||||||
CovMat(0,1) += PntW.second * ( ptP.x * ptP.y) ;
|
m_CovMat(2,0) = m_CovMat(0,2) ;
|
||||||
CovMat(0,2) += PntW.second * ( ptP.x * ptP.z) ;
|
m_CovMat(2,1) = m_CovMat(1,2) ;
|
||||||
CovMat(1,2) += PntW.second * ( ptP.y * ptP.z) ;
|
|
||||||
}
|
|
||||||
CovMat(0,0) = CovMat(0,0) * dScale ;
|
|
||||||
CovMat(1,1) = CovMat(1,1) * dScale ;
|
|
||||||
CovMat(2,2) = CovMat(2,2) * dScale ;
|
|
||||||
CovMat(0,1) = CovMat(0,1) * dScale ;
|
|
||||||
CovMat(0,2) = CovMat(0,2) * dScale ;
|
|
||||||
CovMat(1,2) = CovMat(1,2) * dScale ;
|
|
||||||
CovMat(1,0) = CovMat(0,1) ;
|
|
||||||
CovMat(2,0) = CovMat(0,2) ;
|
|
||||||
CovMat(2,1) = CovMat(1,2) ;
|
|
||||||
|
|
||||||
// calcolo gli autovalori e autovettori
|
// calcolo gli autovalori e autovettori (essendo matrice 3x3 uso metodo diretto)
|
||||||
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es ;
|
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es ;
|
||||||
es.compute( CovMat) ; // non usare computeDirect : errore nell'ordine degli autovettori
|
es.compute( m_CovMat) ; // non usare computeDirect : errore nell'ordine degli autovettori
|
||||||
if ( es.info() == Eigen::NoConvergence)
|
if ( es.info() == Eigen::NoConvergence)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Extern/Eigen/Dense"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class PointsPCA
|
class PointsPCA
|
||||||
@@ -32,9 +33,9 @@ class PointsPCA
|
|||||||
static const int MAX_RANK = 3 ;
|
static const int MAX_RANK = 3 ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
PNTUVECTOR m_vPntW ; // vettore dei punti con i loro pesi
|
double m_dTotW ; // peso totale (se pesi tutti unitari, allora è numero punti)
|
||||||
Point3d m_ptCen ; // baricentro
|
Point3d m_ptCen ; // baricentro
|
||||||
double m_dTotW ; // peso totale
|
Eigen::Matrix3d m_CovMat ; // matrice di covarianza
|
||||||
int m_nRank ; // numero delle componenti principali (MAX_RANK = 3)
|
int m_nRank ; // numero delle componenti principali (MAX_RANK = 3)
|
||||||
Vector3d m_vtPC[MAX_RANK] ; // direzioni delle componenti principali
|
Vector3d m_vtPC[MAX_RANK] ; // direzioni delle componenti principali
|
||||||
} ;
|
} ;
|
||||||
+4
-4
@@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "CurveArc.h"
|
#include "CurveArc.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -62,7 +62,7 @@ bool
|
|||||||
PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge)
|
PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge)
|
||||||
{
|
{
|
||||||
// se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok
|
// se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok
|
||||||
if ( ! m_lUPointBs.empty() && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) {
|
if ( m_lUPointBs.size() > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) {
|
||||||
// assegno parametro e bulge
|
// assegno parametro e bulge
|
||||||
m_lUPointBs.back().dU = dPar ;
|
m_lUPointBs.back().dU = dPar ;
|
||||||
m_lUPointBs.back().dB = dBulge ;
|
m_lUPointBs.back().dB = dBulge ;
|
||||||
@@ -285,10 +285,10 @@ bool
|
|||||||
PolyArc::Join( PolyArc& PA, double dOffsetPar)
|
PolyArc::Join( PolyArc& PA, double dOffsetPar)
|
||||||
{
|
{
|
||||||
// se l'altro poliarco non contiene alcunchè, esco con ok
|
// se l'altro poliarco non contiene alcunchè, esco con ok
|
||||||
if ( PA.m_lUPointBs.empty())
|
if ( PA.m_lUPointBs.size() == 0)
|
||||||
return true ;
|
return true ;
|
||||||
// verifico che l'ultimo punto di questo poliarco coincida con il primo dell'altro
|
// verifico che l'ultimo punto di questo poliarco coincida con il primo dell'altro
|
||||||
if ( ! m_lUPointBs.empty() && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP))
|
if ( m_lUPointBs.size() > 0 && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP))
|
||||||
return false ;
|
return false ;
|
||||||
// cancello l'ultimo di questo
|
// cancello l'ultimo di questo
|
||||||
EraseLastUPoint() ;
|
EraseLastUPoint() ;
|
||||||
|
|||||||
+89
-448
@@ -1,4 +1,4 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2013-2013
|
// EgalTech 2013-2013
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : PolyLine.cpp Data : 22.12.13 Versione : 1.4l3
|
// File : PolyLine.cpp Data : 22.12.13 Versione : 1.4l3
|
||||||
@@ -14,15 +14,13 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "IntersLineLine.h"
|
#include "IntersLineLine.h"
|
||||||
#include "PolygonPlane.h"
|
#include "PolygonPlane.h"
|
||||||
#include "PointsPCA.h"
|
#include "PointsPCA.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "CurveComposite.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
||||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
|
|
||||||
@@ -55,8 +53,8 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
|||||||
{
|
{
|
||||||
// se da aggiungere in coda
|
// se da aggiungere in coda
|
||||||
if ( bEndOrStart) {
|
if ( bEndOrStart) {
|
||||||
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
|
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
|
||||||
if ( ! m_lUPoints.empty() && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
|
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
|
||||||
++ m_nRejected ;
|
++ m_nRejected ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -70,8 +68,8 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
|||||||
}
|
}
|
||||||
// altrimenti si aggiunge in testa
|
// altrimenti si aggiunge in testa
|
||||||
else {
|
else {
|
||||||
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
|
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
|
||||||
if ( ! m_lUPoints.empty() && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
|
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
|
||||||
++ m_nRejected ;
|
++ m_nRejected ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -94,7 +92,7 @@ PolyLine::Close( void)
|
|||||||
// ci devono essere almeno 2 punti
|
// ci devono essere almeno 2 punti
|
||||||
if ( m_lUPoints.size() < 2)
|
if ( m_lUPoints.size() < 2)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico non sia già chiuso
|
// verifico non sia già chiuso
|
||||||
if ( AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first))
|
if ( AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first))
|
||||||
return false ;
|
return false ;
|
||||||
// aggiungo un punto uguale al primo in coda
|
// aggiungo un punto uguale al primo in coda
|
||||||
@@ -221,7 +219,7 @@ PolyLine::ToLoc( const Frame3d& frRef)
|
|||||||
bool
|
bool
|
||||||
PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||||
{
|
{
|
||||||
// se i due riferimenti coincidono, non devo fare alcunché
|
// se i due riferimenti coincidono, non devo fare alcunché
|
||||||
if ( AreSameFrame( frOri, frDest))
|
if ( AreSameFrame( frOri, frDest))
|
||||||
return true ;
|
return true ;
|
||||||
// ciclo sui punti
|
// ciclo sui punti
|
||||||
@@ -235,11 +233,11 @@ PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|||||||
bool
|
bool
|
||||||
PolyLine::Join( PolyLine& PL, double dOffsetPar)
|
PolyLine::Join( PolyLine& PL, double dOffsetPar)
|
||||||
{
|
{
|
||||||
// se l'altra polilinea non contiene alcunchè, esco con ok
|
// se l'altra polilinea non contiene alcunchè, esco con ok
|
||||||
if ( PL.m_lUPoints.empty())
|
if ( PL.m_lUPoints.size() == 0)
|
||||||
return true ;
|
return true ;
|
||||||
// verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra
|
// verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra
|
||||||
if ( ! m_lUPoints.empty() && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first))
|
if ( m_lUPoints.size() > 0 && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first))
|
||||||
return false ;
|
return false ;
|
||||||
// cancello l'ultimo di questa
|
// cancello l'ultimo di questa
|
||||||
EraseLastUPoint() ;
|
EraseLastUPoint() ;
|
||||||
@@ -387,7 +385,7 @@ PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP, bool bNotFirst) const
|
|||||||
bool
|
bool
|
||||||
PolyLine::GetCurrUPoint( double* pdPar, Point3d* pptP) const
|
PolyLine::GetCurrUPoint( double* pdPar, Point3d* pptP) const
|
||||||
{
|
{
|
||||||
// verifico validità punto corrente
|
// verifico validità punto corrente
|
||||||
if ( m_iter == m_lUPoints.end())
|
if ( m_iter == m_lUPoints.end())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -428,7 +426,7 @@ PolyLine::GetFirstULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d*
|
|||||||
bool
|
bool
|
||||||
PolyLine::GetNextULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin) const
|
PolyLine::GetNextULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin) const
|
||||||
{
|
{
|
||||||
// parametro e punto iniziali (è il precedente finale)
|
// parametro e punto iniziali (è il precedente finale)
|
||||||
if ( m_iter == m_lUPoints.end())
|
if ( m_iter == m_lUPoints.end())
|
||||||
return false ;
|
return false ;
|
||||||
if ( pdIni != nullptr)
|
if ( pdIni != nullptr)
|
||||||
@@ -512,19 +510,19 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
|
|||||||
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.25), dLen / 2) ;
|
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.25), dLen / 2) ;
|
||||||
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.75), dLen / 2) ;
|
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.75), dLen / 2) ;
|
||||||
}
|
}
|
||||||
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
|
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
|
||||||
nRank = ptsPCA.GetRank() ;
|
nRank = ptsPCA.GetRank() ;
|
||||||
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
|
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
|
||||||
if ( nRank == 0)
|
if ( nRank == 0)
|
||||||
return ptsPCA.GetCenter( ptCen) ;
|
return ptsPCA.GetCenter( ptCen) ;
|
||||||
// se dimensione 1, allora i punti sono distribuiti su una linea
|
// se dimensione 1, allora i punti sono distribuiti su una linea
|
||||||
if ( nRank == 1) {
|
if ( nRank == 1) {
|
||||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||||
ptsPCA.GetCenter( ptCen) ;
|
ptsPCA.GetCenter( ptCen) ;
|
||||||
ptsPCA.GetPrincipalComponent( 0, vtDir) ;
|
ptsPCA.GetPrincipalComponent( 0, vtDir) ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
|
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
|
||||||
// Center and normal vector
|
// Center and normal vector
|
||||||
ptsPCA.GetCenter( ptCen) ;
|
ptsPCA.GetCenter( ptCen) ;
|
||||||
Vector3d vtX, vtY ;
|
Vector3d vtX, vtY ;
|
||||||
@@ -532,9 +530,9 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
|
|||||||
ptsPCA.GetPrincipalComponent( 1, vtY) ;
|
ptsPCA.GetPrincipalComponent( 1, vtY) ;
|
||||||
vtDir = vtX ^ vtY ;
|
vtDir = vtX ^ vtY ;
|
||||||
if ( ! vtDir.Normalize()) {
|
if ( ! vtDir.Normalize()) {
|
||||||
// riduco la dimensionalità a lineare
|
// riduco la dimensionalità a lineare
|
||||||
nRank = 1 ;
|
nRank = 1 ;
|
||||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||||
ptsPCA.GetCenter( ptCen) ;
|
ptsPCA.GetCenter( ptCen) ;
|
||||||
vtDir = vtX ;
|
vtDir = vtX ;
|
||||||
return true ;
|
return true ;
|
||||||
@@ -563,12 +561,12 @@ PolyLine::IsFlat( Plane3d& plPlane, double dToler) const
|
|||||||
plPlane.Reset() ;
|
plPlane.Reset() ;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// recupero dati sulla planarità della polilinea
|
// recupero dati sulla planarità della polilinea
|
||||||
int nRank ;
|
int nRank ;
|
||||||
Point3d ptCen ;
|
Point3d ptCen ;
|
||||||
Vector3d vtDir ;
|
Vector3d vtDir ;
|
||||||
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||||
// imposto il piano a seconda della dimensionalità
|
// imposto il piano a seconda della dimensionalità
|
||||||
switch ( nRank) {
|
switch ( nRank) {
|
||||||
case 0 : // punto
|
case 0 : // punto
|
||||||
plPlane.Set( ptCen, Z_AX) ;
|
plPlane.Set( ptCen, Z_AX) ;
|
||||||
@@ -589,29 +587,18 @@ PolyLine::IsClosedAndFlat( Plane3d& plPlane, double& dArea, double dToler) const
|
|||||||
// Test if closed
|
// Test if closed
|
||||||
if ( ! IsClosed())
|
if ( ! IsClosed())
|
||||||
return false ;
|
return false ;
|
||||||
|
// Compute a representative plane for the polygon
|
||||||
Point3d ptP ;
|
Point3d ptP ;
|
||||||
// Calcolo il centro (per minimizzare gli errori nelle successive operazioni)
|
|
||||||
Point3d ptCen = ORIG ;
|
|
||||||
int nCount = 0 ;
|
|
||||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
|
||||||
ptCen += ptP ;
|
|
||||||
++ nCount ;
|
|
||||||
}
|
|
||||||
ptCen /= nCount ;
|
|
||||||
Vector3d vtMove = ptCen - ORIG ;
|
|
||||||
// Compute a representative plane for the polygon (faccio il calcolo nel centro e poi traslo al contrario il piano)
|
|
||||||
PolygonPlane PolyPlane ;
|
PolygonPlane PolyPlane ;
|
||||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
||||||
PolyPlane.AddPoint( ptP - vtMove) ;
|
PolyPlane.AddPoint( ptP) ;
|
||||||
if ( ! PolyPlane.GetPlane( plPlane) || ! PolyPlane.GetArea( dArea)) {
|
if ( ! PolyPlane.GetPlane( plPlane) || ! PolyPlane.GetArea( dArea)) {
|
||||||
dArea = 0 ;
|
dArea = 0 ;
|
||||||
return IsFlat( plPlane, dToler) ;
|
return IsFlat( plPlane, dToler) ;
|
||||||
}
|
}
|
||||||
plPlane.Translate( vtMove) ;
|
|
||||||
// Sistemo il piano per l'offset utilizzato
|
|
||||||
// Test each vertex to see if it is farther from plane than allowed max distance
|
// Test each vertex to see if it is farther from plane than allowed max distance
|
||||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||||
double dDist = DistPointPlane( ptP, plPlane) ;
|
double dDist = ( ( ptP - ORIG) * plPlane.GetVersN()) - plPlane.GetDist() ;
|
||||||
if ( abs( dDist) > dToler)
|
if ( abs( dDist) > dToler)
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -652,13 +639,13 @@ PolyLine::GetAreaXY( double& dArea) const
|
|||||||
// verifico sia chiusa
|
// verifico sia chiusa
|
||||||
if ( ! IsClosed())
|
if ( ! IsClosed())
|
||||||
return false ;
|
return false ;
|
||||||
// calcolo l'area considerando solo XY (è la Z di Newell)
|
// calcolo l'area considerando solo XY (è la Z di Newell)
|
||||||
dArea = 0 ;
|
dArea = 0 ;
|
||||||
Point3d ptIni, ptFin ;
|
Point3d ptIni, ptFin ;
|
||||||
for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) {
|
for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) {
|
||||||
dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
|
dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
|
||||||
}
|
}
|
||||||
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
|
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
|
||||||
// significativa anche se sono coincidenti per le nostre tolleranze
|
// significativa anche se sono coincidenti per le nostre tolleranze
|
||||||
ptIni = ptFin ;
|
ptIni = ptFin ;
|
||||||
GetFirstPoint( ptFin) ;
|
GetFirstPoint( ptFin) ;
|
||||||
@@ -759,7 +746,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||||
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
||||||
if ( dMaxSqDist > dSqTol) {
|
if ( dMaxSqDist > dSqTol) {
|
||||||
// inserisco il punto
|
// inserisco il punto
|
||||||
@@ -798,11 +785,11 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
|||||||
vInd.push_back( 0) ;
|
vInd.push_back( 0) ;
|
||||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
||||||
return false ;
|
return false ;
|
||||||
vInd.push_back( int( vPtU.size()) - 1) ;
|
vInd.push_back( vPtU.size() - 1) ;
|
||||||
}
|
}
|
||||||
// altrimenti chiusa
|
// altrimenti chiusa
|
||||||
else {
|
else {
|
||||||
// cerco il punto più distante dal primo
|
// cerco il punto più distante dal primo
|
||||||
double dMaxDist = 0. ;
|
double dMaxDist = 0. ;
|
||||||
int nMaxInd = 0 ;
|
int nMaxInd = 0 ;
|
||||||
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
||||||
@@ -819,20 +806,12 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
|||||||
vInd.push_back( nMaxInd) ;
|
vInd.push_back( nMaxInd) ;
|
||||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
||||||
return false ;
|
return false ;
|
||||||
vInd.push_back( int( vPtU.size()) - 1) ;
|
vInd.push_back( vPtU.size() - 1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ordino in senso crescente
|
// ordino in senso crescente
|
||||||
sort( vInd.begin(), vInd.end()) ;
|
sort( vInd.begin(), vInd.end()) ;
|
||||||
|
|
||||||
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
|
|
||||||
if ( IsClosed() && vInd.size() >= 4) {
|
|
||||||
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[int(vInd.size())-2]].first).IsEpsilon( dToler)) {
|
|
||||||
vInd.erase( vInd.begin()) ;
|
|
||||||
vInd.back() = vInd.front() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rimetto in lista i soli punti rimasti
|
// rimetto in lista i soli punti rimasti
|
||||||
m_lUPoints.clear() ;
|
m_lUPoints.clear() ;
|
||||||
for ( auto Ind : vInd)
|
for ( auto Ind : vInd)
|
||||||
@@ -979,7 +958,7 @@ PolyLine::MyApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// non è stato eliminato alcunché
|
// non è stato eliminato alcunché
|
||||||
// ripristino la tolleranza corrente
|
// ripristino la tolleranza corrente
|
||||||
dCurrToler = dToler ;
|
dCurrToler = dToler ;
|
||||||
// avanzo il terzetto di uno step
|
// avanzo il terzetto di uno step
|
||||||
@@ -1020,7 +999,7 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
|
|||||||
bool
|
bool
|
||||||
PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||||
{
|
{
|
||||||
// ciclo i controlli finchè non ci sono rimozioni
|
// ciclo i controlli finchè non ci sono rimozioni
|
||||||
bool bRemoved = true ;
|
bool bRemoved = true ;
|
||||||
while ( bRemoved) {
|
while ( bRemoved) {
|
||||||
bRemoved = false ;
|
bRemoved = false ;
|
||||||
@@ -1048,7 +1027,7 @@ PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
|||||||
bRemoved = true ;
|
bRemoved = true ;
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
||||||
precP = currP ;
|
precP = currP ;
|
||||||
currP = nextP ;
|
currP = nextP ;
|
||||||
++ nextP ;
|
++ nextP ;
|
||||||
@@ -1075,7 +1054,7 @@ PolyLine::Invert( bool bInvertU)
|
|||||||
m_lUPoints.reverse() ;
|
m_lUPoints.reverse() ;
|
||||||
// se richiesto, inverto anche il parametro U
|
// se richiesto, inverto anche il parametro U
|
||||||
if ( bInvertU) {
|
if ( bInvertU) {
|
||||||
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
|
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
|
||||||
double dUfin = m_lUPoints.front().second ;
|
double dUfin = m_lUPoints.front().second ;
|
||||||
// ciclo su tutti gli elementi
|
// ciclo su tutti gli elementi
|
||||||
for ( auto& UPoint : m_lUPoints) {
|
for ( auto& UPoint : m_lUPoints) {
|
||||||
@@ -1085,35 +1064,6 @@ PolyLine::Invert( bool bInvertU)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
PolyLine::MyRemoveSamePoints( double dToler)
|
|
||||||
{
|
|
||||||
// elimino i punti consecutivi diventati coincidenti (almeno 2)
|
|
||||||
if ( m_lUPoints.size() < 2)
|
|
||||||
return true ;
|
|
||||||
// punto precedente
|
|
||||||
auto precP = m_lUPoints.begin() ;
|
|
||||||
// punto corrente
|
|
||||||
auto currP = next( precP) ;
|
|
||||||
// mentre esiste un corrente
|
|
||||||
while ( currP != m_lUPoints.end()) {
|
|
||||||
// se coincidono
|
|
||||||
if ( AreSamePointEpsilon( precP->first, currP->first, dToler)) {
|
|
||||||
// elimino il punto corrente
|
|
||||||
currP = m_lUPoints.erase( currP) ;
|
|
||||||
// il precedente rimane inalterato
|
|
||||||
}
|
|
||||||
// altrimenti da tenere
|
|
||||||
else {
|
|
||||||
// avanzo la coppia di uno step
|
|
||||||
precP = currP ;
|
|
||||||
++ currP ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
PolyLine::Flatten( double dZ)
|
PolyLine::Flatten( double dZ)
|
||||||
@@ -1122,39 +1072,31 @@ PolyLine::Flatten( double dZ)
|
|||||||
if ( m_lUPoints.empty())
|
if ( m_lUPoints.empty())
|
||||||
return true ;
|
return true ;
|
||||||
// ciclo su tutti gli elementi per portarli alla Z indicata
|
// ciclo su tutti gli elementi per portarli alla Z indicata
|
||||||
for ( auto& UPoint : m_lUPoints)
|
for ( auto& UPoint : m_lUPoints) {
|
||||||
UPoint.first.z = dZ ;
|
UPoint.first.z = dZ ;
|
||||||
// elimino i punti consecutivi diventati coincidenti
|
}
|
||||||
MyRemoveSamePoints() ;
|
// elimino i punti consecutivi diventati coincidenti (almeno 2)
|
||||||
return true ;
|
if ( m_lUPoints.size() < 2)
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
PolyLine::FlattenInAutoPlane( double dToler)
|
|
||||||
{
|
|
||||||
// verifico non sia vuota
|
|
||||||
if ( m_lUPoints.empty())
|
|
||||||
return true ;
|
return true ;
|
||||||
// recupero dati sulla planarità della polilinea
|
// punto precedente
|
||||||
int nRank ;
|
auto precP = m_lUPoints.begin() ;
|
||||||
Point3d ptCen ;
|
// punto corrente
|
||||||
Vector3d vtDir ;
|
auto currP = next( precP) ;
|
||||||
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
// mentre esiste un corrente
|
||||||
// se non planare entro la tolleranza, esco
|
while ( currP != m_lUPoints.end()) {
|
||||||
if ( ! bFlat)
|
// se coincidono
|
||||||
return false ;
|
if ( AreSamePointApprox( precP->first, currP->first)) {
|
||||||
// se punto o linea, non devo fare alcunché
|
// elimino il punto corrente
|
||||||
if ( nRank == 0 || nRank == 1)
|
currP = m_lUPoints.erase( currP) ;
|
||||||
return true ;
|
// il precedente rimane inalterato
|
||||||
// assegno il piano medio
|
}
|
||||||
Plane3d plPlane ;
|
// altrimenti da tenere
|
||||||
plPlane.Set( ptCen, vtDir) ;
|
else {
|
||||||
// proietto i punti su questo piano
|
// avanzo la coppia di uno step
|
||||||
for ( auto& UPoint : m_lUPoints)
|
precP = currP ;
|
||||||
UPoint.first = ProjectPointOnPlane( UPoint.first, plPlane) ;
|
++ currP ;
|
||||||
// elimino i punti consecutivi diventati coincidenti
|
}
|
||||||
MyRemoveSamePoints() ;
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,8 +1269,8 @@ PolyLine::GetMinAreaRectangleXY( Point3d& ptCen, Vector3d& vtAx, double& dLen, d
|
|||||||
bool
|
bool
|
||||||
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
||||||
{
|
{
|
||||||
// se vuota non faccio alcunché
|
// se vuota non faccio alcunché
|
||||||
if ( m_lUPoints.empty())
|
if ( m_lUPoints.size() == 0)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// determino le intersezioni dei lati con il piano
|
// determino le intersezioni dei lati con il piano
|
||||||
@@ -1429,7 +1371,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
return false ;
|
return false ;
|
||||||
// Riferimento alla lista dei punti
|
// Riferimento alla lista dei punti
|
||||||
PNTULIST& List = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
PNTULIST& List = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
double dMinSqDist = SQ_INFINITO ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
Point3d ptMinDist ;
|
Point3d ptMinDist ;
|
||||||
auto itMinDistEnd = List.end() ;
|
auto itMinDistEnd = List.end() ;
|
||||||
@@ -1447,7 +1389,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
}
|
}
|
||||||
// Determino tangente di riferimento
|
// Determino tangente di riferimento
|
||||||
Vector3d vtTang ;
|
Vector3d vtTang ;
|
||||||
// se minima distanza nell'estremo iniziale del segmento
|
// se minima distanza nell'estremo iniziale del segmento
|
||||||
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
||||||
// direzione del segmento
|
// direzione del segmento
|
||||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
@@ -1463,7 +1405,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
vtTang = vtPrevTg + vtCurrTg ;
|
vtTang = vtPrevTg + vtCurrTg ;
|
||||||
vtTang.Normalize() ;
|
vtTang.Normalize() ;
|
||||||
}
|
}
|
||||||
// se altrimenti minima distanza nell'estremo finale del segmento
|
// se altrimenti minima distanza nell'estremo finale del segmento
|
||||||
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
||||||
// direzione del segmento
|
// direzione del segmento
|
||||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
@@ -1479,7 +1421,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
vtTang = vtCurrTg + vtNextTg ;
|
vtTang = vtCurrTg + vtNextTg ;
|
||||||
vtTang.Normalize() ;
|
vtTang.Normalize() ;
|
||||||
}
|
}
|
||||||
// altrimenti minima distanza con l'interno
|
// altrimenti minima distanza con l'interno
|
||||||
else {
|
else {
|
||||||
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
}
|
}
|
||||||
@@ -1518,7 +1460,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol
|
|||||||
// assegno nuovo inizio
|
// assegno nuovo inizio
|
||||||
ptStart = ptEnd ;
|
ptStart = ptEnd ;
|
||||||
}
|
}
|
||||||
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
||||||
return ( dMinSqDist < dToler * dToler) ;
|
return ( dMinSqDist < dToler * dToler) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1531,7 +1473,7 @@ ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
|||||||
return false ;
|
return false ;
|
||||||
// Riferimento alla lista dei punti
|
// Riferimento alla lista dei punti
|
||||||
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
double dMinSqDist = SQ_INFINITO ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
auto itMinDistEnd = LoopList.end() ;
|
auto itMinDistEnd = LoopList.end() ;
|
||||||
auto itStart = LoopList.begin() ;
|
auto itStart = LoopList.begin() ;
|
||||||
@@ -1575,7 +1517,7 @@ SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler,
|
|||||||
return false ;
|
return false ;
|
||||||
// Riferimento alla lista dei punti
|
// Riferimento alla lista dei punti
|
||||||
const PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
const PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||||
double dMinSqDist = SQ_INFINITO ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
auto itMinDistEnd = LoopList.end() ;
|
auto itMinDistEnd = LoopList.end() ;
|
||||||
auto itStart = LoopList.begin() ;
|
auto itStart = LoopList.begin() ;
|
||||||
@@ -1614,9 +1556,8 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
int nPnt2 = PL2.GetPointNbr() ;
|
int nPnt2 = PL2.GetPointNbr() ;
|
||||||
if ( nPnt1 == 0 || nPnt2 == 0)
|
if ( nPnt1 == 0 || nPnt2 == 0)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// indica la presenza di punti interni in comune tra le due polylines
|
bCommonInternalPoints = false ; // indica la presenza di punti interni in comune tra le due polylines
|
||||||
bCommonInternalPoints = false ;
|
|
||||||
|
|
||||||
vPnt1.reserve( PL1.GetPointNbr()) ;
|
vPnt1.reserve( PL1.GetPointNbr()) ;
|
||||||
Point3d ptP1 ;
|
Point3d ptP1 ;
|
||||||
@@ -1640,6 +1581,10 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
int nLastJ = 0 ;
|
int nLastJ = 0 ;
|
||||||
vPnt1[0].second = 0 ;
|
vPnt1[0].second = 0 ;
|
||||||
|
|
||||||
|
double dFirstDist, dFirstParMinDist ;
|
||||||
|
DistPointPolyLine( vPnt1[0].first, PL2, dFirstDist, dFirstParMinDist) ;
|
||||||
|
int nFirstMinJ = ( int)( dFirstParMinDist + 0.5) ;
|
||||||
|
|
||||||
for ( int i = 1 ; i < nTotP1 ; ++ i) {
|
for ( int i = 1 ; i < nTotP1 ; ++ i) {
|
||||||
|
|
||||||
double dDist = INFINITO ;
|
double dDist = INFINITO ;
|
||||||
@@ -1648,7 +1593,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
// distanza del punto dal segmento della polilinea
|
// distanza del punto dal segmento della polilinea
|
||||||
DistPointLine PointLineDistCalc( vPnt1[i].first, vPnt2[j-1].first, vPnt2[j].first) ;
|
DistPointLine PointLineDistCalc( vPnt1[i].first, vPnt2[j-1].first, vPnt2[j].first) ;
|
||||||
double dPlDist ;
|
double dPlDist ;
|
||||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist) {
|
||||||
dDist = dPlDist ;
|
dDist = dPlDist ;
|
||||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||||
dMinDistPar += j - 1 ;
|
dMinDistPar += j - 1 ;
|
||||||
@@ -1656,11 +1601,15 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
}
|
}
|
||||||
int nMinJ = ( int)( dMinDistPar + 0.5) ;
|
int nMinJ = ( int)( dMinDistPar + 0.5) ;
|
||||||
|
|
||||||
|
// eventuale correzione per i primi punti ( da forzare nel vertice 0)
|
||||||
|
if ( nLastJ == 0 && nFirstMinJ > 0.5 * nTotP2 && nMinJ >= nFirstMinJ)
|
||||||
|
nMinJ = 0 ;
|
||||||
|
|
||||||
if ( nMinJ < nLastJ)
|
if ( nMinJ < nLastJ)
|
||||||
nMinJ = nLastJ ;
|
nMinJ = nLastJ ;
|
||||||
|
|
||||||
// verifica se è un punto interno in comune con l'altra polyline
|
// verifica se è un punto interno in comune con l'altra polyline
|
||||||
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||||
bCommonInternalPoints = true ;
|
bCommonInternalPoints = true ;
|
||||||
|
|
||||||
vPnt1[i].second = nMinJ ;
|
vPnt1[i].second = nMinJ ;
|
||||||
@@ -1670,6 +1619,9 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
// calcoli per seconda curva
|
// calcoli per seconda curva
|
||||||
int nLastI = 0 ;
|
int nLastI = 0 ;
|
||||||
vPnt2[0].second = 0 ;
|
vPnt2[0].second = 0 ;
|
||||||
|
|
||||||
|
DistPointPolyLine( vPnt2[0].first, PL1, dFirstDist, dFirstParMinDist) ;
|
||||||
|
int nFirstMinI = ( int)( dFirstParMinDist + 0.5) ;
|
||||||
|
|
||||||
for ( int j = 1 ; j < nTotP2 ; ++ j) {
|
for ( int j = 1 ; j < nTotP2 ; ++ j) {
|
||||||
|
|
||||||
@@ -1679,7 +1631,8 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
// distanza del punto dal segmento della polilinea
|
// distanza del punto dal segmento della polilinea
|
||||||
DistPointLine PointLineDistCalc( vPnt2[j].first, vPnt1[i-1].first, vPnt1[i].first) ;
|
DistPointLine PointLineDistCalc( vPnt2[j].first, vPnt1[i-1].first, vPnt1[i].first) ;
|
||||||
double dPlDist ;
|
double dPlDist ;
|
||||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
PointLineDistCalc.GetDist( dPlDist) ;
|
||||||
|
if ( dPlDist < dDist) {
|
||||||
dDist = dPlDist ;
|
dDist = dPlDist ;
|
||||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||||
dMinDistPar += i - 1 ;
|
dMinDistPar += i - 1 ;
|
||||||
@@ -1687,331 +1640,19 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
}
|
}
|
||||||
int nMinI = ( int)( dMinDistPar + 0.5) ;
|
int nMinI = ( int)( dMinDistPar + 0.5) ;
|
||||||
|
|
||||||
|
// eventuale correzione per primi punti
|
||||||
|
if ( nLastI == 0 && nFirstMinI > 0.5 * nTotP1 && nMinI >= nFirstMinI)
|
||||||
|
nMinI = 0 ;
|
||||||
|
|
||||||
if ( nMinI < nLastI)
|
if ( nMinI < nLastI)
|
||||||
nMinI = nLastI ;
|
nMinI = nLastI ;
|
||||||
|
|
||||||
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||||
bCommonInternalPoints = true ;
|
bCommonInternalPoints = true ;
|
||||||
|
|
||||||
vPnt2[j].second = nMinI ;
|
vPnt2[j].second = nMinI ;
|
||||||
nLastI = nMinI ;
|
nLastI = nMinI ;
|
||||||
}
|
}
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
MatchPolyLinesAddingPoints( const PolyLine& PL1, const PolyLine& PL2, int nType, PNTIVECTOR& vPnt1, PNTIVECTOR& vPnt2)
|
|
||||||
{
|
|
||||||
// prima trovo le associazioni senza aggiunte di punti
|
|
||||||
Point3d ptP2 ;
|
|
||||||
CurveComposite cc1, cc2 ;
|
|
||||||
cc1.FromPolyLine( PL1) ;
|
|
||||||
cc2.FromPolyLine( PL2) ;
|
|
||||||
int nPnt1 = PL1.GetPointNbr() ;
|
|
||||||
int nPnt2 = PL2.GetPointNbr() ;
|
|
||||||
vector<POINTU> vMatch2 ;
|
|
||||||
PL2.GetFirstPoint( ptP2) ;
|
|
||||||
while ( PL2.GetNextPoint( ptP2, true)) {
|
|
||||||
DistPointCurve dpc( ptP2, cc1, false) ;
|
|
||||||
int nFlag = 0 ;
|
|
||||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
|
||||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
|
||||||
vMatch2.emplace_back( ptJoint, dParam) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nAtStart2 = 0 ; // match ripetuti dalla curva U0 allo start della curva U1
|
|
||||||
int nAtEnd2 = 0 ;
|
|
||||||
Point3d ptP1 ; PL1.GetFirstPoint( ptP1) ;
|
|
||||||
int c = 0 ;
|
|
||||||
int nRep1 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1
|
|
||||||
int nRep2 = 0 ;
|
|
||||||
double dLastParamMatch = 0 ;
|
|
||||||
Point3d ptLastPointMatch = ptP1 ;
|
|
||||||
BOOLVECTOR vbRep1( nPnt1) ;
|
|
||||||
INTVECTOR vnAddedOrNextIsRep1 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
|
|
||||||
DBLVECTOR vdSplit1 ;
|
|
||||||
DBLVECTOR vdMatch1 ;
|
|
||||||
fill( vbRep1.begin(), vbRep1.end(), false) ;
|
|
||||||
while ( PL1.GetNextPoint( ptP1, true)) {
|
|
||||||
// devo salvarmi se matcho più punti con lo start o l'end della curva totale
|
|
||||||
DistPointCurve dpc( ptP1, cc2, false) ;
|
|
||||||
int nFlag = 0 ;
|
|
||||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
|
||||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
|
||||||
vdMatch1.push_back( dParam) ;
|
|
||||||
if ( dParam < EPS_SMALL ) {
|
|
||||||
++nAtStart2 ;
|
|
||||||
vbRep1[c] = true ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
else if ( dParam > nPnt2 - EPS_SMALL ) {
|
|
||||||
vbRep1[c] = nAtEnd2 == 0 ? false : true ;
|
|
||||||
vbRep1.back() = true ;
|
|
||||||
++ nAtEnd2 ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
|
|
||||||
dParam = dLastParamMatch ;
|
|
||||||
vbRep1[c] = true ;
|
|
||||||
++ nRep1 ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dLastParamMatch = dParam ;
|
|
||||||
ptLastPointMatch = ptJoint ;
|
|
||||||
// se sono già troppo vicino ad un split esistente allora non faccio nulla
|
|
||||||
if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
vdSplit1.push_back( dParam) ;
|
|
||||||
// verifico se ho un match per questo punto
|
|
||||||
// in tal caso vuol dire che sto creando una ripetizione nRep1
|
|
||||||
int nCase = 0 ;
|
|
||||||
for ( int j = 0 ; j < int( vMatch2.size()) ; ++j) {
|
|
||||||
if ( abs(vMatch2[j].second - (c + 1)) < EPS_SMALL) {
|
|
||||||
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
|
|
||||||
bool bFoundMatch = false ;
|
|
||||||
for ( int z = int( vMatch2[j].second) ; z < int( vdMatch1.size()) ; ++z) {
|
|
||||||
if ( abs( vdMatch1[z] - ( j + 1 )) < EPS_SMALL ) {
|
|
||||||
bFoundMatch = true ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! bFoundMatch) {
|
|
||||||
++ nRep2 ;
|
|
||||||
// capisco se il punto è rep o se lo è il suo successivo
|
|
||||||
if ( j + 1 < dParam)
|
|
||||||
nCase = 1 ;
|
|
||||||
else
|
|
||||||
nCase = 2 ;
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vnAddedOrNextIsRep1.push_back( nCase) ;
|
|
||||||
}
|
|
||||||
++c ;
|
|
||||||
}
|
|
||||||
int nAtStart1 = 0 ;
|
|
||||||
int nAtEnd1 = 0 ;
|
|
||||||
PL2.GetFirstPoint( ptP2) ;
|
|
||||||
c = 0 ;
|
|
||||||
dLastParamMatch = 0 ;
|
|
||||||
ptLastPointMatch = ptP2 ;
|
|
||||||
INTVECTOR vnAddedOrNextIsRep2 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
|
|
||||||
DBLVECTOR vdSplit2 ;
|
|
||||||
BOOLVECTOR vbRep2( nPnt2) ;
|
|
||||||
fill( vbRep2.begin(), vbRep2.end(), false) ;
|
|
||||||
while ( PL2.GetNextPoint( ptP2, true)) {
|
|
||||||
DistPointCurve dpc( ptP2, cc1, false) ;
|
|
||||||
int nFlag = 0 ;
|
|
||||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
|
||||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
|
||||||
if ( dParam < EPS_SMALL ) {
|
|
||||||
++nAtStart1 ;
|
|
||||||
vbRep2[c] = true ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
else if ( dParam > nPnt1 - EPS_SMALL ) {
|
|
||||||
vbRep2[c] = ( nAtEnd1 == 0 ? false : true) ;
|
|
||||||
vbRep2.back() = true ;
|
|
||||||
++ nAtEnd1 ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
|
|
||||||
dParam = dLastParamMatch ;
|
|
||||||
vbRep2[c] = true ;
|
|
||||||
++ nRep2 ;
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dLastParamMatch = dParam ;
|
|
||||||
ptLastPointMatch = ptJoint ;
|
|
||||||
// se sono troppo vicino ad uno split esistente allora non faccio nulla
|
|
||||||
if ( abs( dParam - round( dParam)) < 100 * EPS_PARAM) {
|
|
||||||
++c ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
vdSplit2.push_back( dParam) ;
|
|
||||||
// verifico se ho un match per questo punto
|
|
||||||
// in tal caso vuol dire che sto creando una ripetizione nRep0
|
|
||||||
int nCase = 0 ;
|
|
||||||
for ( int j = 0 ; j < int( vdMatch1.size()) ; ++j) {
|
|
||||||
if ( abs( vdMatch1[j] - (c + 1)) < EPS_SMALL) {
|
|
||||||
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
|
|
||||||
bool bFoundMatch = false ;
|
|
||||||
for ( int z = int( vdMatch1[j]) ; z < int( vMatch2.size()) ; ++z) {
|
|
||||||
if ( abs( vMatch2[z].second - ( j + 1 )) < EPS_SMALL) {
|
|
||||||
bFoundMatch = true ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! bFoundMatch) {
|
|
||||||
++nRep1 ;
|
|
||||||
// capisco se il punto è rep o se lo è il suo successivo
|
|
||||||
if ( j + 1 < dParam)
|
|
||||||
nCase = 1 ;
|
|
||||||
else
|
|
||||||
nCase = 2 ;
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vnAddedOrNextIsRep2.push_back( nCase) ;
|
|
||||||
}
|
|
||||||
++c ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
|
|
||||||
int nUnit = 0 ;
|
|
||||||
if ( ! vdSplit1.empty())
|
|
||||||
nUnit = int( vdSplit1.back()) ;
|
|
||||||
for ( int z = int( vdSplit1.size()) - 1 ; z >= 0 ; --z) {
|
|
||||||
double dSplit = vdSplit1[z] ;
|
|
||||||
int nSplit = int( dSplit) ;
|
|
||||||
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
|
|
||||||
// riscalare
|
|
||||||
if ( nSplit == nUnit && z < int( vdSplit1.size()) - 1) {
|
|
||||||
dSplit = nSplit + ( dSplit - nSplit) / ( vdSplit1[z+1] - nSplit) ;
|
|
||||||
}
|
|
||||||
nUnit = nSplit ;
|
|
||||||
cc2.AddJoint( dSplit) ;
|
|
||||||
switch ( vnAddedOrNextIsRep1[z]) {
|
|
||||||
case 0 :
|
|
||||||
if ( vbRep2[nSplit])
|
|
||||||
++ nRep2 ;
|
|
||||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
|
||||||
vbRep2.insert( vbRep2.begin() + nSplit, vbRep2[nSplit]) ;
|
|
||||||
break ;
|
|
||||||
case 1 :
|
|
||||||
vbRep2.insert( vbRep2.begin() + nSplit, true) ;
|
|
||||||
break ;
|
|
||||||
case 2 :
|
|
||||||
if ( vbRep2[nSplit])
|
|
||||||
--nRep2 ;
|
|
||||||
else
|
|
||||||
vbRep2[nSplit] = true ;
|
|
||||||
vbRep2.insert( vbRep2.begin() + nSplit, false) ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( ! vdSplit2.empty())
|
|
||||||
nUnit = int( vdSplit2.back()) ;
|
|
||||||
for ( int z = int( vdSplit2.size()) - 1 ; z >= 0 ; --z) {
|
|
||||||
double dSplit = vdSplit2[z] ;
|
|
||||||
int nSplit = int( dSplit) ;
|
|
||||||
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
|
|
||||||
// riscalare
|
|
||||||
if ( nSplit == nUnit && z < int( vdSplit2.size()) - 1) {
|
|
||||||
dSplit = nSplit + ( dSplit - nSplit) / (vdSplit2[z+1] - nSplit) ;
|
|
||||||
}
|
|
||||||
nUnit = nSplit ;
|
|
||||||
cc1.AddJoint( dSplit) ;
|
|
||||||
switch ( vnAddedOrNextIsRep2[z]) {
|
|
||||||
case 0 :
|
|
||||||
if ( vbRep1[nSplit])
|
|
||||||
++ nRep1 ;
|
|
||||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
|
||||||
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ;
|
|
||||||
break ;
|
|
||||||
case 1 :
|
|
||||||
vbRep1.insert( vbRep1.begin() + nSplit, true) ;
|
|
||||||
break ;
|
|
||||||
case 2 :
|
|
||||||
if ( vbRep1[nSplit])
|
|
||||||
-- nRep1 ;
|
|
||||||
else
|
|
||||||
vbRep1[nSplit] = true ;
|
|
||||||
vbRep1.insert( vbRep1.begin() + nSplit, false) ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nPnt1 = cc1.GetCurveCount() ;
|
|
||||||
nPnt2 = cc2.GetCurveCount() ;
|
|
||||||
//aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true
|
|
||||||
int nAddedSpan = 0 ;
|
|
||||||
int nCrv1 = 0 ;
|
|
||||||
int nCrv2 = 0 ;
|
|
||||||
while ( nAddedSpan < nPnt1 + nAtStart1 + nAtEnd1 + nRep2) {
|
|
||||||
if ( nCrv1 >= nPnt1)
|
|
||||||
nCrv1 = nPnt1 - 1 ;
|
|
||||||
if ( nCrv2 >= nPnt2)
|
|
||||||
nCrv2 = nPnt2 - 1 ;
|
|
||||||
bool bRep1 = vbRep1[nCrv1] ;
|
|
||||||
bool bRep2 = vbRep2[nCrv2] ;
|
|
||||||
if ( bRep1 && bRep2) {
|
|
||||||
vbRep1[nCrv1] = false ;
|
|
||||||
bRep1 = false ;
|
|
||||||
vbRep2[nCrv2] = false ;
|
|
||||||
bRep2 = false ;
|
|
||||||
-- nRep1 ;
|
|
||||||
-- nRep2 ;
|
|
||||||
}
|
|
||||||
if ( ! bRep1 || nCrv2 == nPnt2 - 1)
|
|
||||||
++ nCrv2 ;
|
|
||||||
if ( ! bRep2 || nCrv1 == nPnt1 - 1)
|
|
||||||
++ nCrv1 ;
|
|
||||||
++ nAddedSpan ;
|
|
||||||
}
|
|
||||||
// se non sono arrivato all'ultima curva su U0 o U1 vuol dire che ho creato delle ripetizioni che non ho contato prima
|
|
||||||
if ( nCrv2 < nPnt2) {
|
|
||||||
nRep2 += nPnt2 - nCrv2 ;
|
|
||||||
for ( int z = int( vbRep2.size()) - 1 ; z >= nCrv2 ; --z)
|
|
||||||
vbRep2[z] = true ;
|
|
||||||
}
|
|
||||||
if( nCrv1 < nPnt1) {
|
|
||||||
nRep1 += nPnt1 - nCrv1 ;
|
|
||||||
for ( int z = int( vbRep1.size()) - 1 ; z >= nCrv1 ; --z)
|
|
||||||
vbRep1[z] = true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trovo il numero di span che dovrà avere la superficie
|
|
||||||
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
|
|
||||||
int nPnt = nPnt1 + nAtStart1 + nAtEnd1 + nRep2 ;
|
|
||||||
|
|
||||||
if ( nPnt != nPnt2 + nAtStart2 + nAtEnd2 + nRep1)
|
|
||||||
LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ;
|
|
||||||
|
|
||||||
// aggiungo i punti di controllo scorrendo in contemporanea le due curve
|
|
||||||
nAddedSpan = 0 ;
|
|
||||||
nCrv1 = 0 ;
|
|
||||||
nCrv2 = 0 ;
|
|
||||||
bool bLast1 = false ;
|
|
||||||
bool bLast2 = false ;
|
|
||||||
while ( nAddedSpan < nPnt) {
|
|
||||||
if ( nCrv1 >= nPnt1) {
|
|
||||||
nCrv1 = nPnt1 - 1 ;
|
|
||||||
bLast1 = true ;
|
|
||||||
}
|
|
||||||
if ( nCrv2 >= nPnt2) {
|
|
||||||
nCrv2 = nPnt2 - 1 ;
|
|
||||||
bLast2 = true ;
|
|
||||||
}
|
|
||||||
bool bRep1 = vbRep1[nCrv1] ;
|
|
||||||
bool bRep2 = vbRep2[nCrv2] ;
|
|
||||||
const ICurve* pSubCrv1 = cc1.GetCurve( nCrv1) ;
|
|
||||||
Point3d ptStart1 ; pSubCrv1->GetStartPoint( ptStart1) ;
|
|
||||||
vPnt1.emplace_back( ptStart1, nAddedSpan) ;
|
|
||||||
const ICurve* pSubCrv2 = cc2.GetCurve( nCrv2) ;
|
|
||||||
Point3d ptStart2 ; pSubCrv2->GetStartPoint( ptStart2) ;
|
|
||||||
vPnt2.emplace_back( ptStart2, nAddedSpan) ;
|
|
||||||
if ( ! bRep2)
|
|
||||||
++ nCrv1 ;
|
|
||||||
if ( ! bRep1)
|
|
||||||
++ nCrv2 ;
|
|
||||||
++ nAddedSpan ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -150,18 +150,12 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
Vector3d vtN = pgFacet.GetVersN() ;
|
Vector3d vtN = pgFacet.GetVersN() ;
|
||||||
PolyLine PL = pgFacet.GetPolyLine() ;
|
PolyLine PL = pgFacet.GetPolyLine() ;
|
||||||
|
|
||||||
// calcolo elevazione massima del contorno della faccia e nel suo centro
|
// calcolo elevazione massima del contorno della faccia
|
||||||
const double RAY_LEN = 100000 ;
|
const double RAY_LEN = 100000 ;
|
||||||
dElev = 0 ;
|
dElev = 0 ;
|
||||||
PNTVECTOR vptP ; vptP.reserve( PL.GetPointNbr()) ;
|
|
||||||
Point3d ptP ;
|
Point3d ptP ;
|
||||||
bool bFound = PL.GetFirstPoint( ptP) ;
|
bool bFound = PL.GetFirstPoint( ptP) ;
|
||||||
while ( bFound) {
|
while ( bFound) {
|
||||||
vptP.push_back( ptP) ;
|
|
||||||
bFound = PL.GetNextPoint( ptP, true) ;
|
|
||||||
}
|
|
||||||
vptP.push_back( ptCen) ;
|
|
||||||
for ( const Point3d& ptP : vptP) {
|
|
||||||
ILSIVECTOR vInters ;
|
ILSIVECTOR vInters ;
|
||||||
IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
|
IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
|
||||||
for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
|
||||||
@@ -177,6 +171,7 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
|
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
dElev = max( dElev, Inters.dU2) ;
|
dElev = max( dElev, Inters.dU2) ;
|
||||||
}
|
}
|
||||||
|
bFound = PL.GetNextPoint( ptP, true) ;
|
||||||
}
|
}
|
||||||
// calcolo elevazione massima degli eventuali spigoli (e vertici) della superficie chiusa dalla parte positiva della faccia e che cadono in essa
|
// calcolo elevazione massima degli eventuali spigoli (e vertici) della superficie chiusa dalla parte positiva della faccia e che cadono in essa
|
||||||
int nEdgeCnt = CldStm.GetEdgeCount() ;
|
int nEdgeCnt = CldStm.GetEdgeCount() ;
|
||||||
|
|||||||
+5
-5
@@ -19,10 +19,10 @@
|
|||||||
void
|
void
|
||||||
PolygonPlane::AddPoint( const Point3d& ptP)
|
PolygonPlane::AddPoint( const Point3d& ptP)
|
||||||
{
|
{
|
||||||
// se è il primo punto (parto da -1 perchè verrà contato alla chiusura)
|
// se è il primo punto (parto da -1 perchè verrà contato alla chiusura)
|
||||||
if ( m_nPntNbr == -1) {
|
if ( m_nPntNbr == -1) {
|
||||||
// inizializzazioni
|
// inizializzazioni
|
||||||
m_dLenN = -1 ;
|
m_dLenN = 0 ;
|
||||||
m_vtN = V_NULL ;
|
m_vtN = V_NULL ;
|
||||||
m_ptMid = ORIG ;
|
m_ptMid = ORIG ;
|
||||||
m_dSXy = 0 ; m_dSXz = 0 ;
|
m_dSXy = 0 ; m_dSXz = 0 ;
|
||||||
@@ -60,16 +60,16 @@ PolygonPlane::AddPoint( const Point3d& ptP)
|
|||||||
bool
|
bool
|
||||||
PolygonPlane::Finalize( void)
|
PolygonPlane::Finalize( void)
|
||||||
{
|
{
|
||||||
// almeno 3 punti (il triangolo è il poligono con minimo numero di lati)
|
// almeno 3 punti (il triangolo è il poligono con minimo numero di lati)
|
||||||
if ( m_nPntNbr + 1 < 3)
|
if ( m_nPntNbr + 1 < 3)
|
||||||
return false ;
|
return false ;
|
||||||
// se il poligono non è stato chiuso, aggiungo calcolo per ultimo lato
|
// se il poligono non è stato chiuso, aggiungo calcolo per ultimo lato
|
||||||
if ( ! AreSamePointExact( m_ptFirst, m_ptLast)) {
|
if ( ! AreSamePointExact( m_ptFirst, m_ptLast)) {
|
||||||
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
||||||
AddPoint( m_ptFirst) ;
|
AddPoint( m_ptFirst) ;
|
||||||
}
|
}
|
||||||
// se non effettuato, eseguo il calcolo finale
|
// se non effettuato, eseguo il calcolo finale
|
||||||
if ( m_dLenN < 0) {
|
if ( m_dLenN < EPS_SMALL) {
|
||||||
// lunghezza della normale (doppio dell'area del poligono)
|
// lunghezza della normale (doppio dell'area del poligono)
|
||||||
m_dLenN = m_vtN.Len() ;
|
m_dLenN = m_vtN.Len() ;
|
||||||
if ( m_dLenN < SQ_EPS_SMALL)
|
if ( m_dLenN < SQ_EPS_SMALL)
|
||||||
|
|||||||
@@ -1,915 +0,0 @@
|
|||||||
//----------------------------------------------------------------------------
|
|
||||||
// EgalTech 2023-2025
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// File : ProjectCurveSurfTm.cpp Data : 29.08.25 Versione : 2.7h2
|
|
||||||
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Modifiche : 31.08.23 DS Creazione modulo.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//--------------------------- 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/EGkIntersPlanePlane.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
||||||
#include "/EgtDev/Include/EGkProjectCurveSurf.h"
|
|
||||||
|
|
||||||
using namespace std ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Angolo limite tra normale al triangolo e direzione di proiezione 89°
|
|
||||||
const double COS_ANG_LIM = 0.0175 ;
|
|
||||||
// Angolo massimo tra normali per effettuare bisezione su spigolo
|
|
||||||
const double COS_ANG_MAX_CORNER = 0.8660 ;
|
|
||||||
// Tipologia di punto
|
|
||||||
const int P5AX_TO_DELETE = -1 ; // da cancellare
|
|
||||||
const int P5AX_OUT = 0 ; // aggiunto prima di inizio o dopo fine
|
|
||||||
const int P5AX_STD = 1 ; // standard
|
|
||||||
const int P5AX_CVEX = 2 ; // su angolo convesso
|
|
||||||
const int P5AX_CONC = 3 ; // in angolo concavo
|
|
||||||
const int P5AX_BEFORE_CONC = 4 ; // adiacente ad angolo concavo
|
|
||||||
const int P5AX_AFTER_CONC = 5 ; // adiacente ad angolo concavo
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static double
|
|
||||||
GetSurfBezierTol( double dLinTol)
|
|
||||||
{
|
|
||||||
return max( dLinTol / 10, EPS_SMALL) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
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& vPt5ax, double dLinTol, double dMaxSegmLen, bool bTestDir)
|
|
||||||
{
|
|
||||||
// Parametri di riferimento
|
|
||||||
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
|
||||||
double dSqTol = dLinTol * dLinTol ;
|
|
||||||
const double LENREF = 200 ;
|
|
||||||
double dCosAngLim = 1 - dSqTol / ( 2 * LENREF * LENREF) ;
|
|
||||||
// Cerco gli angoli interni e marco opportunamente i punti nelle vicinanze fino ai limiti prima e dopo
|
|
||||||
int nInd = 0 ;
|
|
||||||
while ( nInd < int( vPt5ax.size())) {
|
|
||||||
if ( vPt5ax[nInd].nFlag == P5AX_CONC) {
|
|
||||||
// analizzo i punti appena precedenti
|
|
||||||
int nIpv = nInd - 1 ;
|
|
||||||
while ( nIpv >= 0) {
|
|
||||||
double dSqLen = SqDist( vPt5ax[nInd].ptP, vPt5ax[nIpv].ptP) ;
|
|
||||||
if ( dSqLen < dSqMaxLen)
|
|
||||||
vPt5ax[nIpv].nFlag = P5AX_TO_DELETE ;
|
|
||||||
else {
|
|
||||||
vPt5ax[nIpv].nFlag = P5AX_BEFORE_CONC ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
-- nIpv ;
|
|
||||||
}
|
|
||||||
// analizzo i punti appena successivi
|
|
||||||
int nInx = nInd + 1 ;
|
|
||||||
while ( nInx < int( vPt5ax.size())) {
|
|
||||||
double dSqLen = SqDist( vPt5ax[nInd].ptP, vPt5ax[nInx].ptP) ;
|
|
||||||
if ( dSqLen < dSqMaxLen)
|
|
||||||
vPt5ax[nInx].nFlag = P5AX_TO_DELETE ;
|
|
||||||
else {
|
|
||||||
vPt5ax[nInx].nFlag = P5AX_AFTER_CONC ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
++ nInx ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++ nInd ;
|
|
||||||
}
|
|
||||||
// Rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
|
||||||
int nCnt = 0 ;
|
|
||||||
int nPrec = 0 ;
|
|
||||||
int nCurr = 1 ;
|
|
||||||
int nNext = 2 ;
|
|
||||||
while ( nNext < int( vPt5ax.size())) {
|
|
||||||
bool bRemove = false ;
|
|
||||||
// lunghezza del segmento che unisce gli adiacenti
|
|
||||||
double dSqLen = SqDist( vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP) ;
|
|
||||||
// se rimovibile (Flag standard) e lunghezza inferiore al massimo, passo agli altri controlli
|
|
||||||
if ( vPt5ax[nCurr].nFlag == P5AX_STD && dSqLen <= dSqMaxLen) {
|
|
||||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
|
||||||
DistPointLine dPL( vPt5ax[nCurr].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP) ;
|
|
||||||
double dSqDist ;
|
|
||||||
// se distanza inferiore a tolleranza lineare
|
|
||||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
|
||||||
// verifico se errore angolare inferiore a limite
|
|
||||||
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
|
||||||
if ( bTestDir) {
|
|
||||||
Vector3d vtNew = Media( vPt5ax[nPrec].vtDir1, vPt5ax[nNext].vtDir1, dPar) ;
|
|
||||||
if ( vtNew.Normalize() && vtNew * vPt5ax[nCurr].vtDir1 > dCosAngLim)
|
|
||||||
bRemove = true ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Vector3d vtNew = Media( vPt5ax[nPrec].vtDir2, vPt5ax[nNext].vtDir2, dPar) ;
|
|
||||||
if ( vtNew.Normalize() && vtNew * vPt5ax[nCurr].vtDir2 > dCosAngLim)
|
|
||||||
bRemove = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se da eliminare
|
|
||||||
if ( bRemove) {
|
|
||||||
// dichiaro da eliminare il punto
|
|
||||||
vPt5ax[nCurr].nFlag = P5AX_TO_DELETE ;
|
|
||||||
// avanzo con corrente e successivo
|
|
||||||
nCurr = nNext ;
|
|
||||||
++ nNext ;
|
|
||||||
}
|
|
||||||
// altrimenti da tenere
|
|
||||||
else {
|
|
||||||
// avanzo il terzetto di uno step
|
|
||||||
nPrec = nCurr ;
|
|
||||||
nCurr = nNext ;
|
|
||||||
++ nNext ;
|
|
||||||
// incremento contatore dei punti conservati
|
|
||||||
++ nCnt ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copio i punti da conservare in un vettore temporaneo
|
|
||||||
PNT5AXVECTOR vMyPt5ax ;
|
|
||||||
vMyPt5ax.reserve( nCnt) ;
|
|
||||||
for ( const auto& Pt5ax : vPt5ax) {
|
|
||||||
if ( Pt5ax.nFlag != P5AX_TO_DELETE)
|
|
||||||
vMyPt5ax.emplace_back( Pt5ax) ;
|
|
||||||
}
|
|
||||||
// scambio i due vettori
|
|
||||||
vPt5ax.swap( vMyPt5ax) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- vettore di oggetti intersezione massiva rette parallele SurfTM --------
|
|
||||||
typedef std::vector<IntersParLinesSurfTm*> INTPARLINESTMPVECTOR ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static bool
|
|
||||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const Frame3d& frRefLine, const INTPARLINESTMPVECTOR& vpIntPLSTM,
|
|
||||||
double dPar, Point5ax& Pt5ax)
|
|
||||||
{
|
|
||||||
// intersezione retta di proiezione con superfici (conservo l'intersezione più alta)
|
|
||||||
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
|
||||||
int nInd = -1 ;
|
|
||||||
IntLinStmInfo IntRes ;
|
|
||||||
for ( int i = 0 ; i < int( vpIntPLSTM.size()) ; ++ i) {
|
|
||||||
ILSIVECTOR vIntRes ;
|
|
||||||
if ( vpIntPLSTM[i]->GetInters( ptL, 1, 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)
|
|
||||||
--nI ;
|
|
||||||
// se trovata
|
|
||||||
if ( nI >= 0) {
|
|
||||||
if ( nInd < 0) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
|
||||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
|
||||||
if ( dU > dUref) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se trovata
|
|
||||||
if ( nInd >= 0) {
|
|
||||||
// calcolo il punto
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
|
||||||
ptInt = IntRes.ptI2 ;
|
|
||||||
else
|
|
||||||
ptInt = IntRes.ptI ;
|
|
||||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
||||||
Triangle3dEx trTria ;
|
|
||||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
|
||||||
return false ;
|
|
||||||
Vector3d vtN ;
|
|
||||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
||||||
vtN = trTria.GetN() ;
|
|
||||||
// assegno valori al punto 5assi
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = vtN ;
|
|
||||||
Pt5ax.vtDir2 = frRefLine.VersZ() ;
|
|
||||||
Pt5ax.dPar = dPar ;
|
|
||||||
Pt5ax.nFlag = P5AX_STD ;
|
|
||||||
// ritorno con successo
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const Vector3d& vtDir,
|
|
||||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
|
||||||
{
|
|
||||||
// sistemazioni per tipo di superficie
|
|
||||||
CISRFTMPVECTOR vpSurfTm ;
|
|
||||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
|
||||||
const SurfTriMesh* pSurfTm = nullptr ;
|
|
||||||
switch ( vpSurf[i]->GetType()) {
|
|
||||||
case SRF_TRIMESH :
|
|
||||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
|
||||||
break ;
|
|
||||||
case SRF_BEZIER :
|
|
||||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
|
||||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
|
||||||
} break ;
|
|
||||||
case SRF_FLATRGN :
|
|
||||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
|
||||||
break ;
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ( pSurfTm == nullptr)
|
|
||||||
return false ;
|
|
||||||
vpSurfTm.emplace_back( pSurfTm) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// controllo le tolleranze
|
|
||||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
||||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
||||||
// approssimo la curva con una polilinea alla massima risoluzione
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
|
||||||
return false ;
|
|
||||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
|
||||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// Oggetti per calcolo massivo intersezioni tra linee di proiezione e superfici
|
|
||||||
Frame3d frRefLine ;
|
|
||||||
if ( ! frRefLine.Set( ORIG, vtDir))
|
|
||||||
return false ;
|
|
||||||
INTPARLINESTMPVECTOR vpIntPLSTM ; vpIntPLSTM.reserve( vpSurfTm.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vpSurfTm.size()) ; ++ i) {
|
|
||||||
IntersParLinesSurfTm* pIntPLSTM = new IntersParLinesSurfTm( frRefLine, *vpSurfTm[i]) ;
|
|
||||||
if ( pIntPLSTM == nullptr) {
|
|
||||||
for ( int j = 0 ; j < int( vpIntPLSTM.size()) ; ++ j)
|
|
||||||
delete vpIntPLSTM[j] ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
vpIntPLSTM.emplace_back( pIntPLSTM) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
|
||||||
vPt5ax.clear() ;
|
|
||||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
|
||||||
|
|
||||||
// proietto i punti della polilinea sulla superficie
|
|
||||||
double dPar ;
|
|
||||||
Point3d ptP ;
|
|
||||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
|
||||||
while ( bFound) {
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, frRefLine, vpIntPLSTM, dPar, Pt5ax))
|
|
||||||
vPt5ax.emplace_back( Pt5ax) ;
|
|
||||||
// passo al successivo
|
|
||||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Libero oggetti per calcolo massivo
|
|
||||||
for ( int i = 0 ; i < int( vpIntPLSTM.size()) ; ++ i)
|
|
||||||
delete vpIntPLSTM[i] ;
|
|
||||||
|
|
||||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
|
||||||
if ( bSharpEdges) {
|
|
||||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
|
||||||
// precedente
|
|
||||||
int j = i - 1 ;
|
|
||||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
|
||||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
|
||||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
|
||||||
// intersezione tra le due facce
|
|
||||||
Plane3d plPlane1 ; plPlane1.Set( vPt5ax[j].ptP, vPt5ax[j].vtDir1) ;
|
|
||||||
Plane3d plPlane2 ; plPlane2.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir1) ;
|
|
||||||
Point3d ptEdge ; Vector3d vtEdge ;
|
|
||||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptEdge, vtEdge) == IPPT_YES) {
|
|
||||||
Plane3d plPlane3 ; plPlane3.Set( vPt5ax[i].ptP, ( vPt5ax[i].ptP - vPt5ax[j].ptP) ^ vtDir) ;
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntersLinePlane( ptEdge, vtEdge, 1, plPlane3, ptInt, false) == ILPT_YES) {
|
|
||||||
// verifico se spigolo convesso o concavo
|
|
||||||
bool bConvex ;
|
|
||||||
if ( ! AreSamePointApprox( ptInt, vPt5ax[j].ptP))
|
|
||||||
bConvex = ( ( vPt5ax[j].vtDir1 ^ ( ptInt - vPt5ax[j].ptP)) * vtEdge > 0) ;
|
|
||||||
else
|
|
||||||
bConvex = (( vPt5ax[i].vtDir1 ^ ( ptInt - vPt5ax[i].ptP)) * vtEdge < 0) ;
|
|
||||||
// se convesso, metto due punti con direzione appena prima e appena dopo
|
|
||||||
if ( bConvex) {
|
|
||||||
Vector3d vtLine1 = ptInt - vPt5ax[j].ptP ; double dLen1 = vtLine1.Len() ;
|
|
||||||
Vector3d vtLine2 = vPt5ax[i].ptP - ptInt ; double dLen2 = vtLine2.Len() ;
|
|
||||||
if ( dLen1 > 2 * EPS_SMALL) {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt - vtLine1 / dLen1 * 2 * EPS_SMALL ;
|
|
||||||
Pt5ax.vtDir1 = vPt5ax[j].vtDir1 ;
|
|
||||||
Pt5ax.vtDir2 = vtDir ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CVEX ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
if ( dLen2 > 2 * EPS_SMALL) {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt + vtLine2 / dLen2 * 2 * EPS_SMALL ;
|
|
||||||
Pt5ax.vtDir1 = vPt5ax[i].vtDir1 ;
|
|
||||||
Pt5ax.vtDir2 = vtDir ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CVEX ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti concavo, aggiungo un solo punto con la direzione media
|
|
||||||
else {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = Media( vPt5ax[i].vtDir1, vPt5ax[j].vtDir1) ;
|
|
||||||
Pt5ax.vtDir2 = vtDir ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CONC ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rimozione punti in eccesso rispetto alle tolleranze
|
|
||||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static bool
|
|
||||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const IGeoPoint3d& gpRef, double dPar, Point5ax& Pt5ax)
|
|
||||||
{
|
|
||||||
// punto di riferimento
|
|
||||||
Point3d ptMin = gpRef.GetPoint() ;
|
|
||||||
// intersezione della retta di minima distanza con le superfici
|
|
||||||
Vector3d vtLine = ptP - ptMin ;
|
|
||||||
double dLineLen = vtLine.Len() ;
|
|
||||||
if ( dLineLen > EPS_SMALL) {
|
|
||||||
vtLine /= dLineLen ;
|
|
||||||
// conservo l'intersezione più alta
|
|
||||||
int nInd = -1 ;
|
|
||||||
IntLinStmInfo IntRes ;
|
|
||||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
|
||||||
ILSIVECTOR vIntRes ;
|
|
||||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], 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)
|
|
||||||
--nI ;
|
|
||||||
// se trovata
|
|
||||||
if ( nI >= 0) {
|
|
||||||
if ( nInd < 0) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
|
||||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
|
||||||
if ( dU > dUref) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se trovata
|
|
||||||
if ( nInd >= 0) {
|
|
||||||
// calcolo il punto
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
|
||||||
ptInt = IntRes.ptI2 ;
|
|
||||||
else
|
|
||||||
ptInt = IntRes.ptI ;
|
|
||||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
||||||
Triangle3dEx trTria ;
|
|
||||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
|
||||||
return false ;
|
|
||||||
Vector3d vtN ;
|
|
||||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
||||||
vtN = trTria.GetN() ;
|
|
||||||
// assegno valori al punto 5assi
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = vtN ;
|
|
||||||
Pt5ax.vtDir2 = vtLine ;
|
|
||||||
Pt5ax.dPar = dPar ;
|
|
||||||
Pt5ax.nFlag = P5AX_STD ;
|
|
||||||
// ritorno con successo
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const IGeoPoint3d& gpRef,
|
|
||||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
|
||||||
{
|
|
||||||
// sistemazioni per tipo di superficie
|
|
||||||
CISRFTMPVECTOR vpSurfTm ;
|
|
||||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
|
||||||
const SurfTriMesh* pSurfTm = nullptr ;
|
|
||||||
switch ( vpSurf[i]->GetType()) {
|
|
||||||
case SRF_TRIMESH :
|
|
||||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
|
||||||
break ;
|
|
||||||
case SRF_BEZIER :
|
|
||||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
|
||||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
|
||||||
} break ;
|
|
||||||
case SRF_FLATRGN :
|
|
||||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
|
||||||
break ;
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ( pSurfTm == nullptr)
|
|
||||||
return false ;
|
|
||||||
vpSurfTm.emplace_back( pSurfTm) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// controllo le tolleranze
|
|
||||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
||||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
||||||
|
|
||||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
|
||||||
return false ;
|
|
||||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
|
||||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
|
||||||
vPt5ax.clear() ;
|
|
||||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
|
||||||
|
|
||||||
// proietto i punti della polilinea sulla superficie con direzione data dal punto di riferimento
|
|
||||||
double dPar ;
|
|
||||||
Point3d ptP ;
|
|
||||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
|
||||||
while ( bFound) {
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, gpRef, dPar, Pt5ax))
|
|
||||||
vPt5ax.emplace_back( Pt5ax) ;
|
|
||||||
// passo al successivo
|
|
||||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
|
||||||
if ( bSharpEdges) {
|
|
||||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
|
||||||
// precedente
|
|
||||||
int j = i - 1 ;
|
|
||||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
|
||||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
|
||||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
|
||||||
// punto medio
|
|
||||||
Point3d ptMid = Media( vPt5ax[i].ptP, vPt5ax[j].ptP) ;
|
|
||||||
double dMid = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptMid, vpSurfTm, gpRef, dMid, Pt5ax)) {
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
-- i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rimozione punti in eccesso rispetto alle tolleranze
|
|
||||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static bool
|
|
||||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const ICurve& crRef, double dPar, Point5ax& Pt5ax)
|
|
||||||
{
|
|
||||||
// punto a minima distanza
|
|
||||||
DistPointCurve dPC( ptP, crRef) ;
|
|
||||||
Point3d ptMin ;
|
|
||||||
int nFlag ;
|
|
||||||
if ( dPC.GetMinDistPoint( 0, ptMin, nFlag)) {
|
|
||||||
// intersezione della retta di minima distanza con le superfici
|
|
||||||
Vector3d vtLine = ptP - ptMin ;
|
|
||||||
double dLineLen = vtLine.Len() ;
|
|
||||||
if ( dLineLen > EPS_SMALL) {
|
|
||||||
vtLine /= dLineLen ;
|
|
||||||
// conservo l'intersezione più alta
|
|
||||||
int nInd = -1 ;
|
|
||||||
IntLinStmInfo IntRes ;
|
|
||||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
|
||||||
ILSIVECTOR vIntRes ;
|
|
||||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], 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)
|
|
||||||
--nI ;
|
|
||||||
// se trovata
|
|
||||||
if ( nI >= 0) {
|
|
||||||
if ( nInd < 0) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
|
||||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
|
||||||
if ( dU > dUref) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se trovata
|
|
||||||
if ( nInd >= 0) {
|
|
||||||
// assegno il punto
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
|
||||||
ptInt = IntRes.ptI2 ;
|
|
||||||
else
|
|
||||||
ptInt = IntRes.ptI ;
|
|
||||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
||||||
Triangle3dEx trTria ;
|
|
||||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
|
||||||
return false ;
|
|
||||||
Vector3d vtN ;
|
|
||||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
|
||||||
vtN = trTria.GetN() ;
|
|
||||||
// assegno valori al punto 5assi
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = vtN ;
|
|
||||||
Pt5ax.vtDir2 = vtLine ;
|
|
||||||
Pt5ax.dPar = dPar ;
|
|
||||||
Pt5ax.nFlag = P5AX_STD ;
|
|
||||||
// ritorno con successo
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ICurve& crRef,
|
|
||||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
|
||||||
{
|
|
||||||
// Sistemazioni per tipo di superficie
|
|
||||||
CISRFTMPVECTOR vpSurfTm ;
|
|
||||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
|
||||||
const SurfTriMesh* pSurfTm = nullptr ;
|
|
||||||
switch ( vpSurf[i]->GetType()) {
|
|
||||||
case SRF_TRIMESH :
|
|
||||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
|
||||||
break ;
|
|
||||||
case SRF_BEZIER :
|
|
||||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
|
||||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
|
||||||
} break ;
|
|
||||||
case SRF_FLATRGN :
|
|
||||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
|
||||||
break ;
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ( pSurfTm == nullptr)
|
|
||||||
return false ;
|
|
||||||
vpSurfTm.emplace_back( pSurfTm) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controllo le tolleranze
|
|
||||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
||||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
||||||
|
|
||||||
// Approssimo la curva con una polilinea alla massima risoluzione
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
|
||||||
return false ;
|
|
||||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
|
||||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
|
||||||
vPt5ax.clear() ;
|
|
||||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
|
||||||
|
|
||||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
|
||||||
double dPar ;
|
|
||||||
Point3d ptP ;
|
|
||||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
|
||||||
while ( bFound) {
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, crRef, dPar, Pt5ax))
|
|
||||||
vPt5ax.emplace_back( Pt5ax) ;
|
|
||||||
// passo al successivo
|
|
||||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
|
||||||
if ( bSharpEdges) {
|
|
||||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
|
||||||
// precedente
|
|
||||||
int j = i - 1 ;
|
|
||||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
|
||||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
|
||||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
|
||||||
// intersezione tra le due facce
|
|
||||||
Plane3d plPlane1 ; plPlane1.Set( vPt5ax[j].ptP, vPt5ax[j].vtDir1) ;
|
|
||||||
Plane3d plPlane2 ; plPlane2.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir1) ;
|
|
||||||
Point3d ptEdge ; Vector3d vtEdge ;
|
|
||||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptEdge, vtEdge) == IPPT_YES) {
|
|
||||||
Plane3d plPlane3 ; plPlane3.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir2 ^ vPt5ax[j].vtDir2) ;
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntersLinePlane( ptEdge, vtEdge, 1, plPlane3, ptInt, false) == ILPT_YES) {
|
|
||||||
// verifico se spigolo convesso o concavo
|
|
||||||
bool bConvex ;
|
|
||||||
if ( ! AreSamePointApprox( ptInt, vPt5ax[j].ptP))
|
|
||||||
bConvex = ( ( vPt5ax[j].vtDir1 ^ ( ptInt - vPt5ax[j].ptP)) * vtEdge > 0) ;
|
|
||||||
else
|
|
||||||
bConvex = (( vPt5ax[i].vtDir1 ^ ( ptInt - vPt5ax[i].ptP)) * vtEdge < 0) ;
|
|
||||||
// se convesso, metto due punti con direzione appena prima e appena dopo
|
|
||||||
if ( bConvex) {
|
|
||||||
Vector3d vtLine1 = ptInt - vPt5ax[j].ptP ; double dLen1 = vtLine1.Len() ;
|
|
||||||
Vector3d vtLine2 = vPt5ax[i].ptP - ptInt ; double dLen2 = vtLine2.Len() ;
|
|
||||||
if ( dLen1 > 2 * EPS_SMALL) {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt - vtLine1 / dLen1 * 2 * EPS_SMALL ;
|
|
||||||
Pt5ax.vtDir1 = vPt5ax[j].vtDir1 ;
|
|
||||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CVEX ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
if ( dLen2 > 2 * EPS_SMALL) {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt + vtLine2 / dLen2 * 2 * EPS_SMALL ;
|
|
||||||
Pt5ax.vtDir1 = vPt5ax[i].vtDir1 ;
|
|
||||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CVEX ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti concavo, aggiungo un solo punto con la direzione media
|
|
||||||
else {
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = Media( vPt5ax[i].vtDir1, vPt5ax[j].vtDir1) ;
|
|
||||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
|
||||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
Pt5ax.nFlag = P5AX_CONC ;
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
++ i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rimozione punti in eccesso rispetto alle tolleranze
|
|
||||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
static bool
|
|
||||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const SurfTriMesh& stmRef, double dPar, Point5ax& Pt5ax)
|
|
||||||
{
|
|
||||||
// punto sulla superficie guida a minima distanza
|
|
||||||
DistPointSurfTm dPS( ptP, stmRef) ;
|
|
||||||
Point3d ptMin ;
|
|
||||||
int nTriaMin ;
|
|
||||||
if ( dPS.GetMinDistPoint( ptMin) && dPS.GetMinDistTriaIndex ( nTriaMin)) {
|
|
||||||
// recupero direzione della retta di minima distanza, altrimenti normale alla superficie
|
|
||||||
Vector3d vtLine = ptP - ptMin ;
|
|
||||||
double dLineLen = vtLine.Len() ;
|
|
||||||
if ( dLineLen > EPS_SMALL)
|
|
||||||
vtLine /= dLineLen ;
|
|
||||||
else {
|
|
||||||
// calcolo la normale della superficie guida
|
|
||||||
Triangle3dEx trGuide ;
|
|
||||||
if ( ! stmRef.GetTriangle( nTriaMin, trGuide))
|
|
||||||
return false ;
|
|
||||||
if ( ! CalcNormal( ptMin, trGuide, vtLine))
|
|
||||||
vtLine = trGuide.GetN() ;
|
|
||||||
dLineLen = 100 ;
|
|
||||||
}
|
|
||||||
// intersezione della retta con le superfici (conservo l'intersezione più alta)
|
|
||||||
int nInd = -1 ;
|
|
||||||
IntLinStmInfo IntRes ;
|
|
||||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
|
||||||
ILSIVECTOR vIntRes ;
|
|
||||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], 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)
|
|
||||||
--nI ;
|
|
||||||
// se trovata
|
|
||||||
if ( nI >= 0) {
|
|
||||||
if ( nInd < 0) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
|
||||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
|
||||||
if ( dU > dUref) {
|
|
||||||
IntRes = vIntRes[nI] ;
|
|
||||||
nInd = i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se trovata
|
|
||||||
if ( nInd >= 0) {
|
|
||||||
// calcolo il punto
|
|
||||||
Point3d ptInt ;
|
|
||||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
|
||||||
ptInt = IntRes.ptI2 ;
|
|
||||||
else
|
|
||||||
ptInt = IntRes.ptI ;
|
|
||||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
|
||||||
Triangle3dEx trTria ;
|
|
||||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
|
||||||
return false ;
|
|
||||||
Vector3d vtN ;
|
|
||||||
if ( ! CalcNormal( ptMin, trTria, vtN))
|
|
||||||
vtN = trTria.GetN() ;
|
|
||||||
// calcolo la normale della superficie guida
|
|
||||||
Triangle3dEx trGuide ;
|
|
||||||
if ( ! stmRef.GetTriangle( nTriaMin, trGuide))
|
|
||||||
return false ;
|
|
||||||
Vector3d vtN2 ;
|
|
||||||
if ( ! CalcNormal( ptMin, trGuide, vtN2))
|
|
||||||
vtN2 = trGuide.GetN() ;
|
|
||||||
// assegno valori al punto 5assi
|
|
||||||
Pt5ax.ptP = ptInt ;
|
|
||||||
Pt5ax.vtDir1 = vtN ;
|
|
||||||
Pt5ax.vtDir2 = vtN2 ;
|
|
||||||
Pt5ax.dPar = dPar ;
|
|
||||||
Pt5ax.nFlag = P5AX_STD ;
|
|
||||||
// ritorno con successo
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ISurf& sfRef,
|
|
||||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
|
||||||
{
|
|
||||||
// sistemazioni per tipo di superficie
|
|
||||||
CISRFTMPVECTOR vpSurfTm ;
|
|
||||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
|
||||||
const SurfTriMesh* pSurfTm = nullptr ;
|
|
||||||
switch ( vpSurf[i]->GetType()) {
|
|
||||||
case SRF_TRIMESH :
|
|
||||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
|
||||||
break ;
|
|
||||||
case SRF_BEZIER :
|
|
||||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
|
||||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
|
||||||
} break ;
|
|
||||||
case SRF_FLATRGN :
|
|
||||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
|
||||||
break ;
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ( pSurfTm == nullptr)
|
|
||||||
return false ;
|
|
||||||
vpSurfTm.emplace_back( pSurfTm) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sistemazioni per tipo di superficie di riferimento
|
|
||||||
const SurfTriMesh* pRefTm = nullptr ;
|
|
||||||
switch ( sfRef.GetType()) {
|
|
||||||
case SRF_TRIMESH :
|
|
||||||
pRefTm = GetBasicSurfTriMesh( &sfRef) ;
|
|
||||||
break ;
|
|
||||||
case SRF_BEZIER :
|
|
||||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
|
||||||
pRefTm = GetBasicSurfBezier( &sfRef)->GetAuxSurfRefined() ;
|
|
||||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
|
||||||
} break ;
|
|
||||||
case SRF_FLATRGN :
|
|
||||||
pRefTm = GetBasicSurfFlatRegion( &sfRef)->GetAuxSurf() ;
|
|
||||||
break ;
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if ( pRefTm == nullptr)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// controllo le tolleranze
|
|
||||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
||||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
|
||||||
|
|
||||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
|
||||||
return false ;
|
|
||||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
|
||||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
|
||||||
vPt5ax.clear() ;
|
|
||||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
|
||||||
|
|
||||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
|
||||||
double dPar ;
|
|
||||||
Point3d ptP ;
|
|
||||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
|
||||||
while ( bFound) {
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, *pRefTm, dPar, Pt5ax))
|
|
||||||
vPt5ax.emplace_back( Pt5ax) ;
|
|
||||||
// passo al successivo
|
|
||||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
|
||||||
if ( bSharpEdges) {
|
|
||||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
|
||||||
// precedente
|
|
||||||
int j = i - 1 ;
|
|
||||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
|
||||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
|
||||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
|
||||||
// punto medio
|
|
||||||
Point3d ptMid = Media( vPt5ax[i].ptP, vPt5ax[j].ptP) ;
|
|
||||||
double dMid = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
|
||||||
// se trovo proiezione, la salvo
|
|
||||||
Point5ax Pt5ax ;
|
|
||||||
if ( ProjectPointOnSurf( ptMid, vpSurfTm, *pRefTm, dMid, Pt5ax)) {
|
|
||||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
|
||||||
-- i ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rimozione punti in eccesso rispetto alle tolleranze
|
|
||||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2023-2023
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : ProjectCurveSurfTm.cpp Data : 16.11.23 Versione : 2.5kh3
|
||||||
|
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 31.08.23 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
|
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
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 ;
|
||||||
|
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 > cos( 2 * DEGTORAD))
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// controllo le tolleranze
|
||||||
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||||
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||||
|
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||||
|
return false ;
|
||||||
|
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||||
|
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Oggetto per calcolo massivo intersezioni tra linee di proiezione e superficie
|
||||||
|
Frame3d frRefLine ;
|
||||||
|
if ( ! frRefLine.Set( ORIG, vtDir))
|
||||||
|
return false ;
|
||||||
|
IntersParLinesSurfTm intPLSTM( frRefLine, tmSurf) ;
|
||||||
|
|
||||||
|
// Vettore locale dei punti risultanti
|
||||||
|
PNT5AXVECTOR vMyPt5ax ;
|
||||||
|
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||||
|
|
||||||
|
// proietto i punti della polilinea sulla superficie
|
||||||
|
double dPar ;
|
||||||
|
Point3d ptP ;
|
||||||
|
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||||
|
while ( bFound) {
|
||||||
|
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
||||||
|
ILSIVECTOR vIntRes ;
|
||||||
|
intPLSTM.GetInters( ptL, 1, vIntRes, false) ;
|
||||||
|
if ( ! vIntRes.empty()) {
|
||||||
|
// calcolo il punto
|
||||||
|
int nI = int( vIntRes.size()) - 1 ;
|
||||||
|
Point3d ptInt ;
|
||||||
|
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
|
ptInt = vIntRes[nI].ptI2 ;
|
||||||
|
else
|
||||||
|
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))
|
||||||
|
return false ;
|
||||||
|
Vector3d vtN ;
|
||||||
|
double dU, dV, dW ;
|
||||||
|
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||||
|
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||||
|
if ( ! vtN.Normalize())
|
||||||
|
vtN = trTria.GetN() ;
|
||||||
|
// aggiungo al vettore dei proiettati
|
||||||
|
vMyPt5ax.emplace_back( ptInt, vtN, 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) ;
|
||||||
|
|
||||||
|
// copio i punti rimasti nel vettore di ritorno
|
||||||
|
vPt5ax.clear() ;
|
||||||
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||||
|
if ( Pt5ax.nFlag != -1)
|
||||||
|
vPt5ax.emplace_back( Pt5ax) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGeoPoint3d& gpRef,
|
||||||
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||||
|
{
|
||||||
|
// controllo le tolleranze
|
||||||
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||||
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||||
|
|
||||||
|
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||||
|
return false ;
|
||||||
|
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||||
|
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Vettore locale dei punti risultanti
|
||||||
|
PNT5AXVECTOR vMyPt5ax ;
|
||||||
|
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||||
|
|
||||||
|
// proietto i punti della polilinea sulla superficie con direzione data dal punto di riferimento
|
||||||
|
double dPar ;
|
||||||
|
Point3d ptP ;
|
||||||
|
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||||
|
while ( bFound) {
|
||||||
|
// punto di riferimento
|
||||||
|
Point3d ptMin = gpRef.GetPoint() ;
|
||||||
|
// intersezione della retta di minima distanza con la superficie
|
||||||
|
Vector3d vtLine = ptP - ptMin ;
|
||||||
|
double dLineLen = vtLine.Len() ;
|
||||||
|
if ( dLineLen > EPS_SMALL) {
|
||||||
|
vtLine /= dLineLen ;
|
||||||
|
ILSIVECTOR vIntRes ;
|
||||||
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||||
|
if ( vIntRes.size() > 0) {
|
||||||
|
// calcolo il punto
|
||||||
|
int nI = int( vIntRes.size()) - 1 ;
|
||||||
|
Point3d ptInt ;
|
||||||
|
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
|
ptInt = vIntRes[nI].ptI2 ;
|
||||||
|
else
|
||||||
|
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))
|
||||||
|
return false ;
|
||||||
|
Vector3d vtN ;
|
||||||
|
double dU, dV, dW ;
|
||||||
|
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||||
|
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||||
|
if ( ! vtN.Normalize())
|
||||||
|
vtN = trTria.GetN() ;
|
||||||
|
// aggiungo al vettore dei proiettati
|
||||||
|
vMyPt5ax.emplace_back( ptInt, vtN, vtLine, 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) ;
|
||||||
|
|
||||||
|
// copio i punti rimasti nel vettore di ritorno
|
||||||
|
vPt5ax.clear() ;
|
||||||
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||||
|
if ( Pt5ax.nFlag != -1)
|
||||||
|
vPt5ax.emplace_back( Pt5ax) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICurve& crRef,
|
||||||
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||||
|
{
|
||||||
|
// controllo le tolleranze
|
||||||
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||||
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||||
|
|
||||||
|
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||||
|
return false ;
|
||||||
|
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||||
|
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Vettore locale dei punti risultanti
|
||||||
|
PNT5AXVECTOR vMyPt5ax ;
|
||||||
|
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||||
|
|
||||||
|
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||||
|
double dPar ;
|
||||||
|
Point3d ptP ;
|
||||||
|
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||||
|
while ( bFound) {
|
||||||
|
// punto sulla curva a minima distanza
|
||||||
|
DistPointCurve dPC( ptP, crRef) ;
|
||||||
|
Point3d ptMin ;
|
||||||
|
int nFlag ;
|
||||||
|
if ( dPC.GetMinDistPoint( 0, ptMin, nFlag)) {
|
||||||
|
// intersezione della retta di minima distanza con la superficie
|
||||||
|
Vector3d vtLine = ptP - ptMin ;
|
||||||
|
double dLineLen = vtLine.Len() ;
|
||||||
|
if ( dLineLen > EPS_SMALL) {
|
||||||
|
vtLine /= dLineLen ;
|
||||||
|
ILSIVECTOR vIntRes ;
|
||||||
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||||
|
if ( vIntRes.size() > 0) {
|
||||||
|
// calcolo il punto
|
||||||
|
int nI = int( vIntRes.size()) - 1 ;
|
||||||
|
Point3d ptInt ;
|
||||||
|
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
|
ptInt = vIntRes[nI].ptI2 ;
|
||||||
|
else
|
||||||
|
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))
|
||||||
|
return false ;
|
||||||
|
Vector3d vtN ;
|
||||||
|
double dU, dV, dW ;
|
||||||
|
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||||
|
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||||
|
if ( ! vtN.Normalize())
|
||||||
|
vtN = trTria.GetN() ;
|
||||||
|
// aggiungo al vettore dei proiettati
|
||||||
|
vMyPt5ax.emplace_back( ptInt, vtN, vtLine, 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) ;
|
||||||
|
|
||||||
|
// copio i punti rimasti nel vettore di ritorno
|
||||||
|
vPt5ax.clear() ;
|
||||||
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||||
|
if ( Pt5ax.nFlag != -1)
|
||||||
|
vPt5ax.emplace_back( Pt5ax) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISurfTriMesh& tmRef,
|
||||||
|
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||||
|
{
|
||||||
|
// controllo le tolleranze
|
||||||
|
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||||
|
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||||
|
|
||||||
|
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||||
|
return false ;
|
||||||
|
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||||
|
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Vettore locale dei punti risultanti
|
||||||
|
PNT5AXVECTOR vMyPt5ax ;
|
||||||
|
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||||
|
|
||||||
|
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||||
|
double dPar ;
|
||||||
|
Point3d ptP ;
|
||||||
|
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||||
|
while ( bFound) {
|
||||||
|
// punto sulla superficie guida a minima distanza
|
||||||
|
DistPointSurfTm dPS( ptP, tmRef) ;
|
||||||
|
Point3d ptMin ;
|
||||||
|
int nTriaMin ;
|
||||||
|
if ( dPS.GetMinDistPoint( ptMin) && dPS.GetMinDistTriaIndex ( nTriaMin)) {
|
||||||
|
// intersezione della retta di minima distanza con la superficie
|
||||||
|
Vector3d vtLine = ptP - ptMin ;
|
||||||
|
double dLineLen = vtLine.Len() ;
|
||||||
|
if ( dLineLen > EPS_SMALL) {
|
||||||
|
vtLine /= dLineLen ;
|
||||||
|
ILSIVECTOR vIntRes ;
|
||||||
|
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||||
|
if ( vIntRes.size() > 0) {
|
||||||
|
// calcolo il punto
|
||||||
|
int nI = int( vIntRes.size()) - 1 ;
|
||||||
|
Point3d ptInt ;
|
||||||
|
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
|
ptInt = vIntRes[nI].ptI2 ;
|
||||||
|
else
|
||||||
|
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))
|
||||||
|
return false ;
|
||||||
|
Vector3d vtN ;
|
||||||
|
double dU, dV, dW ;
|
||||||
|
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||||
|
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||||
|
if ( ! vtN.Normalize())
|
||||||
|
vtN = trTria.GetN() ;
|
||||||
|
// calcolo la normale della superficie guida
|
||||||
|
Triangle3dEx trGuide ;
|
||||||
|
if ( ! tmRef.GetTriangle( nTriaMin, trGuide))
|
||||||
|
return false ;
|
||||||
|
Vector3d vtN2 ;
|
||||||
|
double dU2, dV2, dW2 ;
|
||||||
|
if ( BarycentricCoord( ptMin, trGuide, dU2, dV2, dW2))
|
||||||
|
vtN2 = dU2 * trGuide.GetVertexNorm( 0) + dV2 * trGuide.GetVertexNorm( 1) + dW2 * trGuide.GetVertexNorm( 2) ;
|
||||||
|
if ( ! vtN2.Normalize())
|
||||||
|
vtN2 = trGuide.GetN() ;
|
||||||
|
// aggiungo al vettore dei proiettati
|
||||||
|
vMyPt5ax.emplace_back( ptInt, vtN, vtN2, 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) ;
|
||||||
|
|
||||||
|
// copio i punti rimasti nel vettore di ritorno
|
||||||
|
vPt5ax.clear() ;
|
||||||
|
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||||
|
if ( Pt5ax.nFlag != -1)
|
||||||
|
vPt5ax.emplace_back( Pt5ax) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "CurveComposite.h"
|
#include "CurveComposite.h"
|
||||||
|
#include "DistPointLine.h"
|
||||||
#include "RemoveCurveDefects.h"
|
#include "RemoveCurveDefects.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|||||||
@@ -1,772 +0,0 @@
|
|||||||
//----------------------------------------------------------------------------
|
|
||||||
// EgalTech 20024
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// File : SbzFromCurves.cpp Data : 07.05.24 Versione : 2.6e2
|
|
||||||
// Contenuto : Implementazione di funzioni per creazione di superfici Sbz
|
|
||||||
// a partire da curve, con diversi metodi.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Modifiche : 07.05.24 DB Creazione modulo.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//--------------------------- Include ----------------------------------------
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "GeoConst.h"
|
|
||||||
#include "CurveLine.h"
|
|
||||||
#include "CurveArc.h"
|
|
||||||
#include "CurveComposite.h"
|
|
||||||
#include "SurfTriMesh.h"
|
|
||||||
#include "SurfBezier.h"
|
|
||||||
#include "Voronoi.h"
|
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
||||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
|
||||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
|
||||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
||||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
||||||
#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
|
|
||||||
#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
|
|
||||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
|
||||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
||||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
||||||
#include <future>
|
|
||||||
|
|
||||||
using namespace std ;
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierByFlatContour( const ICurve* pCurve, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( pCurve == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
// calcolo la polilinea che approssima la curva
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
||||||
return nullptr ;
|
|
||||||
// creo e setto la superficie trimesh
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByFlatContour( PL))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( &vpCurve == nullptr || vpCurve.empty())
|
|
||||||
return nullptr ;
|
|
||||||
// calcolo le polilinee che approssimano le curve della regione
|
|
||||||
POLYLINEVECTOR vPL ;
|
|
||||||
vPL.resize( vpCurve.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
|
||||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
Vector3d vtN ;
|
|
||||||
INTMATRIX vnPLIndMat ;
|
|
||||||
BOOLVECTOR vbInvert ;
|
|
||||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat,vbInvert))
|
|
||||||
return nullptr ;
|
|
||||||
POLYLINEVECTOR vPLOrd ;
|
|
||||||
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) {
|
|
||||||
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++j){
|
|
||||||
vPLOrd.push_back(vPL[vnPLIndMat[i][j]]) ;
|
|
||||||
if( vbInvert[vnPLIndMat[i][j]])
|
|
||||||
vPLOrd.back().Invert() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// creo e setto la superficie di bezier
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByRegion( vPLOrd))
|
|
||||||
return nullptr ;
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
|
||||||
bool bCapEnds, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( pCurve == nullptr || &vtExtr == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
PtrOwner<const ICurve> pBezierForm( CurveToBezierCurve( pCurve)) ;
|
|
||||||
// creo e setto la superficie di Bezier
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfCompo*
|
|
||||||
//GetSurfBezierByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol) ///// RICHIEDE LE SURF COMPO/////////////////
|
|
||||||
//{
|
|
||||||
// // verifica parametri
|
|
||||||
// if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
// // se una sola curva, uso la funzione precedente
|
|
||||||
// if ( vpCurve.size() == 1 )
|
|
||||||
// return GetSurfBezierByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
|
||||||
// // calcolo le polilinee che approssimano le curve della regione
|
|
||||||
// POLYLINEVECTOR vPL ;
|
|
||||||
// Vector3d vtN ;
|
|
||||||
// if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
|
||||||
// return nullptr ;
|
|
||||||
// // verifico la direzione di estrusione
|
|
||||||
// double dOrthoExtr = vtN * vtExtr ;
|
|
||||||
// if ( ( abs( dOrthoExtr) < EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // se componente estrusione negativa, inverto tutti i percorsi
|
|
||||||
// if ( dOrthoExtr < 0) {
|
|
||||||
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
|
|
||||||
// vPL[i].Invert() ;
|
|
||||||
// }
|
|
||||||
// // creo la prima superficie di estremità
|
|
||||||
// PtrOwner<SurfBezier> pSbz1( CreateBasicSurfBezier()) ;
|
|
||||||
// if ( IsNull( pSbz1) || ! pSbz1->CreateByRegion( vPL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // creo la seconda superficie come copia della prima e poi inverto la prima
|
|
||||||
// PtrOwner<ISurfBezier> pSbz2( pSbz1->Clone()) ;
|
|
||||||
// pSbz1->Invert() ;
|
|
||||||
//
|
|
||||||
// // creo e unisco le diverse superfici di estrusione
|
|
||||||
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
||||||
// // estrusione
|
|
||||||
// SurfBezier SbzLat ;
|
|
||||||
// if ( ! SbzLat.CreateByExtrusion( vPL[i], vtExtr)) // qui mi serve la curva e non la polyline della curva. vuol dire che dalla CalcRegionPolyLines devo farmi restituire anche le curve ordinate
|
|
||||||
// return nullptr ;
|
|
||||||
// }
|
|
||||||
// // restituisco la superficie
|
|
||||||
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
|
||||||
bool bCapEnds, double dLinTol) // con l'aggiunta delle SURFCOMPO posso gestire anche i cap e curve che attraversano l'asse
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
// limite minimo su tolleranza
|
|
||||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
||||||
|
|
||||||
// creo e setto la superficie trimesh
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, ANG_FULL, 0))
|
|
||||||
return nullptr ;
|
|
||||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
||||||
double dVol ;
|
|
||||||
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
|
||||||
pSbz->Invert() ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
|
||||||
double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
// limite minimo su tolleranza
|
|
||||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
||||||
|
|
||||||
// creo e setto la superficie bezier
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
||||||
double dVol ;
|
|
||||||
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
|
||||||
pSbz->Invert() ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
|
|
||||||
{
|
|
||||||
// riferimento all'inizio della linea guida
|
|
||||||
Frame3d frStart ;
|
|
||||||
Point3d ptStart ;
|
|
||||||
pGuide->GetStartPoint( ptStart) ;
|
|
||||||
Vector3d vtStart ;
|
|
||||||
pGuide->GetStartDir( vtStart) ;
|
|
||||||
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
||||||
|
|
||||||
// capisco se la guida è una linea spezzata o una curva
|
|
||||||
bool bGuideIsPolyLine = false ;
|
|
||||||
switch ( pGuide->GetType()) {
|
|
||||||
case CRV_COMPO : {
|
|
||||||
bGuideIsPolyLine = true ;
|
|
||||||
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
|
||||||
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
|
||||||
const ICurve* pCrv = pCC->GetCurve( i) ;
|
|
||||||
if( pCrv->GetType() != CRV_LINE) {
|
|
||||||
if ( pCrv->GetType() == CRV_BEZIER) {
|
|
||||||
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
|
||||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bGuideIsPolyLine = false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
case CRV_LINE :
|
|
||||||
bGuideIsPolyLine = true ;
|
|
||||||
break ;
|
|
||||||
case CRV_BEZIER : {
|
|
||||||
// controllo se i punti di controllo sono allineati
|
|
||||||
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
|
||||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bRat = false ;
|
|
||||||
int nSpanV = 0 ;
|
|
||||||
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
||||||
if ( bGuideIsPolyLine ) {
|
|
||||||
if( pGuide->GetType() == CRV_LINE)
|
|
||||||
nSpanV = 1 ;
|
|
||||||
else if ( pGuide->GetType() == CRV_COMPO)
|
|
||||||
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//converto in bezier la guida ( grado 3, non razionale)
|
|
||||||
if ( pGuide->GetType() != CRV_BEZIER)
|
|
||||||
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
|
||||||
else {
|
|
||||||
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
|
||||||
if( ! pGuideBez->IsRational())
|
|
||||||
pCrvV->AddCurve( pGuide->Clone()) ;
|
|
||||||
else
|
|
||||||
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
|
||||||
}
|
|
||||||
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
nSpanV = pCrvV->GetCurveCount() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// converto in bezier la sezione ( grado 3, non razionale)
|
|
||||||
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
|
||||||
if ( pSect->GetType() != CRV_BEZIER)
|
|
||||||
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
|
||||||
else {
|
|
||||||
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
|
||||||
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
|
||||||
}
|
|
||||||
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
|
||||||
|
|
||||||
int nDegV = 3 ;
|
|
||||||
if ( bGuideIsPolyLine)
|
|
||||||
nDegV = 1 ;
|
|
||||||
|
|
||||||
int nDegU = 3 ;
|
|
||||||
// superficie swept
|
|
||||||
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
|
||||||
if ( bGuideIsPolyLine) {
|
|
||||||
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
||||||
// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
||||||
pCrvU->ToLoc( frStart) ;
|
|
||||||
// la guida è una linea spezzata, quindi posso lavorare con gli offset
|
|
||||||
ICRVCOMPOPOVECTOR vCC ;
|
|
||||||
INTMATRIX mRep ; mRep.resize( nSpanU * nDegU + 1) ;
|
|
||||||
int nMaxSpanV = nSpanV ;
|
|
||||||
for( int i = 0 ; i < nSpanU ; ++i) {
|
|
||||||
const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
|
||||||
for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
||||||
Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
|
||||||
// faccio l'offset della guida nel punto di controllo della sezione
|
|
||||||
OffsetCurve OffsCrv ;
|
|
||||||
if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
|
||||||
return nullptr ;
|
|
||||||
vCC.emplace_back() ;
|
|
||||||
vCC.back()->AddCurve(OffsCrv.GetLongerCurve()) ;
|
|
||||||
if ( IsNull( pCrvV))
|
|
||||||
return nullptr ;
|
|
||||||
vCC.back()->Translate( ptCtrl.y * frStart.VersY()) ;
|
|
||||||
//mRep[ i * nDegU + j].resize(vCC.back()->GetCurveCount()) ;
|
|
||||||
nMaxSpanV = max ( nMaxSpanV, vCC.back()->GetCurveCount()) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// devo capire quante span in V devo creare e a quale span appartengono i tratti degli offset
|
|
||||||
for ( int k = 0 ; k < int( vCC.size()) ; ++k) {
|
|
||||||
const ICurveComposite* pCC = vCC[k] ;
|
|
||||||
mRep[k].resize( nMaxSpanV) ;
|
|
||||||
for ( int z = 0 ; z < int( mRep[k].size()) ; ++z) {
|
|
||||||
int nProp = - 1 ; pCC->GetCurveTempProp( z, nProp) ;
|
|
||||||
if ( nProp == 0) {
|
|
||||||
// ho trovato almeno una curva di offset che ha un tratto non derivante direttamente dalla curva originale
|
|
||||||
// tutte le altre curve che hanno curve di offeset che non hanno questo tratto bonus dovranno ripetere il punto di controllo
|
|
||||||
for ( int w = 0 ; w < int( vCC.size()) ; ++w) {
|
|
||||||
const ICurveComposite* pCCOther = vCC[w] ;
|
|
||||||
int nPropCheck = -1 ; pCCOther->GetCurveTempProp( z, nPropCheck) ;
|
|
||||||
if( nPropCheck != 0)
|
|
||||||
mRep[w][z] = 1 ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// conto in quante colonne di mRep la somma degli elementi è != 0
|
|
||||||
// questo numero va aggiunto all'attuale nSpanV
|
|
||||||
int nSpanPlus = 0 ;
|
|
||||||
for( int z = 0 ; z < nMaxSpanV ; ++z) {
|
|
||||||
int nPosTot = 0 ;
|
|
||||||
for ( int k = 0 ; k < int( mRep.size()) ; ++k )
|
|
||||||
nPosTot += mRep[k][z] ;
|
|
||||||
if( nPosTot != 0)
|
|
||||||
nSpanPlus += 1 ;
|
|
||||||
}
|
|
||||||
nMaxSpanV = max( nMaxSpanV, nSpanV + nSpanPlus) ;
|
|
||||||
nSpanV = nMaxSpanV ;
|
|
||||||
|
|
||||||
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
|
||||||
//// aggiungo i punti di controllo alla superficie
|
|
||||||
//for( int i = 0 ; i < nSpanU ; ++i) {
|
|
||||||
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
||||||
// const ICurveComposite* pOffsetCrv = vCC[i*nDegU + j] ;
|
|
||||||
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
|
||||||
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
|
||||||
// if( pCL == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
// if( z == 0) {
|
|
||||||
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
|
||||||
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
|
||||||
// }
|
|
||||||
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
|
||||||
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// aggiungo i punti di controllo alla superficie /// DA CORREGGERE L'AGGIUNTA DEI PUNTI DI CONTROLLO
|
|
||||||
//for( int i = 0 ; i < int( vCC.size()) ; ++i) {
|
|
||||||
// const ICurveComposite* pOffsetCrv = vCC[i] ;
|
|
||||||
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
|
||||||
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
|
||||||
// if( pCL == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
// if( z == 0) {
|
|
||||||
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
|
||||||
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
|
||||||
// }
|
|
||||||
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
|
||||||
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
|
||||||
|
|
||||||
// VERSIONE con le copie della sezione ( superficie skinned)
|
|
||||||
|
|
||||||
// creo delle copie della curva e faccio la skinned
|
|
||||||
// per ogni sottocurva della guida ( che sarà composta da curve di bezier di grado 3)
|
|
||||||
// posiziono una copia della curva di sezione per ogni punto di controllo
|
|
||||||
frStart.Set( ptStart, vtStart) ;
|
|
||||||
pCrvU->ToLoc( frStart) ;
|
|
||||||
ICURVEPOVECTOR vCrvSet ;
|
|
||||||
CICURVEPVECTOR vpCrv ;
|
|
||||||
RotationMinimizingFrame rmfGuide ; rmfGuide.Set( pCrvV, frStart) ;
|
|
||||||
//double dStep = 0.25 ;
|
|
||||||
FRAME3DVECTOR vFrame ;
|
|
||||||
int nSpanV = pCrvV->GetCurveCount() ;
|
|
||||||
int nSplit = 8 * nSpanV ;
|
|
||||||
rmfGuide.GetFramesBySplit( nSplit, vFrame) ;
|
|
||||||
|
|
||||||
for ( int i = 0 ; i < nSpanV ; ++i) {
|
|
||||||
for ( int j = i==0 ? 0 : 1 ; j < nSplit + 1 ; ++j) {
|
|
||||||
ICurve* pNewSect = pCrvU->Clone() ;
|
|
||||||
pNewSect->ToGlob( vFrame[j]) ; // da sistemare se ho più curve ( la pGuide è una compo) e in base allo step di divisione!!!!!!!!! ///////
|
|
||||||
vpCrv.push_back( pNewSect) ;
|
|
||||||
vCrvSet.emplace_back( pNewSect) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////VERSIONE con l'offset dei punti di controllo // richiede l'interpolazione dei punti
|
|
||||||
//
|
|
||||||
//// faccio l'offset della guida e poi riconverto i risultati in curve di bezier tramite interpolazione
|
|
||||||
//
|
|
||||||
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
||||||
//// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
||||||
//pCrvU->ToLoc( frStart) ;
|
|
||||||
//for( int i = 0 ; i < nSpanU ; ++i) {
|
|
||||||
// const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
|
||||||
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
||||||
// Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
|
||||||
// // faccio l'offset della guida nel punto di controllo della sezione
|
|
||||||
// OffsetCurve OffsCrv ;
|
|
||||||
// if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
||||||
// pCrvV->AddCurve( OffsCrv.GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvV))
|
|
||||||
// return nullptr ;
|
|
||||||
// pCrvV->Translate( ptCtrl.y * frStart.VersY()) ;
|
|
||||||
// PNTVECTOR vPnt ;
|
|
||||||
// int nOffCrvs = pCrvV->GetCurveCount() ;
|
|
||||||
// for ( int z = 0 ; z < nOffCrvs ; ++z) {
|
|
||||||
// Point3d ptCtrl ;
|
|
||||||
// if ( z == 0) {
|
|
||||||
// pCrvV->GetCurve(z)->GetStartPoint( ptCtrl) ;
|
|
||||||
// vPnt.push_back( ptCtrl) ;
|
|
||||||
// }
|
|
||||||
// pCrvV->GetCurve(z)->GetEndPoint( ptCtrl) ;
|
|
||||||
// vPnt.push_back( ptCtrl) ;
|
|
||||||
// }
|
|
||||||
// pCrvV.Set( CreateCurveComposite()) ;
|
|
||||||
// pCrvV->AddCurve( InterpolatePointSetWithBezier( vPnt, dLinTol)) ;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// nSpanV = pCrvV->GetCurveCount() ;
|
|
||||||
// pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ; /// NON POSSO REINIZIALIZZARE LA SURF QUI!
|
|
||||||
// /// QUANDO INIZIO A INSERIRE I PUNTI DI CONTROLLO DEVO AVER DEFINITO nSpanV
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // aggiungo i punti di controllo alla superficie
|
|
||||||
// for ( int z = 0 ; z < nSpanV ; ++z) {
|
|
||||||
// const ICurveBezier* pCrvBez = GetCurveBezier( pCrvV->GetCurve( z)) ;
|
|
||||||
// if( pCrvBez == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
// for ( int k = z == 0 ? 0 : 1 ; k < nDegV ; ++k) {
|
|
||||||
// Point3d ptCtrl = pCrvBez->GetControlPoint( k) ;
|
|
||||||
// pSurfBez->SetControlPoint( i * nDegU + j, z * nDegV + k, ptCtrl) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////// se richiesti caps e sezione chiusa e guida aperta /// in attesa della SurfCompo, al momento viene fatto nell'executor
|
|
||||||
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
||||||
// // verifico che le due estremità siano chiuse e piatte
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSurfBez) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
{
|
|
||||||
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
|
|
||||||
bool bRMF = vtAx.IsSmall() ;
|
|
||||||
|
|
||||||
// riferimento all'inizio della linea guida
|
|
||||||
Point3d ptStart ;
|
|
||||||
pGuide->GetStartPoint( ptStart) ;
|
|
||||||
Vector3d vtStart ;
|
|
||||||
pGuide->GetStartDir( vtStart) ;
|
|
||||||
Frame3d frStart ;
|
|
||||||
if ( bRMF) {
|
|
||||||
if ( ! frStart.Set( ptStart, vtStart))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Vector3d vtAxX = vtAx ^ vtStart ;
|
|
||||||
if ( vtAxX.IsSmall()) {
|
|
||||||
vtAxX = FromUprightOrtho( vtAx) ;
|
|
||||||
vtAxX.Rotate( vtAx, 0, 1) ;
|
|
||||||
}
|
|
||||||
if ( ! frStart.Set( ptStart, vtStart, vtAxX))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// capisco se la guida è una linea spezzata o una curva
|
|
||||||
bool bGuideIsPolyLine = false ;
|
|
||||||
switch( pGuide->GetType()) {
|
|
||||||
case CRV_COMPO : {
|
|
||||||
bGuideIsPolyLine = true ;
|
|
||||||
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
|
||||||
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
|
||||||
const ICurve* pCrv = pCC->GetCurve( i) ;
|
|
||||||
if ( pCrv->GetType() != CRV_LINE) {
|
|
||||||
if ( pCrv->GetType() == CRV_BEZIER) {
|
|
||||||
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
|
||||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bGuideIsPolyLine = false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
case CRV_LINE :
|
|
||||||
bGuideIsPolyLine = true ;
|
|
||||||
break ;
|
|
||||||
case CRV_BEZIER : {
|
|
||||||
// controllo se i punti di controllo sono allineati
|
|
||||||
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
|
||||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bRat = false ;
|
|
||||||
int nSpanV = 0 ;
|
|
||||||
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
||||||
if ( bGuideIsPolyLine) {
|
|
||||||
if ( pGuide->GetType() == CRV_LINE)
|
|
||||||
nSpanV = 1 ;
|
|
||||||
else if ( pGuide->GetType() == CRV_COMPO)
|
|
||||||
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// converto in bezier la guida ( grado 3, non razionale)
|
|
||||||
if ( pGuide->GetType() != CRV_BEZIER)
|
|
||||||
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
|
||||||
else {
|
|
||||||
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
|
||||||
if ( ! pGuideBez->IsRational())
|
|
||||||
pCrvV->AddCurve( pGuide->Clone()) ;
|
|
||||||
else
|
|
||||||
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
|
||||||
}
|
|
||||||
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
nSpanV = pCrvV->GetCurveCount() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// converto in bezier la sezione ( grado 3, non razionale)
|
|
||||||
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
|
||||||
if ( pSect->GetType() != CRV_BEZIER)
|
|
||||||
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
|
||||||
else {
|
|
||||||
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
|
||||||
if( ! pSectBez->IsRational())
|
|
||||||
pCrvU->AddCurve( pSect->Clone()) ; ///// questa curva potrebbe non essere di grado 3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
else
|
|
||||||
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
|
||||||
}
|
|
||||||
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
|
|
||||||
FRAME3DVECTOR vFrames ;
|
|
||||||
if ( bRMF) {
|
|
||||||
RotationMinimizingFrame RMF ;
|
|
||||||
if ( bGuideIsPolyLine) {
|
|
||||||
if ( ! RMF.Set( pGuide, frStart) ||
|
|
||||||
! RMF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( ! RMF.Set( pGuide, frStart) ||
|
|
||||||
! RMF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RotationXplaneFrame RXF ;
|
|
||||||
if ( bGuideIsPolyLine) {
|
|
||||||
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
|
||||||
! RXF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
|
||||||
! RXF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
|
|
||||||
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
|
||||||
int nDegU = 9 ; // debug
|
|
||||||
int nDegV = 3 ;
|
|
||||||
if ( bGuideIsPolyLine){
|
|
||||||
nDegV = 1 ;
|
|
||||||
// superficie swept
|
|
||||||
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
|
||||||
pSurfBez->Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
|
||||||
pCrvU->ToLoc( frStart) ;
|
|
||||||
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
|
||||||
PtrOwner<ICurveComposite> pNewSect( pCrvU->Clone()) ;
|
|
||||||
pNewSect->ToGlob( vFrames[f]) ;
|
|
||||||
for ( int i = 0 ; i < nSpanU ; ++i) {
|
|
||||||
const ICurveBezier* pSubCrvBez = GetCurveBezier( pNewSect->GetCurve( i)) ;
|
|
||||||
for ( int j = 0 ; j < nDegU + 1 ; ++j) {
|
|
||||||
Point3d ptCtrl = pSubCrvBez->GetControlPoint( j) ;
|
|
||||||
pSurfBez->SetControlPoint( i * nDegU + j, f, ptCtrl) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Release( pSurfBez) ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
||||||
pCrvU->ToLoc( frStart) ;
|
|
||||||
ICURVEPOVECTOR vCrvSet ;
|
|
||||||
CICURVEPVECTOR vpCrv ;
|
|
||||||
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
|
||||||
ICurve* pNewSect = pCrvU->Clone() ;
|
|
||||||
// porto la curva nel frame corrente
|
|
||||||
pNewSect->ToGlob( vFrames[f]) ;
|
|
||||||
vpCrv.push_back( pNewSect) ;
|
|
||||||
vCrvSet.emplace_back( pNewSect) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// se richiesti caps e sezione chiusa e guida aperta
|
|
||||||
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
||||||
|
|
||||||
// // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->ToGlob( vFrames.front()) ;
|
|
||||||
// // aggiungo
|
|
||||||
// StmFts.AddSurfTriMesh( *pSci) ;
|
|
||||||
|
|
||||||
// // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->ToGlob( vFrames.back()) ;
|
|
||||||
// // inverto
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// // aggiungo
|
|
||||||
// StmFts.AddSurfTriMesh( *pSce) ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
||||||
//double dVol ;
|
|
||||||
//if ( pSTM->GetVolume( dVol) && dVol < 0)
|
|
||||||
// pSTM->Invert() ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( &ptP == nullptr || pCurve == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// creo e setto la superficie trimesh
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifica parametri
|
|
||||||
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
|
||||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
||||||
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
|
||||||
if ( pCurve1->GetType() != CRV_BEZIER)
|
|
||||||
pCC1->AddCurve( CurveToBezierCurve( pCurve1, true, false)) ;
|
|
||||||
else
|
|
||||||
pCC1->AddCurve( pCurve1->Clone()) ;
|
|
||||||
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
||||||
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
|
||||||
if ( pCurve2->GetType() != CRV_BEZIER)
|
|
||||||
pCC2->AddCurve( CurveToBezierCurve( pCurve2, true, false)) ;
|
|
||||||
else
|
|
||||||
pCC2->AddCurve( pCurve2->Clone()) ;
|
|
||||||
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// creo e setto la superficie trimesh
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfBezier*
|
|
||||||
GetSurfBezierSkinned( const CICURVEPVECTOR& vCrv, double dLinTol)
|
|
||||||
{
|
|
||||||
// verifico che le curve siano valide
|
|
||||||
for ( int i = 0 ; i < int( vCrv.size()) ; ++i) {
|
|
||||||
if( vCrv[i] == nullptr || ! vCrv[i]->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// se ho solo due curve allora faccio la rigata
|
|
||||||
if( vCrv.size() == 2)
|
|
||||||
return GetSurfBezierRuled( vCrv[0], vCrv[1], ISurfBezier::RLT_B_MINDIST_PLUS, dLinTol) ;
|
|
||||||
|
|
||||||
//trasformo le curve in curve di bezier, pareggio il numero di sottocurve e il grado
|
|
||||||
|
|
||||||
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
|
||||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
||||||
ICURVEPOVECTOR vCrvBez ;
|
|
||||||
for( int c = 0 ; c < int( vCrv.size()) ; ++c){
|
|
||||||
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
|
|
||||||
if ( vCrv[c]->GetType() != CRV_BEZIER )
|
|
||||||
pCC->AddCurve( CurveToBezierCurve( vCrv[c])) ;
|
|
||||||
else
|
|
||||||
pCC->AddCurve( vCrv[c]->Clone()) ;
|
|
||||||
if ( IsNull( pCC) || ! pCC->IsValid())
|
|
||||||
return nullptr ;
|
|
||||||
vCrvBez.emplace_back( Release( pCC)) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// creo e setto la superficie trimesh
|
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateBySetOfCurves( vCrvBez, true))
|
|
||||||
return nullptr ;
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSbz) ;
|
|
||||||
}
|
|
||||||
+1
-34
@@ -17,13 +17,12 @@
|
|||||||
#include "SurfTriMesh.h"
|
#include "SurfTriMesh.h"
|
||||||
#include "SurfBezier.h"
|
#include "SurfBezier.h"
|
||||||
#include "/EgtDev/Include/EGkSbzStandard.h"
|
#include "/EgtDev/Include/EGkSbzStandard.h"
|
||||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfBezier*
|
ISurfBezier*
|
||||||
GetSurfBezierSphere( const Point3d& ptCenter, double dR)
|
CreateBezierSphere( const Point3d& ptCenter, double dR)
|
||||||
{
|
{
|
||||||
// creo una superficie di Bezier di grado 2 con 45 punti di controllo
|
// creo una superficie di Bezier di grado 2 con 45 punti di controllo
|
||||||
PtrOwner<ISurfBezier> pSrfBez( CreateSurfBezier()) ;
|
PtrOwner<ISurfBezier> pSrfBez( CreateSurfBezier()) ;
|
||||||
@@ -79,35 +78,3 @@ GetSurfBezierSphere( const Point3d& ptCenter, double dR)
|
|||||||
|
|
||||||
return Release( pSrfBez) ;
|
return Release( pSrfBez) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfBezier*
|
|
||||||
//GetSurfBezierCone( const Point3d& ptCenter, double dRadius, const Vector3d& dHeight)
|
|
||||||
//{
|
|
||||||
// // le dimensioni devono essere significative
|
|
||||||
// if ( dRadius < EPS_SMALL || abs( dHeight) < EPS_SMALL)
|
|
||||||
// return nullptr ;
|
|
||||||
// // creo la circonferenza di base
|
|
||||||
// CurveArc cArc ;
|
|
||||||
// cArc.Set( ORIG, Z_AX, dRadius) ;
|
|
||||||
// if ( dHeight < 0)
|
|
||||||
// cArc.Invert() ;
|
|
||||||
// // punto di vertice
|
|
||||||
// Point3d ptTip( 0, 0, dHeight) ;
|
|
||||||
// // creo la superficie laterale del cono
|
|
||||||
// PtrOwner<ISurfBezier> pSbz( GetSurfBezierRuled( ptTip, &cArc)) ;
|
|
||||||
// if ( IsNull( pSbz))
|
|
||||||
// return nullptr ;
|
|
||||||
//
|
|
||||||
// //// creo la superficie di base e la inverto
|
|
||||||
// //PtrOwner<ISurfTriMesh> pSTM1( GetSurfTriMeshByFlatContour( &cArc, dLinTol)) ;
|
|
||||||
// //if ( IsNull( pSTM1))
|
|
||||||
// // return nullptr ;
|
|
||||||
// //pSTM1->Invert() ;
|
|
||||||
// //// la unisco alla superficie del fianco
|
|
||||||
// //if ( ! pSTM->DoSewing( *pSTM1))
|
|
||||||
// // return nullptr ;
|
|
||||||
//
|
|
||||||
// // restituisco la superficie
|
|
||||||
// return Release( pSbz) ;
|
|
||||||
//}
|
|
||||||
|
|||||||
+1
-3
@@ -88,8 +88,6 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
default :
|
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
// per curva approssimata, sistemo...
|
// per curva approssimata, sistemo...
|
||||||
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
||||||
@@ -135,7 +133,7 @@ bool
|
|||||||
SelfIntersCurve::AdjustIntersParams( bool bAdjCrv, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
SelfIntersCurve::AdjustIntersParams( bool bAdjCrv, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||||
{
|
{
|
||||||
// se la curva originale non è stata approssimata o non ci sono auto-intersezioni, non va fatto alcunché
|
// se la curva originale non è stata approssimata o non ci sono auto-intersezioni, non va fatto alcunché
|
||||||
if ( ! bAdjCrv || m_Info.empty())
|
if ( ! bAdjCrv || m_Info.size() == 0)
|
||||||
return true ;
|
return true ;
|
||||||
// procedo ad aggiustare
|
// procedo ad aggiustare
|
||||||
for ( auto& aInfo : m_Info) {
|
for ( auto& aInfo : m_Info) {
|
||||||
|
|||||||
+32
-144
@@ -115,8 +115,7 @@ GetSurfFlatRegionDisk( double dRadius)
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfFlatRegion*
|
ISurfFlatRegion*
|
||||||
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, double dOffsLinTol,
|
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, double dOffsLinTol)
|
||||||
bool bMergeOnlySameProps)
|
|
||||||
{
|
{
|
||||||
// metodo di calcolo impostato da USE_VORONOI
|
// metodo di calcolo impostato da USE_VORONOI
|
||||||
|
|
||||||
@@ -331,7 +330,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
|||||||
else {
|
else {
|
||||||
// calcolo la fat curve con Voronoi
|
// calcolo la fat curve con Voronoi
|
||||||
ICURVEPOVECTOR vFatCurves ;
|
ICURVEPOVECTOR vFatCurves ;
|
||||||
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids, bMergeOnlySameProps))
|
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// costruisco la superficie a partire dalle curve
|
// costruisco la superficie a partire dalle curve
|
||||||
@@ -368,14 +367,25 @@ GetSurfFlatRegionFromTriangle( const Triangle3d& Tria)
|
|||||||
ISurfFlatRegion*
|
ISurfFlatRegion*
|
||||||
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||||
{
|
{
|
||||||
// Creo curva composita.
|
|
||||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
|
||||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( ContourPolyLine))
|
|
||||||
return nullptr ;
|
|
||||||
// Creo la regione.
|
// Creo la regione.
|
||||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pLoop)))
|
if ( IsNull( pSfr))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
// Creo curva composita.
|
||||||
|
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||||
|
if ( IsNull( pLoop))
|
||||||
|
return nullptr ;
|
||||||
|
Point3d ptSt, ptEn ;
|
||||||
|
bool bContinue = ContourPolyLine.GetFirstPoint( ptSt) &&
|
||||||
|
ContourPolyLine.GetNextPoint( ptEn) ;
|
||||||
|
while ( bContinue) {
|
||||||
|
CurveLine cvLine ;
|
||||||
|
cvLine.Set( ptSt, ptEn) ;
|
||||||
|
pLoop->AddCurve( cvLine) ;
|
||||||
|
ptSt = ptEn ;
|
||||||
|
bContinue = ContourPolyLine.GetNextPoint( ptEn) ;
|
||||||
|
}
|
||||||
|
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||||
return Release( pSfr) ;
|
return Release( pSfr) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,17 +401,25 @@ GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
|||||||
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
||||||
// Creo curva composita.
|
// Creo curva composita.
|
||||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( vContoursPolyLineVec[nL]))
|
if ( IsNull( pLoop))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
Point3d ptSt, ptEn ;
|
||||||
|
bool bContinue = vContoursPolyLineVec[nL].GetFirstPoint( ptSt) &&
|
||||||
|
vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||||
|
while ( bContinue) {
|
||||||
|
CurveLine cvLine ;
|
||||||
|
cvLine.Set( ptSt, ptEn) ;
|
||||||
|
pLoop->AddCurve( cvLine) ;
|
||||||
|
ptSt = ptEn ;
|
||||||
|
bContinue = vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||||
|
}
|
||||||
// Loop esterno
|
// Loop esterno
|
||||||
if ( nL == 0) {
|
if ( nL == 0) {
|
||||||
if ( ! pSfr->AddExtLoop( Release( pLoop)))
|
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||||
return nullptr ;
|
|
||||||
}
|
}
|
||||||
// Loop interno
|
// Loop interno
|
||||||
else {
|
else {
|
||||||
if ( ! pSfr->AddIntLoop( Release( pLoop)))
|
pSfr->AddIntLoop( Release( pLoop)) ;
|
||||||
return nullptr ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Release( pSfr) ;
|
return Release( pSfr) ;
|
||||||
@@ -572,134 +590,4 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
|
|||||||
vId.push_back( pCrv->GetTempProp()) ;
|
vId.push_back( pCrv->GetTempProp()) ;
|
||||||
}
|
}
|
||||||
return ( ! vId.empty()) ;
|
return ( ! vId.empty()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
|
|
||||||
{
|
|
||||||
// vnPLIndMat : ogni riga corrisponde ad un chunk, in posizione 0 c'è il loop esterno e nelle successive i loop interni
|
|
||||||
// vbInvert : riferito al vettore delle polyline, riporta true se la polyline è stata invertita
|
|
||||||
|
|
||||||
// ricavo versore normale
|
|
||||||
Plane3d plPlane ; double dArea ;
|
|
||||||
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
|
||||||
return false ;
|
|
||||||
vtN = plPlane.GetVersN() ;
|
|
||||||
|
|
||||||
typedef std::pair<int,double> INDAREA ;
|
|
||||||
std::vector<INDAREA> m_vArea ;
|
|
||||||
// calcolo piano medio e area delle curve
|
|
||||||
m_vArea.reserve( vPL.size()) ;
|
|
||||||
VCT3DVECTOR vvtN ;
|
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
||||||
// calcolo piano medio e area
|
|
||||||
Plane3d plPlane ;
|
|
||||||
double dArea ;
|
|
||||||
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
|
||||||
return false ;
|
|
||||||
// verifico che le normali siano molto vicine
|
|
||||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN))
|
|
||||||
return false ;
|
|
||||||
// salvo la normale
|
|
||||||
vvtN.push_back( plPlane.GetVersN()) ;
|
|
||||||
// assegno il segno all'area secondo il verso della normale
|
|
||||||
if ( ( plPlane.GetVersN() * vtN) > 0)
|
|
||||||
m_vArea.emplace_back( i, dArea) ;
|
|
||||||
else
|
|
||||||
m_vArea.emplace_back( i, - dArea) ;
|
|
||||||
}
|
|
||||||
// ordino in senso decrescente sull'area
|
|
||||||
sort( m_vArea.begin(), m_vArea.end(),
|
|
||||||
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
|
||||||
|
|
||||||
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
|
||||||
Frame3d frRef ; frRef.Set( ORIG, vtN) ;
|
|
||||||
if ( ! frRef.IsValid())
|
|
||||||
return false ;
|
|
||||||
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
||||||
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
|
||||||
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
|
||||||
vCrvCompo[i]->ToLoc( frRef) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// restituisco la normale del loop più grande
|
|
||||||
bool bInvertAll = vvtN[m_vArea[0].first] * vtN < 0 ;
|
|
||||||
vtN = vvtN[m_vArea[0].first] ;
|
|
||||||
|
|
||||||
//// vettore di indici per ordinare le PolyLine
|
|
||||||
INTVECTOR vPL_IndOrder ; vPL_IndOrder.resize( int( vPL.size())) ;
|
|
||||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i)
|
|
||||||
vPL_IndOrder[i] = m_vArea[i].first ;
|
|
||||||
|
|
||||||
// aggiungo le diverse curve
|
|
||||||
bool bFirstCrv ;
|
|
||||||
Plane3d plExtLoop ;
|
|
||||||
double dAreaExtLoop = 0. ;
|
|
||||||
vbInvert.resize( vPL.size()) ;
|
|
||||||
fill( vbInvert.begin(), vbInvert.end(), false) ;
|
|
||||||
do {
|
|
||||||
bFirstCrv = true ;
|
|
||||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
|
||||||
// recupero indice di percorso e verifico sia valido
|
|
||||||
int j = m_vArea[i].first ;
|
|
||||||
if ( j < 0)
|
|
||||||
continue ;
|
|
||||||
// lo inserisco come esterno...
|
|
||||||
if ( bFirstCrv) {
|
|
||||||
vnPLIndMat.push_back({ j}) ;
|
|
||||||
m_vArea[i].first = -1 ;
|
|
||||||
dAreaExtLoop = m_vArea[i].second ;
|
|
||||||
// inverto se necessario
|
|
||||||
if ( m_vArea[i].second < EPS_SMALL) {
|
|
||||||
vCrvCompo[j]->Invert() ;
|
|
||||||
dAreaExtLoop *= -1 ;
|
|
||||||
vbInvert[j] = true ;
|
|
||||||
}
|
|
||||||
bFirstCrv = false ;
|
|
||||||
}
|
|
||||||
// ... altrimenti verifico se il loop è interno o no
|
|
||||||
else {
|
|
||||||
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
|
||||||
// esterno a tutti i loop già inseriti nella riga attuale.
|
|
||||||
// verifica rispetto loop esterno
|
|
||||||
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
|
||||||
CRVCVECTOR ccClass ;
|
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
|
||||||
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
|
||||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
|
||||||
continue ;
|
|
||||||
// verifica rispetto ai loop interni
|
|
||||||
bool bOk = true ;
|
|
||||||
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
|
||||||
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
|
||||||
CRVCVECTOR ccClass2 ;
|
|
||||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
|
||||||
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
|
||||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
|
||||||
bOk = false ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( bOk) {
|
|
||||||
// inserisco nella matrice
|
|
||||||
vnPLIndMat.back().push_back( j) ;
|
|
||||||
m_vArea[i].first = -1 ;
|
|
||||||
// inverto se necessario
|
|
||||||
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
|
||||||
vCrvCompo[j]->Invert() ;
|
|
||||||
vbInvert[j] = true ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ( ! bFirstCrv) ;
|
|
||||||
|
|
||||||
if ( bInvertAll) {
|
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i)
|
|
||||||
vbInvert[i] = ! vbInvert[i] ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
+238
-432
@@ -31,6 +31,10 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
static bool CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||||
|
POLYLINEVECTOR& vPL, Vector3d& vtN) ;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfTriMesh*
|
ISurfTriMesh*
|
||||||
GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||||
@@ -61,25 +65,12 @@ GetSurfTriMeshByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
// calcolo le polilinee che approssimano le curve della regione
|
// calcolo le polilinee che approssimano le curve della regione
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
vPL.resize( vpCurve.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
|
||||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
Vector3d vtN ;
|
Vector3d vtN ;
|
||||||
INTMATRIX vnPLIndMat ;
|
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||||
BOOLVECTOR vbInvert ;
|
|
||||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat, vbInvert))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) {
|
|
||||||
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++j){
|
|
||||||
if( vbInvert[vnPLIndMat[i][j]])
|
|
||||||
vPL[vnPLIndMat[i][j]].Invert() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// creo e setto la superficie trimesh
|
// creo e setto la superficie trimesh
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL, vnPLIndMat))
|
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// salvo tolleranza lineare usata
|
// salvo tolleranza lineare usata
|
||||||
pSTM->SetLinearTolerance( dLinTol) ;
|
pSTM->SetLinearTolerance( dLinTol) ;
|
||||||
@@ -154,20 +145,9 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
|||||||
return GetSurfTriMeshByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
return GetSurfTriMeshByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
||||||
// calcolo le polilinee che approssimano le curve della regione
|
// calcolo le polilinee che approssimano le curve della regione
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
vPL.resize( vpCurve.size()) ;
|
|
||||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
|
||||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
|
||||||
Vector3d vtN ;
|
Vector3d vtN ;
|
||||||
INTMATRIX vnPLIndMat ;
|
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||||
BOOLVECTOR vbInvert ;
|
|
||||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat, vbInvert))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
|
|
||||||
if( vbInvert[i])
|
|
||||||
vPL[i].Invert() ;
|
|
||||||
}
|
|
||||||
// verifico la direzione di estrusione
|
// verifico la direzione di estrusione
|
||||||
double dOrthoExtr = vtN * vtExtr ;
|
double dOrthoExtr = vtN * vtExtr ;
|
||||||
if ( ( abs( dOrthoExtr) < EPS_SMALL))
|
if ( ( abs( dOrthoExtr) < EPS_SMALL))
|
||||||
@@ -179,8 +159,7 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
|||||||
}
|
}
|
||||||
// creo la prima superficie di estremità
|
// creo la prima superficie di estremità
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
// alla funzione CreateByRegion passo anche la matrice che contiene la struttura dei chunk. Le polyline hanno già il verso giusto
|
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL, vnPLIndMat))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// creo la seconda superficie e la unisco alla prima
|
// creo la seconda superficie e la unisco alla prima
|
||||||
{ // copio la prima superficie
|
{ // copio la prima superficie
|
||||||
@@ -351,11 +330,9 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
|||||||
{
|
{
|
||||||
// verifico che la linea guida sia piana
|
// verifico che la linea guida sia piana
|
||||||
Plane3d plGuide ;
|
Plane3d plGuide ;
|
||||||
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
|
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
|
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||||
if ( vtNorm.IsSmall())
|
|
||||||
vtNorm = Z_AX ;
|
|
||||||
// determino se la guida è chiusa
|
// determino se la guida è chiusa
|
||||||
bool bGuideClosed = pGuide->IsClosed() ;
|
bool bGuideClosed = pGuide->IsClosed() ;
|
||||||
// curve di offset
|
// curve di offset
|
||||||
@@ -378,7 +355,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
|||||||
PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
||||||
if ( IsNull( pSrfBot))
|
if ( IsNull( pSrfBot))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSrfBot->Translate( - dDimV * vtNorm) ;
|
pSrfBot->Translate( -dDimV * vtNorm) ;
|
||||||
pSrfBot->Invert() ;
|
pSrfBot->Invert() ;
|
||||||
PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
|
PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
|
||||||
if ( IsNull( pSrfRgt))
|
if ( IsNull( pSrfRgt))
|
||||||
@@ -388,188 +365,74 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
|||||||
if ( IsNull( pSrfLft))
|
if ( IsNull( pSrfLft))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// unisco le parti
|
// unisco le parti
|
||||||
int nBuckets = max( 2 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
||||||
StmFromTriangleSoup stmSoup ;
|
pSTM->DoSewing( *pSrfRgt) ;
|
||||||
if ( ! stmSoup.Start( nBuckets))
|
pSTM->DoSewing( *pSrfLft) ;
|
||||||
return nullptr ;
|
pSTM->DoSewing( *pSrfBot) ;
|
||||||
stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||||
stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
pSTM->SetLinearTolerance( dLinTol) ;
|
||||||
stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
pSTM->SetSmoothAngle( 20) ;
|
||||||
stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
|
||||||
PtrOwner<ISurfTriMesh> pSTM ;
|
|
||||||
// se guida aperta e tappi piatti
|
// se guida aperta e tappi piatti
|
||||||
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
||||||
// completo unione e recupero la superficie risultante
|
|
||||||
if ( ! stmSoup.End())
|
|
||||||
return nullptr ;
|
|
||||||
pSTM.Set( stmSoup.GetSurf()) ;
|
|
||||||
// verifico che le due estremità siano chiuse e piatte
|
// verifico che le due estremità siano chiuse e piatte
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
Plane3d plEnds ; double dArea ;
|
Plane3d plEnds ; double dArea ;
|
||||||
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// calcolo il cap sull'inizio
|
// aggiungo il cap sull'inizio
|
||||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSci->Invert() ;
|
pSci->Invert() ;
|
||||||
// calcolo il cap sulla fine
|
pSTM->DoSewing( *pSci) ;
|
||||||
|
// aggiungo il cap sulla fine
|
||||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSce->Invert() ;
|
pSce->Invert() ;
|
||||||
// cucio i tappi all'estrusione
|
pSTM->DoSewing( *pSce) ;
|
||||||
if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
|
|
||||||
return nullptr ;
|
|
||||||
}
|
}
|
||||||
// se altrimenti guida aperta e tappi arrotondati
|
// se altrimenti guida aperta e tappi arrotondati
|
||||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||||
// step di rotazione per rispettare la tolleranza
|
// step di rotazione per rispettare la tolleranza
|
||||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||||
// se l'offset interno alla guida è chiuso
|
// aggiungo il cap sull'inizio
|
||||||
if ( pCrvL->IsClosed()) {
|
Point3d ptStart ;
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
pGuide->GetStartPoint( ptStart) ;
|
||||||
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
|
Vector3d vtStart ;
|
||||||
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
|
pGuide->GetStartDir( vtStart) ;
|
||||||
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
|
vtStart.Rotate( vtNorm, 0, 1) ;
|
||||||
Point3d ptCenter = Media( ptRight, ptLeft) ;
|
PolyLine PLStart ;
|
||||||
Vector3d vtRight = ptRight - ptCenter ;
|
PLStart.AddUPoint( 0, ptStart) ;
|
||||||
Vector3d vtLeft = ptLeft - ptCenter ;
|
PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ;
|
||||||
double dAng = ANG_STRAIGHT ;
|
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ;
|
||||||
vtRight.GetAngle( vtLeft, dAng) ;
|
PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ;
|
||||||
vtRight.Normalize() ;
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
PolyLine plLoop ;
|
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoop.AddUPoint( 0, ptRight) ; // primo punto
|
|
||||||
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptRight ;
|
|
||||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
|
|
||||||
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
|
|
||||||
// superificie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop) ;
|
|
||||||
// superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
|
|
||||||
pStmBottom->Translate( - dDimV * vtNorm) ;
|
|
||||||
pStmBottom->Invert() ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom) ;
|
|
||||||
// superificie perpendicolare
|
|
||||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp) || ! pStmPerp->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
|
||||||
! pStmPerp->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp) ;
|
|
||||||
}
|
|
||||||
// se l'offset interno della guida è aperto...
|
|
||||||
else {
|
|
||||||
// aggiungo il cap sull'inizio
|
|
||||||
Point3d ptStart ;
|
|
||||||
pGuide->GetStartPoint( ptStart) ;
|
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
|
||||||
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
|
|
||||||
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
|
|
||||||
Vector3d vtLeft = ptSLeft - ptStart ;
|
|
||||||
Vector3d vtRight = ptSRight - ptStart ;
|
|
||||||
double dAng = ANG_STRAIGHT ;
|
|
||||||
vtLeft.GetAngle( vtRight, dAng) ;
|
|
||||||
vtLeft.Normalize() ;
|
|
||||||
PolyLine plLoop ;
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
|
|
||||||
double dAngStep = ceil( dAng / dStepRotDeg) ;
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSLeft ;
|
|
||||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
|
|
||||||
// creo la superficie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
|
|
||||||
// superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
|
|
||||||
pStmBottom_start->Translate( - dDimV * vtNorm) ;
|
|
||||||
pStmBottom_start->Invert() ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
|
|
||||||
// superificie perpendicolare
|
|
||||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp_start) || ! pStmPerp_start->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
|
||||||
! pStmPerp_start->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
|
|
||||||
// aggiungo il cap sulla fine
|
|
||||||
Point3d ptEnd ;
|
|
||||||
pGuide->GetEndPoint( ptEnd) ;
|
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
|
||||||
pCrvL->GetEndPoint( ptSLeft) ;
|
|
||||||
pCrvR->GetEndPoint( ptSRight) ;
|
|
||||||
vtLeft = ptSLeft - ptEnd ;
|
|
||||||
vtRight = ptSRight - ptEnd ;
|
|
||||||
dAng = ANG_STRAIGHT ;
|
|
||||||
vtRight.GetAngle( vtLeft, dAng) ;
|
|
||||||
vtRight.Normalize() ;
|
|
||||||
plLoop.Clear() ;
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoop.AddUPoint( 0, ptSRight) ;
|
|
||||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSRight ;
|
|
||||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
|
|
||||||
// creo la superficie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
|
|
||||||
// creo la superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom_end( CloneSurfTriMesh( pStmTop_end)) ;
|
|
||||||
pStmBottom_end->Translate( - dDimV * vtNorm) ;
|
|
||||||
pStmBottom_end->Invert() ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
|
|
||||||
// creo la superificie perpendicolare alla guida
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp_end) || ! pStmPerp_end->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
|
||||||
! pStmPerp_end->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
|
|
||||||
}
|
|
||||||
// completo unione e recupero la superficie risultante
|
|
||||||
if ( ! stmSoup.End())
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSTM.Set( stmSoup.GetSurf()) ;
|
pSci->Invert() ;
|
||||||
}
|
pSTM->DoSewing( *pSci) ;
|
||||||
else {
|
// aggiungo il cap sulla fine
|
||||||
// completo unione e recupero la superficie risultante
|
Point3d ptEnd ;
|
||||||
if ( ! stmSoup.End())
|
pGuide->GetEndPoint( ptEnd) ;
|
||||||
|
Vector3d vtEnd ;
|
||||||
|
pGuide->GetEndDir( vtEnd) ;
|
||||||
|
vtEnd.Rotate( vtNorm, 0, -1) ;
|
||||||
|
PolyLine PLEnd ;
|
||||||
|
PLEnd.AddUPoint( 0, ptEnd) ;
|
||||||
|
PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ;
|
||||||
|
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ;
|
||||||
|
PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ;
|
||||||
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSTM.Set( stmSoup.GetSurf()) ;
|
pSce->Invert() ;
|
||||||
|
pSTM->DoSewing( *pSce) ;
|
||||||
}
|
}
|
||||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
|
||||||
pSTM->SetLinearTolerance( dLinTol) ;
|
|
||||||
pSTM->SetSmoothAngle( 20) ;
|
|
||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSTM) ;
|
return Release( pSTM) ;
|
||||||
}
|
}
|
||||||
@@ -582,13 +445,13 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
|
|
||||||
// verifico che la linea guida sia piana
|
// verifico che la linea guida sia piana
|
||||||
Plane3d plGuide ;
|
Plane3d plGuide ;
|
||||||
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
|
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
|
// assegno la normale del piano
|
||||||
if ( vtNorm.IsSmall())
|
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||||
vtNorm = Z_AX ;
|
|
||||||
// determino il punto centrale della sezione
|
// determino il punto centrale della sezione
|
||||||
Point3d ptCen ; pGuide->GetStartPoint( ptCen) ;
|
Point3d ptCen ;
|
||||||
|
pGuide->GetStartPoint( ptCen) ;
|
||||||
ptCen -= dDimV / 2 * vtNorm ;
|
ptCen -= dDimV / 2 * vtNorm ;
|
||||||
// determino se la guida è chiusa
|
// determino se la guida è chiusa
|
||||||
bool bGuideClosed = pGuide->IsClosed() ;
|
bool bGuideClosed = pGuide->IsClosed() ;
|
||||||
@@ -617,6 +480,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
||||||
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! bOk ||
|
if ( ! bOk ||
|
||||||
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
||||||
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
||||||
@@ -685,6 +549,10 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
if ( ! stmSoup.End())
|
if ( ! stmSoup.End())
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pSTM.Set( stmSoup.GetSurf()) ;
|
pSTM.Set( stmSoup.GetSurf()) ;
|
||||||
|
// preparo seconda zuppa di triangoli per inserire i tappi
|
||||||
|
StmFromTriangleSoup stmCapSoup ;
|
||||||
|
if ( ! stmCapSoup.Start( nBuckets))
|
||||||
|
return nullptr ;
|
||||||
// verifico che le due estremità siano chiuse e piatte
|
// verifico che le due estremità siano chiuse e piatte
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||||
@@ -712,236 +580,42 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||||
// step di rotazione per rispettare il tipo o la tolleranza
|
// step di rotazione per rispettare il tipo o la tolleranza
|
||||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||||
// se l'offset interno della guida è chiuso...
|
// aggiungo il cap sull'inizio
|
||||||
if ( pCrvL->IsClosed()) {
|
Point3d ptStart ;
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
pGuide->GetStartPoint( ptStart) ;
|
||||||
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
|
Vector3d vtStart ;
|
||||||
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
|
pGuide->GetStartDir( vtStart) ;
|
||||||
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
|
vtStart.Rotate( vtNorm, 0, 1) ;
|
||||||
Point3d ptCenter = Media( ptRight, ptLeft) ;
|
PolyLine PLStart ;
|
||||||
Vector3d vtRight = ptRight - ptCenter ;
|
PLStart.AddUPoint( 0, ptStart) ;
|
||||||
Vector3d vtLeft = ptLeft - ptCenter ;
|
PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ;
|
||||||
double dAng = ANG_STRAIGHT ;
|
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ;
|
||||||
vtRight.GetAngle( vtLeft, dAng) ;
|
PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ;
|
||||||
vtRight.Normalize() ;
|
PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ;
|
||||||
PolyLine plLoop ;
|
PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ;
|
||||||
// creo il loop defininendo i punti
|
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||||
plLoop.AddUPoint( 0, ptRight) ; // primo punto
|
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||||
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptRight ;
|
|
||||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
|
|
||||||
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
|
|
||||||
// superificie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop) ;
|
|
||||||
// superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
|
|
||||||
if ( IsNull( pStmBottom) || ! pStmBottom->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom) ;
|
|
||||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
|
||||||
// NB. Questo angolo va ricalcolato, il bevel è inclinato rispetto alla normale della guida
|
|
||||||
ptCenter.Translate( - dBevelV * vtNorm) ;
|
|
||||||
Point3d ptbRight ; pCrvRb->GetEndPoint( ptbRight) ;
|
|
||||||
Point3d ptbLeft ; pCrvRb->GetStartPoint( ptbLeft) ;
|
|
||||||
Vector3d vtbLeft = ptbLeft - ptCenter ;
|
|
||||||
Vector3d vtbRight = ptbRight - ptCenter ;
|
|
||||||
dAng = ANG_STRAIGHT ;
|
|
||||||
vtbRight.GetAngle( vtbLeft, dAng) ;
|
|
||||||
vtbRight.Normalize() ;
|
|
||||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
PolyLine plLoopB ;
|
|
||||||
plLoopB.AddUPoint( 0, ptbRight) ;
|
|
||||||
dAngStep = ceil( dAng / dStepRotDeg) ;
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptbRight ;
|
|
||||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoopB.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoopB.AddUPoint( dAngStep, ptbLeft) ;
|
|
||||||
// creo la superficie Top Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmbTop_start) ||
|
|
||||||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmbTop_start->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
|
|
||||||
// creo la superificie Bottom Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
|
|
||||||
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
|
|
||||||
// creo la superficie perpendicolare alla guida
|
|
||||||
PolyLine plLoopB1 = plLoopB ;
|
|
||||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp) ||
|
|
||||||
! pStmPerp->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmPerp->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp) ;
|
|
||||||
}
|
|
||||||
// se l'offset interno della guida è aperto...
|
|
||||||
else {
|
|
||||||
// aggiungo il cap sull'inizio
|
|
||||||
Point3d ptStart ;
|
|
||||||
pGuide->GetStartPoint( ptStart) ;
|
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
|
||||||
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
|
|
||||||
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
|
|
||||||
Vector3d vtLeft = ptSLeft - ptStart ;
|
|
||||||
Vector3d vtRight = ptSRight - ptStart ;
|
|
||||||
double dAng = ANG_STRAIGHT ;
|
|
||||||
vtLeft.GetAngle( vtRight, dAng) ;
|
|
||||||
vtLeft.Normalize() ;
|
|
||||||
PolyLine plLoop ;
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
|
|
||||||
double dAngStep = ceil( dAng / dStepRotDeg) ;
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSLeft ;
|
|
||||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
|
|
||||||
// creo la superficie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
|
|
||||||
// creo la superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
|
|
||||||
if ( IsNull( pStmBottom_start) || ! pStmBottom_start->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
|
|
||||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
|
||||||
ptStart.Translate( - dBevelV * vtNorm) ;
|
|
||||||
Point3d ptSbLeft ; pCrvLb->GetStartPoint( ptSbLeft) ;
|
|
||||||
Point3d ptSbRight ; pCrvRb->GetStartPoint( ptSbRight) ;
|
|
||||||
Vector3d vtbLeft = ptSbLeft - ptStart ;
|
|
||||||
Vector3d vtbRight = ptSbRight - ptStart ;
|
|
||||||
dAng = ANG_STRAIGHT ;
|
|
||||||
vtbLeft.GetAngle( vtbRight, dAng) ;
|
|
||||||
vtbLeft.Normalize() ;
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
PolyLine plLoopB ;
|
|
||||||
plLoopB.AddUPoint( 0, ptSbLeft) ;
|
|
||||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSbLeft ;
|
|
||||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoopB.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoopB.AddUPoint( dAngStep, ptSbRight) ; // ultimo punto
|
|
||||||
// creo la superficie Top Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmbTop_start) ||
|
|
||||||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmbTop_start->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
|
|
||||||
// creo la superificie Bottom Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
|
|
||||||
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
|
|
||||||
// creo la superficie perpendicolare alla guida
|
|
||||||
PolyLine plLoopB1 = plLoopB ;
|
|
||||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp_start) ||
|
|
||||||
! pStmPerp_start->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmPerp_start->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
|
|
||||||
// aggiungo il cap sulla fine
|
|
||||||
Point3d ptEnd ;
|
|
||||||
pGuide->GetEndPoint( ptEnd) ;
|
|
||||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
|
||||||
pCrvL->GetEndPoint( ptSLeft) ;
|
|
||||||
pCrvR->GetEndPoint( ptSRight) ;
|
|
||||||
vtLeft = ptSLeft - ptEnd ;
|
|
||||||
vtRight = ptSRight - ptEnd ;
|
|
||||||
dAng = ANG_STRAIGHT ;
|
|
||||||
vtRight.GetAngle( vtLeft, dAng) ;
|
|
||||||
vtRight.Normalize() ;
|
|
||||||
plLoop.Clear() ;
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoop.AddUPoint( 0, ptSRight) ;
|
|
||||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSRight ;
|
|
||||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoop.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
|
|
||||||
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
|
|
||||||
// creo la superficie Top
|
|
||||||
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
|
|
||||||
// creo la superificie Bottom
|
|
||||||
PtrOwner<ISurfTriMesh> pStmBottom_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmBottom_end) ||
|
|
||||||
! pStmBottom_end->CopyFrom( pStmTop_end) ||
|
|
||||||
! pStmBottom_end->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
|
|
||||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
|
||||||
ptEnd.Translate( - dBevelV * vtNorm) ;
|
|
||||||
pCrvLb->GetEndPoint( ptSbLeft) ;
|
|
||||||
pCrvRb->GetEndPoint( ptSbRight) ;
|
|
||||||
vtbLeft = ptSbLeft - ptEnd ;
|
|
||||||
vtbRight = ptSbRight - ptEnd ;
|
|
||||||
dAng = ANG_STRAIGHT ;
|
|
||||||
vtbRight.GetAngle( vtbLeft, dAng) ;
|
|
||||||
vtbRight.Normalize() ;
|
|
||||||
plLoop.EraseLastUPoint() ; // apro il loop
|
|
||||||
// creo il loop defininendo i punti
|
|
||||||
plLoopB.Clear() ;
|
|
||||||
plLoopB.AddUPoint( 0, ptSbRight) ;
|
|
||||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
|
||||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
|
||||||
Point3d ptRot = ptSbRight ;
|
|
||||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
|
||||||
plLoopB.AddUPoint( i, ptRot) ;
|
|
||||||
}
|
|
||||||
plLoopB.AddUPoint( dAngStep, ptSbLeft) ; // ultimo punto
|
|
||||||
// creo la superficie Top Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbTop_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmbTop_end) ||
|
|
||||||
! pStmbTop_end->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmbTop_end->Invert())
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbTop_end) ;
|
|
||||||
// creo la superificie Bottom Bevel
|
|
||||||
PtrOwner<ISurfTriMesh> pStmbBottom_end( CloneSurfTriMesh( pStmbTop_end)) ;
|
|
||||||
if ( IsNull( pStmbBottom_end) || ! pStmbBottom_end->Mirror( ptCen, vtNorm))
|
|
||||||
return nullptr ;
|
|
||||||
stmSoup.AddSurfTriMesh( *pStmbBottom_end) ;
|
|
||||||
// creo la superficie perpendicolare alla guida
|
|
||||||
plLoopB1 = plLoopB ;
|
|
||||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
|
||||||
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStmPerp_end) ||
|
|
||||||
! pStmPerp_end->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
|
||||||
! pStmPerp_end->Invert())
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
|
pSci->Invert() ;
|
||||||
}
|
stmSoup.AddSurfTriMesh( *pSci) ;
|
||||||
|
// aggiungo il cap sulla fine
|
||||||
|
Point3d ptEnd ;
|
||||||
|
pGuide->GetEndPoint( ptEnd) ;
|
||||||
|
Vector3d vtEnd ;
|
||||||
|
pGuide->GetEndDir( vtEnd) ;
|
||||||
|
vtEnd.Rotate( vtNorm, 0, -1) ;
|
||||||
|
PolyLine PLEnd ;
|
||||||
|
PLEnd.AddUPoint( 0, ptEnd) ;
|
||||||
|
PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ;
|
||||||
|
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ;
|
||||||
|
PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ;
|
||||||
|
PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ;
|
||||||
|
PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ;
|
||||||
|
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||||
|
return nullptr ;
|
||||||
|
pSce->Invert() ;
|
||||||
|
stmSoup.AddSurfTriMesh( *pSce) ;
|
||||||
// completo unione e recupero la superficie risultante
|
// completo unione e recupero la superficie risultante
|
||||||
if ( ! stmSoup.End())
|
if ( ! stmSoup.End())
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -960,7 +634,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
|||||||
return Release( pSTM) ;
|
return Release( pSTM) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfTriMesh*
|
ISurfTriMesh*
|
||||||
GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol)
|
GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol)
|
||||||
@@ -1300,9 +973,8 @@ GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
|
// creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
|
||||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
|
||||||
INTMATRIX vnPLIndMat ;
|
if ( ! pSci->CreateByRegion( vPLi))
|
||||||
if ( ! pSci->CreateByRegion( vPLi, vnPLIndMat))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
pStmSwept->DoSewing( *pSci) ;
|
pStmSwept->DoSewing( *pSci) ;
|
||||||
// recupero i loops alla fine
|
// recupero i loops alla fine
|
||||||
@@ -1310,9 +982,8 @@ GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, cons
|
|||||||
if ( ! pStmSwept->GetLoops( vPLe))
|
if ( ! pStmSwept->GetLoops( vPLe))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// creo la superficie alla fine e la attacco
|
// creo la superficie alla fine e la attacco
|
||||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
||||||
vnPLIndMat.clear() ;
|
if ( ! pSce->CreateByRegion( vPLe))
|
||||||
if ( ! pSce->CreateByRegion( vPLe, vnPLIndMat))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// attacco la superficie finale alla swept
|
// attacco la superficie finale alla swept
|
||||||
pSce->Invert() ;
|
pSce->Invert() ;
|
||||||
@@ -1456,3 +1127,138 @@ GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, do
|
|||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSTM) ;
|
return Release( pSTM) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||||
|
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||||
|
{
|
||||||
|
// se non ho curve, non faccio nulla
|
||||||
|
if ( int( vpCurve.size()) == 0)
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
// calcolo le polilinee che approssimano le curve
|
||||||
|
vPL.resize( vpCurve.size()) ;
|
||||||
|
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||||
|
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ricavo versore normale
|
||||||
|
Plane3d plPlane ; double dArea ;
|
||||||
|
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
vtN = plPlane.GetVersN() ;
|
||||||
|
|
||||||
|
typedef std::pair<int,double> INDAREA ;
|
||||||
|
std::vector<INDAREA> m_vArea ;
|
||||||
|
// calcolo piano medio e area delle curve
|
||||||
|
m_vArea.reserve( vPL.size()) ;
|
||||||
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
|
// calcolo piano medio e area
|
||||||
|
Plane3d plPlane ;
|
||||||
|
double dArea ;
|
||||||
|
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||||
|
return false ;
|
||||||
|
// verifico che le normali siano molto vicine
|
||||||
|
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN))
|
||||||
|
return false ;
|
||||||
|
// assegno il segno all'area secondo il verso della normale
|
||||||
|
if ( ( plPlane.GetVersN() * vtN) > 0)
|
||||||
|
m_vArea.emplace_back( i, dArea) ;
|
||||||
|
else
|
||||||
|
m_vArea.emplace_back( i, - dArea) ;
|
||||||
|
}
|
||||||
|
// ordino in senso decrescente sull'area
|
||||||
|
sort( m_vArea.begin(), m_vArea.end(),
|
||||||
|
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||||
|
|
||||||
|
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||||
|
Frame3d frRef ; frRef.Set( ORIG, vtN) ;
|
||||||
|
if ( ! frRef.IsValid())
|
||||||
|
return false ;
|
||||||
|
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||||
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
|
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||||
|
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||||
|
vCrvCompo[i]->ToLoc( frRef) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
|
||||||
|
// successive i loop interni
|
||||||
|
INTMATRIX vnPLIndMat ;
|
||||||
|
|
||||||
|
// vettore di indici per ordinare le PolyLine
|
||||||
|
INTVECTOR vPL_IndOrder ; vPL_IndOrder.resize( int( vPL.size())) ;
|
||||||
|
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i)
|
||||||
|
vPL_IndOrder[i] = m_vArea[i].first ;
|
||||||
|
|
||||||
|
// aggiungo le diverse curve
|
||||||
|
bool bFirstCrv ;
|
||||||
|
Plane3d plExtLoop ;
|
||||||
|
double dAreaExtLoop = 0. ;
|
||||||
|
do {
|
||||||
|
bFirstCrv = true ;
|
||||||
|
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||||
|
// recupero indice di percorso e verifico sia valido
|
||||||
|
int j = m_vArea[i].first ;
|
||||||
|
if ( j < 0)
|
||||||
|
continue ;
|
||||||
|
// lo inserisco come esterno...
|
||||||
|
if ( bFirstCrv) {
|
||||||
|
vnPLIndMat.push_back({ j}) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
dAreaExtLoop = m_vArea[i].second ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second < EPS_SMALL) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
dAreaExtLoop *= -1 ;
|
||||||
|
}
|
||||||
|
bFirstCrv = false ;
|
||||||
|
}
|
||||||
|
// ... altrimenti verifico se il loop è interno o no
|
||||||
|
else {
|
||||||
|
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||||
|
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||||
|
// verifica rispetto loop esterno
|
||||||
|
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass ;
|
||||||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||||
|
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||||
|
continue ;
|
||||||
|
// verifica rispetto ai loop interni
|
||||||
|
bool bOk = true ;
|
||||||
|
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||||
|
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||||
|
CRVCVECTOR ccClass2 ;
|
||||||
|
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
|
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||||
|
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||||
|
bOk = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bOk) {
|
||||||
|
// inserisco nella matrice
|
||||||
|
vnPLIndMat.back().push_back( j) ;
|
||||||
|
m_vArea[i].first = -1 ;
|
||||||
|
// inverto se necessario
|
||||||
|
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
||||||
|
vPL[j].Invert() ;
|
||||||
|
vCrvCompo[j]->Invert() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ( ! bFirstCrv) ;
|
||||||
|
|
||||||
|
// ordino le PolyLine per area
|
||||||
|
POLYLINEVECTOR vPL_tmp ;
|
||||||
|
for ( int i = 0 ; i < int( vPL_IndOrder.size()) ; ++ i)
|
||||||
|
vPL_tmp.push_back( vPL[ vPL_IndOrder[i]]) ;
|
||||||
|
swap( vPL, vPL_tmp) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
+6
-123
@@ -22,18 +22,6 @@
|
|||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfTriMesh*
|
|
||||||
GetSurfTriMeshEmpty( void)
|
|
||||||
{
|
|
||||||
// creo oggetto con superficie vuota
|
|
||||||
PtrOwner<SurfTriMesh> pStm( CreateBasicSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pStm) || ! pStm->AdjustTopology())
|
|
||||||
return nullptr ;
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pStm) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
static SurfTriMesh*
|
static SurfTriMesh*
|
||||||
GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||||
@@ -172,15 +160,15 @@ GetSurfTriMeshPyramid( double dDimX, double dDimY, double dHeight)
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
// creo la polilinea del contorno della base
|
// creo la polilinea del contorno della base
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
PL.AddUPoint( 0, Point3d( -dDimX / 2, -dDimY / 2, 0)) ;
|
PL.AddUPoint( 0, ORIG) ;
|
||||||
PL.AddUPoint( 1, Point3d( dDimX / 2, -dDimY / 2, 0)) ;
|
PL.AddUPoint( 1, Point3d( dDimX, 0, 0)) ;
|
||||||
PL.AddUPoint( 2, Point3d( dDimX / 2, dDimY / 2, 0)) ;
|
PL.AddUPoint( 2, Point3d( dDimX, dDimY, 0)) ;
|
||||||
PL.AddUPoint( 3, Point3d( -dDimX / 2, dDimY / 2, 0)) ;
|
PL.AddUPoint( 3, Point3d( 0, dDimY, 0)) ;
|
||||||
PL.AddUPoint( 4, Point3d( -dDimX / 2, -dDimY / 2, 0)) ;
|
PL.AddUPoint( 4, ORIG) ;
|
||||||
if ( dHeight < 0)
|
if ( dHeight < 0)
|
||||||
PL.Invert() ;
|
PL.Invert() ;
|
||||||
// punto di vertice
|
// punto di vertice
|
||||||
Point3d ptTip( 0, 0, dHeight) ;
|
Point3d ptTip( 0.5 * dDimX, 0.5 * dDimY, dHeight) ;
|
||||||
// creo e setto la superficie trimesh laterale
|
// creo e setto la superficie trimesh laterale
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByPointCurve( ptTip, PL))
|
if ( IsNull( pSTM) || ! pSTM->CreateByPointCurve( ptTip, PL))
|
||||||
@@ -257,111 +245,6 @@ GetSurfTriMeshSphere( double dRadius, double dLinTol)
|
|||||||
return GetSurfTriMeshByRevolve( &cArc, ORIG, Z_AX, true, dLinTol) ;
|
return GetSurfTriMeshByRevolve( &cArc, ORIG, Z_AX, true, dLinTol) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfTriMesh*
|
|
||||||
GetSurfTriMeshPyramidFrustum( double dBaseDimX, double dBaseDimY, double dTopDimX, double dTopDimY, double dHeight)
|
|
||||||
{
|
|
||||||
// le dimensioni devono essere significative
|
|
||||||
if ( ( min( dBaseDimX, dBaseDimY) < EPS_SMALL && min( dTopDimX, dTopDimY) < EPS_SMALL) || abs( dHeight) < EPS_SMALL)
|
|
||||||
return nullptr ;
|
|
||||||
// se piramide
|
|
||||||
if ( min( dTopDimX, dTopDimY) < EPS_SMALL)
|
|
||||||
return GetSurfTriMeshPyramid( dBaseDimX, dBaseDimY, dHeight) ;
|
|
||||||
// se piramide inversa
|
|
||||||
if ( min( dBaseDimX, dBaseDimY) < EPS_SMALL)
|
|
||||||
return GetSurfTriMeshPyramid( dTopDimX, dTopDimY, -dHeight) ;
|
|
||||||
// se parallelepipedo
|
|
||||||
// continuo qui per avere l'origine in centro e non sullo spigolo in basso a sinistra
|
|
||||||
// creo la polilinea del contorno della base
|
|
||||||
PolyLine PL1 ;
|
|
||||||
PL1.AddUPoint( 0, Point3d( -dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
|
||||||
PL1.AddUPoint( 1, Point3d( dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
|
||||||
PL1.AddUPoint( 2, Point3d( dBaseDimX / 2 , dBaseDimY / 2, 0)) ;
|
|
||||||
PL1.AddUPoint( 3, Point3d( -dBaseDimX / 2, dBaseDimY / 2, 0)) ;
|
|
||||||
PL1.AddUPoint( 4, Point3d( -dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
|
||||||
if ( dHeight < 0)
|
|
||||||
PL1.Invert() ;
|
|
||||||
// creo la polilinea del contorno di sopra
|
|
||||||
PolyLine PL2 ;
|
|
||||||
PL2.AddUPoint( 0, Point3d( -dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
|
||||||
PL2.AddUPoint( 1, Point3d( dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
|
||||||
PL2.AddUPoint( 2, Point3d( dTopDimX / 2, dTopDimY / 2, dHeight)) ;
|
|
||||||
PL2.AddUPoint( 3, Point3d( -dTopDimX / 2, dTopDimY / 2, dHeight)) ;
|
|
||||||
PL2.AddUPoint( 4, Point3d( -dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
|
||||||
if ( dHeight < 0)
|
|
||||||
PL2.Invert() ;
|
|
||||||
// creo e setto la superficie trimesh laterale
|
|
||||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
|
||||||
if ( IsNull( pSTM) || ! pSTM->CreateByTwoCurves( PL1, PL2, ISurfTriMesh::RLT_ISOPAR_SMOOTH))
|
|
||||||
return nullptr ;
|
|
||||||
// creo la superficie di base e ne inverto la normale
|
|
||||||
SurfTriMesh STM1 ;
|
|
||||||
if ( ! STM1.CreateByFlatContour( PL1))
|
|
||||||
return nullptr ;
|
|
||||||
STM1.Invert() ;
|
|
||||||
// la unisco alla superficie del fianco
|
|
||||||
if ( ! pSTM->DoSewing( STM1))
|
|
||||||
return nullptr ;
|
|
||||||
// creo la superficie sopra
|
|
||||||
SurfTriMesh STM2 ;
|
|
||||||
if ( ! STM2.CreateByFlatContour( PL2))
|
|
||||||
return nullptr ;
|
|
||||||
// la unisco alla superficie del fianco
|
|
||||||
if ( ! pSTM->DoSewing( STM2))
|
|
||||||
return nullptr ;
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSTM) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
ISurfTriMesh*
|
|
||||||
GetSurfTriMeshConeFrustum( double dBaseRad, double dTopRad, double dHeight, double dLinTol)
|
|
||||||
{
|
|
||||||
// le dimensioni devono essere significative
|
|
||||||
if ( ( dBaseRad < EPS_SMALL && dTopRad < EPS_SMALL) || abs( dHeight) < EPS_SMALL)
|
|
||||||
return nullptr ;
|
|
||||||
// se cono
|
|
||||||
if ( dTopRad < EPS_SMALL)
|
|
||||||
return GetSurfTriMeshCone( dBaseRad, dHeight, dLinTol) ;
|
|
||||||
// se cono rovescio
|
|
||||||
if ( dBaseRad < EPS_SMALL)
|
|
||||||
return GetSurfTriMeshCone( dTopRad, -dHeight, dLinTol) ;
|
|
||||||
// se cilindro
|
|
||||||
if ( abs( dTopRad - dBaseRad) < EPS_SMALL)
|
|
||||||
return GetSurfTriMeshCylinder( dBaseRad, dHeight, dLinTol) ;
|
|
||||||
// creo la circonferenza sotto
|
|
||||||
CurveArc cArc1 ;
|
|
||||||
cArc1.Set( ORIG, Z_AX, dBaseRad) ;
|
|
||||||
if ( dHeight < 0)
|
|
||||||
cArc1.Invert() ;
|
|
||||||
// creo la circonferenza sopra
|
|
||||||
CurveArc cArc2 ;
|
|
||||||
cArc2.Set( Point3d( 0, 0, dHeight), Z_AX, dTopRad) ;
|
|
||||||
if ( dHeight < 0)
|
|
||||||
cArc2.Invert() ;
|
|
||||||
// creo la superficie laterale del cono
|
|
||||||
PtrOwner<ISurfTriMesh> pSTM( GetSurfTriMeshRuled( &cArc1, &cArc2, ISurfTriMesh::RLT_ISOPAR_SMOOTH, dLinTol)) ;
|
|
||||||
if ( IsNull( pSTM))
|
|
||||||
return nullptr ;
|
|
||||||
// creo la superficie sotto e la inverto
|
|
||||||
PtrOwner<ISurfTriMesh> pSTM1( GetSurfTriMeshByFlatContour( &cArc1, dLinTol)) ;
|
|
||||||
if ( IsNull( pSTM1))
|
|
||||||
return nullptr ;
|
|
||||||
pSTM1->Invert() ;
|
|
||||||
// la unisco alla superficie del fianco
|
|
||||||
if ( ! pSTM->DoSewing( *pSTM1))
|
|
||||||
return nullptr ;
|
|
||||||
// creo la superficie sopra
|
|
||||||
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMeshByFlatContour( &cArc2, dLinTol)) ;
|
|
||||||
if ( IsNull( pSTM2))
|
|
||||||
return nullptr ;
|
|
||||||
// la unisco alla superficie del fianco
|
|
||||||
if ( ! pSTM->DoSewing( *pSTM2))
|
|
||||||
return nullptr ;
|
|
||||||
// restituisco la superficie
|
|
||||||
return Release( pSTM) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfTriMesh*
|
ISurfTriMesh*
|
||||||
GetSurfTriMeshPlaneInBox( const Plane3d& plPlane, const BBox3d& b3Box, bool bOnEq, bool bOnCt)
|
GetSurfTriMeshPlaneInBox( const Plane3d& plPlane, const BBox3d& b3Box, bool bOnEq, bool bOnCt)
|
||||||
|
|||||||
+12
-41
@@ -45,7 +45,6 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||||
CNurbsData nuCurve ;
|
CNurbsData nuCurve ;
|
||||||
nuCurve.bPeriodic = true ;
|
nuCurve.bPeriodic = true ;
|
||||||
nuCurve.bRat = snData.bRat ;
|
|
||||||
nuCurve.nDeg = snData.nDegU ;
|
nuCurve.nDeg = snData.nDegU ;
|
||||||
nuCurve.vU = vU ;
|
nuCurve.vU = vU ;
|
||||||
// vettore dei punti di controllo
|
// vettore dei punti di controllo
|
||||||
@@ -63,24 +62,13 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
nuCurve.vCP = vPtCtrl ;
|
nuCurve.vCP = vPtCtrl ;
|
||||||
nuCurve.vW = vWeCtrl ;
|
nuCurve.vW = vWeCtrl ;
|
||||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||||
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
|
NurbsCurveCanonicalize( nuCurve) ;
|
||||||
if ( snData.mCP.size() != nuCurve.vCP.size() ) {
|
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||||
snData.mCP.resize( nuCurve.vCP.size()) ;
|
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||||
if( snData.bRat)
|
|
||||||
snData.mW.resize( nuCurve.vW.size()) ;
|
|
||||||
}
|
|
||||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
|
||||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
|
||||||
if( snData.bRat) {
|
|
||||||
snData.mW[i][j] = nuCurve.vW[i] ;
|
|
||||||
snData.mCP[i][j] *= nuCurve.vW[i] ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snData.vU = nuCurve.vU ;
|
|
||||||
}
|
}
|
||||||
|
snData.vU = nuCurve.vU ;
|
||||||
}
|
}
|
||||||
snData.bPeriodicU = false ;
|
snData.bPeriodicU = false ;
|
||||||
snData.nCPU = int( snData.mCP.size()) ;
|
|
||||||
}
|
}
|
||||||
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
||||||
bool bIsRational = snData.bRat ;
|
bool bIsRational = snData.bRat ;
|
||||||
@@ -94,7 +82,6 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||||
CNurbsData nuCurve ;
|
CNurbsData nuCurve ;
|
||||||
nuCurve.bPeriodic = true ;
|
nuCurve.bPeriodic = true ;
|
||||||
nuCurve.bRat = snData.bRat ;
|
|
||||||
nuCurve.nDeg = snData.nDegV ;
|
nuCurve.nDeg = snData.nDegV ;
|
||||||
nuCurve.vU = vV ;
|
nuCurve.vU = vV ;
|
||||||
// vettore dei punti di controllo
|
// vettore dei punti di controllo
|
||||||
@@ -112,29 +99,15 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
nuCurve.vCP = vPtCtrl ;
|
nuCurve.vCP = vPtCtrl ;
|
||||||
nuCurve.vW = vWeCtrl ;
|
nuCurve.vW = vWeCtrl ;
|
||||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||||
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
|
NurbsCurveCanonicalize( nuCurve) ;
|
||||||
if ( snData.mCP[i].size() != nuCurve.vCP.size()){
|
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||||
snData.mCP[i].clear() ;
|
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||||
snData.mCP[i].resize( nuCurve.vCP.size()) ;
|
|
||||||
if ( snData.bRat ) {
|
|
||||||
snData.mW[i].clear() ;
|
|
||||||
snData.mW[i].resize( nuCurve.vW.size()) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ( int j = 0 ; j < int( nuCurve.vCP.size()) ; ++j ) {
|
|
||||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
|
||||||
if ( snData.bRat ) {
|
|
||||||
snData.mW[i][j] = nuCurve.vW[j] ;
|
|
||||||
snData.mCP[i][j] *= nuCurve.vW[j] ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snData.vV = nuCurve.vU ;
|
|
||||||
}
|
}
|
||||||
|
snData.vV = nuCurve.vU ;
|
||||||
}
|
}
|
||||||
snData.bPeriodicV = false ;
|
snData.bPeriodicV = false ;
|
||||||
snData.nCPV = int( snData.mCP[0].size()) ;
|
|
||||||
}
|
}
|
||||||
return true ;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -631,7 +604,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
pSfr_copy->Translate( vtJoin) ;
|
pSfr_copy->Translate( vtJoin) ;
|
||||||
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
|
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
|
||||||
if ( bRetry)
|
if ( bRetry)
|
||||||
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET
|
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_FILLET) ; // OFFSET
|
||||||
if ( pRescaledSfr->IsValid()) {
|
if ( pRescaledSfr->IsValid()) {
|
||||||
if ( ! pRescaledSfr->Add( *pSfr_copy))
|
if ( ! pRescaledSfr->Add( *pSfr_copy))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -644,8 +617,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
||||||
if ( pRescaledSfr->IsValid()) {
|
if ( pRescaledSfr->IsValid()) {
|
||||||
if ( bRetry)
|
if ( bRetry)
|
||||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET
|
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; //contro OFFSET
|
||||||
delete pSfr ;
|
|
||||||
pSfr = Release( pRescaledSfr) ;
|
pSfr = Release( pRescaledSfr) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -656,8 +628,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
|
|
||||||
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
||||||
if ( bRetry)
|
if ( bRetry)
|
||||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
|
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; // contro OFFSET
|
||||||
delete pSfr ;
|
|
||||||
pSfr = Release( pRescaledSfr) ;
|
pSfr = Release( pRescaledSfr) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+519
-2739
File diff suppressed because it is too large
Load Diff
+36
-60
@@ -22,6 +22,9 @@
|
|||||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
class Tree ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class SurfBezier : public ISurfBezier, public IGeoObjRW
|
class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||||
{
|
{
|
||||||
@@ -66,16 +69,13 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
public : // ISurf
|
public : // ISurf
|
||||||
bool IsSimple( void) const override
|
bool IsSimple( void) const override
|
||||||
{ return true ; }
|
{ return true ; }
|
||||||
bool IsClosed( void) const override ;
|
bool IsClosed( void) const override
|
||||||
|
{ return false ; }
|
||||||
bool GetArea( double& dArea) const override ;
|
bool GetArea( double& dArea) const override ;
|
||||||
bool GetVolume( double& dVolume) const override
|
bool GetVolume( double& dVolume) const override
|
||||||
{ if ( &dVolume == nullptr)
|
{ if ( &dVolume == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
if ( m_pSTM == nullptr)
|
|
||||||
GetAuxSurf() ;
|
|
||||||
dVolume = 0 ;
|
dVolume = 0 ;
|
||||||
if ( m_pSTM != nullptr)
|
|
||||||
m_pSTM->GetVolume( dVolume) ;
|
|
||||||
return true ; }
|
return true ; }
|
||||||
bool GetCentroid( Point3d& ptCen) const override ;
|
bool GetCentroid( Point3d& ptCen) const override ;
|
||||||
bool Invert( void) override ;
|
bool Invert( void) override ;
|
||||||
@@ -99,7 +99,6 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
{ return GetControlWeight( GetInd( nIndU, nIndV), pbOk) ; }
|
{ return GetControlWeight( GetInd( nIndU, nIndV), pbOk) ; }
|
||||||
double GetControlWeight( int nInd, bool* pbOk) const override ;
|
double GetControlWeight( int nInd, bool* pbOk) const override ;
|
||||||
bool IsAPoint( void) const override ;
|
bool IsAPoint( void) const override ;
|
||||||
bool GetPoint( double dU, double dV, Side nUs, Side nVs, Point3d& ptPos) const override ;
|
|
||||||
bool GetPointD1D2( double dU, double dV, Side nUs, Side nVs,
|
bool GetPointD1D2( double dU, double dV, Side nUs, Side nVs,
|
||||||
Point3d& ptPos,
|
Point3d& ptPos,
|
||||||
Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr,
|
Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr,
|
||||||
@@ -110,43 +109,35 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ;
|
Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ;
|
||||||
CurveComposite* GetCurveOnU( double dV) const override ;
|
CurveComposite* GetCurveOnU( double dV) const override ;
|
||||||
CurveComposite* GetCurveOnV( double dU) const override ;
|
CurveComposite* GetCurveOnV( double dU) const override ;
|
||||||
CurveComposite* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni)
|
CurveComposite* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni)
|
||||||
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
|
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
|
||||||
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
||||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||||
const SurfTriMesh* GetAuxSurfRefined( void) const override ;
|
|
||||||
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL) const override ;
|
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL) const override ;
|
||||||
// funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione.
|
// funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione.
|
||||||
bool GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const override ;
|
bool GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const override ;
|
||||||
bool GetTriangles2D( std::vector<std::tuple<int,Point3d, Point3d, Point3d>>& vTria2D) const override ;
|
bool GetTriangles2D( std::vector<std::tuple<int,Point3d, Point3d, Point3d>>& vTria2D) const override ;
|
||||||
// funzioni che servono per ricavare l'immagine nel parametrico di un punto appartenente alla trimesh ausiliaria della superficie di Bezier
|
// funzioni che servono per ricavare l'immagine nel parametrico di un punto appartenente alla trimesh ausiliaria della superficie di Bezier
|
||||||
// a nIL si può passare 5 come valore di default
|
// a nIL si può passare 5 come valore di default
|
||||||
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL = 5) const override ;
|
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL = 5) const override ;
|
||||||
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL, const Point3d& ptIPrev, bool* bTroughEdge = nullptr) const override ;
|
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL, const Point3d& ptIPrev, bool* bTroughEdge = nullptr) const override ;
|
||||||
// restituisce il corrispettivo parametrico di un punto qualunque della trimesh associata alla superficie
|
// restituisce il corrispettivo parametrico di un punto qualunque della trimesh associata alla superficie
|
||||||
// ptIPrev è un punto addizionale che precede o segue il punto pt3D nel caso in cui il punto faccia parte di una curva 3d sulla superficie
|
// ptIPrev è un punto addizionale che precede o segue il punto pt3D nel caso in cui il punto faccia parte di una curva 3d sulla superficie
|
||||||
// pPlCut è il piano di taglio su cui dovrebbe giacere il punto raffinato
|
// pPlCut è il piano di taglio su cui dovrebbe giacere il punto raffinato
|
||||||
bool UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d& ptIPrev, bool* bTroughEdge = nullptr, const Plane3d* plCut = nullptr) const override ;
|
bool UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d& ptIPrev, bool* bTroughEdge = nullptr, const Plane3d* plCut = nullptr) const override ;
|
||||||
// pPlCut è il piano di taglio su cui giace la curva
|
// pPlCut è il piano di taglio su cui giace la curva
|
||||||
bool UnprojectCurveFromStm( const ICurveComposite* pCC, ICRVCOMPOPVECTOR& vpCC, const Plane3d* pPlCut) const override ;
|
bool UnprojectCurveFromStm( const ICurveComposite* pCC, ICRVCOMPOPVECTOR& vpCC, const Plane3d* pPlCut) const override ;
|
||||||
// funzione per tagliare una superficie di bezier con un piano ( cancello la parte dal lato positivo della normale del piano).
|
// funzione per tagliare una superficie di bezier con un piano ( cancello la parte dal lato positivo della normale del piano).
|
||||||
// bSaveOnEq indica se tenere i triangoli (della trimesh associata) che sono sul piano
|
// bSaveOnEq indica se tenere i triangoli (della trimesh associata) che sono sul piano
|
||||||
bool Cut( const Plane3d& plPlane, bool bSaveOnEq = false) override ;
|
bool Cut( const Plane3d& plPlane, bool bSaveOnEq = false) override ;
|
||||||
|
// funzione che calcola se gli edge sono collassati in poli. DEVE ESSERE STATA CHIAMATA PRIMA DI UN CUT
|
||||||
|
bool CalcPoles( void) override ;
|
||||||
// funzioni per incrementare le coordinate restando dentro lo spazio parametrico
|
// funzioni per incrementare le coordinate restando dentro lo spazio parametrico
|
||||||
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
|
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
|
||||||
bool IncreaseUV( Point3d& ptUV, Vector3d vtH , Point3d* ptUVCopy, bool bModifyOrig) const override ;
|
bool IncreaseUV( Point3d& ptUV, Vector3d vtH , Point3d* ptUVCopy, bool bModifyOrig) const override ;
|
||||||
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
|
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
|
||||||
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
|
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
|
||||||
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ; // se la superficie non è trimmata restituisce un vettore di 4 elementi. Se la superficie è chiusa lungo un parametro i lati algi estremi di quel parametro saranno null.
|
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
|
||||||
bool IsPlanar( void) const override ;
|
|
||||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
|
||||||
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
|
||||||
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, bool bDeg3OrDeg2 = false) override ;
|
|
||||||
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) override ;
|
|
||||||
bool CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
|
|
||||||
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
|
||||||
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
|
||||||
PNTVECTOR GetAllControlPoints( void) const ;
|
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -158,7 +149,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
SurfBezier( void) ;
|
SurfBezier( void) ;
|
||||||
SurfBezier( const SurfBezier& sbSrc) : m_pSTM( nullptr), m_pSTMRefined( nullptr), m_pTrimReg(nullptr)
|
SurfBezier( const SurfBezier& sbSrc)
|
||||||
{ if ( ! CopyFrom( sbSrc))
|
{ if ( ! CopyFrom( sbSrc))
|
||||||
LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") }
|
LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") }
|
||||||
SurfBezier& operator =( const SurfBezier& sbSrc)
|
SurfBezier& operator =( const SurfBezier& sbSrc)
|
||||||
@@ -169,7 +160,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
private :
|
private :
|
||||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||||
enum ParDir { ON_U = 1, ON_V = 2} ;
|
enum ParDir { ON_U = 1, ON_V = 2} ;
|
||||||
static const int MAXDEG = 21 ;
|
static const int MAXDEG = 11 ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool CopyFrom( const SurfBezier& sbSrc) ;
|
bool CopyFrom( const SurfBezier& sbSrc) ;
|
||||||
@@ -199,45 +190,30 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
double GetCurveOnVApproxLen( double dU) const ;
|
double GetCurveOnVApproxLen( double dU) const ;
|
||||||
// funzione che proietta nello spazio parametrico un trim derivante da un taglio con un piano, categorizzandolo come aperto o chiuso ( nel parametrico)
|
// funzione che proietta nello spazio parametrico un trim derivante da un taglio con un piano, categorizzandolo come aperto o chiuso ( nel parametrico)
|
||||||
bool AddCurveCompoToCuts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed, double dToler = EPS_SMALL, const Plane3d* pPlCut = nullptr) const ;
|
bool AddCurveCompoToCuts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed, double dToler = EPS_SMALL, const Plane3d* pPlCut = nullptr) const ;
|
||||||
ISurfFlatRegion* CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed) const ;
|
|
||||||
// restituisce il singolo edge della superficie non trimmata
|
// restituisce il singolo edge della superficie non trimmata
|
||||||
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
|
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
|
||||||
// funzione che calcola se gli edge sono collassati in poli
|
bool UpdateEdgesFromTree( Tree& tr) const ;
|
||||||
bool CalcPoles( void) const ;
|
|
||||||
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
|
|
||||||
bool ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
|
|
||||||
bool ReorderPntEnhancedVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
|
|
||||||
bool GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const ;
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria per la visualizzazione
|
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria
|
||||||
mutable SurfTriMesh* m_pSTMRefined ; // superficie trimesh ausiliaria raffinata per i calcoli
|
Status m_nStatus ; // stato
|
||||||
Status m_nStatus ; // stato
|
int m_nDegU ; // grado in U
|
||||||
int m_nDegU ; // grado in U
|
int m_nDegV ; // grado in V
|
||||||
int m_nDegV ; // grado in V
|
int m_nSpanU ; // numero di pezze in U
|
||||||
int m_nSpanU ; // numero di pezze in U
|
int m_nSpanV ; // numero di pezze in V
|
||||||
int m_nSpanV ; // numero di pezze in V
|
bool m_bRat ; // flag di razionale/polinomiale
|
||||||
bool m_bRat ; // flag di razionale/polinomiale
|
bool m_bTrimmed ; // flag per presenza regione di trim
|
||||||
bool m_bTrimmed ; // flag per presenza regione di trim
|
mutable bool m_bClosedU ; // flag che indica se la superficie è chiusa lungo il parametro U
|
||||||
mutable bool m_bClosedU ; // flag che indica se la superficie è chiusa lungo il parametro U
|
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V
|
||||||
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V
|
mutable BOOLVECTOR m_vbPole ; // vettore di flag che indicano se i lati sono collassati in dei poli
|
||||||
mutable BOOLVECTOR m_vbPole ; // vettore di flag che indicano se i lati sono collassati in dei poli
|
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
mutable vector<ICRVCOMPOPOVECTOR> m_mCCEdge ;// vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
|
||||||
mutable std::vector<ICRVCOMPOPOVECTOR> m_mCCEdge ; // vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
|
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
|
||||||
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
|
|
||||||
mutable int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
|
|
||||||
mutable DBLVECTOR m_vBernU ;
|
|
||||||
mutable PNTVECTOR m_ptTemp ;
|
|
||||||
mutable DBLVECTOR m_vBernV ;
|
|
||||||
mutable PNTVECTOR m_ptTempW ;
|
|
||||||
mutable DBLVECTOR m_dTempW ;
|
|
||||||
mutable PNTVECTOR m_vPtWCtrlLoc ;
|
|
||||||
mutable DBLVECTOR m_vWeCtrlLoc ;
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
+29
-299
@@ -109,25 +109,18 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
|||||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||||
return false ;
|
return false ;
|
||||||
// aggiungo le singole curve
|
// aggiungo le singole curve
|
||||||
int nExtAdded = 0 ;
|
|
||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
for ( auto& pSingCrv : CrvLst) {
|
for ( auto& pSingCrv : CrvLst) {
|
||||||
bool bAdded = false ;
|
if ( ! AddSimpleExtLoop( pSingCrv))
|
||||||
if ( AddSimpleExtLoop( pSingCrv, bAdded))
|
|
||||||
++ nExtAdded ;
|
|
||||||
else
|
|
||||||
bOk = false ;
|
bOk = false ;
|
||||||
|
|
||||||
}
|
}
|
||||||
return ( bOk && nExtAdded > 0) ;
|
return bOk ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||||
{
|
{
|
||||||
// default
|
|
||||||
bAdded = false ;
|
|
||||||
// acquisisco la curva
|
// acquisisco la curva
|
||||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||||
if ( IsNull( pMyCrv))
|
if ( IsNull( pMyCrv))
|
||||||
@@ -140,10 +133,8 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
|||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||||
return false ;
|
return false ;
|
||||||
if ( dArea < SQ_EPS_SMALL)
|
|
||||||
return true ;
|
|
||||||
// se sto costruendo il primo chunk
|
// se sto costruendo il primo chunk
|
||||||
if ( m_vExtInd.empty()) {
|
if ( m_vExtInd.size() == 0) {
|
||||||
// assegno il riferimento intrinseco
|
// assegno il riferimento intrinseco
|
||||||
if ( ! m_frF.Set( ORIG + plPlane.GetVersN() * plPlane.GetDist(), plPlane.GetVersN()))
|
if ( ! m_frF.Set( ORIG + plPlane.GetVersN() * plPlane.GetDist(), plPlane.GetVersN()))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -207,7 +198,6 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
|||||||
m_OGrMgr.Reset() ;
|
m_OGrMgr.Reset() ;
|
||||||
// imposto ricalcolo Voronoi
|
// imposto ricalcolo Voronoi
|
||||||
ResetVoronoiObject() ;
|
ResetVoronoiObject() ;
|
||||||
bAdded = true ;
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +547,7 @@ SurfFlatRegion::Load( NgeReader& ngeIn)
|
|||||||
string sName ;
|
string sName ;
|
||||||
int j ;
|
int j ;
|
||||||
bool bOk = ngeIn.ReadString( sName, ";") &&
|
bool bOk = ngeIn.ReadString( sName, ";") &&
|
||||||
FromString( sName.substr( 2), j) && i == j ;
|
FromString( sName.substr(2), j) && i == j ;
|
||||||
int nChunk = 0, nLoop = 0 ;
|
int nChunk = 0, nLoop = 0 ;
|
||||||
bOk = ngeIn.ReadInt( nChunk, ",") &&
|
bOk = ngeIn.ReadInt( nChunk, ",") &&
|
||||||
ngeIn.ReadInt( nLoop, ";", true) ;
|
ngeIn.ReadInt( nLoop, ";", true) ;
|
||||||
@@ -827,7 +817,7 @@ SurfFlatRegion::ConvertArcsToBezierCurves( void)
|
|||||||
// ciclo sui loop
|
// ciclo sui loop
|
||||||
for ( auto& pLoop : m_vpLoop) {
|
for ( auto& pLoop : m_vpLoop) {
|
||||||
if ( pLoop->GetType() == CRV_ARC) {
|
if ( pLoop->GetType() == CRV_ARC) {
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc(pLoop)) ;
|
ICurve* pCrvNew = ArcToBezierCurve( pLoop) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
delete pLoop ;
|
delete pLoop ;
|
||||||
@@ -922,6 +912,9 @@ SurfFlatRegion::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|||||||
bool
|
bool
|
||||||
SurfFlatRegion::GetArea( double& dArea) const
|
SurfFlatRegion::GetArea( double& dArea) const
|
||||||
{
|
{
|
||||||
|
// controllo parametro di ritorno
|
||||||
|
if ( &dArea == nullptr)
|
||||||
|
return false ;
|
||||||
// inizio con area nulla
|
// inizio con area nulla
|
||||||
dArea = 0 ;
|
dArea = 0 ;
|
||||||
// la regione deve essere validata
|
// la regione deve essere validata
|
||||||
@@ -944,6 +937,9 @@ SurfFlatRegion::GetArea( double& dArea) const
|
|||||||
bool
|
bool
|
||||||
SurfFlatRegion::GetGrossArea( double& dArea) const
|
SurfFlatRegion::GetGrossArea( double& dArea) const
|
||||||
{
|
{
|
||||||
|
// controllo parametro di ritorno
|
||||||
|
if ( &dArea == nullptr)
|
||||||
|
return false ;
|
||||||
// inizio con area nulla
|
// inizio con area nulla
|
||||||
dArea = 0 ;
|
dArea = 0 ;
|
||||||
// la regione deve essere validata
|
// la regione deve essere validata
|
||||||
@@ -967,6 +963,9 @@ SurfFlatRegion::GetGrossArea( double& dArea) const
|
|||||||
bool
|
bool
|
||||||
SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
||||||
{
|
{
|
||||||
|
// controllo parametro di ritorno
|
||||||
|
if ( &ptCen == nullptr)
|
||||||
|
return false ;
|
||||||
// la regione deve essere validata
|
// la regione deve essere validata
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||||
return false ;
|
return false ;
|
||||||
@@ -992,20 +991,13 @@ SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
int
|
|
||||||
SurfFlatRegion::GetChunkCount( void) const
|
|
||||||
{
|
|
||||||
// la regione deve essere validata
|
|
||||||
if ( m_nStatus != OK)
|
|
||||||
return 0 ;
|
|
||||||
return int( m_vExtInd.size()) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const
|
SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const
|
||||||
{
|
{
|
||||||
|
// controllo parametro di ritorno
|
||||||
|
if ( &ptCen == nullptr)
|
||||||
|
return false ;
|
||||||
// la regione deve essere validata
|
// la regione deve essere validata
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||||
return false ;
|
return false ;
|
||||||
@@ -1019,53 +1011,13 @@ SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
int
|
||||||
SurfFlatRegion::GetChunkArea( int nChunk, double& dArea) const
|
SurfFlatRegion::GetChunkCount( void) const
|
||||||
{
|
{
|
||||||
// default, area nulla
|
|
||||||
dArea = 0 ;
|
|
||||||
// la regione deve essere validata
|
// la regione deve essere validata
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
if ( m_nStatus != OK)
|
||||||
return false ;
|
return 0 ;
|
||||||
// il chunk deve esistere
|
return int( m_vExtInd.size()) ;
|
||||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
|
||||||
return false ;
|
|
||||||
// calcolo l'area
|
|
||||||
bool bOk = true ;
|
|
||||||
for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) {
|
|
||||||
const ICurve* pLoop = GetMyLoop( nChunk, nL) ;
|
|
||||||
double dLoopArea ;
|
|
||||||
if ( pLoop != nullptr && pLoop->GetAreaXY( dLoopArea))
|
|
||||||
dArea += dLoopArea ;
|
|
||||||
else
|
|
||||||
bOk = false ;
|
|
||||||
}
|
|
||||||
return bOk ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::GetChunkPerimeter( int nChunk, double& dLen) const
|
|
||||||
{
|
|
||||||
// default, perimetro nullo
|
|
||||||
dLen = 0 ;
|
|
||||||
// la regione deve essere validata
|
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
|
||||||
return false ;
|
|
||||||
// il chunk deve esistere
|
|
||||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
|
||||||
return false ;
|
|
||||||
// calcolo il perimetro
|
|
||||||
bool bOk = true ;
|
|
||||||
for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) {
|
|
||||||
const ICurve* pLoop = GetMyLoop( nChunk, nL) ;
|
|
||||||
double dLoopLen ;
|
|
||||||
if ( pLoop != nullptr && pLoop->GetLength( dLoopLen))
|
|
||||||
dLen += dLoopLen ;
|
|
||||||
else
|
|
||||||
bOk = false ;
|
|
||||||
}
|
|
||||||
return bOk ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1166,19 +1118,6 @@ SurfFlatRegion::GetLoop( int nChunk, int nLoop) const
|
|||||||
return pCrv ;
|
return pCrv ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
int
|
|
||||||
SurfFlatRegion::GetLoopCurveCount( int nChunk, int nLoop) const
|
|
||||||
{
|
|
||||||
// recupero il loop nel riferimento intrinseco
|
|
||||||
const ICurve* pMyCrv = GetMyLoop( nChunk, nLoop) ;
|
|
||||||
if ( pMyCrv == nullptr)
|
|
||||||
return 0 ;
|
|
||||||
// restituisco il numero di curve di cui è composto
|
|
||||||
const ICurveComposite* pMyCompo = GetCurveComposite( pMyCrv) ;
|
|
||||||
return ( pMyCompo == nullptr ? 1 : pMyCompo->GetCurveCount()) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const
|
SurfFlatRegion::ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const
|
||||||
@@ -1210,26 +1149,21 @@ SurfFlatRegion::CalcAuxSurf( double dLinTol, double dAngTolDeg) const
|
|||||||
for ( int i = 0 ; i < GetChunkCount() ; ++ i) {
|
for ( int i = 0 ; i < GetChunkCount() ; ++ i) {
|
||||||
// calcolo le polilinee che approssimano i loop
|
// calcolo le polilinee che approssimano i loop
|
||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
vPL.reserve( GetLoopCount( i)) ;
|
vPL.resize( GetLoopCount( i)) ;
|
||||||
int j = 0 ;
|
int j = 0 ;
|
||||||
ICurve* pLoop = GetMyLoop( i, j) ;
|
ICurve* pLoop = GetMyLoop( i, j) ;
|
||||||
while ( pLoop != nullptr) {
|
while ( pLoop != nullptr) {
|
||||||
// approssimo con linee a destra per non avere problemi in punti di contatto tra esterni e interni
|
// approssimo con linee a destra per non avere problemi in punti di contatto tra esterni e interni
|
||||||
vPL.emplace_back( PolyLine()) ;
|
if ( ! pLoop->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_RIGHT, vPL[j]))
|
||||||
if ( ! pLoop->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_RIGHT, vPL.back()))
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
double dLoopArea ;
|
|
||||||
if ( ! vPL.back().GetAreaXY( dLoopArea) || abs( dLoopArea) <= 25 * SQ_EPS_SMALL)
|
|
||||||
vPL.pop_back() ;
|
|
||||||
pLoop = GetMyLoop( i, ++j) ;
|
pLoop = GetMyLoop( i, ++j) ;
|
||||||
}
|
}
|
||||||
// se chunk abbastanza grande, creo la superficie trimesh relativa
|
// se chunk abbastanza grande, creo la superficie trimesh relativa
|
||||||
double dArea ;
|
double dArea ;
|
||||||
if ( ! vPL.empty() && vPL[0].GetAreaXY( dArea) && dArea > 25 * SQ_EPS_SMALL) {
|
if ( vPL[0].GetAreaXY( dArea) && dArea > 100 * SQ_EPS_SMALL) {
|
||||||
// creo, setto la superficie trimesh ed elimino punti ripetuti
|
// creo, setto la superficie trimesh ed elimino punti ripetuti
|
||||||
PtrOwner<SurfTriMesh> pChSTM( CreateBasicSurfTriMesh()) ;
|
PtrOwner<SurfTriMesh> pChSTM( CreateBasicSurfTriMesh()) ;
|
||||||
INTMATRIX vnPLIndMat ;
|
if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL) || ! pChSTM->DoCompacting())
|
||||||
if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL, vnPLIndMat) || ! pChSTM->DoCompacting())
|
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// porto la trimesh in globale al riferimento intrinseco
|
// porto la trimesh in globale al riferimento intrinseco
|
||||||
pChSTM->ToGlob( m_frF) ;
|
pChSTM->ToGlob( m_frF) ;
|
||||||
@@ -1237,10 +1171,7 @@ SurfFlatRegion::CalcAuxSurf( double dLinTol, double dAngTolDeg) const
|
|||||||
pSTM->DoSewing( *pChSTM) ;
|
pSTM->DoSewing( *pChSTM) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// se vuota
|
// la restituisco
|
||||||
if ( pSTM->IsEmpty())
|
|
||||||
pSTM->AdjustTopology() ;
|
|
||||||
// la restituisco
|
|
||||||
return Release( pSTM) ;
|
return Release( pSTM) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,56 +1226,6 @@ SurfFlatRegion::CloneChunk( int nChunk) const
|
|||||||
return Release( pSfr) ;
|
return Release( pSfr) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::EraseChunk(int nChunk)
|
|
||||||
{
|
|
||||||
// la regione deve essere validata
|
|
||||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
|
||||||
return false ;
|
|
||||||
// il chunk deve esistere
|
|
||||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
|
||||||
return false ;
|
|
||||||
// se un solo chunk, resetto la regione
|
|
||||||
if ( GetChunkCount() == 1) {
|
|
||||||
Clear() ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// se ultimo chunk
|
|
||||||
if ( nChunk == m_vExtInd.size() - 1) {
|
|
||||||
// elimino i loop
|
|
||||||
for ( int i = m_vExtInd[nChunk] ; i < int( m_vpLoop.size()) ; ++ i) {
|
|
||||||
delete m_vpLoop[i] ;
|
|
||||||
m_vpLoop[i] = nullptr ;
|
|
||||||
}
|
|
||||||
m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.end()) ;
|
|
||||||
// elimino indice di loop esterno
|
|
||||||
m_vExtInd.pop_back() ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
// numero di loop da eliminare
|
|
||||||
int nLoopCnt = m_vExtInd[nChunk+1] - m_vExtInd[nChunk] ;
|
|
||||||
// elimino i loop
|
|
||||||
for ( int i = m_vExtInd[nChunk] ; i < m_vExtInd[nChunk+1] ; ++ i) {
|
|
||||||
delete m_vpLoop[i] ;
|
|
||||||
m_vpLoop[i] = nullptr ;
|
|
||||||
}
|
|
||||||
m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.begin() + m_vExtInd[nChunk+1]) ;
|
|
||||||
// elimino indice di loop esterno
|
|
||||||
m_vExtInd.erase( m_vExtInd.begin() + nChunk) ;
|
|
||||||
// aggiorno indice inizio chunk successivi
|
|
||||||
for ( int i = nChunk ; i < int( m_vExtInd.size()) ; ++i)
|
|
||||||
m_vExtInd[i] -= nLoopCnt ;
|
|
||||||
}
|
|
||||||
// imposto ricalcolo della grafica
|
|
||||||
m_OGrMgr.Reset() ;
|
|
||||||
ResetAuxSurf() ;
|
|
||||||
// imposto ricalcolo Voronoi
|
|
||||||
ResetVoronoiObject() ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||||
@@ -1599,154 +1480,3 @@ SurfFlatRegion::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const
|
|||||||
|
|
||||||
return m_pVoronoiObj->CalcMedialAxis( vCrvs, nSide) ;
|
return m_pVoronoiObj->CalcMedialAxis( vCrvs, nSide) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::GetChunkMaxOffset( int nChunk, double& dOffs) const
|
|
||||||
{
|
|
||||||
// verifico se è stato calcolato Voronoi
|
|
||||||
if ( m_pVoronoiObj == nullptr)
|
|
||||||
if ( ! CalcVoronoiObject())
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// il massimo offset per il chunk è il massimo offset del suo loop esterno
|
|
||||||
// ( il diagramma di Voronoi tiene già conto della limitazione con i loop interni)
|
|
||||||
int nInd = GetIndFromChunkLoop( nChunk, 0) ;
|
|
||||||
return m_pVoronoiObj->CalcLimitOffset( nInd, true, dOffs) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::GetMaxOffset( double& dOffs) const
|
|
||||||
{
|
|
||||||
int nChunks = GetChunkCount() ;
|
|
||||||
if ( nChunks == 0)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo il massimo fra gli offset limite di tutti i suoi chunks
|
|
||||||
if ( ! GetChunkMaxOffset( 0, dOffs))
|
|
||||||
return false ;
|
|
||||||
for ( int i = 1 ; i < nChunks ; i++) {
|
|
||||||
double dCurrOffs ;
|
|
||||||
if ( ! GetChunkMaxOffset( i, dCurrOffs))
|
|
||||||
return false ;
|
|
||||||
if ( dCurrOffs > dOffs)
|
|
||||||
dOffs = dCurrOffs ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd)
|
|
||||||
{
|
|
||||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
|
||||||
if ( pLoop == nullptr)
|
|
||||||
return false ;
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
if ( nCrv != 0)
|
|
||||||
return false ;
|
|
||||||
pLoop->SetTempProp( nProp, nPropInd) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
return GetBasicCurveComposite( pLoop)->SetCurveTempProp( nCrv, nProp, nPropInd) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd) const
|
|
||||||
{
|
|
||||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
|
||||||
if ( pLoop == nullptr)
|
|
||||||
return false ;
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
if ( nCrv != 0)
|
|
||||||
return false ;
|
|
||||||
nProp = pLoop->GetTempProp( nPropInd) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
return GetBasicCurveComposite( pLoop)->GetCurveTempProp( nCrv, nProp, nPropInd) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::ResetAllCurveTempProps( void)
|
|
||||||
{
|
|
||||||
for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) {
|
|
||||||
for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) {
|
|
||||||
ICurve* pLoop = GetMyLoop( nC, nL) ;
|
|
||||||
if ( pLoop != nullptr) {
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
pLoop->SetTempProp( 0, 0) ;
|
|
||||||
pLoop->SetTempProp( 0, 1) ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ;
|
|
||||||
for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) {
|
|
||||||
pCompoLoop->SetCurveTempProp( nI, 0, 0) ;
|
|
||||||
pCompoLoop->SetCurveTempProp( nI, 0, 1) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd)
|
|
||||||
{
|
|
||||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
|
||||||
if ( pLoop == nullptr)
|
|
||||||
return false ;
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
if ( nCrv != 0)
|
|
||||||
return false ;
|
|
||||||
pLoop->SetTempParam( dParam, nParamInd) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
return GetBasicCurveComposite( pLoop)->SetCurveTempParam( nCrv, dParam, nParamInd) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dParam, int nParamInd) const
|
|
||||||
{
|
|
||||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
|
||||||
if ( pLoop == nullptr)
|
|
||||||
return false ;
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
if ( nCrv != 0)
|
|
||||||
return false ;
|
|
||||||
dParam = pLoop->GetTempParam( nParamInd) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
return GetBasicCurveComposite( pLoop)->GetCurveTempParam( nCrv, dParam, nParamInd) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
SurfFlatRegion::ResetAllCurveTempParams( void)
|
|
||||||
{
|
|
||||||
for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) {
|
|
||||||
for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) {
|
|
||||||
ICurve* pLoop = GetMyLoop( nC, nL) ;
|
|
||||||
if ( pLoop != nullptr) {
|
|
||||||
if ( pLoop->GetType() != CRV_COMPO) {
|
|
||||||
pLoop->SetTempParam( 0, 0) ;
|
|
||||||
pLoop->SetTempParam( 0, 1) ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ;
|
|
||||||
for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) {
|
|
||||||
pCompoLoop->SetCurveTempParam( nI, 0, 0) ;
|
|
||||||
pCompoLoop->SetCurveTempParam( nI, 0, 1) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|||||||
+9
-21
@@ -94,30 +94,18 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
{ return m_frF.Orig() ; }
|
{ return m_frF.Orig() ; }
|
||||||
const Vector3d& GetNormVersor( void) const override
|
const Vector3d& GetNormVersor( void) const override
|
||||||
{ return m_frF.VersZ() ; }
|
{ return m_frF.VersZ() ; }
|
||||||
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ;
|
|
||||||
void ResetVoronoiObject( void) const override ;
|
|
||||||
bool GetMaxOffset( double& dOffs) const override ;
|
|
||||||
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ;
|
|
||||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
|
||||||
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
|
||||||
int GetChunkCount( void) const override ;
|
int GetChunkCount( void) const override ;
|
||||||
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
|
||||||
bool EraseChunk(int nChunk) override ;
|
|
||||||
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
|
||||||
bool GetChunkArea( int nChunk, double& dArea) const override ;
|
|
||||||
bool GetChunkPerimeter( int nChunk, double& dLen) const override ;
|
|
||||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
|
||||||
bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ;
|
|
||||||
int GetLoopCount( int nChunk) const override ;
|
int GetLoopCount( int nChunk) const override ;
|
||||||
int GetLoopCurveCount( int nChunk, int nLoop) const override ;
|
|
||||||
ICurve* GetLoop( int nChunk, int nLoop) const override ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
ICurve* GetLoop( int nChunk, int nLoop) const override ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||||
bool ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const override ;
|
bool ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const override ;
|
||||||
bool SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd = 0) override ;
|
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||||
bool GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd = 0) const override ;
|
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
||||||
bool ResetAllCurveTempProps( void) override ;
|
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
||||||
bool SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd = 0) override ;
|
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
||||||
bool GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dParam, int nParamInd = 0) const override ;
|
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||||
bool ResetAllCurveTempParams( void) override ;
|
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ;
|
||||||
|
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ;
|
||||||
|
void ResetVoronoiObject( void) const override ;
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -148,7 +136,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
|
|
||||||
private :
|
private :
|
||||||
bool CopyFrom( const SurfFlatRegion& clSrc) ;
|
bool CopyFrom( const SurfFlatRegion& clSrc) ;
|
||||||
bool AddSimpleExtLoop( ICurve* pCrv, bool& bAdded) ;
|
bool AddSimpleExtLoop( ICurve* pCrv) ;
|
||||||
bool MyAddExtLoop( ICurve* pCrv) ;
|
bool MyAddExtLoop( ICurve* pCrv) ;
|
||||||
bool AddSimpleIntLoop( ICurve* pCrv) ;
|
bool AddSimpleIntLoop( ICurve* pCrv) ;
|
||||||
bool MyAddIntLoop( ICurve* pCrv, int nChunk) ;
|
bool MyAddIntLoop( ICurve* pCrv, int nChunk) ;
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
|
|||||||
|
|
||||||
// creo una nuova regione a partire da questi loop
|
// creo una nuova regione a partire da questi loop
|
||||||
PtrOwner<SurfFlatRegion> pSfr ;
|
PtrOwner<SurfFlatRegion> pSfr ;
|
||||||
if ( vpLoop.empty())
|
if ( vpLoop.size() == 0)
|
||||||
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
||||||
else
|
else
|
||||||
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
||||||
@@ -258,7 +258,7 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
|
|||||||
|
|
||||||
// creo una nuova regione a partire da questi loop
|
// creo una nuova regione a partire da questi loop
|
||||||
PtrOwner<SurfFlatRegion> pSfr ;
|
PtrOwner<SurfFlatRegion> pSfr ;
|
||||||
if ( vpLoop.empty())
|
if ( vpLoop.size() == 0)
|
||||||
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
||||||
else
|
else
|
||||||
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// costruisco la superficie
|
// costruisco la superficie
|
||||||
if ( ! vOffs.empty()) {
|
if ( vOffs.size() > 0) {
|
||||||
PCRV_DEQUE vLoops ;
|
PCRV_DEQUE vLoops ;
|
||||||
for ( int i = 0 ; i < int( vOffs.size()) ; i ++) {
|
for ( int i = 0 ; i < int( vOffs.size()) ; i ++) {
|
||||||
vOffs[i]->ToLoc( m_frF) ;
|
vOffs[i]->ToLoc( m_frF) ;
|
||||||
@@ -162,7 +162,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// verifico di avere ancora dei loops
|
// verifico di avere ancora dei loops
|
||||||
if ( ! vLoops.empty()) {
|
if ( vLoops.size() > 0) {
|
||||||
pSfr.Set( MyNewSurfFromLoops( vLoops)) ;
|
pSfr.Set( MyNewSurfFromLoops( vLoops)) ;
|
||||||
if ( IsNull( pSfr)) {
|
if ( IsNull( pSfr)) {
|
||||||
MyTestAndDelete( vLoops) ;
|
MyTestAndDelete( vLoops) ;
|
||||||
|
|||||||
+91
-880
File diff suppressed because it is too large
Load Diff
+21
-64
@@ -1,7 +1,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2014-2025
|
// EgalTech 2014-2023
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : SurfTriMesh.h Data : 28.03.25 Versione : 2.7c4
|
// File : SurfTriMesh.h Data : 09.12.23 Versione : 2.5l2
|
||||||
// Contenuto : Dichiarazione della classe Superficie TriMesh.
|
// Contenuto : Dichiarazione della classe Superficie TriMesh.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
#include "GeoObjRW.h"
|
#include "GeoObjRW.h"
|
||||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||||
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
||||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -53,16 +52,16 @@ class StmTria
|
|||||||
public :
|
public :
|
||||||
StmTria( void)
|
StmTria( void)
|
||||||
: nIdVert{ SVT_NULL, SVT_NULL, SVT_NULL}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
: nIdVert{ SVT_NULL, SVT_NULL, SVT_NULL}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||||
StmTria( const int nIdV[3])
|
StmTria( const int nIdV[3])
|
||||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||||
StmTria( const int nIdV[3], int nTF)
|
StmTria( const int nIdV[3], int nTF)
|
||||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||||
vtN(), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
vtN(), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||||
StmTria( const int nIdV[3], const int nIdA[3], const Vector3d& vtV, int nTF, int nEF)
|
StmTria( const int nIdV[3], const int nIdA[3], const Vector3d& vtV, int nTF, int nEF)
|
||||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ nIdA[0], nIdA[1], nIdA[2]}, nETempFlag{ 0, 0, 0},
|
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ nIdA[0], nIdA[1], nIdA[2]}, nETempFlag{ 0, 0, 0},
|
||||||
vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||||
public :
|
public :
|
||||||
int nIdVert[3] ;
|
int nIdVert[3] ;
|
||||||
int nIdAdjac[3] ;
|
int nIdAdjac[3] ;
|
||||||
@@ -71,25 +70,9 @@ class StmTria
|
|||||||
int nIdFacet ;
|
int nIdFacet ;
|
||||||
int nTFlag ;
|
int nTFlag ;
|
||||||
int nEFlag ;
|
int nEFlag ;
|
||||||
mutable int nShell ;
|
mutable int nPart ;
|
||||||
mutable int nTemp ;
|
mutable int nTemp ;
|
||||||
mutable int nTempShell ;
|
mutable int nTempPart ;
|
||||||
} ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Classe Part
|
|
||||||
class StmPart
|
|
||||||
{
|
|
||||||
public :
|
|
||||||
StmPart( void)
|
|
||||||
: bClosed( false) {}
|
|
||||||
StmPart( bool bClo, const INTVECTOR& vSh)
|
|
||||||
: bClosed( bClo), vShell( vSh) {}
|
|
||||||
int GetShellCount( void)
|
|
||||||
{ return ( vShell.empty() ? 0 : int( vShell.size()) - ( vShell[0] == -1 ? 1 : 0)) ; }
|
|
||||||
public :
|
|
||||||
bool bClosed ;
|
|
||||||
INTVECTOR vShell ;
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -252,7 +235,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool RemoveTriangle( int nId) override ;
|
bool RemoveTriangle( int nId) override ;
|
||||||
bool AdjustTopology( void) override ;
|
bool AdjustTopology( void) override ;
|
||||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
bool CreateByFlatContour( const PolyLine& PL) override ;
|
||||||
bool CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL) override ;
|
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
||||||
bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) override ;
|
bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) override ;
|
||||||
bool CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) override ;
|
bool CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) override ;
|
||||||
bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nRuledType) override ;
|
bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nRuledType) override ;
|
||||||
@@ -296,7 +279,6 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
SurfTriMesh* CloneTriangle( int nT) const override ;
|
SurfTriMesh* CloneTriangle( int nT) const override ;
|
||||||
bool GetLoops( POLYLINEVECTOR& vPL) const override ;
|
bool GetLoops( POLYLINEVECTOR& vPL) const override ;
|
||||||
bool GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ;
|
bool GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ;
|
||||||
bool GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ;
|
|
||||||
int GetFacetCount( void) const override ;
|
int GetFacetCount( void) const override ;
|
||||||
int GetFacetSize( void) const override
|
int GetFacetSize( void) const override
|
||||||
{ return int( m_vFacet.size()) ; }
|
{ return int( m_vFacet.size()) ; }
|
||||||
@@ -328,25 +310,14 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool Intersect( const ISurfTriMesh& Other) override ;
|
bool Intersect( const ISurfTriMesh& Other) override ;
|
||||||
bool Subtract( const ISurfTriMesh& Other) override ;
|
bool Subtract( const ISurfTriMesh& Other) override ;
|
||||||
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
||||||
bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
||||||
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
||||||
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
||||||
const BBox3d& GetAllTriaBox( void) const override ;
|
const BBox3d& GetAllTriaBox( void) const override ;
|
||||||
int GetShellCount( void) const override ;
|
int GetPartCount( void) const override ;
|
||||||
bool GetShellArea( int nShell, double& dArea) const override ;
|
|
||||||
bool RemoveShell( int nShell) override ;
|
|
||||||
SurfTriMesh* CloneShell( int nShell) const override ;
|
|
||||||
bool GetPartLocalBBox( int nP, BBox3d& b3Loc) const override ;
|
|
||||||
bool GetPartBBox( int nP, const Frame3d& frRef, BBox3d& b3Ref) const override ;
|
|
||||||
int GetPartCount( void) const override ;
|
|
||||||
bool RemovePart( int nPart) override ;
|
bool RemovePart( int nPart) override ;
|
||||||
bool GetPartArea( int nPart, double& dArea) const override ;
|
|
||||||
bool GetPartVolume( int nPart, double& dVolume) const override ;
|
|
||||||
bool GetPartLoops( int nPart, POLYLINEVECTOR& vPL) const override ;
|
|
||||||
SurfTriMesh* ClonePart( int nPart) const override ;
|
SurfTriMesh* ClonePart( int nPart) const override ;
|
||||||
bool SetTFlag( int nId, int nTFlag) override ;
|
|
||||||
bool GetTFlag( int nId, int& nFlag) const override ;
|
|
||||||
int GetMaxTFlag( void) const override
|
int GetMaxTFlag( void) const override
|
||||||
{ return m_nMaxTFlag ; }
|
{ return m_nMaxTFlag ; }
|
||||||
bool ResetTFlags( void) override ;
|
bool ResetTFlags( void) override ;
|
||||||
@@ -369,20 +340,18 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
LOG_ERROR( GetEGkLogger(), "SurfTriMesh : copy error")
|
LOG_ERROR( GetEGkLogger(), "SurfTriMesh : copy error")
|
||||||
return *this ; }
|
return *this ; }
|
||||||
bool Clear( void) ;
|
bool Clear( void) ;
|
||||||
bool CreateByRegion( const POLYLINEVECTOR& vPL, const INTMATRIX& vnPLIndMat) ;
|
|
||||||
bool ExistsTriangle( int nT) const
|
bool ExistsTriangle( int nT) const
|
||||||
{ return ( nT >= 0 && nT < GetTriangleSize() && m_vTria[nT].nIdVert[0] != SVT_DEL) ; }
|
{ return ( nT >= 0 && nT < GetTriangleSize() && m_vTria[nT].nIdVert[0] != SVT_DEL) ; }
|
||||||
bool GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const ;
|
bool GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const ;
|
||||||
|
bool GetTFlag( int nId, int& nFlag) const ;
|
||||||
bool GetTempInt( int nId, int& nTempInt) const ;
|
bool GetTempInt( int nId, int& nTempInt) const ;
|
||||||
bool ResetTempInts( void) const ;
|
bool ResetTempInts( void) const ;
|
||||||
|
bool SetTFlag( int nId, int nTFlag) ;
|
||||||
bool SetTempInt( int nId, int nTempInt) const ;
|
bool SetTempInt( int nId, int nTempInt) const ;
|
||||||
bool AddTriaFromZMap( const TRIA3DEXVECTOR& vTria, PointGrid3d& VertGrid, double dVertexTol = 2 * EPS_SMALL) ;
|
|
||||||
bool AdjustTopologyFromZMap( void) ;
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
typedef std::vector<StmVert> VERTVECTOR ;
|
typedef std::vector<StmVert> VERTVECTOR ;
|
||||||
typedef std::vector<StmTria> TRIAVECTOR ;
|
typedef std::vector<StmTria> TRIAVECTOR ;
|
||||||
typedef std::vector<StmPart> PARTVECTOR ;
|
|
||||||
typedef std::vector<StmFacEdge> FACEDGEVECTOR ;
|
typedef std::vector<StmFacEdge> FACEDGEVECTOR ;
|
||||||
typedef std::deque<Stm3Int> TRINTDEQUE ;
|
typedef std::deque<Stm3Int> TRINTDEQUE ;
|
||||||
|
|
||||||
@@ -393,7 +362,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool CopyFrom( const SurfTriMesh& clSrc) ;
|
bool CopyFrom( const SurfTriMesh& clSrc) ;
|
||||||
bool Validate( bool bCorrect = false) ;
|
bool Validate( bool bCorrect = false) ;
|
||||||
bool AdjustVertices( void) ;
|
bool AdjustVertices( void) ;
|
||||||
bool AdjustAdjacencies( bool AdjustVert = true) ;
|
bool AdjustAdjacencies( void) ;
|
||||||
bool AdjustOrientations( void) ;
|
bool AdjustOrientations( void) ;
|
||||||
bool AdjustTriaOrientation( TRINTDEQUE& S3iQ) ;
|
bool AdjustTriaOrientation( TRINTDEQUE& S3iQ) ;
|
||||||
bool TestSealing( void) ;
|
bool TestSealing( void) ;
|
||||||
@@ -427,27 +396,23 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool UpdateFacetEdging( void) ;
|
bool UpdateFacetEdging( void) ;
|
||||||
void ResetHashGrids3d( void) const ;
|
void ResetHashGrids3d( void) const ;
|
||||||
bool VerifyHashGrids3d( void) const ;
|
bool VerifyHashGrids3d( void) const ;
|
||||||
bool VerifyConnection( bool bShellsAndParts = true) const ;
|
bool VerifyConnection( void) const ;
|
||||||
bool IsShellClosed( int nShell) const ;
|
|
||||||
bool IsPartClosed( int nPart) const ;
|
|
||||||
bool CutTriangleByPlane( int nTriaId, const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
bool CutTriangleByPlane( int nTriaId, const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||||
bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||||
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
||||||
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
||||||
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
||||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||||
bool IdentifyShells( void) const ;
|
bool IdentifyParts( void) const ;
|
||||||
bool RemoveDoubleTriangles( bool& bModified) ;
|
bool RemoveDoubleTriangles( bool& bModified) ;
|
||||||
bool RemoveTJunctions( bool& bModified, double dMinSqDist = SQ_EPS_TRIA_H) ;
|
bool RemoveTJunctions( bool& bModified) ;
|
||||||
bool FlipTriangles( int nTA, int nTB) ;
|
bool FlipTriangles( int nTA, int nTB) ;
|
||||||
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true, double dTolAlign = 50 * EPS_SMALL) ;
|
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true) ;
|
||||||
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||||
bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) ;
|
bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) ;
|
||||||
bool AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, double dTolAlign, bool& bModif) const ;
|
|
||||||
bool RemoveInvalidTriangles( const INTVECTOR& vIds) ;
|
|
||||||
bool FindAdjacentOnLongerEdge( int nT, int& nEdge, int& nAdjTrg) const ;
|
|
||||||
private :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
Status m_nStatus ; // stato
|
Status m_nStatus ; // stato
|
||||||
@@ -469,10 +434,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||||
int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli
|
int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli
|
||||||
mutable int m_nShells ; // numero di gusci connessi (-1 se da calcolare)
|
mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare)
|
||||||
mutable PARTVECTOR m_vPart ; // vettore delle parti (flag chiusura e elenco shell, prima sempre esterna o infinita)
|
|
||||||
mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento
|
mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento
|
||||||
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
|
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -490,10 +454,3 @@ inline SurfTriMesh* GetBasicSurfTriMesh( IGeoObj* pGObj)
|
|||||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
return ( static_cast<SurfTriMesh*>( pGObj)) ; }
|
return ( static_cast<SurfTriMesh*>( pGObj)) ; }
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Raccolte di puntatori a SurfTriMesh
|
|
||||||
typedef std::vector<const SurfTriMesh*> CISRFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
|
||||||
typedef std::vector<SurfTriMesh*> ISRFTMPVECTOR ; // vettore di puntatori a SurfTriMesh
|
|
||||||
typedef std::list<SurfTriMesh*> ISRFTMPLIST ; // lista di puntatori a SurfTriMesh
|
|
||||||
typedef std::vector<PtrOwner<SurfTriMesh>> ISRFTMPOVECTOR ; // vettore di puntatori esclusivi a SurfTriMesh
|
|
||||||
|
|||||||
+388
-285
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user