Compare commits
357 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da8f40db17 | |||
| 5468e3f4fa | |||
| 88684e305f | |||
| f8ca8029d7 | |||
| aa9c46cbb5 | |||
| f0cf3c9559 | |||
| 9a638b9470 | |||
| b07fbfc72e | |||
| 0317c37557 | |||
| a98b6bcc09 | |||
| c19861a911 | |||
| 8f8597d442 | |||
| 0c0eb9ef8f | |||
| 4ffb7087bd | |||
| dc070c4556 | |||
| 60729d5f39 | |||
| da7e9dd6e2 | |||
| aeff9fb418 | |||
| e9e897593b | |||
| bfc09d135c | |||
| 0998d0fffc | |||
| 93c87ee720 | |||
| a67a0502fa | |||
| cec0a48be4 | |||
| 0cc63d40eb | |||
| 623eb6e630 | |||
| 1f22299096 | |||
| 3f6c439983 | |||
| 8e22267476 | |||
| aa2b6ccde5 | |||
| ec6cb79a8d | |||
| 76dceb4fc9 | |||
| b1564f7de0 | |||
| 21e4bd6d93 | |||
| 2101d72abe | |||
| 7a01f67c8b | |||
| 2267343afe | |||
| 9a5fe24781 | |||
| 4050aa11c5 | |||
| b75ddae396 | |||
| 2d3f8487ee | |||
| 964647d7e6 | |||
| f78dd0fa83 | |||
| 55ce22b06c | |||
| 50df4f3503 | |||
| 5c8f0c79f6 | |||
| de3f187ddf | |||
| f649954ee1 | |||
| 6e08f2a878 | |||
| 887922a715 | |||
| 640fef2e0a | |||
| 1a338a1a82 | |||
| 4f3fe68283 | |||
| 3908e11d18 | |||
| 4e6c5112e4 | |||
| e1ab88302f | |||
| 2b4090619b | |||
| b90289e42b | |||
| 5e84408685 | |||
| b53c2f833a | |||
| b5fcceaa75 | |||
| f0bfbb6c85 | |||
| 2710f735d1 | |||
| ddffbd2c88 | |||
| fde952499d | |||
| b28102a8cc | |||
| f46db233dc | |||
| df10b45c6b | |||
| 1b13580340 | |||
| 742305b99b | |||
| 1261de4dbb | |||
| b50588f974 | |||
| 9b87de9fa2 | |||
| 5bab4a9aa8 | |||
| c3e7d3d8c7 | |||
| 89c22ffd06 | |||
| 5375752609 | |||
| 0a8f26c993 | |||
| cba9c253e1 | |||
| 71f3bf8809 | |||
| d491536eb4 | |||
| e68465c80b | |||
| dfb8fd2160 | |||
| 746fa61e08 | |||
| d0e0c46e2c | |||
| 19c7f63303 | |||
| 87f6a29db3 | |||
| b04d1ed7a9 | |||
| 54dba7ab41 | |||
| 146c06d27f | |||
| 7c45c1e287 | |||
| d6dc5b8428 | |||
| 28695f9138 | |||
| 66cec4a872 | |||
| 8d1d3f766a | |||
| befed079c8 | |||
| b9138029db | |||
| 2246dbc284 | |||
| 67180b3569 | |||
| 3a2aa2c679 | |||
| 9dd4e043d4 | |||
| 4748bd5ac8 | |||
| 649f97e933 | |||
| 21feed172d | |||
| e853ff7f13 | |||
| 95ff8b21b9 | |||
| a7be952e11 | |||
| 7a67ce9333 | |||
| 695350d3f6 | |||
| aade1d19f1 | |||
| fd4677d099 | |||
| f7a28447fb | |||
| 79b470b18b | |||
| f6d3873ecb | |||
| 92a8cdad99 | |||
| 0c346e2bc7 | |||
| d54caf4ae3 | |||
| ff9ea34ae1 | |||
| c7035305e2 | |||
| bc3c1e377e | |||
| 98eff1b0b9 | |||
| 052cc9e841 | |||
| b6a7ce4eef | |||
| 7a66ad27d8 | |||
| b4878f1ac0 | |||
| 447ebe11e5 | |||
| 8981057d29 | |||
| 3270b573a8 | |||
| 6df0cf3203 | |||
| d67cca385e | |||
| f9d67442d6 | |||
| dea96ccbcc | |||
| 0f4be10330 | |||
| 121abf5864 | |||
| 38e836de2b | |||
| 376c4e3693 | |||
| 48ffd52b16 | |||
| 9a16259ff5 | |||
| 10ae269882 | |||
| 9d845179a4 | |||
| 88bf84cca1 | |||
| 5ba8f1df36 | |||
| c4a05bcb2f | |||
| 5841c9cae0 | |||
| 4fd03a78de | |||
| 420c072670 | |||
| 36477623b8 | |||
| 84d859dfe2 | |||
| 09220bfd68 | |||
| 42aaf6f3eb | |||
| 3f1f365451 | |||
| 9a29ee0e27 | |||
| 619905d720 | |||
| 36ce855ef3 | |||
| 9b0f2c7f59 | |||
| c637ccec47 | |||
| 8f27154604 | |||
| 5d02732db6 | |||
| 36657e17c4 | |||
| e2008bd479 | |||
| e32b85bc2d | |||
| 6dfc50e630 | |||
| b4820ff255 | |||
| 515247a394 | |||
| b5c649821f | |||
| 9ba0c6f4cc | |||
| 35fc94d8cb | |||
| a0316e280c | |||
| 84bcc715a8 | |||
| b34d31029b | |||
| f67865f9cc | |||
| f48053a541 | |||
| 8e917aa6d2 | |||
| f08dee836b | |||
| 261e9ac0c8 | |||
| b51d0c3e64 | |||
| ac23938dd0 | |||
| b9bac347e8 | |||
| 980a1f62df | |||
| 10c5d0fffe | |||
| d7d36b670a | |||
| 581551ee3e | |||
| 487ce0c84b | |||
| 5679733028 | |||
| cd0fc4e449 | |||
| e20b4b5b78 | |||
| b931582120 | |||
| bf14ab1332 | |||
| 3b81a6b92e | |||
| 01bf44cf1e | |||
| b5d879cd3d | |||
| 2b3c285190 | |||
| 99bb83211c | |||
| b854c9588b | |||
| 2361225321 | |||
| eaf1138624 | |||
| ef5c67a4d5 | |||
| 3e924113d3 | |||
| dcc3fc772a | |||
| a48f373e4d | |||
| ffd714d069 | |||
| dc082d495e | |||
| e8e57ff793 | |||
| 3e16c4b56c | |||
| 77d3fcc7af | |||
| 7322bf5034 | |||
| 2ed2a34d55 | |||
| d340505593 | |||
| 247849d112 | |||
| fcbdee1dba | |||
| 33d1ef4123 | |||
| fe2aba43e5 | |||
| c0b5f38301 | |||
| 1c157f323e | |||
| 3e6aa0d81b | |||
| 34089648b0 | |||
| 0bef1638d0 | |||
| 1d4bccac4b | |||
| cc7aa66904 | |||
| 303a270359 | |||
| 17759877d4 | |||
| 5f56152a8b | |||
| d6567e94c4 | |||
| d00064a671 | |||
| dc91f932f7 | |||
| a3f05c41fe | |||
| d911862c84 | |||
| 1b025ec60e | |||
| 9d18e1a9ba | |||
| 3143c00729 | |||
| 3a8900983a | |||
| 971a76e473 | |||
| 621bf93ee9 | |||
| 35c019a03e | |||
| de97f249a2 | |||
| 81f0cc23bf | |||
| 8a0234093e | |||
| 88d355f2f7 | |||
| 20fd06d67c | |||
| 52f2785e67 | |||
| 2e2bd0ceec | |||
| e4c3c9a2a4 | |||
| e490c173e8 | |||
| 7e165a6dea | |||
| 49ff6e79a8 | |||
| 1160e3d067 | |||
| 91d667bcfc | |||
| b23df89cd3 | |||
| cf9737a48e | |||
| ae52115bda | |||
| 3dd9466938 | |||
| c0f7eb6727 | |||
| 76e2843ed3 | |||
| faa2004c29 | |||
| c9a59dc5ea | |||
| aaaf951990 | |||
| cc263089ca | |||
| d99b8f4c86 | |||
| f5e5441469 | |||
| 4206a4822f | |||
| 788a5bc4eb | |||
| a5a96c2bb5 | |||
| 881691e678 | |||
| 80f4d64ad4 | |||
| 7d9a641e39 | |||
| d82ccd8947 | |||
| 318b1e4b2f | |||
| 583e30170a | |||
| fe46b8ebd2 | |||
| 6a845e4f81 | |||
| 46e18b3977 | |||
| 20d146268b | |||
| 5013fc2b6c | |||
| 32a0e1d2b5 | |||
| 7ce9e7e26c | |||
| 9a6e972521 | |||
| 8c008f36c2 | |||
| eae29d4854 | |||
| 2bd53476ca | |||
| 015065f3c8 | |||
| 12862a6c76 | |||
| 9d869411e8 | |||
| 0c3c17e0f4 | |||
| 47f6eedd9c | |||
| b36adefd10 | |||
| 8cf8c0def5 | |||
| 1e6a70c60d | |||
| 9712e8c526 | |||
| 6b1f932dfc | |||
| 7882964b26 | |||
| 9653ba8d53 | |||
| ba66891539 | |||
| 4ab4a2fc81 | |||
| a6d9811595 | |||
| c94a62f5b2 | |||
| 535011072d | |||
| 718f5ce716 | |||
| 3f02119ef7 | |||
| 632b711b2a | |||
| 07faeaaa11 | |||
| 104726c5ee | |||
| e2445c0a15 | |||
| d253312139 | |||
| 9880fa0173 | |||
| 5952eee22c | |||
| 4483434711 | |||
| d276809906 | |||
| 93678ce56c | |||
| 8c4b0bde37 | |||
| 67c03daa42 | |||
| 469d1c3445 | |||
| 4268da4a1f | |||
| 7d3284fef3 | |||
| 3857cd4b5a | |||
| a04a748552 | |||
| 13ecae3829 | |||
| 1acd97d42a | |||
| 4f485d0e87 | |||
| d48348fa1c | |||
| 003dd0bdef | |||
| 6a92f6b80f | |||
| bf3760808e | |||
| ec109908fa | |||
| 3630b85632 | |||
| 45226d0b6f | |||
| fdce6e1853 | |||
| 8ffa9d7fb7 | |||
| 96ea6bc73e | |||
| 360484c9af | |||
| 47606bffcd | |||
| 7a2af0b5f2 | |||
| 8d2ae598e5 | |||
| aea99a635f | |||
| ce139c6925 | |||
| 4b19936136 | |||
| 6efb3a6e7f | |||
| 5dcf5f5616 | |||
| 451ef8356b | |||
| 3a623996d2 | |||
| 4bada73c83 | |||
| 156d0eea4b | |||
| 6e810f050e | |||
| 6bfb5c619f | |||
| c303b1273d | |||
| 8d0c04e092 | |||
| 5d62db3e73 | |||
| 8be2246249 | |||
| 1005aae0e9 | |||
| 0f8012ce61 | |||
| 2c159d7ce6 | |||
| b4058ad363 | |||
| 6b5de066b7 | |||
| 56cff98cf3 | |||
| 3168bee865 | |||
| 3d2f8c1495 | |||
| a3531c4841 | |||
| d7ec1fd304 |
@@ -317,6 +317,8 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
|
||||
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||
// unisco eventuali tratti allineati
|
||||
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 "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
+2
-1
@@ -134,7 +134,8 @@ 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
|
||||
// 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
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
|
||||
+8
-8
@@ -133,22 +133,22 @@ Attribs::Load( NgeReader& ngeIn)
|
||||
unsigned char ucLev ;
|
||||
if ( ! ngeIn.ReadUchar( ucLev, ","))
|
||||
return false ;
|
||||
m_Data[LEVEL] = CLIP( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
m_Data[LEVEL] = Clamp( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
// modo
|
||||
unsigned char ucMode ;
|
||||
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
||||
return false ;
|
||||
m_Data[MODE] = CLIP( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
m_Data[MODE] = Clamp( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
// stato (se SEL è convertito in ON)
|
||||
unsigned char ucStat ;
|
||||
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
||||
return false ;
|
||||
m_Data[STATUS] = CLIP( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
m_Data[STATUS] = Clamp( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
// marcatura (sempre OFF)
|
||||
unsigned char ucMark ;
|
||||
if ( ! ngeIn.ReadUchar( ucMark, ";"))
|
||||
return false ;
|
||||
m_Data[MARK] = CLIP( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
m_Data[MARK] = Clamp( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
// materiale
|
||||
if ( ! ngeIn.ReadInt( m_Material, ";"))
|
||||
return false ;
|
||||
@@ -185,22 +185,22 @@ Attribs::DataFromString( const string& sParam)
|
||||
int nLev ;
|
||||
if ( ! FromString( vsParams[0], nLev))
|
||||
return false ;
|
||||
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
// modo
|
||||
int nMode ;
|
||||
if ( ! FromString( vsParams[1], nMode))
|
||||
return false ;
|
||||
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
// stato (ammessi solo OFF e ON)
|
||||
int nStat ;
|
||||
if ( ! FromString( vsParams[2], nStat))
|
||||
return false ;
|
||||
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
// marcatura (ammesso solo OFF)
|
||||
int nMark ;
|
||||
if ( ! FromString( vsParams[3], nMark))
|
||||
return false ;
|
||||
m_Data[MARK] = CLIP( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
#include "/EgtDev/Include/EGkGdbConst.h"
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
#include "/EgtDev/Include/EgtStringBase.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
|
||||
class NgeWriter ;
|
||||
class NgeReader ;
|
||||
class GeomDB ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define CLIP( nV, nMIN, nMAX) (( nV < nMIN) ? nMIN : (( nV > nMAX) ? nMAX : nV))
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class Attribs
|
||||
{
|
||||
@@ -46,14 +44,14 @@ class Attribs
|
||||
bool Load( NgeReader& ngeIn) ;
|
||||
void SetLevel( int nLev)
|
||||
{ m_OldData[LEVEL] = m_Data[LEVEL] ;
|
||||
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
||||
void RevertLevel( void)
|
||||
{ std::swap( m_Data[LEVEL], m_OldData[LEVEL]) ; }
|
||||
int GetLevel( void) const
|
||||
{ return m_Data[LEVEL] ; }
|
||||
void SetMode( int nMode)
|
||||
{ m_OldData[MODE] = m_Data[MODE] ;
|
||||
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
||||
void RevertMode( void)
|
||||
{ std::swap( m_Data[MODE], m_OldData[MODE]) ; }
|
||||
int GetMode( void) const
|
||||
@@ -61,13 +59,13 @@ class Attribs
|
||||
void SetStatus( int nStat)
|
||||
{ if ( m_Data[STATUS] != GDB_ST_SEL)
|
||||
m_OldData[STATUS] = m_Data[STATUS] ;
|
||||
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
||||
void RevertStatus( void)
|
||||
{ SetStatus( m_OldData[STATUS]) ; }
|
||||
int GetStatus( void) const
|
||||
{ return m_Data[STATUS] ; }
|
||||
void SetMark( void)
|
||||
{ m_Data[MARK] = GDB_MK_ON ; }
|
||||
void SetMark( int nMark)
|
||||
{ m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_ON_2) ; }
|
||||
void ResetMark( void)
|
||||
{ m_Data[MARK] = GDB_MK_OFF ; }
|
||||
int GetMark( void) const
|
||||
|
||||
+9
-6
@@ -83,7 +83,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||
const PolyLine& PL, double& dDist)
|
||||
const PolyLine& PL, double& dDist, double dTol)
|
||||
{
|
||||
// calcolo la curva dove giacciono i punti di giunzione tra i due archi del biarco
|
||||
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)
|
||||
dU = 0.5 ;
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
@@ -142,7 +142,10 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
Point3d ptPrev = ptCurr ;
|
||||
while ( bPnt) {
|
||||
double dLen = Dist( ptCurr, ptPrev) ;
|
||||
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ;
|
||||
int nStep = 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) {
|
||||
double dCoeff = double( i) / nStep ;
|
||||
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
|
||||
@@ -163,7 +166,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
static ICurve*
|
||||
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))
|
||||
return nullptr ;
|
||||
|
||||
@@ -205,14 +208,14 @@ CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dD
|
||||
double dDir0RelDeg = DiffAngle( dDir0Deg, dDirDiffDeg) ;
|
||||
// direzione iniziale secondo arco limite rispetto a direzione P0->P1 (dalla finale simmetrico e invert)
|
||||
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)
|
||||
dDir1RelDeg = ( dDir0RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||
else if ( abs( abs( dDir0RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
||||
dDir0RelDeg = ( dDir1RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||
// intervallo angolare ammissibile a partire da direzione iniziale primo arco ammissibile ( == Dir0)
|
||||
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))
|
||||
pArc->ToExplementary() ;
|
||||
// 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,
|
||||
const PolyLine& PL, double& dDist) ;
|
||||
const PolyLine& PL, double& dDist, double dTol) ;
|
||||
|
||||
|
||||
@@ -0,0 +1,513 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CAvSilhouetteSurfTm.cpp Data : 08.06.24 Versione : 2.6f2
|
||||
// Contenuto : Implementazione della funzione CAvSilhouetteSurfTm.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.06.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CAvSilhouetteSurfTm.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Funzioni locali per calcolo isolinee con metodo Marching Squares
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Quadrato (C=corner E=edge) :
|
||||
//
|
||||
// C3 - E2 - C2
|
||||
// | |
|
||||
// E3 E1
|
||||
// | |
|
||||
// C0 - E0 - C1
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static Point3d
|
||||
CalcPoint( const Point3d& ptS, const Point3d& ptE, double dLevel,
|
||||
const ICAvToolSurfTm& cavTstm, const Frame3d &frGrid)
|
||||
{
|
||||
// Distanza tra gli estremi iniziali
|
||||
double dDist = max( abs( ptS.x - ptE.x), abs( ptS.y - ptE.y)) ;
|
||||
|
||||
// Ricerca con metodo di bisezione (si arresta quando il medio è allineato agli estremi)
|
||||
const int MAX_ITER = 10 ;
|
||||
int nCount = 0 ;
|
||||
Point3d ptP1 = ptS ;
|
||||
Point3d ptP2 = ptE ;
|
||||
Point3d ptMid = Media( ptP1, ptP2) ;
|
||||
while ( nCount < MAX_ITER) {
|
||||
// verifica del punto medio
|
||||
ptMid.z = 0 ;
|
||||
Point3d ptTest = GetToGlob( ptMid + cavTstm.GetToolHeight() * Z_AX, frGrid) ;
|
||||
double dMove ;
|
||||
cavTstm.TestPosition( ptTest, frGrid.VersZ(), frGrid.VersZ(), dMove) ;
|
||||
ptMid.z = dMove ;
|
||||
// se sta sulla linea che unisce gli estremi, basta interpolazione lineare
|
||||
if ( abs( ptMid.z - ( ptP1.z + ptP2.z) / 2) < EPS_SMALL / 2)
|
||||
return Media( ptP1, ptP2, ( ptP1.z - dLevel) / ( ptP1.z - ptP2.z)) ;
|
||||
// altrimenti nuova suddivisione della parte con estremi da parte opposta rispetto al livello
|
||||
bool b1On = ( ptP1.z > dLevel) ;
|
||||
bool bMidOn = ( ptMid.z > dLevel) ;
|
||||
if ( b1On != bMidOn)
|
||||
ptP2 = ptMid ;
|
||||
else
|
||||
ptP1 = ptMid ;
|
||||
ptMid = Media( ptP1, ptP2) ;
|
||||
++ nCount ;
|
||||
}
|
||||
ptMid.z = dLevel ;
|
||||
return ptMid ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
ProcessSquare( int nFlag, int& nI1s, int& nI1e, int& nI2s, int& nI2e)
|
||||
{
|
||||
static int LineTable[16][5] = { { 0, -1, -1, -1, -1},
|
||||
{ 1, 0, 3, -1, -1},
|
||||
{ 1, 1, 0, -1, -1},
|
||||
{ 1, 1, 3, -1, -1},
|
||||
{ 1, 2, 1, -1, -1},
|
||||
{ 2, 0, 1, 2, 3},
|
||||
{ 1, 2, 0, -1, -1},
|
||||
{ 1, 2, 3, -1, -1},
|
||||
{ 1, 3, 2, -1, -1},
|
||||
{ 1, 0, 2, -1, -1},
|
||||
{ 2, 1, 2, 3, 0},
|
||||
{ 1, 1, 2, -1, -1},
|
||||
{ 1, 3, 1, -1, -1},
|
||||
{ 1, 0, 1, -1, -1},
|
||||
{ 1, 3, 0, -1, -1},
|
||||
{ 0, -1, -1, -1, -1}} ;
|
||||
// flag fuori dai limiti
|
||||
if ( nFlag < 0 || nFlag > 15)
|
||||
return -1 ;
|
||||
// nessuna linea
|
||||
if ( LineTable[nFlag][0] == 0)
|
||||
return 0 ;
|
||||
// una linea
|
||||
else if ( LineTable[nFlag][0] == 1) {
|
||||
nI1s = LineTable[nFlag][1] ;
|
||||
nI1e = LineTable[nFlag][2] ;
|
||||
return 1 ;
|
||||
}
|
||||
// due linee
|
||||
else if ( LineTable[nFlag][0] == 2) {
|
||||
nI1s = LineTable[nFlag][1] ;
|
||||
nI1e = LineTable[nFlag][2] ;
|
||||
nI2s = LineTable[nFlag][3] ;
|
||||
nI2e = LineTable[nFlag][4] ;
|
||||
return 2 ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
TestSubEdges( unordered_map<int, Point3d>& umEdgePnt, const INTVECTOR& vEdgeInd, int nFirst, int nLast,
|
||||
const DBLVECTOR& vdGrid, int nStepX, double dStep,
|
||||
double dLevel, const ICAvToolSurfTm& cavTstm, const Frame3d &frGrid)
|
||||
{
|
||||
for ( int k = nFirst ; k <= nLast ; ++ k) {
|
||||
// recupero i differenti indici
|
||||
int nKey = vEdgeInd[k] ;
|
||||
int nInd = nKey / 2 ;
|
||||
bool bOnX = ( ( nKey % 2) == 0) ;
|
||||
int j = nInd / ( nStepX + 1) ;
|
||||
int i = nInd % ( nStepX + 1) ;
|
||||
// determino i punti estremi dell'edge
|
||||
Point3d ptS{ i * dStep, j * dStep, vdGrid[nInd]} ;
|
||||
Point3d ptE{ ptS.x + ( bOnX ? dStep : 0), ptS.y + ( bOnX ? 0 : dStep), vdGrid[nInd + ( bOnX ? 1 : nStepX + 1)]} ;
|
||||
// calcolo il punto
|
||||
Point3d ptQ = CalcPoint( ptS, ptE, dLevel, cavTstm, frGrid) ;
|
||||
umEdgePnt[ nKey] = ptQ ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep, double dRad,
|
||||
double dLevel, const ICAvToolSurfTm& cavTstm, const Frame3d &frGrid, POLYLINEVECTOR& vPL)
|
||||
{
|
||||
// Analizzo gli edge da cui passano le curve cercate
|
||||
unordered_map<int, Point3d> umEdgePnt( 4 * ( nStepX + nStepY)) ;
|
||||
INTVECTOR vEdgeInd ;
|
||||
vEdgeInd.reserve( 4 * ( nStepX + nStepY)) ;
|
||||
for ( int j = 0 ; j < nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i < nStepX ; ++ i) {
|
||||
// indici dei vertici nella griglia
|
||||
int nInd0 = i + j * ( nStepX + 1) ;
|
||||
int nInd1 = ( i + 1) + j * ( nStepX + 1) ;
|
||||
int nInd2 = ( i + 1) + ( j + 1) * ( nStepX + 1) ;
|
||||
int nInd3 = i + ( j + 1) * ( nStepX + 1) ;
|
||||
// flag del quadrato
|
||||
bool bUp0 = ( vdGrid[nInd0] > dLevel) ;
|
||||
bool bUp1 = ( vdGrid[nInd1] > dLevel) ;
|
||||
bool bUp2 = ( vdGrid[nInd2] > dLevel) ;
|
||||
bool bUp3 = ( vdGrid[nInd3] > dLevel) ;
|
||||
// se tutti uguali, passo al successivo
|
||||
if ( bUp0 == bUp1 && bUp0 == bUp2 && bUp0 == bUp3)
|
||||
continue ;
|
||||
// verifico quali calcolare
|
||||
if ( bUp0 != bUp1) {
|
||||
int nKey = 2 * nInd0 ;
|
||||
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
|
||||
umEdgePnt[ nKey] = P_INVALID ;
|
||||
vEdgeInd.emplace_back( nKey) ;
|
||||
}
|
||||
}
|
||||
if ( bUp3 != bUp2) {
|
||||
int nKey = 2 * nInd3 ;
|
||||
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
|
||||
umEdgePnt[ nKey] = P_INVALID ;
|
||||
vEdgeInd.emplace_back( nKey) ;
|
||||
}
|
||||
}
|
||||
if ( bUp0 != bUp3) {
|
||||
int nKey = 2 * nInd0 + 1 ;
|
||||
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
|
||||
umEdgePnt[ nKey] = P_INVALID ;
|
||||
vEdgeInd.emplace_back( nKey) ;
|
||||
}
|
||||
}
|
||||
if ( bUp1 != bUp2) {
|
||||
int nKey = 2 * nInd1 + 1 ;
|
||||
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
|
||||
umEdgePnt[ nKey] = P_INVALID ;
|
||||
vEdgeInd.emplace_back( nKey) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Numero di edge da valutare
|
||||
int nEdgeCnt = int( vEdgeInd.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 || nEdgeCnt < 50) {
|
||||
TestSubEdges( umEdgePnt, vEdgeInd, 0, nEdgeCnt - 1, vdGrid, nStepX, dStep, dLevel, cavTstm, frGrid) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
const int MAX_PARTS = 32 ;
|
||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||
// calcolo le parti del vettore
|
||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||
int nPartDim = nEdgeCnt / nPartCnt + 1 ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
vFstLst[i].first = i * nPartDim ;
|
||||
vFstLst[i].second = min( ( i + 1) * nPartDim, nEdgeCnt) - 1 ;
|
||||
}
|
||||
// processo le parti
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||
vRes[i] = async( launch::async, &TestSubEdges, ref( umEdgePnt), cref( vEdgeInd), vFstLst[i].first, vFstLst[i].second,
|
||||
cref( vdGrid), nStepX, dStep, dLevel, cref( cavTstm), cref( frGrid)) ;
|
||||
// attendo i risultati
|
||||
int nFin = 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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Predispongo il concatenamento
|
||||
BIPNTVECTOR vBiPnt ;
|
||||
vBiPnt.reserve( 2 * ( nStepX + nStepY)) ;
|
||||
ChainCurves chainC ;
|
||||
chainC.Init( false, EPS_SMALL, 2 * ( nStepX + nStepY)) ;
|
||||
// Ciclo sui quadrati da analizzare
|
||||
for ( int j = 0 ; j < nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i < nStepX ; ++ i) {
|
||||
// indici dei vertici nella griglia
|
||||
int nInd0 = i + j * ( nStepX + 1) ;
|
||||
int nInd1 = ( i + 1) + j * ( nStepX + 1) ;
|
||||
int nInd2 = ( i + 1) + ( j + 1) * ( nStepX + 1) ;
|
||||
int nInd3 = i + ( j + 1) * ( nStepX + 1) ;
|
||||
// flag del quadrato
|
||||
int nFlag = ( vdGrid[nInd0] > dLevel ? 1 : 0) +
|
||||
( vdGrid[nInd1] > dLevel ? 2 : 0) +
|
||||
( vdGrid[nInd2] > dLevel ? 4 : 0) +
|
||||
( vdGrid[nInd3] > dLevel ? 8 : 0) ;
|
||||
// se quadrato con vertici tutti dello stesso tipo, passo al successivo
|
||||
if ( nFlag == 0 || nFlag == 15)
|
||||
continue ;
|
||||
// chiavi
|
||||
int vKey[4] = { 2 * nInd0, 2 * nInd1 + 1, 2 * nInd3, 2 * nInd0 + 1} ;
|
||||
// calcolo segmenti da inserire
|
||||
int nI1s, nI1e, nI2s, nI2e ;
|
||||
int nSegCnt = ProcessSquare( nFlag, nI1s, nI1e, nI2s, nI2e) ;
|
||||
if ( nSegCnt == -1)
|
||||
return false ;
|
||||
else if ( nSegCnt == 1) {
|
||||
Point3d ptL1s = umEdgePnt.find( vKey[nI1s])->second ;
|
||||
Point3d ptL1e = umEdgePnt.find( vKey[nI1e])->second ;
|
||||
vBiPnt.emplace_back( ptL1s, ptL1e) ;
|
||||
Vector3d vtDir1 = ptL1e - ptL1s ; vtDir1.Normalize() ;
|
||||
chainC.AddCurve( int( vBiPnt.size()), ptL1s, vtDir1, ptL1e, vtDir1) ;
|
||||
}
|
||||
else if ( nSegCnt == 2) {
|
||||
Point3d ptL1s = umEdgePnt.find( vKey[nI1s])->second ;
|
||||
Point3d ptL1e = umEdgePnt.find( vKey[nI1e])->second ;
|
||||
vBiPnt.emplace_back( ptL1s, ptL1e) ;
|
||||
Vector3d vtDir1 = ptL1e - ptL1s ; vtDir1.Normalize() ;
|
||||
chainC.AddCurve( int( vBiPnt.size()), ptL1s, vtDir1, ptL1e, vtDir1) ;
|
||||
Point3d ptL2s = umEdgePnt.find( vKey[nI2s])->second ;
|
||||
Point3d ptL2e = umEdgePnt.find( vKey[nI2e])->second ;
|
||||
vBiPnt.emplace_back( ptL2s, ptL2e) ;
|
||||
Vector3d vtDir2 = ptL2e - ptL2s ; vtDir2.Normalize() ;
|
||||
chainC.AddCurve( int( vBiPnt.size()), ptL2s, vtDir2, ptL2e, vtDir2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recupero i contorni
|
||||
INTVECTOR vnId ;
|
||||
while ( chainC.GetChainFromNear( ORIG, false, vnId)) {
|
||||
// creo una composita
|
||||
CurveComposite crvCompo ;
|
||||
crvCompo.AddPoint( vBiPnt[vnId[0]-1].first) ;
|
||||
for ( int i = 0 ; i < int( vnId.size()) ; ++ i) {
|
||||
Point3d ptCurr = vBiPnt[vnId[i]-1].second ;
|
||||
crvCompo.AddLine( ptCurr) ;
|
||||
}
|
||||
// la chiudo
|
||||
crvCompo.Close() ;
|
||||
// elimino le parti allineate
|
||||
crvCompo.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
|
||||
// salto i contorni orari con area inferiore al doppio del quadrato
|
||||
double dCmpArea ;
|
||||
if ( ! crvCompo.GetAreaXY( dCmpArea) || ( dCmpArea < 0 && abs( dCmpArea) < 2 * dStep * dStep))
|
||||
continue ;
|
||||
// per test mettere a 1
|
||||
#if 0
|
||||
vPL.emplace_back( PolyLine()) ;
|
||||
crvCompo.ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL.back()) ;
|
||||
#else
|
||||
// eseguo offset a sinistra pari allo step
|
||||
OffsetCurve offsCompo ;
|
||||
offsCompo.Make( &crvCompo, -( dRad - 2 * EPS_SMALL), ICurve::OFF_CHAMFER) ;
|
||||
PtrOwner<ICurve> pCrvOffset( offsCompo.GetLongerCurve()) ;
|
||||
if ( ! IsNull( pCrvOffset)) {
|
||||
vPL.emplace_back( PolyLine()) ;
|
||||
pCrvOffset->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL.back()) ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Silhouette rispetto ad una direzione e sopra una quota di una superficie TriMesh
|
||||
// ( dTol è il passo della griglia di campionamento e il raggio del cilindro di prova)
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvSilhouetteSurfTm( const ISurfTriMesh& Stm, const Plane3d& plPlane, double dTol, POLYLINEVECTOR& vPL)
|
||||
{
|
||||
// verifico superficie
|
||||
if ( &Stm == nullptr || ! Stm.IsValid())
|
||||
return false ;
|
||||
// verifico piano
|
||||
if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
|
||||
return false ;
|
||||
// verifico tolleranza
|
||||
dTol = max( dTol, 100 * EPS_SMALL) ;
|
||||
// verifico parametri di ritorno
|
||||
if ( &vPL == nullptr)
|
||||
return false ;
|
||||
vPL.clear() ;
|
||||
|
||||
// sistema di riferimento nel piano
|
||||
Frame3d frGrid ;
|
||||
if ( ! frGrid.Set( plPlane.GetPoint(), plPlane.GetVersN()))
|
||||
return false ;
|
||||
|
||||
// bounding box della superficie nel riferimento del piano
|
||||
BBox3d b3Surf ;
|
||||
if ( ! Stm.GetBBox( GetInvert( frGrid), b3Surf, BBF_STANDARD))
|
||||
return false ;
|
||||
// calcolo dati della griglia
|
||||
const double EXTRA_XY = 1.5 * dTol ;
|
||||
const double EXTRA_Z = 10 * dTol ;
|
||||
b3Surf.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ;
|
||||
int nStepX = int( ceil( b3Surf.GetDimX() / dTol)) ;
|
||||
int nStepY = int( ceil( b3Surf.GetDimY() / dTol)) ;
|
||||
frGrid.ChangeOrig( GetToGlob( b3Surf.GetMin(), frGrid)) ;
|
||||
double dDimZ = b3Surf.GetDimZ() ;
|
||||
double dLevelOffs = - b3Surf.GetMin().z ;
|
||||
|
||||
// calcolo dei punti della griglia (sul top del cilindro)
|
||||
PNTUVECTOR vPntM( ( nStepX + 1) * ( nStepY + 1)) ;
|
||||
for ( int j = 0 ; j <= nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i <= nStepX ; ++ i) {
|
||||
int nInd = i + j * ( nStepX + 1) ;
|
||||
Point3d ptP = GetToGlob( Point3d( i * dTol, j * dTol, dDimZ), frGrid) ;
|
||||
vPntM[nInd] = { ptP, 0.} ;
|
||||
}
|
||||
}
|
||||
|
||||
// esecuzione della verifica
|
||||
double dRad = SQRT1_2 * dTol ;
|
||||
CAvToolSurfTm cavTstm ;
|
||||
cavTstm.SetStdTool( dDimZ, dRad, 0) ;
|
||||
cavTstm.SetSurfTm( Stm) ;
|
||||
if ( ! cavTstm.TestSeries( vPntM, frGrid.VersZ(), frGrid.VersZ(), -1))
|
||||
return false ;
|
||||
|
||||
// griglia degli spostamenti
|
||||
DBLVECTOR vdGrid( ( nStepX + 1) * ( nStepY + 1)) ;
|
||||
for ( int j = 0 ; j <= nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i <= nStepX ; ++ i) {
|
||||
int nInd = i + j * ( nStepX + 1) ;
|
||||
vdGrid[nInd] = vPntM[nInd].second ;
|
||||
}
|
||||
}
|
||||
|
||||
// calcolo della silhouette con il metodo MarchingSquares
|
||||
double dLevel = dLevelOffs ;
|
||||
if ( ! MarchingSquares( vdGrid, nStepX, nStepY, dTol, dRad, dLevel, cavTstm, frGrid, vPL))
|
||||
return false ;
|
||||
// riporto nella corretta posizione le curve trovate
|
||||
for ( auto& PL : vPL)
|
||||
PL.ToGlob( frGrid) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Silhouette rispetto ad una direzione e sopra diverse quote di una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
ICAvParSilhouettesSurfTm*
|
||||
CreateCAvParSilhouettesSurfTm( void)
|
||||
{
|
||||
return static_cast<ICAvParSilhouettesSurfTm*> ( new(nothrow) CAvParSilhouettesSurfTm) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CAvParSilhouettesSurfTm::CAvParSilhouettesSurfTm( void)
|
||||
: m_dTol( 100 * EPS_SMALL), m_nStepX( 0), m_nStepY( 0), m_dRad( m_dTol), m_dLevelOffs( 0), m_bGridOk( false)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvParSilhouettesSurfTm::SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol)
|
||||
{
|
||||
m_vpStm = vpStm ;
|
||||
m_frGrid = frPlanes ;
|
||||
m_dTol = max( dTol, 100 * EPS_SMALL) ;
|
||||
m_dRad = SQRT1_2 * m_dTol ;
|
||||
m_nStepX = 0 ;
|
||||
m_nStepY = 0 ;
|
||||
m_dDimZ = 0 ;
|
||||
m_dLevelOffs = 0 ;
|
||||
m_bGridOk = false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvParSilhouettesSurfTm::Prepare( void)
|
||||
{
|
||||
// ingombro delle superfici nel riferimento dei piani
|
||||
BBox3d b3All ;
|
||||
Frame3d frInv = GetInvert( m_frGrid) ;
|
||||
for ( auto pStm : m_vpStm) {
|
||||
BBox3d b3Surf ;
|
||||
if ( ! pStm->GetBBox( frInv, b3Surf, BBF_STANDARD))
|
||||
return false ;
|
||||
b3All.Add( b3Surf) ;
|
||||
}
|
||||
|
||||
// calcolo dati della griglia
|
||||
const double EXTRA_XY = 1.5 * m_dTol ;
|
||||
const double EXTRA_Z = 10 * m_dTol ;
|
||||
b3All.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ;
|
||||
m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ;
|
||||
m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ;
|
||||
m_frGrid.ChangeOrig( GetToGlob( b3All.GetMin(), m_frGrid)) ;
|
||||
m_dDimZ = b3All.GetDimZ() ;
|
||||
m_dLevelOffs = - b3All.GetMin().z ;
|
||||
|
||||
// calcolo dei punti della griglia (sul top del cilindro)
|
||||
PNTUVECTOR vPntM( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
|
||||
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
|
||||
int nInd = i + j * ( m_nStepX + 1) ;
|
||||
Point3d ptP = GetToGlob( Point3d( i * m_dTol, j * m_dTol, m_dDimZ), m_frGrid) ;
|
||||
vPntM[nInd] = { ptP, 0.} ;
|
||||
}
|
||||
}
|
||||
|
||||
// esecuzione della verifica
|
||||
if ( ! m_cavTstm.SetStdTool( m_dDimZ, m_dRad, 0))
|
||||
return false ;
|
||||
if ( m_vpStm.empty() || ! m_cavTstm.SetSurfTm( *( m_vpStm[0])))
|
||||
return false ;
|
||||
for ( int k = 1 ; k < int( m_vpStm.size()) ; ++ k)
|
||||
m_cavTstm.AddSurfTm( *( m_vpStm[k])) ;
|
||||
if ( ! m_cavTstm.TestSeries( vPntM, m_frGrid.VersZ(), m_frGrid.VersZ(), -1))
|
||||
return false ;
|
||||
|
||||
// griglia degli spostamenti
|
||||
m_vdGrid.clear() ;
|
||||
m_vdGrid.resize( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
|
||||
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
|
||||
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
|
||||
int nInd = i + j * ( m_nStepX + 1) ;
|
||||
m_vdGrid[nInd] = vPntM[nInd].second ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
|
||||
{
|
||||
// reset risultato
|
||||
vPL.clear() ;
|
||||
|
||||
// se necessario eseguo i calcoli preparatori
|
||||
if ( ! m_bGridOk && ! Prepare())
|
||||
return false ;
|
||||
m_bGridOk = true ;
|
||||
|
||||
// calcolo della silhouette con il metodo MarchingSquares
|
||||
dLevel += m_dLevelOffs ;
|
||||
double dCalcLevel = max( dLevel, 0.) ;
|
||||
if ( ! MarchingSquares( m_vdGrid, m_nStepX, m_nStepY, m_dTol, m_dRad, dCalcLevel, m_cavTstm, m_frGrid, vPL))
|
||||
return false ;
|
||||
// riporto nella corretta posizione le curve trovate
|
||||
for ( auto& PL : vPL) {
|
||||
if ( dLevel < dCalcLevel - EPS_SMALL)
|
||||
PL.Translate( Vector3d{ 0, 0, dLevel - dCalcLevel}) ;
|
||||
PL.ToGlob( m_frGrid) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
|
||||
{
|
||||
public :
|
||||
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol) 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 ;
|
||||
int m_nStepX ;
|
||||
int m_nStepY ;
|
||||
double m_dRad ;
|
||||
double m_dDimZ ;
|
||||
double m_dLevelOffs ;
|
||||
bool m_bGridOk ;
|
||||
DBLVECTOR m_vdGrid ;
|
||||
} ;
|
||||
+216
-42
@@ -1,21 +1,21 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2018-2018
|
||||
// EgalTech 2018-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CAvToolSurfTm.cpp Data : 08.05.18 Versione : 1.9e2
|
||||
// File : CAvToolSurfTm.cpp Data : 07.06.24 Versione : 2.6f2
|
||||
// Contenuto : Implementazione della classe CAvToolSurfTm.
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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 "CAvToolTriangle.h"
|
||||
#include "CAvToolSurfTm.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
@@ -37,10 +37,29 @@ CreateCAvToolSurfTm( void)
|
||||
// CAvToolSurfTm
|
||||
//----------------------------------------------------------------------------
|
||||
CAvToolSurfTm::CAvToolSurfTm( void)
|
||||
: m_Tool( false)
|
||||
: m_frMove( 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
|
||||
CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||
@@ -50,6 +69,9 @@ CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||
// 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() ;
|
||||
// non tocco l'utensile
|
||||
// aggiungo la superficie
|
||||
return AddSurfTm( Stm) ;
|
||||
}
|
||||
@@ -99,40 +121,186 @@ CAvToolSurfTm::SetGenTool( const ICurveComposite* pToolOutline)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist)
|
||||
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, Vector3d* pvtTriaN) const
|
||||
{
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Imposto il riferimento di movimento
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
m_frMove.Set( ORIG, vtMove) ;
|
||||
// Eseguo controllo
|
||||
// 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 ;
|
||||
Vector3d vtTriaN ;
|
||||
dTotDist = MyTestPositionHG( ptCurr, vtDir, vtTriaN) ;
|
||||
if ( pvtTriaN != nullptr)
|
||||
*pvtTriaN = vtTriaN ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
// Altrimenti eseguo controllo diretto
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPosition( ptCurr, vtDir) ;
|
||||
Vector3d vtTriaN ;
|
||||
dTotDist = MyTestPosition( ptCurr, vtDir, vtMove, vtTriaN) ;
|
||||
if ( pvtTriaN != nullptr)
|
||||
*pvtTriaN = vtTriaN ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol)
|
||||
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))
|
||||
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 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
|
||||
CAvToolSurfTm::TestSubSeries( int nId, PNTUVECTOR& 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
|
||||
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
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
if ( lPntM.empty())
|
||||
return true ;
|
||||
// Imposto il riferimento di movimento
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
// Controllo la tolleranza lineare (se negativa non vanno fatti controlli sui punti medi)
|
||||
if ( dLinTol > -EPS_ZERO)
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
else
|
||||
m_frMove.Set( ORIG, vtMove) ;
|
||||
// Predispongo Hash Grid
|
||||
if ( ! PrepareHashGrid())
|
||||
return false ;
|
||||
dLinTol = -1 ;
|
||||
// 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( lPntM.size()) ;
|
||||
// Recupero il numero massimo di thread concorrenti
|
||||
@@ -140,8 +308,9 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
bool bOk = true ;
|
||||
// Se un solo thread o pochi punti
|
||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol) ;
|
||||
ProcessEvents( 100, 0) ;
|
||||
m_nCurrPnt = 0 ;
|
||||
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol, dProgCoeff) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
@@ -161,7 +330,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
m_bBreak = false ;
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol) ;
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol, dProgCoeff) ;
|
||||
// attendo i risultati
|
||||
int nFin = 0 ;
|
||||
int nNextPE = 0 ;
|
||||
@@ -173,7 +342,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
}
|
||||
}
|
||||
if ( m_nCurrPnt > nNextPE) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 10) ;
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
||||
nNextPE += STEP_PE ;
|
||||
if ( nRes == 1)
|
||||
m_bBreak = true ;
|
||||
@@ -185,16 +354,14 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
lPntM.pop_back() ;
|
||||
lPntM.splice( lPntM.end(), vlPntM[i]) ;
|
||||
}
|
||||
ProcessEvents( 100, 0) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// pulisco HashGrid 2d
|
||||
m_HGrids.Clear() ;
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
|
||||
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff)
|
||||
{
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
if ( lPntM.empty())
|
||||
@@ -206,11 +373,13 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
while ( itPntMCurr != lPntM.end()) {
|
||||
// verifico il punto
|
||||
ptCurr = itPntMCurr->first ;
|
||||
itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ;
|
||||
if ( itPntMCurr->second < - EPS_SMALL)
|
||||
Vector3d vtTriaN ;
|
||||
double dMove = MyTestPositionHG( itPntMCurr->first, vtDir, vtTriaN) ;
|
||||
itPntMCurr->second = dMove ;
|
||||
if ( dMove < - EPS_SMALL)
|
||||
return false ;
|
||||
// se esiste il punto precedente devo verificare il medio
|
||||
if ( itPntMPrev != lPntM.end()) {
|
||||
// se esiste il punto precedente e richiesto devo verificare il medio
|
||||
if ( itPntMPrev != lPntM.end() && dLinTol > 0) {
|
||||
MyTestMidPointHG( lPntM, itPntMPrev, itPntMCurr, ptPrev, ptCurr, vtDir, dLinTol, 1) ;
|
||||
}
|
||||
// passo al successivo
|
||||
@@ -222,7 +391,7 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
if ( nId == -1) {
|
||||
// gestione eventi (ogni STEP_PE punti)
|
||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 0) ;
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
||||
if ( nRes == 1)
|
||||
return false ;
|
||||
}
|
||||
@@ -239,7 +408,7 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
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 Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const
|
||||
{
|
||||
// se superato limite di ricursione, esco
|
||||
const int MAX_LEV = 10 ;
|
||||
@@ -249,7 +418,8 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
||||
Point3d ptMid = Media( ptPrev, ptCurr, 0.5) ;
|
||||
// ne effettuo la correzione per evitare la collisione
|
||||
Point3d ptNewMid = ptMid ;
|
||||
double dMidMove = MyTestPositionHG( ptNewMid, vtDir) ;
|
||||
Vector3d vtTriaN ;
|
||||
double dMidMove = MyTestPositionHG( ptNewMid, vtDir, vtTriaN) ;
|
||||
if ( dMidMove < - EPS_SMALL)
|
||||
return false ;
|
||||
// massima distanza ammissibile
|
||||
@@ -258,7 +428,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 ||
|
||||
SqDist( itPntMPrev->first, itPntMCurr->first) > dMaxSqDist) {
|
||||
// aggiungo
|
||||
lPntM.emplace( itPntMCurr, ptNewMid, - dMidMove) ;
|
||||
lPntM.emplace( itPntMCurr, ptNewMid, dMidMove) ;
|
||||
auto itPntMMid = itPntMCurr ;
|
||||
-- itPntMMid ;
|
||||
// verifico intervallo precedente
|
||||
@@ -271,20 +441,22 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
|
||||
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const
|
||||
{
|
||||
double dTotDist = 0 ;
|
||||
vtTriaN = V_NULL ;
|
||||
for ( auto pStm : m_vSTM) {
|
||||
Triangle3d Tria ;
|
||||
for ( int nTria = pStm->GetFirstTriangle( Tria) ;
|
||||
nTria != SVT_NULL ;
|
||||
nTria = pStm->GetNextTriangle( 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)
|
||||
return -1 ;
|
||||
if ( dDist > EPS_SMALL) {
|
||||
dTotDist += dDist ;
|
||||
ptT += dDist * m_frMove.VersZ() ;
|
||||
ptT += dDist * vtMove ;
|
||||
vtTriaN = Tria.GetN() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,7 +465,7 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const
|
||||
{
|
||||
// calcolo box utensile nel riferimento di movimento
|
||||
BBox3d b3Tool ;
|
||||
@@ -315,6 +487,7 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
}
|
||||
// ciclo sui triangoli che intersecano box in 2d
|
||||
double dTotDist = 0 ;
|
||||
vtTriaN = V_NULL ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
@@ -330,6 +503,7 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
if ( dDist > EPS_SMALL) {
|
||||
dTotDist += dDist ;
|
||||
ptT += dDist * m_frMove.VersZ() ;
|
||||
vtTriaN = Tria.GetN() ;
|
||||
}
|
||||
else if ( dDist < -EPS_SMALL)
|
||||
return -1 ;
|
||||
@@ -372,7 +546,7 @@ CAvToolSurfTm::PrepareHashGrid( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
CAvToolSurfTm::GetSurfInd( int nT)
|
||||
CAvToolSurfTm::GetSurfInd( int nT) const
|
||||
{
|
||||
// verifico la presenza di almeno un intervallo
|
||||
if ( m_vBaseInd.size() < 2)
|
||||
|
||||
+11
-7
@@ -36,20 +36,24 @@ class CAvToolSurfTm : public ICAvToolSurfTm
|
||||
{ return m_Tool.GetHeigth() ; }
|
||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
||||
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist) override ;
|
||||
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol) override ;
|
||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ;
|
||||
bool TestSeries( PNTUVECTOR& 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 :
|
||||
CAvToolSurfTm( void) ;
|
||||
bool Clear( void) ;
|
||||
|
||||
private :
|
||||
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol) ;
|
||||
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir) ;
|
||||
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir) ;
|
||||
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, double dProgCoeff) ;
|
||||
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const ;
|
||||
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const ;
|
||||
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 Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ;
|
||||
bool PrepareHashGrid( void) ;
|
||||
int GetSurfInd( int nT) ;
|
||||
int GetSurfInd( int nT) const ;
|
||||
|
||||
private :
|
||||
typedef std::vector<const SurfTriMesh*> CSURFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@
|
||||
#include "CAvToolTriangle.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "CDeUtility.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
@@ -2503,7 +2503,7 @@ DiskSegmentEscapeDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
|
||||
double dSegDist = 0. ;
|
||||
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
|
||||
// Soluzione interna al segmento
|
||||
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen) {
|
||||
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen + EPS_ZERO) {
|
||||
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
|
||||
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
|
||||
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
|
||||
|
||||
+39
-2
@@ -1,13 +1,14 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2016-2020
|
||||
// EgalTech 2016-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDBoxSurfTm.cpp Data : 09.01.20 Versione : 2.2a2
|
||||
// File : CDeBoxClosedSurfTm.cpp Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione della verifica di collisione tra
|
||||
// BoundingBox e Closed SurftriMesh.
|
||||
//
|
||||
//
|
||||
// Modifiche : 05.10.16 DS Creazione modulo.
|
||||
// 09.01.20 DS Cambio nome alla funzione.
|
||||
// 24.03.24 DS Aggiunta TestCylSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -66,3 +67,39 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, const ISurfTri
|
||||
// Se il box è interno c'è collisione
|
||||
return DistBoxCenSurfCalc.IsPointInside() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra il box e la superficie : restituisce true in caso di interferenza.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestBoxSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// Se il box non è ben definito non ha senso proseguire
|
||||
if ( vtDiag.IsSmall())
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del parallelepipedo
|
||||
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxL.Expand( dSafeDist) ;
|
||||
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
|
||||
return false ;
|
||||
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeBoxTria( frBox, vtDiag, Tria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeSurfTmSurfTm.h Data : 14.06.23 Versione : 2.5f3
|
||||
// File : CDeClosedSurfTmClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// SurfTm e SurfTm.
|
||||
//
|
||||
// Modifiche : 13.11.20 LM Creazione modulo.
|
||||
//
|
||||
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -122,3 +122,89 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
|
||||
return ( DistPoinASrfB.IsPointInside() || DistPoinBSrfA.IsPointInside()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
||||
{
|
||||
// Recupero le superfici base
|
||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||
const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ;
|
||||
// Se le superfici non sono valide, non ha senso proseguire
|
||||
if ( pSrfA == nullptr || ! pSrfA->IsValid() ||
|
||||
pSrfB == nullptr || ! pSrfB->IsValid())
|
||||
return true ;
|
||||
// Se i box delle superfici non si intersecano, ho finito.
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxB.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di A che interferiscono col box di B
|
||||
INTVECTOR vTriaIndex ;
|
||||
pSrfA->GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
|
||||
// Ciclo sui triangoli della superficie A che interferiscono col box della superficie B.
|
||||
for ( int nTA : vTriaIndex) {
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( pSrfA->GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
|
||||
continue ;
|
||||
BBox3d b3BoxTriaA ;
|
||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxTriaA.Expand( dSafeDist) ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vNearTria ;
|
||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||
pSrfB->ResetTempInts() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
for ( int nTB : vNearTria) {
|
||||
// Recupero il triangolo corrente della superficie B.
|
||||
// Se triangolo non valido salto al successivo.
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! ( pSrfB->GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
|
||||
continue ;
|
||||
// Se necessario considero l'offset
|
||||
if ( dSafeDist > EPS_SMALL) {
|
||||
int nAdjTriaId[3] ;
|
||||
pSrfB->GetTriangleAdjacencies( nTB, nAdjTriaId) ;
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
continue ;
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
Frame3d frCyl ;
|
||||
frCyl.Set( trTriaB.GetP( nVB), vtEdgeV) ;
|
||||
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
|
||||
return true ;
|
||||
}
|
||||
// Traslo il triangolo
|
||||
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
|
||||
}
|
||||
// Processo il triangolo: se i due triangoli collidono ho finito.
|
||||
if ( CDeTriaTria( trTriaA, trTriaB))
|
||||
return true ;
|
||||
// Segno il triangolo come processato: nTemp = 1
|
||||
pSrfB->SetTempInt( nTB, 1) ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDCylSurfTm.cpp Data : 09.11.20 Versione :
|
||||
// File : CDeConeFrustumClosedSurfTm.cpp Data : 24.031.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione della verifica di collisione tra
|
||||
// Cone e Closed SurftriMesh.
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.11.20 LM Creazione modulo.
|
||||
// 24.03.24 DS Aggiunta TestConeFrustumSurfTm.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -69,4 +70,44 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
|
||||
DistPointSurfTm DistConeCenSurfCalc( ptConeCen, Stm) ;
|
||||
// Se il tronco di cono è interno c'è collisione
|
||||
return DistConeCenSurfCalc.IsPointInside() ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra il tronco di cono e la superficie : restituisce true in caso di interferenza.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestConeFrustumSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
|
||||
const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// Se il tronco di cono non è ben definito non ha senso proseguire
|
||||
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Recupero BBox della trimesh
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del tronco di cono
|
||||
double dMaxRad = max( dBaseRad, dTopRad) ;
|
||||
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
|
||||
Point3d( dMaxRad, dMaxRad, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3ConeL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del cono
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
|
||||
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeConeFrustumTria( frCone, dBaseRad, dTopRad, dHeight, trTria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeConTria.cpp Data : 28.10.20 Versione : 2.2k1
|
||||
// File : CDeConeFrustumTria.h Data : 28.10.20 Versione : 2.2k1
|
||||
// Contenuto : Dichiarazione della verifica di collisione tra
|
||||
// Cone e Triangle3d.
|
||||
//
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeConvexTorusTria.cpp Data : 18.11.20 Versione :
|
||||
// File : CDeConvexTorusTria.cpp Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// toro convesso e SurfTriMesh.
|
||||
//
|
||||
// Modifiche : 18.11.20 LM Creazione modulo.
|
||||
//
|
||||
// 24.03.24 DS Aggiunta TestConvexTorusSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -66,3 +66,42 @@ CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||
// Se il toro è interno c'è collisione
|
||||
return ( DistConeOrigSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra il toro convesso e la superficie : restituisce true in caso di interferenza
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestConvexTorusSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
|
||||
const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// I raggi devono essere non nulli
|
||||
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL)
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Box della superficie
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Box del toro (sempre completo)
|
||||
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
|
||||
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3TorusL.Expand( dSafeDist) ;
|
||||
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del toro
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
|
||||
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, trTria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
+45
-2
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDCylSurfTm.cpp Data : 15.02.24 Versione : 2.6b2
|
||||
// File : CDeCylClosedSurfTm.cpp Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione della verifica di collisione tra
|
||||
// Cylinder e Closed SurftriMesh.
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.01.20 DS Creazione modulo.
|
||||
//
|
||||
// 24.03.24 DS Aggiunta TestCylSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -73,3 +73,46 @@ CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMe
|
||||
// Se il cilindro è interno c'è collisione
|
||||
return ( DistCylCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra il cilindro e la superficie : restituisce true in caso di interferenza
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestCylSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// Il cilindro deve essere ben definito
|
||||
if ( dR < EPS_SMALL || dH < EPS_SMALL)
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Recupero BBox della superficie poligonale
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// Sistemazioni cilindro
|
||||
Frame3d frMyCyl = frCyl ;
|
||||
if ( dH < 0) {
|
||||
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
|
||||
dH = -dH ;
|
||||
}
|
||||
// Calcolo il BBox del cilindro
|
||||
BBox3d b3CylL( Point3d( -dR, -dR, 0),
|
||||
Point3d( dR, dR, dH)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3CylL.Expand( dSafeDist) ;
|
||||
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
|
||||
// Se i BBox non interferiscono, non c'è interferenza
|
||||
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
|
||||
return false ;
|
||||
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeCylTria( frMyCyl, dR, dH, Tria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "CDeCylTria.h"
|
||||
#include "CDeConvexTorusTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDePyramidClosedSurfTm.h Data : 09.11.20 Versione :
|
||||
// File : CDeRectPrismoidClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// Prismoide a basi rettangolari e Closed SurfTriMesh.
|
||||
//
|
||||
// Modifiche : 09.11.20 LM Creazione modulo.
|
||||
//
|
||||
// 24.03.24 DS Aggiunta TestRectPrismoidSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -74,3 +74,48 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
|
||||
// C'è collisione se il tronco di piramide è interno
|
||||
return ( DistPyrCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra il Prismoide a basi rettangolari e la superficie : restituisce true in caso di interferenza.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestRectPrismoidSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
|
||||
double dLenghtTopX, double dLenghtTopY, double dHeight,
|
||||
const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// Se il tronco di piramide non è definito non ha senso proseguire.
|
||||
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
|
||||
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
|
||||
dHeight < EPS_SMALL)
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Recupero BBox della trimesh
|
||||
BBox3d b3Surf = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox del tronco di piramide
|
||||
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
|
||||
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
|
||||
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
|
||||
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3PyrL.Expand( dSafeDist) ;
|
||||
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
|
||||
return false ;
|
||||
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
|
||||
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
for ( int nT : vT) {
|
||||
Triangle3d trTria ;
|
||||
if ( Stm.GetTriangle( nT, trTria)) {
|
||||
if ( CDeRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight,
|
||||
trTria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
+38
-3
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDCylSurfTm.cpp Data : 09.01.20 Versione : 2.2a2
|
||||
// File : CDCylSurfTm.cpp Data : 24.03.24 Versione : 2.6c2
|
||||
// Contenuto : Implementazione della verifica di collisione tra
|
||||
// Sphere e Closed SurftriMesh.
|
||||
//
|
||||
//
|
||||
// Modifiche : 09.01.20 DS Creazione modulo.
|
||||
//
|
||||
// 24.03.24 DS Aggiunta TestSpheSurfTm.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -60,3 +60,38 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, const ISurfTriMesh& Stm, d
|
||||
// C'è collisione se la sfera è interna.
|
||||
return ( DistCenSurfCalc.IsPointInside()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Verifica l'interferenza tra la sfera e la superficie : restituisce true in caso di interferenza
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestSpheSurfTm( const Point3d& ptCen, double dR, const ISurfTriMesh& Stm, double dSafeDist)
|
||||
{
|
||||
// Il raggio deve essere non nullo
|
||||
if ( dR < EPS_SMALL)
|
||||
return true ;
|
||||
// Se superficie non valida, non ha senso proseguire
|
||||
if ( ! Stm.IsValid())
|
||||
return true ;
|
||||
// Recupero BBox del poliedro
|
||||
BBox3d b3Poly = Stm.GetAllTriaBox() ;
|
||||
// Calcolo il BBox della sfera
|
||||
BBox3d b3Sphe( ptCen, dR) ;
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3Sphe.Expand( dSafeDist) ;
|
||||
// Se i BBox non interferiscono, non c'è collisione
|
||||
if ( ! b3Sphe.Overlaps( b3Poly))
|
||||
return false ;
|
||||
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
|
||||
INTVECTOR vT ;
|
||||
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
|
||||
for ( int nT : vT) {
|
||||
Triangle3d Tria ;
|
||||
if ( Stm.GetTriangle( nT, Tria)) {
|
||||
if ( CDeSpheTria( ptCen, dR, Tria, dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
+1
-2
@@ -12,11 +12,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "CDeTriaTria.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "CDeUtility.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+6976
-1605
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
+55
-45
@@ -189,7 +189,7 @@ CurveArc::Set3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d&
|
||||
// calcolo del versore normale
|
||||
m_VtN = vtA ^ vtB ;
|
||||
double dNSqLen = m_VtN.SqLen() ;
|
||||
// se i punti sono praticamente allineati non si può calcolare la circonferenza
|
||||
// se i punti sono praticamente allineati non si può calcolare la circonferenza
|
||||
if ( ! m_VtN.Normalize( EPS_ZERO))
|
||||
return false ;
|
||||
// calcolo del centro
|
||||
@@ -216,17 +216,17 @@ CurveArc::Set3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d&
|
||||
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, dAng2Deg, bDet2) || ! bDet2)
|
||||
return false ;
|
||||
// deduzione dell'angolo al centro
|
||||
// se uno dei due angoli è nullo, errore
|
||||
// se uno dei due angoli è nullo, errore
|
||||
if ( abs( dAng1Deg) < EPS_ANG_SMALL || abs( dAng2Deg) < EPS_ANG_SMALL)
|
||||
return false ;
|
||||
// se i due angoli hanno lo stesso segno e Ang1 è minore di Ang2 in modulo
|
||||
// se i due angoli hanno lo stesso segno e Ang1 è minore di Ang2 in modulo
|
||||
else if ( dAng1Deg * dAng2Deg > 0 && abs( dAng1Deg) < abs( dAng2Deg))
|
||||
m_dAngCenDeg = dAng2Deg ;
|
||||
// altrimenti hanno segno opposto oppure Ang1 è maggiore di Ang2 in modulo
|
||||
// altrimenti hanno segno opposto oppure Ang1 è maggiore di Ang2 in modulo
|
||||
else
|
||||
m_dAngCenDeg = - _copysign( ANG_FULL, dAng2Deg) + dAng2Deg ;
|
||||
}
|
||||
// non c'è DeltaN
|
||||
// non c'è DeltaN
|
||||
m_dDeltaN = 0 ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
@@ -255,7 +255,7 @@ CurveArc::Set2PNB( const Point3d& ptIni, const Point3d& ptFin, const Vector3d& v
|
||||
Vector3d vtDiff = ptFin - ptIni ;
|
||||
if ( vtDiff.IsSmall())
|
||||
return false ;
|
||||
// deltaN eventuale ( è componente parallela a VtN)
|
||||
// deltaN eventuale ( è componente parallela a VtN)
|
||||
m_dDeltaN = vtDiff * m_VtN ;
|
||||
vtDiff -= m_dDeltaN * m_VtN ;
|
||||
if ( abs( m_dDeltaN) < EPS_SMALL)
|
||||
@@ -304,7 +304,7 @@ CurveArc::Set2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStart
|
||||
// calcolo del versore normale
|
||||
m_VtN = vtA ^ vtB ;
|
||||
double dNSqLen = m_VtN.SqLen() ;
|
||||
// se tangente e punti sono praticamente allineati non si può calcolare la circonferenza
|
||||
// se tangente e punti sono praticamente allineati non si può calcolare la circonferenza
|
||||
if ( ! m_VtN.Normalize( EPS_ZERO))
|
||||
return false ;
|
||||
// calcolo del centro
|
||||
@@ -321,7 +321,7 @@ CurveArc::Set2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStart
|
||||
double dAng1Deg ;
|
||||
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, dAng1Deg, bDet1) || ! bDet1)
|
||||
return false ;
|
||||
// poichè il senso di rotazione è sempre CCW, se l'angolo è negativo prendo il suo complemento al giro
|
||||
// poichè il senso di rotazione è sempre CCW, se l'angolo è negativo prendo il suo complemento al giro
|
||||
if ( dAng1Deg < 0)
|
||||
m_dAngCenDeg = ANG_FULL + dAng1Deg ;
|
||||
else
|
||||
@@ -414,7 +414,7 @@ CurveArc::Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bo
|
||||
bool bDet ;
|
||||
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, m_dAngCenDeg, bDet) || ! bDet)
|
||||
return false ;
|
||||
// quando è 180deg il segno è determinato solo dal senso
|
||||
// quando è 180deg il segno è determinato solo dal senso
|
||||
if ( abs( m_dAngCenDeg - ANG_STRAIGHT) < 10 * EPS_ANG_SMALL &&
|
||||
( ( bCCW && m_dAngCenDeg < 0) ||
|
||||
( ! bCCW && m_dAngCenDeg > 0)))
|
||||
@@ -529,7 +529,7 @@ CurveArc::SetC2P( const Point3d& ptCen, const Point3d& ptStart, const Point3d& p
|
||||
if ( m_dRad < EPS_ZERO)
|
||||
return false ;
|
||||
m_VtS /= m_dRad ;
|
||||
// calcolo l'angolo al centro (la funzione trova sempre il più piccolo)
|
||||
// calcolo l'angolo al centro (la funzione trova sempre il più piccolo)
|
||||
bool bDet ;
|
||||
if ( ! m_VtS.GetRotation( ( ptNearEnd - m_PtCen), m_VtN, m_dAngCenDeg, bDet) || ! bDet)
|
||||
return false ;
|
||||
@@ -733,7 +733,7 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
// assegno il box nel riferimento
|
||||
@@ -820,7 +820,7 @@ CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
}
|
||||
}
|
||||
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
vtFrExtr.ToGlob( frRef) ;
|
||||
@@ -838,7 +838,7 @@ bool
|
||||
CurveArc::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
// limito l'angolo al centro a un giro se è piatto ( non è elica)
|
||||
// limito l'angolo al centro a un giro se è piatto ( non è elica)
|
||||
if ( abs( m_dDeltaN) < EPS_SMALL) {
|
||||
if ( m_dAngCenDeg > ANG_FULL)
|
||||
m_dAngCenDeg = ANG_FULL ;
|
||||
@@ -1167,7 +1167,7 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLin
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
|
||||
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
|
||||
return false ;
|
||||
@@ -1241,7 +1241,7 @@ CurveArc::CopyParamRange( double dUStart, double dUEnd) const
|
||||
return nullptr ;
|
||||
// se il parametro start supera quello di end
|
||||
if ( dUStart > dUEnd - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
if ( ! IsClosed())
|
||||
return nullptr ;
|
||||
// se curva chiusa, il trim si avvolge attorno al punto di giunzione
|
||||
@@ -1331,7 +1331,7 @@ bool
|
||||
CurveArc::MyExtendedOffset( double dDist, bool bAll, int nType)
|
||||
{
|
||||
// bAll == true fa accettare raggi nulli ==> da usare solo internamente
|
||||
// quando si è sicuri di aumentare subito il raggio o di cancellare
|
||||
// quando si è sicuri di aumentare subito il raggio o di cancellare
|
||||
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -1409,7 +1409,7 @@ CurveArc::ModifyEnd( const Point3d& ptNewEnd)
|
||||
ptOldEndIntr.ToLoc( frIntr) ;
|
||||
Point3d ptEndIntr = ptNewEnd ;
|
||||
ptEndIntr.ToLoc( frIntr) ;
|
||||
// se coincidono nel piano XY, è cambiato solo il deltaN
|
||||
// se coincidono nel piano XY, è cambiato solo il deltaN
|
||||
if ( AreSamePointXYExact( ptOldEndIntr, ptEndIntr)) {
|
||||
m_dDeltaN += ptEndIntr.z - ptOldEndIntr.z ;
|
||||
}
|
||||
@@ -1615,8 +1615,10 @@ CurveArc::Translate( const Vector3d& vtMove)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// traslo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Translate( vtMove) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1634,12 +1636,14 @@ CurveArc::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, dou
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// ruoto Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1787,7 +1791,7 @@ CurveArc::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -1815,11 +1819,11 @@ CurveArc::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vt
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità dei parametri
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
// possibile solo se l'arco è piatto e il piano di scorrimento coincide con quello dell'arco
|
||||
// possibile solo se l'arco è piatto e il piano di scorrimento coincide con quello dell'arco
|
||||
if ( ! ( abs( m_dDeltaN) < EPS_SMALL) ||
|
||||
! AreSameOrOppositeVectorExact( m_VtN, vtNorm))
|
||||
return false ;
|
||||
@@ -1849,16 +1853,18 @@ CurveArc::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToGlob( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1876,16 +1882,18 @@ CurveArc::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToLoc( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1903,16 +1911,18 @@ CurveArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->LocToLoc( frOri, frDest) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1989,12 +1999,12 @@ CurveArc::MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, doub
|
||||
// verifica posizione punto su arco
|
||||
nPos = PP_NULL ; // fuori
|
||||
if ( abs( DiffAngle( dAngDeg, 0) * DEGTORAD * m_dRad) < dLinTol) {
|
||||
nPos = ( IsACircle() ? PP_MID : PP_START) ; // se cerchio è interno, altrimenti vicino a inizio
|
||||
nPos = ( IsACircle() ? PP_MID : PP_START) ; // se cerchio è interno, altrimenti vicino a inizio
|
||||
dU = AngleNearAngle( dAngDeg, 0) / m_dAngCenDeg ;
|
||||
dU = max( dU, 0.) ;
|
||||
}
|
||||
else if ( abs( DiffAngle( dAngDeg, m_dAngCenDeg) * DEGTORAD * m_dRad) < dLinTol) {
|
||||
nPos = ( IsACircle() ? PP_MID : PP_END) ; // se cerchio è interno, altrimenti vicino a fine
|
||||
nPos = ( IsACircle() ? PP_MID : PP_END) ; // se cerchio è interno, altrimenti vicino a fine
|
||||
dU = AngleNearAngle( dAngDeg, m_dAngCenDeg) / m_dAngCenDeg ;
|
||||
dU = min( dU, 1.) ;
|
||||
}
|
||||
@@ -2011,7 +2021,7 @@ CurveArc::ChangeRadius( double dNewRadius)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico validità del raggio
|
||||
// verifico validità del raggio
|
||||
if ( ! ( dNewRadius > EPS_SMALL && dNewRadius < MAX_ARC_RAD))
|
||||
return false ;
|
||||
|
||||
@@ -2057,7 +2067,7 @@ CurveArc::ChangeAngCenter( double dNewAngCenDeg)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// verifico accettabilità angolo
|
||||
// verifico accettabilità angolo
|
||||
if ( ! ( abs( m_dAngCenDeg) > EPS_ANG_ZERO))
|
||||
return false ;
|
||||
|
||||
@@ -2153,11 +2163,11 @@ CurveArc::Flip( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Oggetto locale per approssimazione di archi
|
||||
// Approx interna è quella cordale standard.
|
||||
// Approx esterna è quella tangente a inizio e fine con metà tratto e un punto in più.
|
||||
// Approx interna è quella cordale standard.
|
||||
// Approx esterna è quella tangente a inizio e fine con metà tratto e un punto in più.
|
||||
// I punti si calcolano a partire dal triangolo tra due punti consecutivi interni e il centro,
|
||||
// usando il versore medio dal centro e moltiplicandolo per il coefficiente ( 2 / ( 1 + cosA)).
|
||||
// Il versore dell'ultimo punto è già stato calcolato per il penultimo.
|
||||
// Il versore dell'ultimo punto è già stato calcolato per il penultimo.
|
||||
//----------------------------------------------------------------------------
|
||||
ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, bool bInside, const CurveArc& arArc)
|
||||
{
|
||||
@@ -2281,7 +2291,7 @@ CurveArc::GetVoronoiObject() const
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
|
||||
// se non è stato calcolato, lo calcolo
|
||||
// se non è stato calcolato, lo calcolo
|
||||
if ( m_pVoronoiObj == nullptr)
|
||||
CalcVoronoiObject() ;
|
||||
|
||||
|
||||
+5
-2
@@ -186,7 +186,10 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
CurveArc( void) ;
|
||||
@@ -200,13 +203,13 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
bool MyExtendedOffset( double dDist, bool bAll, int nType = OFF_FILLET) ;
|
||||
bool MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, double dLinTol) const ;
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveArc& caSrc) ;
|
||||
bool Validate( void) ;
|
||||
bool GetDir( double dU, Vector3d& vtDir) const ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
@@ -222,7 +225,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
double m_dDeltaN ; // variazione di quota lungo VtN della fine rispetto all'inizio
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable Voronoi* m_pVoronoiObj ; // Voronoi
|
||||
} ;
|
||||
|
||||
+986
-35
File diff suppressed because it is too large
Load Diff
@@ -33,4 +33,5 @@ bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
||||
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurveBezier* pCrvBez) ;
|
||||
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
||||
|
||||
+257
-16
@@ -13,13 +13,13 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveAux.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointCrvBezier.h"
|
||||
#include "BiArcs.h"
|
||||
#include "GeoConst.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
@@ -27,12 +27,16 @@
|
||||
#include "Bernstein.h"
|
||||
#include "deCasteljau.h"
|
||||
#include "Voronoi.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/ENkPolynomial.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include <array>
|
||||
|
||||
using namespace std ;
|
||||
@@ -138,6 +142,32 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
||||
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
|
||||
CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
@@ -195,6 +225,35 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
SetControlPoint( 1, ptNew1, dW) ;
|
||||
SetControlPoint( 2, ptNew2, dW) ;
|
||||
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
|
||||
@@ -204,6 +263,30 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
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
|
||||
CurveBezier::IsAPoint( void) const
|
||||
@@ -1486,7 +1569,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
}
|
||||
@@ -1723,12 +1806,24 @@ CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
// verifico che i trim non cancellino interamente la curva
|
||||
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
|
||||
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
|
||||
if ( ! TrimEndAtParam( dUEndTrim))
|
||||
return false ;
|
||||
// trim iniziale con il parametro opportunamente ricalcolato
|
||||
double dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||
return TrimStartAtParam( dNewUStartTrim) ;
|
||||
double dNewUStartTrim ;
|
||||
if( m_bRat)
|
||||
GetParamAtPoint( ptStart, dNewUStartTrim) ;
|
||||
else
|
||||
dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||
//trim iniziale
|
||||
if( ! TrimStartAtParam( dNewUStartTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1744,7 +1839,10 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimStartAtParam( dUTrim) ;
|
||||
if( ! TrimStartAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1760,7 +1858,10 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimEndAtParam( dUTrim) ;
|
||||
if( ! TrimEndAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1873,8 +1974,10 @@ CurveBezier::Translate( const Vector3d& vtMove)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// traslo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Translate( vtMove) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1897,8 +2000,10 @@ CurveBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng,
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// ruoto Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2032,8 +2137,10 @@ CurveBezier::ToGlob( const Frame3d& frRef)
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToGlob( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2061,8 +2168,10 @@ CurveBezier::ToLoc( const Frame3d& frRef)
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToLoc( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2090,8 +2199,10 @@ CurveBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->LocToLoc( frOri, frDest) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2142,3 +2253,133 @@ CurveBezier::ResetVoronoiObject() const
|
||||
delete m_pVoronoiObj ;
|
||||
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[0] ;
|
||||
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 ;
|
||||
}
|
||||
|
||||
+14
-5
@@ -117,7 +117,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||
bool Invert( void) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override
|
||||
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
|
||||
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
|
||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||
@@ -137,7 +137,9 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
bool Init( int nDeg, bool bIsRational) override ;
|
||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl) 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 FromLine( const ICurveLine& crLine) override ;
|
||||
int GetDegree( void) const override
|
||||
{ return m_nDeg ; }
|
||||
bool IsRational( void) const override
|
||||
@@ -147,11 +149,18 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
double GetControlWeight( int nInd, bool* pbOk = NULL) const override ;
|
||||
bool GetControlPolygonLength( double& dLen) 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 ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
CurveBezier( void) ;
|
||||
@@ -165,6 +174,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
bool ApproxWithLines( int nStep, PolyLine& PL) const ;
|
||||
bool GetApproxLength( double& dLen) const ;
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveBezier& cbSrc) ;
|
||||
@@ -183,23 +193,22 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
bool ToPowerBase( PolynomialPoint3d& pol3P) const ;
|
||||
bool ToPowerBase( PolynomialPoint3d& pol3Num, Polynomial& polDen) const ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
static const int MAXDEG = 11 ;
|
||||
static const int MAXDEG = 21 ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Status m_nStatus ; // stato
|
||||
int m_nDeg ; // grado
|
||||
bool m_bRat ; // flag di razionale/polinomiale
|
||||
mutable double m_dParSing ; // eventuale parametro della singolarità (-1=no, -2=da calcolare)
|
||||
mutable double m_dParSing ; // eventuale parametro della singolarità (-1=no, -2=da calcolare)
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable Voronoi* m_pVoronoiObj ; // Voronoi
|
||||
} ;
|
||||
|
||||
+9
-9
@@ -16,8 +16,8 @@
|
||||
#include "CurveComposite.h"
|
||||
#include "CalcDerivate.h"
|
||||
#include "BiArcs.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||
@@ -439,12 +439,12 @@ CurveByApprox::CalcSplitPoints( double dLinTol, double dAngTolDeg, double dLinFe
|
||||
m_vSplits.push_back(i) ;
|
||||
continue ;
|
||||
}
|
||||
// verifico linearità del tratto precedente
|
||||
// verifico linearità del tratto precedente
|
||||
bool bPrevLin = vtPrev.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i-1] * m_vPrevDer[i]) > dAngTolCos &&
|
||||
( vtPrev ^ m_vNextDer[i-1]).SqLen() < dSqLinTol &&
|
||||
( vtPrev ^ m_vPrevDer[i]).SqLen() < dSqLinTol ;
|
||||
// verifico linearità del tratto successivo
|
||||
// verifico linearità del tratto successivo
|
||||
bool bNextLin = vtNext.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i] * m_vPrevDer[i+1]) > dAngTolCos &&
|
||||
( vtNext ^ m_vNextDer[i]).SqLen() < dSqLinTol &&
|
||||
@@ -483,7 +483,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
double dMaxDist ;
|
||||
|
||||
// se la polilinea ha più di 2 punti
|
||||
// se la polilinea ha più di 2 punti
|
||||
if ( PL.GetPointNbr() > 2) {
|
||||
// calcolo punti e direzioni agli estremi della polilinea usando la curva di Bezier
|
||||
int nI ;
|
||||
@@ -501,11 +501,11 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
ptP1 = m_vPnt[nI] ;
|
||||
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
}
|
||||
// se la polilinea è formata da 2 punti
|
||||
// se la polilinea è formata da 2 punti
|
||||
else if ( PL.GetPointNbr() == 2) {
|
||||
// se molto vicini, esco
|
||||
double dLen ;
|
||||
@@ -561,7 +561,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
return false ;
|
||||
}
|
||||
|
||||
// spezzo l'intervallo in due parti a metà
|
||||
// spezzo l'intervallo in due parti a metà
|
||||
double dParStart, dParEnd ;
|
||||
if ( ! PL.GetFirstU( dParStart) || ! PL.GetLastU( dParEnd))
|
||||
return false ;
|
||||
@@ -569,9 +569,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
PolyLine PL2 ;
|
||||
if ( ! PL.Split( dParMid, PL2))
|
||||
return false ;
|
||||
// prima metà
|
||||
// prima metà
|
||||
if ( ! BiArcOrSplit( nLev + 1, PL, dLinTol, dAngTolDeg, PA))
|
||||
return false ;
|
||||
// seconda metà
|
||||
// seconda metà
|
||||
return BiArcOrSplit( nLev + 1, PL2, dLinTol, dAngTolDeg, PA) ;
|
||||
}
|
||||
|
||||
+218
-163
@@ -14,7 +14,6 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistPointCrvComposite.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
@@ -27,6 +26,7 @@
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "Voronoi.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
@@ -186,7 +186,7 @@ CurveComposite::AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart, dou
|
||||
bool
|
||||
CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinTol)
|
||||
{
|
||||
// prendo la proprietà del puntatore
|
||||
// prendo la proprietà del puntatore
|
||||
PtrOwner<ICurve> pCrv( pSmplCrv) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
@@ -211,15 +211,15 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
if ( ! pCrv->GetStartPoint( ptCrvStart) || ! pCrv->GetEndPoint( ptCrvEnd))
|
||||
return false ;
|
||||
|
||||
// se non è la prima
|
||||
// se non è la prima
|
||||
if ( ! m_CrvSmplS.empty()) {
|
||||
// se inserita alla fine
|
||||
if ( bEndOrStart) {
|
||||
// verifico sia in continuità con il finale attuale
|
||||
// verifico sia in continuità con il finale attuale
|
||||
Point3d ptEnd ;
|
||||
GetEndPoint( ptEnd) ;
|
||||
if ( ! AreSamePointEpsilon( ptCrvStart, ptEnd, EPS_CONNECT)) {
|
||||
// se in tolleranza, modifico l'inizio dell'entità
|
||||
// se in tolleranza, modifico l'inizio dell'entità
|
||||
if ( SqDist( ptCrvStart, ptEnd) < ( dLinTol * dLinTol)) {
|
||||
// lunghezza della curva originale
|
||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||
@@ -237,11 +237,11 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
}
|
||||
// altrimenti inserita all'inizio
|
||||
else {
|
||||
// verifico sia in continuità con l'iniziale attuale
|
||||
// verifico sia in continuità con l'iniziale attuale
|
||||
Point3d ptStart ;
|
||||
GetStartPoint( ptStart) ;
|
||||
if ( ! AreSamePointEpsilon( ptCrvEnd, ptStart, EPS_CONNECT)) {
|
||||
// se in tolleranza, modifico la fine dell'entità
|
||||
// se in tolleranza, modifico la fine dell'entità
|
||||
if ( SqDist( ptCrvEnd, ptStart) < ( dLinTol * dLinTol)) {
|
||||
// lunghezza della curva originale
|
||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||
@@ -286,14 +286,20 @@ CurveComposite::Close( void)
|
||||
if ( ! GetStartPoint( ptStart) ||
|
||||
! GetEndPoint( ptEnd))
|
||||
return false ;
|
||||
// se distanza inferiore al limite ridotto, non faccio alcunché
|
||||
// se distanza inferiore al limite ridotto, non faccio alcunché
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT))
|
||||
return true ;
|
||||
// se molto vicini li modifico
|
||||
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) ;
|
||||
if ( ! ModifyStart( ptMid) ||
|
||||
! ModifyEnd( ptMid))
|
||||
if ( ! m_CrvSmplS.front()->ModifyStart( ptMid) ||
|
||||
! m_CrvSmplS.back()->ModifyEnd( ptMid))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo la linea di chiusura
|
||||
@@ -324,7 +330,7 @@ CurveComposite::FromSplit( const ICurve& cCrv, int nParts)
|
||||
if ( ! cCrv.IsValid() || ! cCrv.IsSimple())
|
||||
return false ;
|
||||
|
||||
// se 1 parte o meno, non fa alcunchè
|
||||
// se 1 parte o meno, non fa alcunchè
|
||||
if ( nParts <= 1)
|
||||
return true ;
|
||||
|
||||
@@ -565,11 +571,11 @@ CurveComposite::Clone( void) const
|
||||
bool
|
||||
CurveComposite::CopyFrom( const IGeoObj* pGObjSrc)
|
||||
{
|
||||
// se sorgente è una curva composita
|
||||
// se sorgente è una curva composita
|
||||
const CurveComposite* pCC = GetBasicCurveComposite( pGObjSrc) ;
|
||||
if ( pCC != nullptr)
|
||||
return CopyFrom( *pCC) ;
|
||||
// se sorgente è un'altro tipo di curva
|
||||
// se sorgente è un'altro tipo di curva
|
||||
const ICurve* pCrv = ::GetCurve( pGObjSrc) ;
|
||||
if ( pCrv != nullptr) {
|
||||
Clear() ;
|
||||
@@ -598,6 +604,10 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
|
||||
if ( ! AddCurve( *pCrv))
|
||||
return false ;
|
||||
}
|
||||
if ( ccSrc.m_nStatus == IS_A_POINT) {
|
||||
m_ptStart = ccSrc.m_ptStart ;
|
||||
m_nStatus = IS_A_POINT ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -656,7 +666,7 @@ CurveComposite::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
while ( pCrvSmpl != nullptr && i < MAX_CRV) {
|
||||
// assegno ed emetto nome e tipo della curva semplice
|
||||
sOut += "#" + ToString( i) + " " + pCrvSmpl->GetTitle() + szNewLine ;
|
||||
// salvataggio della curva semplice
|
||||
// dati della curva semplice
|
||||
if ( ! pCrvSmpl->Dump( sOut, bMM, szNewLine))
|
||||
return false ;
|
||||
// passo alla successiva
|
||||
@@ -745,7 +755,7 @@ CurveComposite::Load( NgeReader& ngeIn)
|
||||
ICurve* pCrv = ::GetCurve( pGeoO) ;
|
||||
bOk = bOk && ( pCrv != nullptr && pCrv->IsSimple()) ;
|
||||
// aggiungo questa curva (sicuramente semplice)
|
||||
bOk = bOk && AddSimpleCurve( pCrv) ;
|
||||
bOk = bOk && AddSimpleCurve( pCrv, true, 10 * EPS_SMALL) ;
|
||||
// se errore
|
||||
if ( ! bOk)
|
||||
return false ;
|
||||
@@ -782,7 +792,7 @@ CurveComposite::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
// passo alla curva successiva
|
||||
pCrvSmpl = GetNextCurve() ;
|
||||
}
|
||||
// se c'è estrusione, devo tenerne conto (curve componenti sempre con vtExtr e dThick nulli)
|
||||
// se c'è estrusione, devo tenerne conto (curve componenti sempre con vtExtr e dThick nulli)
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ;
|
||||
Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ;
|
||||
@@ -799,7 +809,7 @@ CurveComposite::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
// inizializzo il box
|
||||
@@ -816,7 +826,7 @@ CurveComposite::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// passo alla curva successiva
|
||||
pCrvSmpl = GetNextCurve() ;
|
||||
}
|
||||
// se c'è estrusione, devo tenerne conto (curve componenti sempre con vtExtr e dThick nulli)
|
||||
// se c'è estrusione, devo tenerne conto (curve componenti sempre con vtExtr e dThick nulli)
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
vtFrExtr.ToGlob( frRef) ;
|
||||
@@ -838,14 +848,14 @@ CurveComposite::Validate( void)
|
||||
// ciclo su tutte le curve
|
||||
int nCount = 0 ;
|
||||
for ( auto Iter = m_CrvSmplS.cbegin() ; Iter != m_CrvSmplS.cend() ; ++Iter) {
|
||||
// verifico validità della curva e sua semplicità
|
||||
// verifico validità della curva e sua semplicità
|
||||
if ( ! (*Iter)->IsValid() || (*Iter)->GetType() == CRV_COMPO) {
|
||||
m_nStatus = ERR ;
|
||||
return false ;
|
||||
}
|
||||
// incremento contatore
|
||||
++ nCount ;
|
||||
// verifico continuità con la precedente (se non è la prima)
|
||||
// verifico continuità con la precedente (se non è la prima)
|
||||
if ( nCount > 1) {
|
||||
(*Iter)->GetStartPoint( ptStart) ;
|
||||
if ( ! AreSamePointApprox( ptPrevEnd, ptStart)) {
|
||||
@@ -870,7 +880,7 @@ CurveComposite::Validate( void)
|
||||
bool
|
||||
CurveComposite::TestClosure( void)
|
||||
{
|
||||
// se non è chiusa, esco subito
|
||||
// se non è chiusa, esco subito
|
||||
if ( ! IsClosed())
|
||||
return true ;
|
||||
// verifico ed eventualmente aggiusto coincidenza punti estremi
|
||||
@@ -878,10 +888,15 @@ CurveComposite::TestClosure( void)
|
||||
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
|
||||
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
||||
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) ;
|
||||
if ( ! m_CrvSmplS.front()->ModifyStart( ptM) ||
|
||||
! m_CrvSmplS.back()->ModifyEnd( ptM))
|
||||
return false ;
|
||||
return ( m_CrvSmplS.front()->ModifyStart( ptM) &&
|
||||
m_CrvSmplS.back()->ModifyEnd( ptM)) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
@@ -937,9 +952,11 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
}
|
||||
} break ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
// recupero dati sulla planarità della polilinea
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
@@ -1022,7 +1039,7 @@ CurveComposite::GetMidPoint( Point3d& ptMid) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
double dLen, dMid ;
|
||||
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
|
||||
return false ;
|
||||
@@ -1083,7 +1100,7 @@ CurveComposite::GetMidDir( Vector3d& vtDir) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
// determino il valore del parametro a metà lunghezza
|
||||
double dLen, dMid ;
|
||||
if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid))
|
||||
return false ;
|
||||
@@ -1363,7 +1380,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
||||
|
||||
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
|
||||
// se speciale, approssimo ogni singola entità e conservo le estremità interne (joint)
|
||||
if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) {
|
||||
// eseguo approssimazione
|
||||
double dStartPar = 0 ;
|
||||
@@ -1409,7 +1426,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
|
||||
if ( ! PL.ApproxOnSide( vtExtr, ( nType == APL_LEFT || nType == APL_LEFT_CONVEX), dLinTol))
|
||||
return false ;
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
// se necessario, sistemo per convessità dalla parte ammessa
|
||||
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
|
||||
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
|
||||
return false ;
|
||||
@@ -1418,7 +1435,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
}
|
||||
|
||||
// altrimenti standard
|
||||
// prima approssimazione lineare a 10 * Epsilon di ogni singola entità
|
||||
// prima approssimazione lineare a 10 * Epsilon di ogni singola entità
|
||||
if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
|
||||
return false ;
|
||||
// eliminazione dei punti in tolleranza
|
||||
@@ -1436,7 +1453,7 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
Frame3d frNat ;
|
||||
if ( ! m_VtExtr.IsSmall()) {
|
||||
frNat.Set( ORIG, m_VtExtr) ;
|
||||
@@ -1500,7 +1517,7 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin
|
||||
double dMlStartPar = 0 ;
|
||||
CurveByApprox crvByApprox ;
|
||||
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
// determino riferimento naturale della curva in base all'estrusione o al piano medio se questa è nulla
|
||||
Frame3d frNat ;
|
||||
if ( ! m_VtExtr.IsSmall()) {
|
||||
frNat.Set( ORIG, m_VtExtr) ;
|
||||
@@ -1617,12 +1634,12 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
|
||||
if ( dUStart < - EPS_PARAM || dUStart > dMaxU + EPS_PARAM ||
|
||||
dUEnd < - EPS_PARAM || dUEnd > dMaxU + EPS_PARAM)
|
||||
return nullptr ;
|
||||
// se i parametri coincidono, non resta alcunchè
|
||||
// se i parametri coincidono, non resta alcunchè
|
||||
if ( abs( dUEnd - dUStart) < EPS_PARAM)
|
||||
return nullptr ;
|
||||
// se il parametro start supera quello di end
|
||||
if ( dUStart > dUEnd - EPS_PARAM) {
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
|
||||
if ( ! IsClosed())
|
||||
return nullptr ;
|
||||
// se curva chiusa, il trim si avvolge attorno al punto di giunzione
|
||||
@@ -1681,7 +1698,7 @@ CurveComposite::Invert( void)
|
||||
bool
|
||||
CurveComposite::SimpleOffset( double dDist, int nType)
|
||||
{
|
||||
// se distanza di offset nulla, non devo fare alcunché
|
||||
// se distanza di offset nulla, non devo fare alcunché
|
||||
if ( abs( dDist) < EPS_SMALL)
|
||||
return true ;
|
||||
|
||||
@@ -1842,7 +1859,7 @@ CurveComposite::AddArcTg( const Point3d& ptNew, bool bEndOrStart)
|
||||
return false ;
|
||||
// recupero il versore normale al piano ( estrusione oppure se nulla asse Z locale)
|
||||
Vector3d vtN = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
|
||||
// costruisco l'arco (in casi articolari può essere una linea)
|
||||
// costruisco l'arco (in casi articolari può essere una linea)
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
// se da aggiungere alla fine
|
||||
if ( bEndOrStart) {
|
||||
@@ -1875,7 +1892,7 @@ CurveComposite::AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEn
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK && m_nStatus != TO_VERIFY)
|
||||
return false ;
|
||||
// costruisco l'arco (in casi articolari può essere una linea)
|
||||
// costruisco l'arco (in casi articolari può essere una linea)
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
// se da aggiungere alla fine
|
||||
if ( bEndOrStart) {
|
||||
@@ -1917,7 +1934,7 @@ CurveComposite::AddJoint( double dU)
|
||||
if ( IsNull( pCrv1) || IsNull( pCrv2))
|
||||
return false ;
|
||||
// della prima curva tengo la parte dall'inizio al parametro, della seconda la rimanente
|
||||
// ( se non riesco a trimmare, la nuova giunzione coincide con una già esistente, esco con successo)
|
||||
// ( se non riesco a trimmare, la nuova giunzione coincide con una già esistente, esco con successo)
|
||||
if ( ! pCrv1->TrimEndAtParam( dLocU) || ! pCrv2->TrimStartAtParam( dLocU))
|
||||
return true ;
|
||||
// elimino la curva originale
|
||||
@@ -1955,17 +1972,17 @@ CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
||||
else if ( IsClosed())
|
||||
nNextCrv = 0 ;
|
||||
ICurve* pNextCrv = ( nNextCrv != -1 ? m_CrvSmplS[ nNextCrv] : nullptr) ;
|
||||
// recupero punto iniziale dell'entità precedente (se esiste)
|
||||
// recupero punto iniziale dell'entità precedente (se esiste)
|
||||
Point3d ptStart ;
|
||||
if ( pPrevCrv != nullptr && ! pPrevCrv->GetStartPoint( ptStart))
|
||||
return false ;
|
||||
// recupero punto finale dell'entità successiva (se esiste)
|
||||
// recupero punto finale dell'entità successiva (se esiste)
|
||||
Point3d ptEnd ;
|
||||
if ( pNextCrv != nullptr && ! pNextCrv->GetEndPoint( ptEnd))
|
||||
return false ;
|
||||
// modifico il punto finale dell'eventuale entità precedente
|
||||
// modifico il punto finale dell'eventuale entità precedente
|
||||
if ( pPrevCrv != nullptr && ! pPrevCrv->ModifyEnd( ptNewJoint)) {
|
||||
// se entità precedente si annulla, la elimino
|
||||
// se entità precedente si annulla, la elimino
|
||||
if ( AreSamePointApprox( ptStart, ptNewJoint)) {
|
||||
delete pPrevCrv ;
|
||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nPrevCrv) ;
|
||||
@@ -1982,9 +1999,9 @@ CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
||||
delete( pPrevCrv) ;
|
||||
}
|
||||
}
|
||||
// modifico il punto iniziale dell'eventuale entità successiva
|
||||
// modifico il punto iniziale dell'eventuale entità successiva
|
||||
if ( pNextCrv != nullptr && ! pNextCrv->ModifyStart( ptNewJoint)) {
|
||||
// se entità successiva si annulla, la elimino
|
||||
// se entità successiva si annulla, la elimino
|
||||
if ( AreSamePointApprox( ptNewJoint, ptEnd)) {
|
||||
delete pNextCrv ;
|
||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nNextCrv) ;
|
||||
@@ -2101,17 +2118,17 @@ CurveComposite::MoveCurve( int nCrv, const Vector3d& vtMove)
|
||||
else if ( IsClosed())
|
||||
nNextCrv = 0 ;
|
||||
ICurve* pNextCrv = ( nNextCrv != -1 ? m_CrvSmplS[ nNextCrv] : nullptr) ;
|
||||
// recupero punti iniziale e finale dell'entità precedente (se esiste)
|
||||
// recupero punti iniziale e finale dell'entità precedente (se esiste)
|
||||
Point3d ptPrevStart, ptPrevEnd ;
|
||||
if ( pPrevCrv != nullptr && ( ! pPrevCrv->GetStartPoint( ptPrevStart) || ! pPrevCrv->GetEndPoint( ptPrevEnd)))
|
||||
return false ;
|
||||
// recupero punti iniziale e finale dell'entità successiva (se esiste)
|
||||
// recupero punti iniziale e finale dell'entità successiva (se esiste)
|
||||
Point3d ptNextStart, ptNextEnd ;
|
||||
if ( pNextCrv != nullptr && ( ! pNextCrv->GetStartPoint( ptNextStart) || ! pNextCrv->GetEndPoint( ptNextEnd)))
|
||||
return false ;
|
||||
// modifico il punto finale dell'eventuale entità precedente
|
||||
// modifico il punto finale dell'eventuale entità precedente
|
||||
if ( pPrevCrv != nullptr && ! pPrevCrv->ModifyEnd( ptPrevEnd + vtMove)) {
|
||||
// se entità precedente si annulla, la elimino
|
||||
// se entità precedente si annulla, la elimino
|
||||
if ( AreSamePointApprox( ptPrevStart, ptPrevEnd + vtMove)) {
|
||||
delete pPrevCrv ;
|
||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nPrevCrv) ;
|
||||
@@ -2130,9 +2147,9 @@ CurveComposite::MoveCurve( int nCrv, const Vector3d& vtMove)
|
||||
delete( pPrevCrv) ;
|
||||
}
|
||||
}
|
||||
// modifico il punto iniziale dell'eventuale entità successiva
|
||||
// modifico il punto iniziale dell'eventuale entità successiva
|
||||
if ( pNextCrv != nullptr && ! pNextCrv->ModifyStart( ptNextStart + vtMove)) {
|
||||
// se entità successiva si annulla, la elimino
|
||||
// se entità successiva si annulla, la elimino
|
||||
if ( AreSamePointApprox( ptNextStart + vtMove, ptNextEnd)) {
|
||||
delete pNextCrv ;
|
||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nNextCrv) ;
|
||||
@@ -2209,7 +2226,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
return false ;
|
||||
// recupero la curva corrente
|
||||
ICurve* pCrv = m_CrvSmplS[nCrv] ;
|
||||
// se già linea non devo fare alcunchè
|
||||
// se già linea non devo fare alcunchè
|
||||
if ( pCrv->GetType() == CRV_LINE)
|
||||
return true ;
|
||||
// recupero gli estremi
|
||||
@@ -2237,7 +2254,7 @@ CurveComposite::ModifyCurveToLine( int nCrv)
|
||||
bool
|
||||
CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
{
|
||||
// verifico validità parametro
|
||||
// verifico validità parametro
|
||||
double dMaxU = double( m_CrvSmplS.size()) ;
|
||||
if ( dUTrim < -EPS_PARAM || dUTrim > dMaxU - EPS_PARAM)
|
||||
return false ;
|
||||
@@ -2267,7 +2284,7 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
break ;
|
||||
}
|
||||
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
|
||||
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
|
||||
else {
|
||||
break ;
|
||||
}
|
||||
@@ -2280,7 +2297,7 @@ CurveComposite::TrimStartAtParam( double dUTrim)
|
||||
bool
|
||||
CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
{
|
||||
// verifico validità parametro
|
||||
// verifico validità parametro
|
||||
double dMaxU = double( m_CrvSmplS.size()) ;
|
||||
if ( dUTrim < EPS_PARAM || dUTrim > dMaxU + EPS_PARAM)
|
||||
return false ;
|
||||
@@ -2301,7 +2318,7 @@ CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
dUToTrim -= ( dParEnd - dParStart) ;
|
||||
// se da cancellare
|
||||
if ( bToErase) {
|
||||
// cancello l'entità, la tolgo dalla lista e passo alla successiva
|
||||
// cancello l'entità, la tolgo dalla lista e passo alla successiva
|
||||
delete (*Iter) ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
}
|
||||
@@ -2311,7 +2328,7 @@ CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
}
|
||||
// se lunghezza parametrica ancora da tagliare nulla (entro la tolleranza)
|
||||
else if ( dUToTrim > - EPS_PARAM) {
|
||||
// passo alla entità successiva
|
||||
// passo alla entità successiva
|
||||
++ Iter ;
|
||||
// dichiaro ingresso in zona da cancellare
|
||||
bToErase = true ;
|
||||
@@ -2324,7 +2341,7 @@ CurveComposite::TrimEndAtParam( double dUTrim)
|
||||
bToErase = true ;
|
||||
continue ;
|
||||
}
|
||||
// passo alla entità successiva
|
||||
// passo alla entità successiva
|
||||
++ Iter ;
|
||||
// dichiaro ingresso in zona da cancellare
|
||||
bToErase = true ;
|
||||
@@ -2389,7 +2406,7 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
bool
|
||||
CurveComposite::TrimStartAtLen( double dLenTrim)
|
||||
{
|
||||
// verifico validità lunghezza risultante
|
||||
// verifico validità lunghezza risultante
|
||||
if ( dLenTrim < EPS_ZERO)
|
||||
return true ;
|
||||
double dLen ;
|
||||
@@ -2443,7 +2460,7 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
|
||||
bool
|
||||
CurveComposite::TrimEndAtLen( double dLenTrim)
|
||||
{
|
||||
// verifico validità lunghezza risultante
|
||||
// verifico validità lunghezza risultante
|
||||
if ( dLenTrim < EPS_SMALL)
|
||||
return false ;
|
||||
double dLen ;
|
||||
@@ -2456,7 +2473,7 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
|
||||
double dLenToTrim = dLenTrim ;
|
||||
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
|
||||
double dCrvLen = 0 ;
|
||||
// se non sono già nella zona da cancellare, aggiorno lunghezze
|
||||
// se non sono già nella zona da cancellare, aggiorno lunghezze
|
||||
if ( ! bToErase) {
|
||||
// lunghezza della curva
|
||||
if ( ! (*Iter)->GetLength( dCrvLen))
|
||||
@@ -2466,18 +2483,18 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
|
||||
}
|
||||
// se da cancellare
|
||||
if ( bToErase) {
|
||||
// cancello l'entità, la tolgo dalla lista e passo alla successiva
|
||||
// cancello l'entità, la tolgo dalla lista e passo alla successiva
|
||||
delete (*Iter) ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
}
|
||||
// se lunghezza ancora da tagliare non nulla
|
||||
else if ( dLenToTrim > EPS_SMALL) {
|
||||
// passo alla entità successiva
|
||||
// passo alla entità successiva
|
||||
++ Iter ;
|
||||
}
|
||||
// se lunghezza ancora da tagliare nulla (entro la tolleranza)
|
||||
else if ( dLenToTrim > - EPS_SMALL) {
|
||||
// passo alla entità successiva
|
||||
// passo alla entità successiva
|
||||
++ Iter ;
|
||||
// dichiaro ingresso in zona da cancellare
|
||||
bToErase = true ;
|
||||
@@ -2489,7 +2506,7 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
|
||||
m_nStatus = ERR ;
|
||||
return false ;
|
||||
}
|
||||
// passo alla entità successiva
|
||||
// passo alla entità successiva
|
||||
++ Iter ;
|
||||
// dichiaro ingresso in zona da cancellare
|
||||
bToErase = true ;
|
||||
@@ -2565,8 +2582,10 @@ CurveComposite::Translate( const Vector3d& vtMove)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// traslo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Translate( vtMove) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2584,12 +2603,14 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// ruoto Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2649,9 +2670,9 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
|
||||
// se tutto bene, passo alla prossima
|
||||
if ( bOk)
|
||||
++Iter ;
|
||||
// altrimenti, l'entità si è annullata => devo toglierla dalla lista e cancellarla
|
||||
// altrimenti, l'entità si è annullata => devo toglierla dalla lista e cancellarla
|
||||
else {
|
||||
// si è annullata l'entità, la elimino e la tolgo dalla lista
|
||||
// si è annullata l'entità, la elimino e la tolgo dalla lista
|
||||
delete (*Iter) ;
|
||||
Iter = m_CrvSmplS.erase( Iter) ;
|
||||
}
|
||||
@@ -2699,7 +2720,7 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -2725,7 +2746,7 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -2760,16 +2781,18 @@ CurveComposite::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToGlob( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2790,16 +2813,18 @@ CurveComposite::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToLoc( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2820,16 +2845,18 @@ CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
return true ;
|
||||
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->LocToLoc( frOri, frDest) ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -2976,7 +3003,7 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast)
|
||||
bool
|
||||
CurveComposite::IsParamAtJoint( double dU) const
|
||||
{
|
||||
// se aperta e all'inizio o alla fine o lontano dagli interi non è giunzione
|
||||
// se aperta e all'inizio o alla fine o lontano dagli interi non è giunzione
|
||||
bool bClosed = IsClosed() ;
|
||||
if ( ( ! bClosed && abs( dU) < EPS_PARAM) ||
|
||||
( ! bClosed && abs( dU - double( m_CrvSmplS.size())) < EPS_PARAM) ||
|
||||
@@ -2994,7 +3021,7 @@ CurveComposite::ChangeStartPoint( double dU)
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
|
||||
// questa funzione gestisce già anche il cambio di inizio su curve chiuse
|
||||
// questa funzione gestisce già anche il cambio di inizio su curve chiuse
|
||||
return TrimStartEndAtParam( dU, dU) ;
|
||||
}
|
||||
|
||||
@@ -3004,19 +3031,19 @@ CurveComposite::ArcsToBezierCurves( void)
|
||||
{
|
||||
// verifico le singole curve
|
||||
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
|
||||
// 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) {
|
||||
// eseguo trasformazione
|
||||
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( (*Iter))) ;
|
||||
if ( IsNull( pNewCrv))
|
||||
return false ;
|
||||
// se risultato è singola curva
|
||||
// se risultato è singola curva
|
||||
if ( pNewCrv->IsSimple()) {
|
||||
// elimino l'arco e lo sostituisco con la curva di Bezier
|
||||
delete (*Iter) ;
|
||||
(*Iter) = Release( pNewCrv) ;
|
||||
}
|
||||
// altrimenti è una curva composita
|
||||
// altrimenti è una curva composita
|
||||
else {
|
||||
CurveComposite* pCC = GetBasicCurveComposite( pNewCrv) ;
|
||||
if ( pCC == nullptr)
|
||||
@@ -3058,13 +3085,13 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
|
||||
(*Iter)->SetExtrusion( V_NULL) ;
|
||||
if ( IsNull( pNewCrv))
|
||||
return false ;
|
||||
// se risultato è singola curva
|
||||
// se risultato è singola curva
|
||||
if ( pNewCrv->IsSimple()) {
|
||||
// elimino la curva originale e la sostituisco con l'arco
|
||||
delete (*Iter) ;
|
||||
(*Iter) = Release( pNewCrv) ;
|
||||
}
|
||||
// altrimenti è una curva composita
|
||||
// altrimenti è una curva composita
|
||||
else {
|
||||
CurveComposite* pCC = GetBasicCurveComposite( pNewCrv) ;
|
||||
if ( pCC == nullptr)
|
||||
@@ -3130,7 +3157,7 @@ CurveComposite::StraightArcsToLines( double dLinTol, double dAngTolDeg)
|
||||
static int
|
||||
MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp)
|
||||
{
|
||||
// verifico compatibilità delle proprietà
|
||||
// verifico compatibilità delle proprietà
|
||||
int nTpr0P = pCrvP->GetTempProp( 0) ;
|
||||
int nTpr0C = pCrvC->GetTempProp( 0) ;
|
||||
int nTpr1P = pCrvP->GetTempProp( 1) ;
|
||||
@@ -3177,7 +3204,7 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
if ( pLineC->ModifyStart( pLineP->GetStart())) {
|
||||
// diminuisco la tolleranza corrente dell'errore attuale
|
||||
dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ;
|
||||
// se curve originali con proprietà diversa, la cancello
|
||||
// se curve originali con proprietà diversa, la cancello
|
||||
if ( nTpr0P != nTpr0C)
|
||||
pLineC->SetTempProp( 0, 0) ;
|
||||
if ( nTpr1P != nTpr1C)
|
||||
@@ -3202,7 +3229,7 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// verifico la coincidenza dei raggi
|
||||
if ( abs( pArcP->GetRadius() - pArcC->GetRadius()) > dCurrLinTol)
|
||||
return 0 ;
|
||||
// verifico la collinearità delle normali (tenendo conto del raggio)
|
||||
// verifico la collinearità delle normali (tenendo conto del raggio)
|
||||
if ( ! (( pArcP->GetNormVersor() - pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall() &&
|
||||
! (( pArcP->GetNormVersor() + pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall())
|
||||
return 0 ;
|
||||
@@ -3212,61 +3239,64 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// verifico di non superare l'angolo giro al centro
|
||||
if ( abs( pArcP->GetAngCenter() + pArcC->GetAngCenter()) > ANG_FULL + EPS_ANG_SMALL)
|
||||
return 0 ;
|
||||
// se archi piatti
|
||||
if ( pArcP->IsPlane() && pArcC->IsPlane()) {
|
||||
// se calcolo nuovo arco ok, procedo con l'unione
|
||||
Point3d ptP1 ;
|
||||
pArcP->GetStartPoint( ptP1) ;
|
||||
Point3d ptP2 ;
|
||||
pArcP->GetEndPoint( ptP2) ;
|
||||
Point3d ptP3 ;
|
||||
pArcC->GetEndPoint( ptP3) ;
|
||||
// verifico se circonferenza completa
|
||||
bool bCirc = ( AreSamePointApprox( ptP1, ptP3)) ;
|
||||
if ( bCirc)
|
||||
pArcC->GetMidPoint( ptP3) ;
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
||||
// verifico normale al piano dell'arco
|
||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||
NewArc.InvertN() ;
|
||||
// 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
|
||||
// verifico se archi piatti
|
||||
bool bPlaneArcs = pArcP->IsPlane() && pArcC->IsPlane() ;
|
||||
// se archi non piatti verifico coincidenza pendenza sulla normale
|
||||
if ( ! bPlaneArcs) {
|
||||
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
||||
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
||||
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) > dCurrLinTol)
|
||||
return 0 ;
|
||||
}
|
||||
// verifico coincidenza pendenza sulla normale
|
||||
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
||||
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
||||
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) < dCurrLinTol) {
|
||||
// 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 ;
|
||||
|
||||
// se calcolo nuovo arco ok, procedo con l'unione
|
||||
Point3d ptP1 ;
|
||||
pArcP->GetStartPoint( ptP1) ;
|
||||
Point3d ptP2 ;
|
||||
pArcP->GetEndPoint( ptP2) ;
|
||||
Point3d ptP3 ;
|
||||
pArcC->GetEndPoint( ptP3) ;
|
||||
|
||||
// se archi non piani costruisco arco sul piano definito dalla normale e dal punto di partenza del primo arco
|
||||
Frame3d frRef ;
|
||||
if ( ! frRef.Set( ptP1, pArcP->GetNormVersor()))
|
||||
return 0 ;
|
||||
if ( ! bPlaneArcs) {
|
||||
ptP1.Scale( frRef, 1, 1, 0) ;
|
||||
ptP2.Scale( frRef, 1, 1, 0) ;
|
||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
||||
}
|
||||
|
||||
// verifico se circonferenza completa
|
||||
bool bCirc = ( AreSamePointApprox( ptP1, ptP3)) ;
|
||||
if ( bCirc) {
|
||||
pArcC->GetMidPoint( ptP3) ;
|
||||
if ( ! bPlaneArcs)
|
||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
||||
}
|
||||
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
||||
// 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
|
||||
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 ;
|
||||
}
|
||||
|
||||
// nessuna fusione
|
||||
@@ -3293,11 +3323,11 @@ CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd,
|
||||
while ( iterC != m_CrvSmplS.end()) {
|
||||
// se curve unite
|
||||
switch ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dCosAngTol, bNeedSameProp)) {
|
||||
case -1 : // cancello l'entità precedente e la tolgo dalla lista
|
||||
case -1 : // cancello l'entità precedente e la tolgo dalla lista
|
||||
delete (*iterP) ;
|
||||
iterC = m_CrvSmplS.erase( iterP) ;
|
||||
break ;
|
||||
case 1 : // cancello l'entità corrente e la tolgo dalla lista
|
||||
case 1 : // cancello l'entità corrente e la tolgo dalla lista
|
||||
delete (*iterC) ;
|
||||
iterC = m_CrvSmplS.erase( iterC) ;
|
||||
iterC = prev( iterC) ;
|
||||
@@ -3314,11 +3344,11 @@ CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd,
|
||||
if ( bStartEnd && m_CrvSmplS.size() >= 2 && IsClosed()) {
|
||||
iterC = m_CrvSmplS.begin() ;
|
||||
switch ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dCosAngTol, bNeedSameProp)) {
|
||||
case -1 : // cancello l'entità precedente e la tolgo dalla lista
|
||||
case -1 : // cancello l'entità precedente e la tolgo dalla lista
|
||||
delete (*iterP) ;
|
||||
m_CrvSmplS.erase( iterP) ;
|
||||
break ;
|
||||
case 1 : // cancello l'entità corrente e la tolgo dalla lista
|
||||
case 1 : // cancello l'entità corrente e la tolgo dalla lista
|
||||
delete (*iterC) ;
|
||||
m_CrvSmplS.erase( iterC) ;
|
||||
break ;
|
||||
@@ -3377,7 +3407,7 @@ SplitTopBottomArcs( CurveComposite& cCompo)
|
||||
// le ordino in senso crescente di ampiezza assoluta
|
||||
if ( abs( dAng1) > abs( dAng2))
|
||||
swap( dAng1, dAng2) ;
|
||||
// verifico se la prima di queste rotazioni è compresa nell'arco
|
||||
// verifico se la prima di queste rotazioni è compresa nell'arco
|
||||
if ( abs( dAng1) > EPS_ANG_SMALL && abs( dAng1) < abs( pArc->GetAngCenter()) - EPS_ANG_SMALL) {
|
||||
cCompo.AddJoint( i + dAng1 / pArc->GetAngCenter()) ;
|
||||
}
|
||||
@@ -3427,7 +3457,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg)
|
||||
Point3d ptStart, ptEnd ;
|
||||
pCompo->GetStartPoint( ptStart) ;
|
||||
pCompo->GetEndPoint( ptEnd) ;
|
||||
// se curva pressochè verticale non sottende alcunché, quindi la salto
|
||||
// se curva pressochè verticale non sottende alcunché, quindi la salto
|
||||
if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL)
|
||||
continue ;
|
||||
// ordino gli estremi
|
||||
@@ -3533,7 +3563,7 @@ CurveComposite::IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const
|
||||
// elimino i punti allineati entro la tolleranza
|
||||
if ( ! PL.RemoveAlignedPoints( dLinTol))
|
||||
return false ;
|
||||
// se sono rimasti due punti è una retta
|
||||
// se sono rimasti due punti è una retta
|
||||
return ( PL.GetPointNbr() == 2) ;
|
||||
}
|
||||
|
||||
@@ -3541,7 +3571,7 @@ CurveComposite::IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const
|
||||
bool
|
||||
CurveComposite::IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const
|
||||
{
|
||||
// deve essere una sola entità
|
||||
// deve essere una sola entità
|
||||
if ( GetCurveCount() != 1)
|
||||
return false ;
|
||||
// deve essere un arco di circonferenza completo
|
||||
@@ -3564,7 +3594,7 @@ CurveComposite::IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
|
||||
// se è formata da una sola entità arco che è una circonferenza
|
||||
// se è formata da una sola entità arco che è una circonferenza
|
||||
if ( IsOneCircle( ptCen, vtN, dRad, bCCW))
|
||||
return true ;
|
||||
|
||||
@@ -3601,10 +3631,10 @@ CurveComposite::IsARectangle( double dLinTol, Point3d& ptP, Vector3d& vtL1, Vect
|
||||
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
|
||||
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
|
||||
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
|
||||
// verifico che le diagonali si incontrino nel loro punto medio (-> è un parallelogramma)
|
||||
// verifico che le diagonali si incontrino nel loro punto medio (-> è un parallelogramma)
|
||||
if ( ! AreSamePointEpsilon( Media( ptV1, ptV3), Media( ptV2, ptV4), dLinTol / 2))
|
||||
return false ;
|
||||
// verifico che le diagonali abbiano la stessa lunghezza (-> è un rettangolo)
|
||||
// verifico che le diagonali abbiano la stessa lunghezza (-> è un rettangolo)
|
||||
if ( abs( Dist( ptV1, ptV3) - Dist( ptV2, ptV4)) > dLinTol)
|
||||
return false ;
|
||||
// assegno i parametri del rettangolo
|
||||
@@ -3637,7 +3667,7 @@ CurveComposite::IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vect
|
||||
Point3d ptV2 ; PL.GetNextPoint( ptV2) ;
|
||||
Point3d ptV3 ; PL.GetNextPoint( ptV3) ;
|
||||
Point3d ptV4 ; PL.GetNextPoint( ptV4) ;
|
||||
// verifico se V4->V3 è parallelo a V1->V2
|
||||
// verifico se V4->V3 è parallelo a V1->V2
|
||||
double dV3B12, dV4B12 ;
|
||||
if ( ! DistPointLine( ptV3, ptV1, ptV2, false).GetDist( dV3B12) ||
|
||||
! DistPointLine( ptV4, ptV1, ptV2, false).GetDist( dV4B12))
|
||||
@@ -3649,7 +3679,7 @@ CurveComposite::IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vect
|
||||
vtB2 = ptV3 - ptV4 ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se V1->V4 è parallelo a V2->V3
|
||||
// verifico se V1->V4 è parallelo a V2->V3
|
||||
double dV1B23, dV4B23 ;
|
||||
if ( ! DistPointLine( ptV1, ptV2, ptV3, false).GetDist( dV1B23) ||
|
||||
! DistPointLine( ptV4, ptV2, ptV3, false).GetDist( dV4B23))
|
||||
@@ -3661,7 +3691,7 @@ CurveComposite::IsATrapezoid( double dLinTol, Point3d& ptP, Vector3d& vtB1, Vect
|
||||
vtB2 = ptV4 - ptV1 ;
|
||||
return true ;
|
||||
}
|
||||
// non è un trapezio
|
||||
// non è un trapezio
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -3747,7 +3777,7 @@ CurveComposite::GetVoronoiObject() const
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
|
||||
// se non è stato calcolato, lo calcolo
|
||||
// se non è stato calcolato, lo calcolo
|
||||
if ( m_pVoronoiObj == nullptr)
|
||||
CalcVoronoiObject() ;
|
||||
|
||||
@@ -3763,3 +3793,28 @@ CurveComposite::ResetVoronoiObject() const
|
||||
delete m_pVoronoiObj ;
|
||||
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
|
||||
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != IS_A_POINT)
|
||||
return false ;
|
||||
// restituisco il punto
|
||||
ptStart = m_ptStart ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
+9
-4
@@ -150,7 +150,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool IsParamAtJoint( double dU) const override ;
|
||||
ICurve* RemoveFirstOrLastCurve( bool bLast = true) override ;
|
||||
bool ChangeStartPoint( double dU) override ;
|
||||
bool AddPoint( const Point3d& ptStart) override ;
|
||||
bool AddPoint( const Point3d& ptStart) override ; // funzione per aggiungere il ptStart prima di usare la funzione AddLine
|
||||
bool AddLine( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
bool AddLineTg( double dLen, bool bEndOrStart = true) override ;
|
||||
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||
@@ -177,11 +177,16 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
||||
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
||||
bool GetCurveTempParam( int nCrv, double& dParam, int nParamInd = 0) 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
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
CurveComposite( void) ;
|
||||
@@ -195,6 +200,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool RelocateFrom( CurveComposite& ccSrc) ;
|
||||
bool GetApproxLength( double& dLen) const ;
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveComposite& ccSrc) ;
|
||||
@@ -206,10 +212,9 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ;
|
||||
bool IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2, IS_A_POINT = 3} ;
|
||||
|
||||
private :
|
||||
typedef std::deque<ICurve*> PCRVSMPL_DEQUE ;
|
||||
@@ -222,7 +227,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
|
||||
double m_dThick ; // spessore
|
||||
Point3d m_ptStart ; // punto iniziale per composita vuota per Add di linee o archi
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable Voronoi* m_pVoronoiObj ; // Voronoi
|
||||
mutable PCSD_CONST_ITER m_Iter ; // iteratore
|
||||
|
||||
+38
-28
@@ -14,11 +14,11 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "Voronoi.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
@@ -162,7 +162,7 @@ CurveLine::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
// dati generali di una curva
|
||||
if ( ! CurveDump( *this, sOut, bMM, szNewLine))
|
||||
return false ;
|
||||
// parametri : sono già compresi nei dati generali (PS e PE)
|
||||
// parametri : sono già compresi nei dati generali (PS e PE)
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ CurveLine::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
|
||||
return false ;
|
||||
// assegno il box in locale
|
||||
b3Loc.Set( m_PtStart, m_PtEnd) ;
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Point3d ptMinExtr = b3Loc.GetMin() + m_VtExtr * m_dThick ;
|
||||
Point3d ptMaxExtr = b3Loc.GetMax() + m_VtExtr * m_dThick ;
|
||||
@@ -241,7 +241,7 @@ CurveLine::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
// porto gli estremi nel riferimento passato
|
||||
@@ -251,7 +251,7 @@ CurveLine::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
|
||||
ptFrEnd.ToGlob( frRef) ;
|
||||
// assegno il box nel riferimento
|
||||
b3Ref.Set( ptFrStart, ptFrEnd) ;
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
// se c'è estrusione, devo tenerne conto
|
||||
if ( ! m_VtExtr.IsSmall() && abs( m_dThick) > EPS_SMALL) {
|
||||
Vector3d vtFrExtr = m_VtExtr ;
|
||||
vtFrExtr.ToGlob( frRef) ;
|
||||
@@ -390,7 +390,7 @@ CurveLine::GetLength( double& dLen) const
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// la lunghezza è la distanza tra gli estremi
|
||||
// la lunghezza è la distanza tra gli estremi
|
||||
dLen = Dist( m_PtStart, m_PtEnd) ;
|
||||
|
||||
return ( dLen > EPS_SMALL) ;
|
||||
@@ -416,7 +416,7 @@ CurveLine::GetLengthAtParam( double dU, double& dLen) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
// la lunghezza totale è la distanza tra gli estremi
|
||||
// la lunghezza totale è la distanza tra gli estremi
|
||||
double dTotLen = Dist( m_PtStart, m_PtEnd) ;
|
||||
|
||||
// fine
|
||||
@@ -448,7 +448,7 @@ CurveLine::GetParamAtLength( double dLen, double& dU) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
// la lunghezza totale è la distanza tra gli estremi
|
||||
// la lunghezza totale è la distanza tra gli estremi
|
||||
double dTotLen = Dist( m_PtStart, m_PtEnd) ;
|
||||
|
||||
// se dopo fine, errore
|
||||
@@ -811,8 +811,10 @@ CurveLine::Translate( const Vector3d& vtMove)
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// traslo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Translate( vtMove) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -830,12 +832,14 @@ CurveLine::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, do
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// ruoto Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -894,7 +898,7 @@ CurveLine::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -919,7 +923,7 @@ CurveLine::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& v
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -949,16 +953,18 @@ CurveLine::ToGlob( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToGlob( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -973,16 +979,18 @@ CurveLine::ToLoc( const Frame3d& frRef)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->ToLoc( frRef) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -997,16 +1005,18 @@ CurveLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
// imposto ricalcolo di Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// trasformo Voronoi
|
||||
if ( m_pVoronoiObj != nullptr)
|
||||
m_pVoronoiObj->LocToLoc( frOri, frDest) ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -1065,7 +1075,7 @@ CurveLine::GetVoronoiObject() const
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
|
||||
// se non è stato calcolato, lo calcolo
|
||||
// se non è stato calcolato, lo calcolo
|
||||
if ( m_pVoronoiObj == nullptr)
|
||||
CalcVoronoiObject() ;
|
||||
|
||||
|
||||
+6
-3
@@ -146,7 +146,10 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
CurveLine( void) ;
|
||||
@@ -158,12 +161,12 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
LOG_ERROR( GetEGkLogger(), "CurveLine : copy error")
|
||||
return *this ; }
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveLine& clSrc) ;
|
||||
bool Validate( void) ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
@@ -175,7 +178,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
Point3d m_PtEnd ; // punto finale
|
||||
Vector3d m_VtExtr ; // vettore estrusione
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable Voronoi* m_pVoronoiObj ; // Voronoi
|
||||
} ;
|
||||
|
||||
+3
-4
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2022
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1
|
||||
// File : DistLineLine.cpp Data : 10.05.24 Versione : 2.6e3
|
||||
// Contenuto : Implementazione della classe distanza fra elementi lineari.
|
||||
//
|
||||
//
|
||||
@@ -12,11 +12,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
#include "/EgtDev/Include/EGkGeoConst.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 "stdafx.h"
|
||||
#include "DllMain.h"
|
||||
#include "DistPointCrvAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "DistPointCrvAux.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -50,7 +50,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
||||
}
|
||||
// altrimenti, per curve successive
|
||||
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 ;
|
||||
if ( pCrvSmpl->GetLocalBBox( b3B) &&
|
||||
b3B.SqDistFromPoint( ptP) <= m_dDist * m_dDist) {
|
||||
@@ -105,7 +105,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
// con minima distanza più bassa
|
||||
// con minima distanza più bassa
|
||||
else if ( dCurrDist < m_dDist) {
|
||||
// aggiorno i minimi
|
||||
m_dDist = dCurrDist ;
|
||||
|
||||
+3
-1
@@ -13,10 +13,10 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistPointArc.h"
|
||||
#include "DistPointCrvBezier.h"
|
||||
#include "DistPointCrvComposite.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bI
|
||||
case CRV_COMPO :
|
||||
CrvCompositeCalculate( ptP, Curve) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// salvo il punto
|
||||
m_ptP = ptP ;
|
||||
|
||||
+4
-4
@@ -1,19 +1,19 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistPointLine.cpp Data : 17.12.13 Versione : 1.4l1
|
||||
// File : DistPointLine.cpp Data : 20.05.24 Versione : 2.6e5
|
||||
// Contenuto : Implementazione della classe distanza punto da linea/segmento.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 17.12.13 DS Creazione modulo.
|
||||
//
|
||||
// 20.05.24 DS Reso pubblico in Include.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 ;
|
||||
} ;
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 ;
|
||||
}
|
||||
+99
-30
@@ -15,15 +15,16 @@
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// 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.
|
||||
// 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.
|
||||
// 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 vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
||||
static bool
|
||||
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||
@@ -33,7 +34,7 @@ BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDi
|
||||
// Se box A vuoto, risultato vuoto
|
||||
if ( boxA.IsEmpty())
|
||||
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 ;
|
||||
if ( boxB.IsSmall() || ! boxA.FindIntersection( boxB, boxInt)) {
|
||||
vBoxDiff.emplace_back( boxA) ;
|
||||
@@ -93,6 +94,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
{
|
||||
// Inizializzo distanza non calcolata
|
||||
m_dDist = - 1. ;
|
||||
// Controllo se la superficie è chiusa
|
||||
m_bIsSurfClosed = tmSurf.IsClosed() ;
|
||||
|
||||
// Lavoro con l'oggetto superficie trimesh di base
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
||||
@@ -104,8 +107,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( b3Stm.IsEmpty())
|
||||
return ;
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
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 ;
|
||||
@@ -115,14 +118,17 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
BBox3d boxPPrev( ptP) ;
|
||||
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
int nMinDistTriaIndex = SVT_NULL ;
|
||||
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() ;
|
||||
bool bContinue = true ;
|
||||
|
||||
// creazione del vettore dei triangoli più vicini a ptP
|
||||
vector<pair<int, Triangle3d>> vTria ; // <indice triangolo, Triangolo>
|
||||
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 ;
|
||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||
// Ciclo sui box differenza
|
||||
@@ -130,12 +136,12 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
for ( const auto& b3Box : vBox) {
|
||||
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.SqDistFromPoint( ptP) > dMinSqDist)
|
||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.DistFromPoint( ptP) > dMinDist)
|
||||
continue ;
|
||||
// ricerca sui triangoli nel box
|
||||
bCollide = true ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
INTVECTOR vnIds ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
// Ciclo sui triangoli del sotto-box corrente
|
||||
for ( auto nT : vnIds) {
|
||||
int nTriaTemp ;
|
||||
@@ -143,19 +149,30 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
||||
pStm->SetTempInt( nT, 1) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
double dCurrDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetDist( dCurrDist)) {
|
||||
// se distanze uguali...
|
||||
if ( abs( dCurrDist - dMinDist) < EPS_SMALL)
|
||||
// aggiungo il triangolo
|
||||
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
|
||||
if ( ! bCollide || dMinSqDist < EPS_SMALL * EPS_SMALL)
|
||||
if ( ! bCollide || dMinDist < EPS_SMALL)
|
||||
bContinue = false ;
|
||||
else {
|
||||
boxPPrev = boxP ;
|
||||
@@ -163,15 +180,67 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
}
|
||||
}
|
||||
|
||||
if ( nMinDistTriaIndex != SVT_NULL) {
|
||||
m_dDist = sqrt( max( dMinSqDist, 0.)) ;
|
||||
// se non ho trovato nessun triangolo, esco
|
||||
if ( nMinDistTriaIndex == SVT_NULL)
|
||||
return ;
|
||||
|
||||
// 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_ptMinDistPoint = ptMinDistPoint ;
|
||||
Triangle3d trMinDistTria ;
|
||||
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
trMinDistTria.Validate() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ;
|
||||
m_bIsInside = false ;
|
||||
return ;
|
||||
}
|
||||
// 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 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -224,8 +293,8 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( b3Stm.IsEmpty())
|
||||
return SVT_NULL ;
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
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 ;
|
||||
@@ -237,11 +306,11 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// Variabili distanza minima
|
||||
int nVert = SVT_NULL ;
|
||||
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() ;
|
||||
bool bContinue = true ;
|
||||
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 ;
|
||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||
// Ciclo sui box differenza
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
+26
-2
@@ -281,6 +281,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="BBox3d.cpp" />
|
||||
<ClCompile Include="BiArcs.cpp" />
|
||||
<ClCompile Include="CalcPocketing.cpp" />
|
||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||
@@ -309,16 +310,41 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CurveByApprox.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||
<ClCompile Include="DistPointSurfFr.cpp" />
|
||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||
<ClCompile Include="IntersLineSurfBez.cpp" />
|
||||
<ClCompile Include="PolygonElevation.cpp" />
|
||||
<ClCompile Include="ProjectCurveSurfBez.cpp" />
|
||||
<ClCompile Include="Quaternion.cpp" />
|
||||
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
||||
<ClCompile Include="RotationXplaneFrame.cpp" />
|
||||
<ClCompile Include="SbzFromCurves.cpp" />
|
||||
<ClCompile Include="SbzStandard.cpp" />
|
||||
<ClCompile Include="Voronoi.cpp" />
|
||||
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkDistLineLine.h" />
|
||||
<ClInclude Include="..\Include\EGkDistPointLine.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
||||
<ClInclude Include="..\Include\EGkQuaternion.h" />
|
||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
||||
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
||||
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
||||
<ClInclude Include="CAvSilhouetteSurfTm.h" />
|
||||
<ClInclude Include="CDeBoxTria.h" />
|
||||
<ClInclude Include="CDeCapsTria.h" />
|
||||
<ClInclude Include="CDeConeFrustumTria.h" />
|
||||
@@ -576,12 +602,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="CAvSimpleSurfFrMove.h" />
|
||||
<ClInclude Include="CAvToolSurfTm.h" />
|
||||
<ClInclude Include="CreateCurveAux.h" />
|
||||
<ClInclude Include="DistLineLine.h" />
|
||||
<ClInclude Include="DistPointArc.h" />
|
||||
<ClInclude Include="DistPointCrvAux.h" />
|
||||
<ClInclude Include="DistPointCrvBezier.h" />
|
||||
<ClInclude Include="DistPointCrvComposite.h" />
|
||||
<ClInclude Include="DistPointLine.h" />
|
||||
<ClInclude Include="DllMain.h" />
|
||||
<ClInclude Include="earcut.hpp" />
|
||||
<ClInclude Include="ExtDimension.h" />
|
||||
|
||||
@@ -43,15 +43,18 @@
|
||||
<Filter Include="File di origine\GeoOffset">
|
||||
<UniqueIdentifier>{f07670fd-9429-4b7e-ac6d-1c0022e756fb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoCollision">
|
||||
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoProject">
|
||||
<UniqueIdentifier>{d96752da-1884-4a73-ba1b-5b20b606e469}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoElevation">
|
||||
<UniqueIdentifier>{4c6a9dc5-8fac-4ecd-bde6-3e37e056712e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoCollisionAvoid">
|
||||
<UniqueIdentifier>{ae52e402-3063-45e3-b9f7-1710035a1f56}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoCollisionDetection">
|
||||
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vector3d.cpp">
|
||||
@@ -273,6 +276,9 @@
|
||||
<ClCompile Include="IntersLineSurfTm.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineSurfBez.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CircleCenTgCurve.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
@@ -372,17 +378,8 @@
|
||||
<ClCompile Include="IntersLineSurfStd.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvToolTriangle.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvToolSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeBoxTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersSurfTmSurfTm.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
@@ -400,19 +397,19 @@
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeCylTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeBoxClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeCylClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeSpheTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeSpheClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfBezier.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
@@ -430,34 +427,34 @@
|
||||
<Filter>File di origine\GeoDist</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeTriaTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeConeTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeUtility.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeClosedSurfTmClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeConeFrustumClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeConeFrustumTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeConvexTorusClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeConvexTorusTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeRectPrismoidClosedSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
@@ -469,7 +466,7 @@
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CDeCapsTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
<Filter>File di origine\GeoCollisionDetection</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Circle2P.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
@@ -510,6 +507,48 @@
|
||||
<ClCompile Include="PolygonElevation.cpp">
|
||||
<Filter>File di origine\GeoElevation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp">
|
||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvToolSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvToolTriangle.cpp">
|
||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineVolZmap.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersPlaneVolZmap.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SbzStandard.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RotationMinimizingFrame.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RotationXplaneFrame.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Quaternion.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ProjectCurveSurfBez.cpp">
|
||||
<Filter>File di origine\GeoProject</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SbzFromCurves.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DistPointSurfFr.cpp">
|
||||
<Filter>File di origine\GeoDist</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -566,9 +605,6 @@
|
||||
<ClInclude Include="DistPointArc.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistPointLine.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistPointCrvBezier.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
@@ -1091,9 +1127,6 @@
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistLineLine.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CDeUtility.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
@@ -1169,6 +1202,33 @@
|
||||
<ClInclude Include="Voronoi.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkQuaternion.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+140
-47
@@ -21,12 +21,14 @@
|
||||
#include "FontManager.h"
|
||||
#include "FontAux.h"
|
||||
#include "CurveArc.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkExtText.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include <new>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -63,7 +65,7 @@ ExtDimension::~ExtDimension( void)
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExtDimension::SetStyle( double dExtLineLen, double dArrowLen, double dTextDist, bool bLenIsMM,
|
||||
int nDecDigit, const string& sFont, double dTextHeight)
|
||||
int nDecDigit, const string& sFont, double dTextHeight)
|
||||
{
|
||||
m_dExtLineLen = max( dExtLineLen, MIN_EXTLINELEN) ;
|
||||
m_dArrowLen = max( dArrowLen, MIN_ARROWLEN) ;
|
||||
@@ -200,7 +202,7 @@ ExtDimension::SetDiametral( const Point3d& ptCen, const Point3d& ptPos,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d& ptP2, const Point3d& ptPos,
|
||||
ExtDimension::SetAngular( const Point3d& ptV, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const string& sText)
|
||||
{
|
||||
// dichiaro quota non ancora determinata
|
||||
@@ -209,17 +211,16 @@ ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d
|
||||
m_vtN = vtN ;
|
||||
if ( ! m_vtN.Normalize())
|
||||
return false ;
|
||||
// porto i punti nel piano definito da P1 e N
|
||||
m_ptP1 = ptP1 ;
|
||||
m_ptP2 = ptP2 - ( ptP2 - m_ptP1) * m_vtN * m_vtN ;
|
||||
m_ptP6 = ptV - ( ptV - m_ptP1) * m_vtN * m_vtN ;
|
||||
m_ptPos = ptPos - ( ptPos - m_ptP1) * m_vtN * m_vtN ;
|
||||
// verifico che i punti di misura non siano coincidenti
|
||||
if ( AreSamePointApprox( m_ptP1, m_ptP2) || AreSamePointApprox( m_ptP1, m_ptP6) || AreSamePointApprox( m_ptP2, m_ptP5))
|
||||
return false ;
|
||||
// direzione di riferimento ( nel piano perpendicolare a vtN)
|
||||
// porto i punti e le direzioni nel piano definito da V e N
|
||||
m_ptP6 = ptV ;
|
||||
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
||||
m_vtDir = m_ptPos - m_ptP6 ;
|
||||
double dLenDir = m_vtDir.Len() ;
|
||||
Vector3d vtLine1 = OrthoCompo( ptP1 - m_ptP6, m_vtN) ;
|
||||
Vector3d vtLine2 = OrthoCompo( ptP2 - m_ptP6, m_vtN) ;
|
||||
// verifico che i punti di misura non siano coincidenti
|
||||
if ( ! vtLine1.Normalize() || ! vtLine2.Normalize() || dLenDir < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// controllo se è testo o se è la misura
|
||||
double dFactor ;
|
||||
@@ -243,20 +244,12 @@ ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d
|
||||
m_vtDir = m_ptPos - m_ptP6 ;
|
||||
dLenDir = m_vtDir.Len() ;
|
||||
}
|
||||
// calcolo le direzioni su cui giacciono i due lati dell'angolo
|
||||
Vector3d vtLine1 = m_ptP1 - m_ptP6 ;
|
||||
Vector3d vtLine2 = m_ptP2 - m_ptP6 ;
|
||||
double dLen1 = vtLine1.Len() ;
|
||||
double dLen2 = vtLine2.Len() ;
|
||||
if ( ! vtLine1.Normalize() || ! vtLine2.Normalize())
|
||||
return false ;
|
||||
// segnalo se i punti che definiscono i lati sono più lontani dal centro di ptPos
|
||||
bool bPt1Close = ( dLenDir < dLen1 ? true : false) ;
|
||||
bool bPt2Close = ( dLenDir < dLen2 ? true : false) ;
|
||||
m_ptP5 = m_ptP1 + ( dLenDir - dLen1) * vtLine1 ;
|
||||
Point3d ptP5_bis = m_ptP2 + ( dLenDir - dLen2) * vtLine2 ;
|
||||
m_ptP3 = m_ptP5 + ( bPt1Close ? - vtLine1 : vtLine1) * m_dExtLineLen ;
|
||||
m_ptP4 = ptP5_bis + ( bPt2Close ? - vtLine2 : vtLine2) * m_dExtLineLen ;
|
||||
// assegno gli altri punti notevoli della quotatura
|
||||
m_ptP1 = m_ptP6 ;
|
||||
m_ptP2 = m_ptP6 ;
|
||||
m_ptP5 = m_ptP6 + vtLine1 * dLenDir ;
|
||||
m_ptP3 = m_ptP6 + vtLine1 * ( dLenDir + m_dExtLineLen) ;
|
||||
m_ptP4 = m_ptP6 + vtLine2 * ( dLenDir + m_dExtLineLen) ;
|
||||
|
||||
// assegnazione del testo
|
||||
m_sText = sText ;
|
||||
@@ -266,7 +259,99 @@ ExtDimension::SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d
|
||||
m_bToCalc = true ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ExtDimension::SetAngularEx( const Point3d& ptV1, const Point3d& ptP1,
|
||||
const Point3d& ptV2, const Point3d& ptP2, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const string& sText)
|
||||
{
|
||||
// dichiaro quota non ancora determinata
|
||||
m_nType = DT_NONE ;
|
||||
// verifico la definizione del versore normale
|
||||
m_vtN = vtN ;
|
||||
if ( ! m_vtN.Normalize())
|
||||
return false ;
|
||||
// calcolo l'intersezione tra le due linee
|
||||
CurveLine Line1 ;
|
||||
if ( ! Line1.Set( ptV1, ptP1) || ! Line1.SetExtrusion( m_vtN))
|
||||
return false ;
|
||||
CurveLine Line2 ;
|
||||
if ( ! Line2.Set( ptV2, ptP2) || ! Line2.SetExtrusion( m_vtN))
|
||||
return false ;
|
||||
IntersLineLine IntLL( Line1, Line2, false) ;
|
||||
IntCrvCrvInfo Info ;
|
||||
if ( ! IntLL.GetIntCrvCrvInfo( Info) || Info.bOverlap)
|
||||
return false ;
|
||||
Point3d ptV = Media( Info.IciA[0].ptI, Info.IciB[0].ptI) ;
|
||||
// porto i punti e le direzioni nel piano definito da V1 e N
|
||||
m_ptP6 = ptV ;
|
||||
m_ptPos = ptPos - ( ptPos - m_ptP6) * m_vtN * m_vtN ;
|
||||
m_vtDir = m_ptPos - m_ptP6 ;
|
||||
double dLenDir = m_vtDir.Len() ;
|
||||
Vector3d vtLine1 = OrthoCompo( ptP1 - m_ptP6, m_vtN) ;
|
||||
Vector3d vtLine2 = OrthoCompo( ptP2 - m_ptP6, m_vtN) ;
|
||||
// verifico che i punti di misura non siano coincidenti
|
||||
if ( ! vtLine1.Normalize() || ! vtLine2.Normalize() || dLenDir < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// controllo se è testo o se è la misura
|
||||
double dFactor ;
|
||||
if ( m_sCalcText.find( IS_MEASURE) != string::npos) {
|
||||
m_sCalcText = "300.00" ;
|
||||
double dHalfDist = GetTextHalfDist( m_ptPos) ;
|
||||
dFactor = 2.5 * dHalfDist ;
|
||||
m_sCalcText = "" ;
|
||||
}
|
||||
else {
|
||||
double dHalfDist = GetTextHalfDist( m_ptPos) ;
|
||||
dFactor = 2.5 * dHalfDist ;
|
||||
}
|
||||
// allungo m_vtDir se è troppo vicino al centro
|
||||
if ( m_vtDir.Len() < dFactor) {
|
||||
Vector3d vtDir_n = m_vtDir ;
|
||||
if ( ! vtDir_n.Normalize())
|
||||
return false ;
|
||||
m_ptPos = m_ptP6 + dFactor * vtDir_n ;
|
||||
// ricalcolo m_vtDir
|
||||
m_vtDir = m_ptPos - m_ptP6 ;
|
||||
dLenDir = m_vtDir.Len() ;
|
||||
}
|
||||
// assegno gli altri punti notevoli della quotatura
|
||||
// se i ptV concidono con l'intersezione tra le linee le sposto leggermente verso l'altro punto di quel lato
|
||||
Point3d ptV1New = ptV1 ;
|
||||
Point3d ptV2New = ptV2 ;
|
||||
if ( AreSamePointApprox( ptV1, ptV)) {
|
||||
Vector3d vtDir1 ; Line1.GetStartDir( vtDir1) ;
|
||||
double dLen ; Line1.GetLength( dLen) ;
|
||||
dLen = max( min( 1., dLen/ 10), 0.01) ;
|
||||
ptV1New = ptV1 + vtDir1 * dLen ;
|
||||
}
|
||||
if ( AreSamePointApprox( ptV2, ptV)) {
|
||||
Vector3d vtDir2 ; Line2.GetStartDir( vtDir2) ;
|
||||
double dLen ; Line2.GetLength( dLen) ;
|
||||
dLen = max( min( 1., dLen/ 10), 0.01) ;
|
||||
ptV2New = ptV2 + vtDir2 * dLen ;
|
||||
}
|
||||
m_ptP1 = ptV1New - ( ptV1New - m_ptP6) * m_vtN * m_vtN ;
|
||||
m_ptP2 = ptV2New - ( ptV2New - m_ptP6) * m_vtN * m_vtN ;
|
||||
m_ptP5 = m_ptP6 + vtLine1 * dLenDir ;
|
||||
double dLen1 = Dist( m_ptP6, m_ptP1) ;
|
||||
m_ptP3 = m_ptP6 + vtLine1 * ( dLenDir + m_dExtLineLen * ( dLen1 < dLenDir ? 1 : -1)) ;
|
||||
double dLen2 = Dist( m_ptP6, m_ptP2) ;
|
||||
m_ptP4 = m_ptP6 + vtLine2 * ( dLenDir + m_dExtLineLen * ( dLen2 < dLenDir ? 1 : -1)) ;
|
||||
|
||||
// assegnazione del testo
|
||||
m_sText = sText ;
|
||||
// assegno il tipo
|
||||
m_nType = DT_ANGULAR ;
|
||||
// imposto da calcolare
|
||||
m_bToCalc = true ;
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1012,6 +1097,7 @@ ExtDimension::Update( void) const
|
||||
if ( ! GetTextMyBBox( b3Text) && ! b3Text.IsEmpty())
|
||||
return false ;
|
||||
double dHeight = b3Text.GetMax().y - b3Text.GetMin().y ;
|
||||
double dLength = b3Text.GetMax().x - b3Text.GetMin().x ;
|
||||
Vector3d vtPerpDir = m_ptPos - m_ptP6 ;
|
||||
if ( ! vtPerpDir.Normalize())
|
||||
return false ;
|
||||
@@ -1020,11 +1106,11 @@ ExtDimension::Update( void) const
|
||||
if ( ! frRef.Set( m_ptP6, m_vtN))
|
||||
return false ;
|
||||
double dAngDeg = 0 ;
|
||||
if ( ! m_vtDir.GetAngle( frRef.VersX(), dAngDeg) || ! vtPerpDir.Rotate( m_vtN, ( dAngDeg < 90 ? 90 : -90)))
|
||||
if ( ! m_vtDir.GetAngle( frRef.VersX(), dAngDeg) || ! vtPerpDir.Rotate( m_vtN, ( dAngDeg < 90 ? 90 : -90)))
|
||||
return false ;
|
||||
m_ptCalcPos = m_ptCalcPos + 0.6 * dHeight * vtPerpDir ;
|
||||
// semidistanza di interruzione
|
||||
double dHalfDist = GetTextHalfDist( m_ptCalcPos) ;
|
||||
double dHalfDist = GetTextHalfDist( m_ptCalcPos, false) ;
|
||||
// lunghezza della linea di misura
|
||||
double dLen = Dist( m_ptP1, m_ptP2) ;
|
||||
// determino come orientare le frecce e dove mettere il testo
|
||||
@@ -1049,7 +1135,16 @@ ExtDimension::Update( void) const
|
||||
Vector3d vtRad = m_ptPos - m_ptP5 ;
|
||||
if ( ! vtRad.Normalize())
|
||||
return false ;
|
||||
m_ptCalcPos = m_ptPos + vtRad * ( dHalfDist + 2 * m_dArrowLen) ;
|
||||
m_ptCalcPos = m_ptPos + vtRad * ( 2 * m_dArrowLen + m_dTextDist) ;
|
||||
const double COMP_LIM = 0.1 ; // circa 5.7deg
|
||||
if ( vtRad.x > COMP_LIM)
|
||||
m_ptCalcPos += dLength / 2 * X_AX ;
|
||||
else if ( vtRad.x < -COMP_LIM)
|
||||
m_ptCalcPos -= dLength / 2 * X_AX ;
|
||||
if ( vtRad.y > COMP_LIM)
|
||||
m_ptCalcPos += dHeight / 2 * Y_AX ;
|
||||
else if ( vtRad.y < -COMP_LIM)
|
||||
m_ptCalcPos -= dHeight / 2 * Y_AX ;
|
||||
}
|
||||
// dichiaro ricalcolo eseguito
|
||||
m_bToCalc = false ;
|
||||
@@ -1058,8 +1153,8 @@ ExtDimension::Update( void) const
|
||||
case DT_ANGULAR : {
|
||||
// angolo
|
||||
double dAngDeg, dAngDeg1, dAngDeg2 = 0 ;
|
||||
Vector3d vtLine1 = m_ptP1 - m_ptP6 ;
|
||||
Vector3d vtLine2 = m_ptP2 - m_ptP6 ;
|
||||
Vector3d vtLine1 = m_ptP3 - m_ptP6 ;
|
||||
Vector3d vtLine2 = m_ptP4 - m_ptP6 ;
|
||||
Vector3d vtLine3 = m_ptPos - m_ptP6 ;
|
||||
// calcolo gli angoli tra m_ptPos e i due punti che identificano i lati dell'angolo
|
||||
// per capire se sto calcolando l'angolo interno o esterno
|
||||
@@ -1074,10 +1169,9 @@ ExtDimension::Update( void) const
|
||||
ReplaceString( m_sCalcText, IS_MEASURE, sAngDeg + "°") ;
|
||||
}
|
||||
// calcolo ptP5_bis
|
||||
double dLen2 = vtLine2.Len() ;
|
||||
if ( ! vtLine2.Normalize())
|
||||
return false ;
|
||||
Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ;
|
||||
Point3d ptP5_bis = m_ptP6 + m_vtDir.Len() * vtLine2 ;
|
||||
// calcolo l'arco su cui metterò la misura
|
||||
PtrOwner<CurveArc> pCrvPos( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCrvPos) || ! pCrvPos->Set3P( ptP5_bis, m_ptPos, m_ptP5, false))
|
||||
@@ -1288,15 +1382,12 @@ ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST&
|
||||
if ( IsNull( pCrvPos))
|
||||
return false ;
|
||||
// calcolo ptP5_bis
|
||||
Vector3d vtLine2 = m_ptP2 - m_ptP6 ;
|
||||
double dLen2 = vtLine2.Len() ;
|
||||
Vector3d vtLine2 = m_ptP4 - m_ptP6 ;
|
||||
if ( ! vtLine2.Normalize())
|
||||
return false ;
|
||||
Point3d ptP5_bis = m_ptP2 + ( m_vtDir.Len() - dLen2) * vtLine2 ;
|
||||
Point3d ptP5_bis = m_ptP6 + m_vtDir.Len() * vtLine2 ;
|
||||
// approssimerò l'arco con una polyline
|
||||
PolyLine plApprox ;
|
||||
double dLinTol = 0.01 ;
|
||||
double dAngTolDeg = 0.01 ;
|
||||
// se non ho testo
|
||||
if ( IsEmptyOrSpaces( m_sCalcText) || ! m_bCalcTextOn) {
|
||||
if ( ! pCrvPos->SetC2PN( m_ptP6, ptP5_bis, m_ptP5, m_vtN) || ! pCrvPos->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, plApprox))
|
||||
@@ -1337,7 +1428,7 @@ ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST&
|
||||
dFactor = 0 ;
|
||||
}
|
||||
lstPL.emplace_back() ;
|
||||
Vector3d vtLine1 = m_ptP1 - m_ptP6 ;
|
||||
Vector3d vtLine1 = m_ptP3 - m_ptP6 ;
|
||||
if ( ! vtLine1.Normalize())
|
||||
return false ;
|
||||
GetArrowHead( m_ptP5, ( m_bCalcArrowIn ? vtEndDir : - vtEndDir) + vtLine1 * dFactor, lstPL.back()) ;
|
||||
@@ -1356,23 +1447,25 @@ ExtDimension::ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST&
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
ExtDimension::GetTextHalfDist( const Point3d& ptText) const
|
||||
ExtDimension::GetTextHalfDist( const Point3d& ptText, bool bUseRot) const
|
||||
{
|
||||
// semi distanza di interruzione
|
||||
double dHalfDist = m_dTextHeight / 2 + m_dTextDist ;
|
||||
// recupero il box di ingombro del testo
|
||||
BBox3d b3Text ;
|
||||
Vector3d vtDir = m_vtDir ;
|
||||
if ( m_nType == DT_ANGULAR)
|
||||
vtDir.Normalize() ;
|
||||
if ( GetTextMyBBox( ptText, b3Text) && ! b3Text.IsEmpty()) {
|
||||
double dHalfL = ( b3Text.GetMax().x - b3Text.GetMin().x) / 2 ;
|
||||
double dHalfH = ( b3Text.GetMax().y - b3Text.GetMin().y) / 2 ;
|
||||
dHalfDist = sqrt( dHalfL * dHalfL + dHalfH * dHalfH) ;
|
||||
if ( abs( vtDir.x) > EPS_ZERO)
|
||||
dHalfDist = min( dHalfDist, dHalfL / abs( vtDir.x)) ;
|
||||
if ( abs( vtDir.y) > EPS_ZERO)
|
||||
dHalfDist = min( dHalfDist, dHalfH / abs( vtDir.y)) ;
|
||||
if ( bUseRot) {
|
||||
Vector3d vtDir = m_vtDir ;
|
||||
vtDir.Normalize() ;
|
||||
double dCoeff = ( dHalfH > 1 ? dHalfL / dHalfH : 0) ;
|
||||
if ( abs( vtDir.x) > dCoeff * abs( vtDir.y))
|
||||
dHalfDist = min( dHalfDist, dHalfL / abs( vtDir.x)) ;
|
||||
else
|
||||
dHalfDist = min( dHalfDist, dHalfH / abs( vtDir.y)) ;
|
||||
}
|
||||
dHalfDist += m_dTextDist ;
|
||||
}
|
||||
return dHalfDist ;
|
||||
|
||||
+10
-4
@@ -28,7 +28,7 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
ExtDimension* Clone( void) const override ;
|
||||
GeoObjType GetType( void) const override ;
|
||||
bool IsValid( void) const override
|
||||
{ return ( m_nType != DT_NONE) ; }
|
||||
{ return ( m_nType != DT_NONE) ; }
|
||||
const std::string& GetTitle( void) const override ;
|
||||
bool Dump( std::string& sOut, bool bMM = true, const char* szNewLine = "\n") const override ;
|
||||
bool GetLocalBBox( BBox3d& b3Loc, int nFlag = BBF_STANDARD) const override ;
|
||||
@@ -71,8 +71,11 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
bool SetDiametral( const Point3d& ptCen, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
bool SetAngular( const Point3d& ptP1, const Point3d& ptV, const Point3d& ptP2, const Point3d& ptPos,
|
||||
bool SetAngular( const Point3d& ptV, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
bool SetAngularEx( const Point3d& ptV1, const Point3d& ptP1,
|
||||
const Point3d& ptV2, const Point3d& ptP2, const Point3d& ptPos,
|
||||
const Vector3d& vtN, const std::string& sText) override ;
|
||||
const Vector3d& GetNormVersor( void) const override
|
||||
{ return m_vtN ; }
|
||||
const Vector3d& GetDirVersor( void) const override
|
||||
@@ -105,12 +108,16 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
{ return m_dTextHeight ; }
|
||||
bool GetMidPoint( Point3d& ptMid) const override ;
|
||||
bool GetCenterPoint( Point3d& ptCen) const override ;
|
||||
const std::string& GetSubType( void) const override ;
|
||||
bool ApproxWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
ExtDimension( void) ;
|
||||
@@ -124,9 +131,8 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
|
||||
private :
|
||||
bool CopyFrom( const ExtDimension& gpSrc) ;
|
||||
const std::string& GetSubType( void) const ;
|
||||
bool Update( void) const ;
|
||||
double GetTextHalfDist( const Point3d& ptText) const ;
|
||||
double GetTextHalfDist( const Point3d& ptText, bool bUseRot = true) const ;
|
||||
bool GetArrowHead( const Point3d& ptTip, const Vector3d& vtDir, PolyLine& PL) const ;
|
||||
bool SetCurrFont( FontManager& fntMgr) const ;
|
||||
bool ApproxTextWithLines( double dLinTol, double dAngTolDeg, POLYLINELIST& lstPL) const ;
|
||||
|
||||
@@ -113,7 +113,10 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
ExtText( void) ;
|
||||
|
||||
+49
-13
@@ -18,6 +18,7 @@
|
||||
#include "/EgtDev/Include/EGkFilletChamfer.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EgkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -40,13 +41,21 @@ CalcForFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1))
|
||||
return false ;
|
||||
double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1
|
||||
// calcolo gli offset nel piano locale e dal lato opportuno di una copia della curva 1
|
||||
PtrOwner<ICurve> pCopy1( cCrv1.Clone()) ;
|
||||
if ( IsNull( pCopy1))
|
||||
return false ;
|
||||
pCopy1->ToLoc( frIntr) ;
|
||||
pCopy1->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET))
|
||||
OffsetCurve OffsCrv1 ;
|
||||
OffsCrv1.Make( pCopy1, dOffs1, ICurve::OFF_FILLET) ;
|
||||
ICURVEPOVECTOR vOffs1 ;
|
||||
ICurve* pCrv = OffsCrv1.GetLongerCurve() ;
|
||||
while ( pCrv != nullptr) {
|
||||
vOffs1.emplace_back( pCrv) ;
|
||||
pCrv = OffsCrv1.GetLongerCurve() ;
|
||||
}
|
||||
if ( vOffs1.empty())
|
||||
return false ;
|
||||
|
||||
// determino il lato di offset della curva 2
|
||||
@@ -54,23 +63,50 @@ CalcForFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2))
|
||||
return false ;
|
||||
double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ;
|
||||
// calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2
|
||||
// calcolo gli offset nel piano locale e dal lato opportuno di una copia della curva 2
|
||||
PtrOwner<ICurve> pCopy2( cCrv2.Clone()) ;
|
||||
if ( IsNull( pCopy2))
|
||||
return false ;
|
||||
pCopy2->ToLoc( frIntr) ;
|
||||
pCopy2->SetExtrusion( Z_AX) ;
|
||||
if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET))
|
||||
OffsetCurve OffsCrv2 ;
|
||||
OffsCrv2.Make( pCopy2, dOffs2, ICurve::OFF_FILLET) ;
|
||||
ICURVEPOVECTOR vOffs2 ;
|
||||
pCrv = OffsCrv2.GetLongerCurve() ;
|
||||
while ( pCrv != nullptr) {
|
||||
vOffs2.emplace_back( pCrv) ;
|
||||
pCrv = OffsCrv2.GetLongerCurve() ;
|
||||
}
|
||||
if ( vOffs2.empty())
|
||||
return false ;
|
||||
|
||||
// calcolo l'intersezione tra le due curve
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
// calcolo le intersezioni tra tutte le curve di offset e seleziono quella più vicina ai punti passati
|
||||
Point3d ptInt1 = P_INVALID, ptInt2 = P_INVALID ;
|
||||
Point3d ptNearI = Media( ptNear1, ptNear2) ;
|
||||
ptNearI.ToLoc( frIntr) ;
|
||||
IntersCurveCurve intCC( *pCopy1, *pCopy2) ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptNearI, ptInt1) ||
|
||||
! intCC.GetIntersPointNearTo( 1, ptNearI, ptInt2))
|
||||
return false ;
|
||||
double dMinDist = INFINITO ;
|
||||
for ( int i = 0 ; i < int( vOffs1.size()) ; i++) {
|
||||
for ( int j = 0 ; j < int( vOffs2.size()) ; j ++) {
|
||||
IntersCurveCurve intCC( *vOffs1[i], *vOffs2[j]) ;
|
||||
if ( intCC.GetIntersCount() == 0)
|
||||
continue ;
|
||||
Point3d ptInt1Curr, ptInt2Curr ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptNearI, ptInt1Curr) ||
|
||||
! intCC.GetIntersPointNearTo( 1, ptNearI, ptInt2Curr))
|
||||
return false ;
|
||||
Point3d ptCenCurr = Media( ptInt1Curr, ptInt2Curr) ;
|
||||
double dDist = Dist( ptNearI, ptCenCurr) ;
|
||||
if ( dDist < dMinDist - EPS_SMALL) {
|
||||
dMinDist = dDist ;
|
||||
ptInt1 = ptInt1Curr ;
|
||||
ptInt2 = ptInt2Curr ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non sono state trovate intersezioni esco
|
||||
if ( ! ptInt1.IsValid() || ! ptInt2.IsValid())
|
||||
return false ;
|
||||
|
||||
ptInt1.ToGlob( frIntr) ;
|
||||
ptInt2.ToGlob( frIntr) ;
|
||||
ptCen = Media( ptInt1, ptInt2) ;
|
||||
@@ -105,7 +141,7 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
const ICurve& cCrv2, const Point3d& ptNear2,
|
||||
const Vector3d& vtNorm, double dRadius, double& dPar1, double& dPar2)
|
||||
{
|
||||
// verifico validità parametri ricevuti
|
||||
// verifico validità parametri ricevuti
|
||||
if ( &cCrv1 == nullptr || &ptNear1 == nullptr ||
|
||||
&cCrv2 == nullptr || &ptNear2 == nullptr ||
|
||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||
@@ -119,7 +155,7 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
ptCen, ptTg1, ptTg2, nSide1, nSide2, dSinA, dTgPar1, dTgPar2))
|
||||
return nullptr ;
|
||||
|
||||
// se tangenti parallele al contatto con fillet, ricalcolo con raggio più piccolo
|
||||
// se tangenti parallele al contatto con fillet, ricalcolo con raggio più piccolo
|
||||
bool bParallel = ( abs( dSinA) < EPS_SMALL) ;
|
||||
if ( bParallel) {
|
||||
Point3d ptQQQ, ptQQ1, ptQQ2 ;
|
||||
@@ -165,7 +201,7 @@ CreateChamfer( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
const ICurve& cCrv2, const Point3d& ptNear2,
|
||||
const Vector3d& vtNorm, double dDist, double& dPar1, double& dPar2)
|
||||
{
|
||||
// verifico validità parametri ricevuti
|
||||
// verifico validità parametri ricevuti
|
||||
if ( &cCrv1 == nullptr || &ptNear1 == nullptr ||
|
||||
&cCrv2 == nullptr || &ptNear2 == nullptr ||
|
||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||
|
||||
+17
@@ -37,6 +37,23 @@ Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX,
|
||||
! m_vtVersZ.Normalize())
|
||||
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
|
||||
if ( ! Verify())
|
||||
return false ;
|
||||
|
||||
+10
-2
@@ -101,6 +101,10 @@ GdbGeo::Save( int nBaseId, NgeWriter& ngeOut, INTUNORDSET* pSavedIds) const
|
||||
if ( pGObjRW == nullptr)
|
||||
return false ;
|
||||
|
||||
// eventuali modifiche prima del salvataggio
|
||||
if ( ! pGObjRW->PreSave( * const_cast<GdbGeo*>( this)))
|
||||
return false ;
|
||||
|
||||
// tipo entità e identificativi
|
||||
if ( ! ngeOut.WriteKey( pGObjRW->GetNgeId()))
|
||||
return false ;
|
||||
@@ -124,7 +128,11 @@ GdbGeo::Save( int nBaseId, NgeWriter& ngeOut, INTUNORDSET* pSavedIds) const
|
||||
// parametri geometrici
|
||||
if ( ! ngeOut.WriteKey( NGE_G))
|
||||
return false ;
|
||||
return pGObjRW->Save( ngeOut) ;
|
||||
if ( ! pGObjRW->Save( ngeOut))
|
||||
return false ;
|
||||
|
||||
// eventuali ripristini dopo il salvataggio
|
||||
return pGObjRW->PostSave( * const_cast<GdbGeo*>( this)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -181,7 +189,7 @@ GdbGeo::Load( int nNgeId, NgeReader& ngeIn, int nBaseGdbId, int& nParentId)
|
||||
|
||||
// parametri geometrici
|
||||
IGeoObjRW* pGObjRW = dynamic_cast<IGeoObjRW*>( m_pGeoObj) ;
|
||||
return ( pGObjRW != nullptr && pGObjRW->Load( ngeIn)) ;
|
||||
return ( pGObjRW != nullptr && pGObjRW->Load( ngeIn) && pGObjRW->PostLoad( *this)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+2
-2
@@ -1254,13 +1254,13 @@ GdbIterator::GetCalcStatus( int& nStat) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::SetMark( void)
|
||||
GdbIterator::SetMark( int nMark)
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// imposto la marcatura
|
||||
return m_pCurrObj->SetMark() ;
|
||||
return m_pCurrObj->SetMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ class GdbIterator : public IGdbIterator
|
||||
bool RevertStatus( void) override ;
|
||||
bool GetStatus( int& nStat) const override ;
|
||||
bool GetCalcStatus( int& nStat) const override ;
|
||||
bool SetMark( void) override ;
|
||||
bool SetMark( int nMark = GDB_MK_ON) override ;
|
||||
bool ResetMark( void) override ;
|
||||
bool GetMark( int& nMark) const override ;
|
||||
bool GetCalcMark( int& nMark) const override ;
|
||||
|
||||
+4
-4
@@ -612,14 +612,14 @@ GdbObj::GetCalcStatus( int& nStat, int nLev) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::SetMark( void)
|
||||
GdbObj::SetMark( int nMark)
|
||||
{
|
||||
// verifico esistenza (con eventuale creazione) degli attributi
|
||||
if ( GetSafeAttribs() == nullptr)
|
||||
return false ;
|
||||
|
||||
// assegno la marcatura
|
||||
m_pAttribs->SetMark() ;
|
||||
m_pAttribs->SetMark( nMark) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -659,8 +659,8 @@ GdbObj::GetCalcMark( int& nMark) const
|
||||
nObjMark = m_pAttribs->GetMark() ;
|
||||
|
||||
// se la marcatura è ON, non ho bisogno di sapere altro
|
||||
if ( nObjMark == GDB_MK_ON) {
|
||||
nMark = GDB_MK_ON ;
|
||||
if ( nObjMark == GDB_MK_ON || nObjMark == GDB_MK_ON_2) {
|
||||
nMark = nObjMark ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class GdbObj
|
||||
bool IsSelected( void) const ;
|
||||
bool GetStatus( int& nStat) const ;
|
||||
bool GetCalcStatus( int& nStat, int nLev = 0) const ;
|
||||
bool SetMark( void) ;
|
||||
bool SetMark( int nMark) ;
|
||||
bool ResetMark( void) ;
|
||||
bool GetMark( int& nMark) const ;
|
||||
bool GetCalcMark( int& nMark) const ;
|
||||
|
||||
@@ -83,7 +83,10 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
GeoFrame3d( void) ;
|
||||
|
||||
+7
-3
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
// EgalTech 2014-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : GeoObjRW.h Data : 14.03.14 Versione : 1.5d5
|
||||
// File : GeoObjRW.h Data : 08.03.24 Versione : 2.6c2
|
||||
// Contenuto : Dichiarazione della interfaccia IGeoObjRW.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 20.11.13 DS Creazione modulo.
|
||||
//
|
||||
// 08.03.24 DS Aggiunte PreSave, PostSave, PreLoad e PostLoad.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
class NgeWriter ;
|
||||
class NgeReader ;
|
||||
class GdbGeo ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class __declspec( novtable) IGeoObjRW
|
||||
@@ -22,5 +23,8 @@ class __declspec( novtable) IGeoObjRW
|
||||
public :
|
||||
virtual int GetNgeId( void) const = 0 ;
|
||||
virtual bool Save( NgeWriter& ngeOut) const = 0 ;
|
||||
virtual bool PreSave( GdbGeo& Wrapper) const = 0 ;
|
||||
virtual bool PostSave( GdbGeo& Wrapper) const = 0 ;
|
||||
virtual bool Load( NgeReader& ngeIn) = 0 ;
|
||||
virtual bool PostLoad( GdbGeo& Wrapper) = 0 ;
|
||||
} ;
|
||||
|
||||
@@ -77,7 +77,10 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
GeoPoint3d( void) ;
|
||||
|
||||
@@ -91,7 +91,10 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
bool Save( NgeWriter& ngeOut) const override ;
|
||||
bool PreSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool PostSave( GdbGeo& Wrapper) const override { return true ; }
|
||||
bool Load( NgeReader& ngeIn) override ;
|
||||
bool PostLoad( GdbGeo& Wrapper) override { return true ; }
|
||||
|
||||
public :
|
||||
GeoVector3d( void) ;
|
||||
|
||||
+2
-2
@@ -2310,7 +2310,7 @@ GeomDB::GetCalcStatus( int nId, int& nStat) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::SetMark( int nId)
|
||||
GeomDB::SetMark( int nId, int nMark)
|
||||
{
|
||||
// recupero l'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
@@ -2318,7 +2318,7 @@ GeomDB::SetMark( int nId)
|
||||
return false ;
|
||||
|
||||
// imposto la marcatura
|
||||
return pGdbObj->SetMark() ;
|
||||
return pGdbObj->SetMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -136,7 +136,7 @@ class GeomDB : public IGeomDB
|
||||
bool RevertStatus( int nId) override ;
|
||||
bool GetStatus( int nId, int& nStat) const override ;
|
||||
bool GetCalcStatus( int nId, int& nStat) const override ;
|
||||
bool SetMark( int nId) override ;
|
||||
bool SetMark( int nId, int nMark = GDB_MK_ON) override ;
|
||||
bool ResetMark( int nId) override ;
|
||||
bool GetMark( int nId, int& nMark) const override ;
|
||||
bool GetCalcMark( int nId, int& nMark) const override ;
|
||||
|
||||
+11
-11
@@ -116,7 +116,7 @@ HashGrid1d::~HashGrid1d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -396,8 +396,10 @@ HashGrid1d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_CellCount *= 2 ;
|
||||
@@ -641,17 +643,15 @@ HashGrids1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
void
|
||||
HashGrids1d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -125,7 +125,7 @@ HashGrid2d::~HashGrid2d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -445,8 +445,10 @@ HashGrid2d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_xCellCount *= 2 ;
|
||||
@@ -695,17 +697,15 @@ HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
void
|
||||
HashGrids2d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -132,7 +132,7 @@ HashGrid3d::~HashGrid3d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -486,8 +486,10 @@ HashGrid3d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_xCellCount *= 2 ;
|
||||
@@ -739,17 +741,15 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
void
|
||||
HashGrids3d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+8
-5
@@ -17,6 +17,9 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const double EPS_INTER_ARC = 0.1 * EPS_SMALL ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
{
|
||||
@@ -60,15 +63,15 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
vtDir /= dDist ;
|
||||
|
||||
// cerchi esterni -> nessuna intersezione
|
||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_SMALL)
|
||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_INTER_ARC)
|
||||
return ;
|
||||
|
||||
// cerchi interni -> nessuna intersezione
|
||||
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_SMALL)
|
||||
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_INTER_ARC)
|
||||
return ;
|
||||
|
||||
// cerchi coincidenti -> sovrapposizioni e/o intersezioni agli estremi
|
||||
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_SMALL) {
|
||||
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_INTER_ARC) {
|
||||
// coefficiente da parametro dell'arco 1 a lunghezza
|
||||
double dU2L = abs( m_Arc1.GetAngCenter()) * DEGTORAD * m_Arc1.GetRadius() ;
|
||||
// determino se sono equiversi o controversi
|
||||
@@ -236,7 +239,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
double dSqH = m_Arc1.GetRadius() * m_Arc1.GetRadius() - dA * dA ;
|
||||
|
||||
// cerchi tangenti esterni -> una intersezione
|
||||
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
||||
// tolleranza tangenziale sull'intersezione
|
||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||
// calcolo il punto di intersezione
|
||||
@@ -358,7 +361,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
}
|
||||
|
||||
// cerchi tangenti interni -> una intersezione
|
||||
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
||||
// tolleranza tangenziale sull'intersezione
|
||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||
// determino quale dei due contiene l'altro
|
||||
|
||||
@@ -78,6 +78,8 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
LineCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
@@ -91,6 +93,8 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
ArcCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
@@ -104,8 +108,12 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
CrvCompoCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// per curve approssimate, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv[0] != m_pCurve[0]), ( pCalcCrv[1] != m_pCurve[1])) ;
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersCurveSurfTm.cpp Data : 23.02.24 Versione : 2.6b4
|
||||
// Contenuto : Implementazione della intersezione curva/superficie trimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 23.02.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurveSurfTm.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
UpdateInfoIntersCurveSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen, double dUs, double dUe,
|
||||
int nT, const Triangle3d& Tria, ICSIVECTOR& vInfo)
|
||||
{
|
||||
Point3d ptInt, ptInt2 ;
|
||||
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, true) ;
|
||||
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
||||
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||
double dCosDN = vtDir * Tria.GetN() ;
|
||||
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
|
||||
}
|
||||
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
||||
double dU = dUs + ( ptInt - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||
double dU2 = dUs + ( ptInt2 - ptL) * vtDir / dLen * ( dUe - dUs) ;
|
||||
double dCosDN = vtDir * Tria.GetN() ;
|
||||
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
if ( vInfo.size() == 0)
|
||||
return ;
|
||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
[]( const IntCrvStmInfo& a, const IntCrvStmInfo& b)
|
||||
{ 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) ;
|
||||
return ( dUa < dUb) ; }) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di una curva con una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveSurfTm( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, ICSIVECTOR& vInfo)
|
||||
{
|
||||
// verifico i parametri ricevuti
|
||||
if ( & Curve == nullptr || &Stm == nullptr || &vInfo == nullptr)
|
||||
return false ;
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
vInfo.clear() ;
|
||||
|
||||
// approssimo la curva con una spezzata
|
||||
PolyLine PL ;
|
||||
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return false ;
|
||||
|
||||
// per ogni segmento dell'approssimante cerco l'intersezione con la superficie
|
||||
double dParS, dParE ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
bool bFound = PL.GetFirstULine( &dParS, &ptStart, &dParE, &ptEnd) ;
|
||||
while ( bFound) {
|
||||
Vector3d vtDir = ptEnd - ptStart ;
|
||||
double dLen = vtDir.Len() ;
|
||||
if ( dLen > EPS_SMALL) {
|
||||
vtDir /= dLen ;
|
||||
// cerco i triangoli intersecati dal segmento
|
||||
const double BOX_STEP = 10 ;
|
||||
int nStep = int( ceil( dLen / BOX_STEP)) ;
|
||||
Vector3d vtStep = dLen / nStep * vtDir ;
|
||||
INTVECTOR vPrevT ;
|
||||
for ( int i = 0 ; i < nStep ; ++ i) {
|
||||
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
|
||||
INTVECTOR vT ;
|
||||
if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) {
|
||||
for ( auto nT : vT) {
|
||||
// se triangolo non ancora intersecato
|
||||
if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) {
|
||||
vPrevT.emplace_back( nT) ;
|
||||
Triangle3d Tria ;
|
||||
Stm.GetTriangle( nT, Tria) ;
|
||||
// aggiorno info con intersezione
|
||||
UpdateInfoIntersCurveSurfTm( ptStart, vtDir, dLen, dParS, dParE, nT, Tria, vInfo) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// passo al segmento successivo
|
||||
bFound = PL.GetNextULine( &dParS, &ptStart, &dParE, &ptEnd) ;
|
||||
}
|
||||
|
||||
// ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea
|
||||
OrderInfoIntersCurveSurfTm( vInfo) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveSurfTmExt( const ICurve& Curve, const ISurfTriMesh& Stm, double dLinTol, INTDBLVECTOR& vInters)
|
||||
{
|
||||
ICSIVECTOR vInfo ;
|
||||
vInters.clear() ;
|
||||
return ( IntersCurveSurfTm( Curve, Stm, dLinTol, vInfo) && FilterCurveSurfTmInters( Curve, vInfo, vInters)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
FilterCurveSurfTmInters( const ICurve& Curve, const ICSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
{
|
||||
// verifico i parametri ricevuti
|
||||
if ( & Curve == nullptr || &vInfo == nullptr || &vInters == nullptr)
|
||||
return false ;
|
||||
vInters.clear() ;
|
||||
// info sulla curva
|
||||
bool bClosedCrv = Curve.IsClosed() ;
|
||||
double dParSCrv, dParECrv ;
|
||||
Curve.GetDomain( dParSCrv, dParECrv) ;
|
||||
// ciclo sulle intersezioni
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = CSIT_NONE ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = CSIT_IN_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = CSIT_OUT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
vInters.emplace_back( CSIT_IN_ON, Info.dU) ;
|
||||
vInters.emplace_back( CSIT_ON_IN, Info.dU2) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
int nStart = ( bClosedCrv ? 0 : 1) ;
|
||||
for ( int j = nStart ; j < int( vInters.size()) ; ) {
|
||||
// intersezione precedente
|
||||
int i = ( j > 0 ? j - 1 : int( vInters.size()) - 1) ;
|
||||
// se hanno lo stesso parametro
|
||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_PARAM ||
|
||||
( bClosedCrv && abs( vInters[i].second - dParECrv) < EPS_PARAM && abs( vInters[j].second - dParSCrv) < EPS_PARAM)) {
|
||||
// flag per eseguita cancellazione
|
||||
bool bSomeErased = false ;
|
||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||
if ( ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_OUT_IN) ||
|
||||
( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_IN_OUT)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una entrante e l'altra uscente, cambio in touch da fuori ed elimino la seconda
|
||||
else if ( vInters[i].first == CSIT_OUT_IN && vInters[j].first == CSIT_IN_OUT) {
|
||||
vInters[i].first = CSIT_OUT_OUT ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una uscente e l'altra entrante, cambio in touch da dentro ed elimino la seconda
|
||||
else if ( vInters[i].first == CSIT_IN_OUT && vInters[j].first == CSIT_OUT_IN) {
|
||||
vInters[i].first = CSIT_IN_IN ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una touch da fuori o da dentro e l'altra entrante o uscente, elimino la prima
|
||||
else if ( ( vInters[i].first == CSIT_OUT_OUT || vInters[i].first == CSIT_IN_IN) &&
|
||||
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT)) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una entrante o uscente e l'altra touch da fuori o da dentro, elimino la seconda
|
||||
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT) &&
|
||||
( vInters[j].first == CSIT_OUT_OUT || vInters[j].first == CSIT_IN_IN)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == CSIT_OUT_IN || vInters[i].first == CSIT_IN_OUT || vInters[i].first == CSIT_NONE) &&
|
||||
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
|
||||
vInters[j].first = ( vInters[i].first == CSIT_IN_OUT ? CSIT_IN_ON : CSIT_OUT_ON) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
|
||||
( vInters[j].first == CSIT_OUT_IN || vInters[j].first == CSIT_IN_OUT || vInters[j].first == CSIT_NONE)) {
|
||||
vInters[i].first = ( vInters[j].first == CSIT_IN_OUT ? CSIT_ON_OUT : CSIT_ON_IN) ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( ( vInters[i].first == CSIT_ON_IN || vInters[i].first == CSIT_ON_OUT) &&
|
||||
( vInters[j].first == CSIT_IN_ON || vInters[j].first == CSIT_OUT_ON)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + ( j > 0 ? i : i - 1)) ;
|
||||
bSomeErased = true ;
|
||||
}
|
||||
if ( bSomeErased) {
|
||||
if ( j > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato assi devono essere nel medesimo sistema di riferimento.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
// In caso di intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
// Con intersezione viene restituito true e i parametri lunghezza in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCaps.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ IntersLineLine::IntersLineLine( const CurveLine& Line1, const CurveLine& Line2,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
IntersLineLine::IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine& Line2)
|
||||
IntersLineLine::IntersInfiniteLines( const CurveLine& Line1, const CurveLine& Line2)
|
||||
{
|
||||
// linea 1 : Start, End, Direzione e Lunghezza
|
||||
Point3d ptS1 = Line1.GetStart() ;
|
||||
@@ -118,7 +118,7 @@ IntersLineLine::IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine&
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
IntersLineLine::IntersFiniteLines( const ICurveLine& Line1, const ICurveLine& Line2)
|
||||
IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line2)
|
||||
{
|
||||
// verifico sovrapposizione box
|
||||
BBox3d boxL1 ;
|
||||
|
||||
+2
-2
@@ -38,8 +38,8 @@ class IntersLineLine
|
||||
|
||||
private :
|
||||
IntersLineLine( void) ;
|
||||
void IntersInfiniteLines( const ICurveLine& Line1, const ICurveLine& Line2) ;
|
||||
void IntersFiniteLines( const ICurveLine& Line1, const ICurveLine& Line2) ;
|
||||
void IntersInfiniteLines( const CurveLine& Line1, const CurveLine& Line2) ;
|
||||
void IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line2) ;
|
||||
|
||||
private :
|
||||
bool m_bOverlaps ;
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfBez.cpp Data : 06.02.24 Versione : 2.6b1
|
||||
// Contenuto : Implementazione della intersezione linea/superficie bezier.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 06.02.24 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool bFinite,
|
||||
const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz)
|
||||
{
|
||||
// la funzione raffina la posisione del punto ptSP, minimizzando la distanza dalla retta e restituisce il punto di intersezione ptIBz
|
||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
// usando un algoritmo di newton cerco di avvicinarmi il più possibile alla retta
|
||||
DistPointLine dpl( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||
double dDistNew = 0, dDistPre = 0 ;
|
||||
dpl.GetDist(dDistNew) ;
|
||||
|
||||
int nCount = 0 ;
|
||||
double dh = EPS_SMALL ;
|
||||
pSurfBz->GetPointD1D2( ptSP.x, ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
// metodo di newton in più dimensioni
|
||||
// vario sia il parametro U che il parametro V e verifico se la distanza dalla retta diminuisce per scostamenti positivi o negativi.
|
||||
while ( dDistNew > EPS_SMALL && nCount < 100) {
|
||||
dDistPre = dDistNew ;
|
||||
Point3d ptIBzNew1 ;
|
||||
pSurfBz->GetPointD1D2( ( ptSP.x + dh) / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ;
|
||||
DistPointLine dplNewU( ptIBzNew1, ptL, vtL, dLen, bFinite) ;
|
||||
dplNewU.GetDist( dDistNew) ;
|
||||
double dfdU = ( dDistNew - dDistPre) / dh ;
|
||||
Point3d ptIBzNew2 ;
|
||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ( ptSP.y + dh) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ;
|
||||
DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ;
|
||||
dplNewV.GetDist( dDistNew) ;
|
||||
double dfdV = ( dDistNew - dDistPre) / dh ;
|
||||
// mi avvicino cercando di annullare la distanza in un colpo solo
|
||||
double dr = - dDistPre / ( dfdU + dfdV) ;
|
||||
pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU) / SBZ_TREG_COEFF, ( ptSP.y + dr * dfdV) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||
dplNew.GetDist( dDistNew) ;
|
||||
++ nCount ;
|
||||
}
|
||||
|
||||
return ( nCount != 99) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
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)
|
||||
{
|
||||
if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) {
|
||||
double dU = ( ptIBz - ptL) * vtDir ;
|
||||
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
|
||||
}
|
||||
else if ( nILT == ILTT_SEGM || nILT == ILTT_SEGM_ON_EDGE) {
|
||||
double dU = ( ptIBz - ptL) * vtDir ;
|
||||
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
||||
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
if ( vInfo.size() == 0)
|
||||
return ;
|
||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
|
||||
{ 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) ;
|
||||
return ( dUa < dUb) ; }) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di una linea con una superficie di Bezier
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz,
|
||||
ILSBIVECTOR& vInfo, bool bFinite)
|
||||
{
|
||||
PtrOwner<ICurveLine> pCL( CreateCurveLine()) ;
|
||||
if ( bFinite)
|
||||
pCL->SetPVL(ptL, vtL, dLen) ;
|
||||
else
|
||||
pCL->SetPVL(ptL, vtL, 1e6) ;
|
||||
// verifico linea
|
||||
Vector3d vtDir = vtL ;
|
||||
if ( ! vtDir.Normalize( EPS_ZERO))
|
||||
return false ;
|
||||
// verifico superficie
|
||||
if ( pSurfBz == nullptr)
|
||||
return false ;
|
||||
// verifico parametro di ritorno
|
||||
if ( &vInfo == nullptr)
|
||||
return false ;
|
||||
vInfo.clear() ;
|
||||
|
||||
// trovo le intersezioni con la trimesh ausiliaria
|
||||
const ISurfTriMesh* pSurfTm = pSurfBz->GetAuxSurf() ;
|
||||
ILSIVECTOR vInfoTm ;
|
||||
if ( ! IntersLineSurfTm( ptL, vtL, dLen, *pSurfTm, vInfoTm, bFinite))
|
||||
return false ;
|
||||
// ricavo le intersezioni con la superficie di Bezier
|
||||
for ( IntLinStmInfo InfoTm : vInfoTm ) {
|
||||
// devo raffinare i parametri lungo la curva, l'angolo e i punti di intersezione
|
||||
Point3d ptI, ptI2 ;
|
||||
// devo trovare le intersezioni
|
||||
Point3d ptSP, ptSP2 ; // coordinate parametriche delle soluzioni
|
||||
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI, ptSP, InfoTm.nILTT) ;
|
||||
Point3d ptIBz, ptIBz2 ;
|
||||
if ( ! RefineIntersNewton( ptL, vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz)) {
|
||||
/////// posso provare anche a rilanciare newton con un punto di partenza diverso oppure con una direzione di avvicinamento diversa///////////////////////////////////
|
||||
// per restare nel triangolo mi sposto verso un vertice
|
||||
int nVert[3] ;
|
||||
pSurfTm->GetTriangle( InfoTm.nT, nVert) ;
|
||||
double dU0, dV0 ;
|
||||
pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ;
|
||||
ptSP = ptSP + Point3d(dU0, dV0, 0) ;
|
||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||
return false ;
|
||||
}
|
||||
Vector3d vtN ;
|
||||
pSurfBz->GetPointNrmD1D2(ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ;
|
||||
double dCos = vtN * vtL ;
|
||||
double dCos2 = 0 ;
|
||||
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
|
||||
if ( InfoTm.nILTT == ILTT_SEGM || InfoTm.nILTT == ILTT_SEGM_ON_EDGE ) {
|
||||
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
|
||||
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
||||
int nVert[3] ;
|
||||
pSurfTm->GetTriangle( InfoTm.nT, nVert) ;
|
||||
double dU0, dV0 ;
|
||||
pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ;
|
||||
ptSP = ptSP + Point3d(dU0, dV0, 0) ;
|
||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||
return false ;
|
||||
}
|
||||
pSurfBz->GetPointNrmD1D2( ptSP2.x / SBZ_TREG_COEFF, ptSP2.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ;
|
||||
dCos2 = vtN * vtL ;
|
||||
}
|
||||
UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ;
|
||||
}
|
||||
|
||||
OrderInfoIntersLineSurfBz( vInfo) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
{
|
||||
// tengo per buone la classificazione delle intersezioni fatte sulla trimesh
|
||||
// ciclo sulle intersezioni
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = LSBT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = LSBT_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = LSBT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
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_FIN, Info.dU2) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se hanno lo stesso parametro
|
||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||
if ( ( vInters[i].first == LSBT_IN && vInters[j].first == LSBT_IN) ||
|
||||
( vInters[i].first == LSBT_OUT && vInters[j].first == LSBT_OUT)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
else if ( ( vInters[i].first == LSBT_IN && vInters[j].first == LSBT_OUT) ||
|
||||
( vInters[i].first == LSBT_OUT && vInters[j].first == LSBT_IN)) {
|
||||
vInters[i].first = LSBT_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == LSBT_IN || vInters[i].first == LSBT_OUT || vInters[i].first == LSBT_TOUCH) && vInters[j].first == LSBT_TG_INI) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( vInters[i].first == LSBT_TG_FIN && ( vInters[j].first == LSBT_IN || vInters[j].first == LSBT_OUT || vInters[j].first == LSBT_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( i > 0 && vInters[i].first == LSBT_TG_FIN && vInters[j].first == LSBT_TG_INI) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
+72
-5
@@ -21,7 +21,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
static void
|
||||
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
||||
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dL
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
static void
|
||||
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
@@ -52,6 +52,8 @@ OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
||||
[]( 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 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) ; }) ;
|
||||
}
|
||||
|
||||
@@ -81,7 +83,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
// lo ingrandisco per non avere problemi con faccia piana su piani canonici
|
||||
b3Stm.Expand( 10 * EPS_SMALL) ;
|
||||
double dU1, dU2 ;
|
||||
if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
|
||||
if ( ! IntersLineBox( ptL, vtDir, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2))
|
||||
return true ;
|
||||
if ( bFinite) {
|
||||
dU1 = max( dU1, 0.) ;
|
||||
@@ -89,12 +91,12 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
if ( dU2 - dU1 < EPS_SMALL)
|
||||
return true ;
|
||||
}
|
||||
Point3d ptStart = ptL + dU1 * vtL ;
|
||||
Point3d ptStart = ptL + dU1 * vtDir ;
|
||||
double dLenEff = dU2 - dU1 ;
|
||||
// cerco i triangoli intersecati dalla linea
|
||||
const double BOX_STEP = 10 ;
|
||||
int nStep = int( ceil( dLenEff / BOX_STEP)) ;
|
||||
Vector3d vtStep = dLenEff / nStep * vtL ;
|
||||
Vector3d vtStep = dLenEff / nStep * vtDir ;
|
||||
INTVECTOR vPrevT ;
|
||||
for ( int i = 0 ; i < nStep ; ++ i) {
|
||||
BBox3d b3Box( ptStart + i * vtStep, ptStart + ( i + 1) * vtStep) ;
|
||||
@@ -189,3 +191,68 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
{
|
||||
// ciclo sulle intersezioni
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = LST_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = LST_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = LST_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
vInters.emplace_back( LST_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( LST_TG_FIN, Info.dU2) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se hanno lo stesso parametro
|
||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
||||
( vInters[i].first == LST_OUT && vInters[j].first == LST_OUT)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
else if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_OUT) ||
|
||||
( vInters[i].first == LST_OUT && vInters[j].first == LST_IN)) {
|
||||
vInters[i].first = LST_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == LST_IN || vInters[i].first == LST_OUT || vInters[i].first == LST_TOUCH) && vInters[j].first == LST_TG_INI) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( vInters[i].first == LST_TG_FIN && ( vInters[j].first == LST_IN || vInters[j].first == LST_OUT || vInters[j].first == LST_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( i > 0 && vInters[i].first == LST_TG_FIN && vInters[j].first == LST_TG_INI) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@
|
||||
#include "CurveLine.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <array>
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
|
||||
// Contenuto : Implementazione della intersezione linea/VolZmap.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.02.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "VolZmap.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di una linea con la superficie di un solido VolZmap
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineVolZmap( const Point3d& ptL, const Vector3d& vtL, const IVolZmap& Vzm, ILZIVECTOR& vInfo)
|
||||
{
|
||||
// verifico linea
|
||||
Vector3d vtDir = vtL ;
|
||||
if ( ! vtDir.Normalize( EPS_ZERO))
|
||||
return false ;
|
||||
// verifico volume
|
||||
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||
if ( pVzm == nullptr)
|
||||
return false ;
|
||||
// verifico parametro di ritorno
|
||||
if ( &vInfo == nullptr)
|
||||
return false ;
|
||||
|
||||
// eseguo intersezione
|
||||
return pVzm->GetLineIntersection( ptL, vtL, vInfo) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
FilterLineVolZmapInters( const ILZIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
{
|
||||
// ciclo sulle intersezioni
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = LZT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = LZT_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = LZT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
vInters.emplace_back( LZT_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( LZT_TG_FIN, Info.dU2) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se hanno lo stesso parametro
|
||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||
if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_IN) ||
|
||||
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_OUT)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
else if ( ( vInters[i].first == LZT_IN && vInters[j].first == LZT_OUT) ||
|
||||
( vInters[i].first == LZT_OUT && vInters[j].first == LZT_IN)) {
|
||||
vInters[i].first = LZT_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una puntuale e l'altra inizio di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == LZT_IN || vInters[i].first == LZT_OUT || vInters[i].first == LZT_TOUCH) && vInters[j].first == LZT_TG_INI) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( vInters[i].first == LZT_TG_FIN && ( vInters[j].first == LZT_IN || vInters[j].first == LZT_OUT || vInters[j].first == LZT_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( i > 0 && vInters[i].first == LZT_TG_FIN && vInters[j].first == LZT_TG_INI) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersPlaneVolZmap.cpp Data : 22.02.24 Versione : 2.6b4
|
||||
// Contenuto : Implementazione della intersezione piano/VolZmap.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.02.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "VolZmap.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneVolZmap.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di unpiano con la superficie di un solido VolZmap
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
|
||||
{
|
||||
// verifico volume
|
||||
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||
if ( pVzm == nullptr)
|
||||
return false ;
|
||||
// verifico parametro di ritorno
|
||||
if ( &vpLoop == nullptr)
|
||||
return false ;
|
||||
|
||||
// eseguo intersezione
|
||||
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
|
||||
}
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersTriaTria.h"
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkLineTgCurvePerpCurve.h"
|
||||
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkLineTgTwoCurves.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
+6
-8
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -25,11 +25,7 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||
{
|
||||
// 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 ++) {
|
||||
// recupero la curva
|
||||
PtrOwner<ICurve> pCrv( pCrvCo->GetCurve(i)->Clone()) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
if ( IsFillet( pCrv, dDist))
|
||||
if ( IsFillet( pCrvCo->GetCurve( i), dDist))
|
||||
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
||||
else
|
||||
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
||||
@@ -39,12 +35,14 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IsFillet( ICurve* pCrv, double dDist)
|
||||
IsFillet( const ICurve* pCrv, double dDist)
|
||||
{
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// deve essere un arco
|
||||
if ( pCrv->GetType() != CRV_ARC)
|
||||
return false ;
|
||||
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||
// deve avere raggio uguale alla distanza di offset
|
||||
if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// 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,6 +16,6 @@
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
||||
bool IsFillet( ICurve* pCrv, double dDist) ;
|
||||
bool IsFillet( const ICurve* pCrv, double dDist) ;
|
||||
bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ;
|
||||
bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
||||
|
||||
+29
-23
@@ -74,7 +74,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// verifico che la curva esista
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// verifico se la curva è un segmento di retta
|
||||
// verifico se la curva è un segmento di retta
|
||||
bool bIsLine = false ;
|
||||
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||
if ( pLine != nullptr)
|
||||
@@ -85,7 +85,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( pCompo != nullptr && pCompo->IsALine( m_dLinTol, ptStart, ptEnd))
|
||||
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 ;
|
||||
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL) && ! bIsLine)
|
||||
return false ;
|
||||
@@ -167,7 +167,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// -------------------- OFFSET STANDARD ---------------------------------
|
||||
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))
|
||||
return false ;
|
||||
|
||||
@@ -187,11 +187,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( ! ccCopy.MergeCurves( m_dLinTol, ANG_TOL_STD_DEG, bClosed, true))
|
||||
return false ;
|
||||
|
||||
// verifico se il punto iniziale è stato modificato
|
||||
// verifico se il punto iniziale è stato modificato
|
||||
Point3d ptNewStart ; ccCopy.GetStartPoint( ptNewStart) ;
|
||||
bChangeStart = ( ! AreSamePointApprox( ptNewStart, ptStart)) ;
|
||||
|
||||
// calcolo le lunghezze delle diverse entità
|
||||
// calcolo le lunghezze delle diverse entità
|
||||
DBLVECTOR vLens ;
|
||||
{
|
||||
const ICurve* pCrv1 = ccCopy.GetFirstCurve() ;
|
||||
@@ -203,7 +203,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
pCrv1 = ccCopy.GetNextCurve() ;
|
||||
}
|
||||
}
|
||||
// calcolo gli angoli tra le diverse entità
|
||||
// calcolo gli angoli tra le diverse entità
|
||||
DBLVECTOR vAngs ;
|
||||
{
|
||||
vAngs.push_back( 0) ;
|
||||
@@ -230,7 +230,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
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 ;
|
||||
if ( ! ccCopy2.CopyFrom( &ccCopy))
|
||||
return false ;
|
||||
@@ -285,9 +285,9 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
|
||||
// se originale chiuso, devo confrontare anche ultima e prima curva
|
||||
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() ;
|
||||
// la curva successiva ora è la prima dell'offset
|
||||
// la curva successiva ora è la prima dell'offset
|
||||
ICurve* pCrv2 = m_CrvLst.front() ;
|
||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||
CurveComposite ccTemp ;
|
||||
@@ -334,7 +334,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
bool bNextInt = NextIsLine( iIter, m_CrvLst, bClosed) &&
|
||||
NextIsLonger( nInd1, vLens, bClosed) &&
|
||||
( ( 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 ;
|
||||
if ( bPrevInt && bNextInt) {
|
||||
double dTgA = tan( 0.5 * ( ANG_STRAIGHT - abs( vAngs[nInd1-1])) * DEGTORAD) ;
|
||||
@@ -502,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
|
||||
if ( ! bClosed) {
|
||||
// ciconferenza sull'estremità iniziale
|
||||
// ciconferenza sull'estremità iniziale
|
||||
Point3d ptStart ; ccCopy.GetStartPoint( ptStart) ;
|
||||
PtrOwner<CurveArc> pCircS( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCircS) || ! pCircS->Set( ptStart, Z_AX, abs( dDist)))
|
||||
@@ -551,7 +551,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// passo alla successiva
|
||||
++ iIter ;
|
||||
}
|
||||
// circonferenza sull'estremità finale
|
||||
// circonferenza sull'estremità finale
|
||||
Point3d ptEnd ; ccCopy.GetEndPoint( ptEnd) ;
|
||||
PtrOwner<CurveArc> pCircE( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCircE) || ! pCircE->Set( ptEnd, Z_AX, abs( dDist)))
|
||||
@@ -697,6 +697,12 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// calcolo offset con Voronoi
|
||||
ICURVEPOVECTOR vOffs ;
|
||||
voronoiObj->CalcOffset( vOffs, dDist, nType) ;
|
||||
if ( vOffs.size() == 0) {
|
||||
// se non ho ottenuto offset ritento con valore leggermente diverso per le tolleranze di vroni
|
||||
double dCorr = ( dDist > 0 ? - VRONI_OFFS_TOL : VRONI_OFFS_TOL) ;
|
||||
voronoiObj->CalcOffset( vOffs, dDist + dCorr, nType) ;
|
||||
}
|
||||
|
||||
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
|
||||
m_CrvLst.emplace_back( Release( vOffs[i])) ;
|
||||
|
||||
@@ -817,7 +823,7 @@ PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bo
|
||||
// se non esiste e curva chiusa prendo l'ultimo
|
||||
if ( iPrev == CrvLst.end() && bClosed)
|
||||
-- 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 )
|
||||
return false ;
|
||||
// test superato
|
||||
@@ -830,7 +836,7 @@ PreviousIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
||||
{
|
||||
// massimo indice nel vettore
|
||||
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)
|
||||
return false ;
|
||||
// indice del precedente nel vettore di lunghezze
|
||||
@@ -854,7 +860,7 @@ NextIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool b
|
||||
// se non esiste e curva chiusa prendo il primo
|
||||
if ( iNext == CrvLst.end() && bClosed)
|
||||
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 )
|
||||
return false ;
|
||||
// test superato
|
||||
@@ -867,7 +873,7 @@ NextIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
||||
{
|
||||
// massimo indice nel vettore
|
||||
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)
|
||||
return false ;
|
||||
// indice del successivo nel vettore di lunghezze
|
||||
@@ -946,7 +952,7 @@ VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
||||
nRes = 4 ;
|
||||
return true ;
|
||||
}
|
||||
// se coincidono esattamente, va bene così
|
||||
// se coincidono esattamente, va bene così
|
||||
if ( AreSamePointExact( ptP1, ptP2)) {
|
||||
nRes = 0 ;
|
||||
return true ;
|
||||
@@ -976,7 +982,7 @@ VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
||||
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
|
||||
if ( intCC.GetIntersCount() == 0)
|
||||
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 ;
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
@@ -1024,7 +1030,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
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) &&
|
||||
( ( dDist < 0 && dAngDeg > 0) ||
|
||||
( dDist > 0 && dAngDeg < 0)))
|
||||
@@ -1066,7 +1072,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
return false ;
|
||||
ptP1a = ptP1 + vtDir1 * dLen ;
|
||||
ptP2a = ptP2 - vtDir2 * dLen ;
|
||||
// se prima c'è linea posso allungarla
|
||||
// se prima c'è linea posso allungarla
|
||||
if ( pCrv1->GetType() == CRV_LINE)
|
||||
pCrv1->ModifyEnd( ptP1a) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1085,7 +1091,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||
return false ;
|
||||
}
|
||||
// se dopo c'è linea posso allungarla
|
||||
// se dopo c'è linea posso allungarla
|
||||
if ( pCrv2->GetType() == CRV_LINE)
|
||||
pCrv2->ModifyStart( ptP2a) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1108,7 +1114,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
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)
|
||||
pCrv1->ModifyEnd( ptPc) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1119,7 +1125,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||
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)
|
||||
pCrv2->ModifyStart( ptPc) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
|
||||
+1
-1
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveArc.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <algorithm>
|
||||
|
||||
+128
-104
@@ -1,4 +1,4 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PolyLine.cpp Data : 22.12.13 Versione : 1.4l3
|
||||
@@ -14,13 +14,13 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "PointsPCA.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
|
||||
@@ -53,7 +53,7 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
||||
{
|
||||
// se da aggiungere in coda
|
||||
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.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
|
||||
++ m_nRejected ;
|
||||
return true ;
|
||||
@@ -68,7 +68,7 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
||||
}
|
||||
// altrimenti si aggiunge in testa
|
||||
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.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
|
||||
++ m_nRejected ;
|
||||
return true ;
|
||||
@@ -92,7 +92,7 @@ PolyLine::Close( void)
|
||||
// ci devono essere almeno 2 punti
|
||||
if ( m_lUPoints.size() < 2)
|
||||
return false ;
|
||||
// verifico non sia già chiuso
|
||||
// verifico non sia già chiuso
|
||||
if ( AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first))
|
||||
return false ;
|
||||
// aggiungo un punto uguale al primo in coda
|
||||
@@ -219,7 +219,7 @@ PolyLine::ToLoc( const Frame3d& frRef)
|
||||
bool
|
||||
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))
|
||||
return true ;
|
||||
// ciclo sui punti
|
||||
@@ -233,7 +233,7 @@ PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
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.size() == 0)
|
||||
return true ;
|
||||
// verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra
|
||||
@@ -385,7 +385,7 @@ PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP, bool bNotFirst) const
|
||||
bool
|
||||
PolyLine::GetCurrUPoint( double* pdPar, Point3d* pptP) const
|
||||
{
|
||||
// verifico validità punto corrente
|
||||
// verifico validità punto corrente
|
||||
if ( m_iter == m_lUPoints.end())
|
||||
return false ;
|
||||
|
||||
@@ -426,7 +426,7 @@ PolyLine::GetFirstULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d*
|
||||
bool
|
||||
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())
|
||||
return false ;
|
||||
if ( pdIni != nullptr)
|
||||
@@ -510,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.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() ;
|
||||
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
|
||||
if ( nRank == 0)
|
||||
return ptsPCA.GetCenter( ptCen) ;
|
||||
// se dimensione 1, allora i punti sono distribuiti su una linea
|
||||
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.GetPrincipalComponent( 0, vtDir) ;
|
||||
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
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
Vector3d vtX, vtY ;
|
||||
@@ -530,9 +530,9 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
|
||||
ptsPCA.GetPrincipalComponent( 1, vtY) ;
|
||||
vtDir = vtX ^ vtY ;
|
||||
if ( ! vtDir.Normalize()) {
|
||||
// riduco la dimensionalità a lineare
|
||||
// riduco la dimensionalità a lineare
|
||||
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) ;
|
||||
vtDir = vtX ;
|
||||
return true ;
|
||||
@@ -561,12 +561,12 @@ PolyLine::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
plPlane.Reset() ;
|
||||
return false ;
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
// recupero dati sulla planarità della polilinea
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||
// imposto il piano a seconda della dimensionalità
|
||||
// imposto il piano a seconda della dimensionalità
|
||||
switch ( nRank) {
|
||||
case 0 : // punto
|
||||
plPlane.Set( ptCen, Z_AX) ;
|
||||
@@ -587,18 +587,29 @@ PolyLine::IsClosedAndFlat( Plane3d& plPlane, double& dArea, double dToler) const
|
||||
// Test if closed
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// Compute a representative plane for the polygon
|
||||
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 ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
||||
PolyPlane.AddPoint( ptP) ;
|
||||
PolyPlane.AddPoint( ptP - vtMove) ;
|
||||
if ( ! PolyPlane.GetPlane( plPlane) || ! PolyPlane.GetArea( dArea)) {
|
||||
dArea = 0 ;
|
||||
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
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||
double dDist = ( ( ptP - ORIG) * plPlane.GetVersN()) - plPlane.GetDist() ;
|
||||
double dDist = DistPointPlane( ptP, plPlane) ;
|
||||
if ( abs( dDist) > dToler)
|
||||
return false ;
|
||||
}
|
||||
@@ -639,13 +650,13 @@ PolyLine::GetAreaXY( double& dArea) const
|
||||
// verifico sia chiusa
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// calcolo l'area considerando solo XY (è la Z di Newell)
|
||||
// calcolo l'area considerando solo XY (è la Z di Newell)
|
||||
dArea = 0 ;
|
||||
Point3d 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
|
||||
}
|
||||
// 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
|
||||
ptIni = ptFin ;
|
||||
GetFirstPoint( ptFin) ;
|
||||
@@ -721,15 +732,42 @@ PolyLine::AdjustForMaxSegmentLen( double dMaxLen)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool
|
||||
PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol)
|
||||
DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const int nIndStart,
|
||||
const int nIndEnd, INTVECTOR& vInd)
|
||||
{
|
||||
for ( const auto& ptQ : vRPT) {
|
||||
double dSqDist ;
|
||||
if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
||||
// se indici uguali, ritorno
|
||||
if ( nIndStart == nIndEnd)
|
||||
return true ;
|
||||
|
||||
// distanza massima e indice del punto associato
|
||||
double dMaxSqDist = 0. ;
|
||||
int nMaxInd = 0 ;
|
||||
|
||||
// scorro i punti intermedi tra nIndStart e nIndEnd
|
||||
for ( int i = nIndStart + 1 ; i < nIndEnd ; ++ i) {
|
||||
double dCurrSqDist = 0. ;
|
||||
// distanza tra il punto attuale e la retta tra i punti di indici nIndStart ed nIndEnd
|
||||
DistPointLine DPL( vPtU[i].first, vPtU[nIndStart].first, vPtU[nIndEnd].first) ;
|
||||
if ( DPL.GetSqDist( dCurrSqDist) && dCurrSqDist > dMaxSqDist) {
|
||||
// aggiorno i parametri
|
||||
dMaxSqDist = dCurrSqDist ;
|
||||
nMaxInd = i ;
|
||||
}
|
||||
}
|
||||
|
||||
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
||||
if ( dMaxSqDist > dSqTol) {
|
||||
// inserisco il punto
|
||||
vInd.push_back( nMaxInd) ;
|
||||
// split
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vInd) ||
|
||||
! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vInd))
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -743,59 +781,61 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
||||
// controllo minimo valore di tolleranza
|
||||
dToler = max( dToler, LIN_TOL_MIN) ;
|
||||
double dSqTol = dToler * dToler ;
|
||||
// si analizza la distanza di un punto dal segmento che unisce precedente e successivo
|
||||
// punto precedente
|
||||
auto precP = m_lUPoints.begin() ;
|
||||
// punto corrente
|
||||
auto currP = next( precP) ;
|
||||
// punto successivo
|
||||
auto nextP = next( currP) ;
|
||||
// lista dei punti appena rimossi
|
||||
PNTVECTOR vRPT ; vRPT.reserve( 20) ;
|
||||
// mentre esiste un successivo
|
||||
while ( nextP != m_lUPoints.end()) {
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
||||
double dSqDist ;
|
||||
// se da eliminare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
||||
// aggiungo il punto nella lista dei rimossi
|
||||
vRPT.emplace_back( currP->first) ;
|
||||
// elimino il punto
|
||||
m_lUPoints.erase( currP) ;
|
||||
// avanzo con corrente e successivo
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
|
||||
// vettore contenente i punti della polyline
|
||||
PNTUVECTOR vPtU ; vPtU.reserve( m_lUPoints.size()) ;
|
||||
for ( const auto& ptCurr : m_lUPoints)
|
||||
vPtU.emplace_back( ptCurr) ;
|
||||
|
||||
// vettore indici dei punti rimanenti
|
||||
INTVECTOR vInd ; vInd.reserve( vPtU.size()) ;
|
||||
|
||||
// se aperta
|
||||
if ( ! IsClosed()) {
|
||||
// considero tutti i punti della PolyLine
|
||||
vInd.push_back( 0) ;
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
||||
return false ;
|
||||
vInd.push_back( vPtU.size() - 1) ;
|
||||
}
|
||||
// altrimenti chiusa
|
||||
else {
|
||||
// cerco il punto più distante dal primo
|
||||
double dMaxDist = 0. ;
|
||||
int nMaxInd = 0 ;
|
||||
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
||||
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
|
||||
if ( dCurrDist > dMaxDist) {
|
||||
dMaxDist = dCurrDist ;
|
||||
nMaxInd = i ;
|
||||
}
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// cancello la lista dei rimossi
|
||||
vRPT.clear() ;
|
||||
// avanzo il terzetto di uno step
|
||||
precP = currP ;
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
// recupero due PolyLine di approssimazione
|
||||
vInd.push_back( 0) ;
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vInd))
|
||||
return false ;
|
||||
vInd.push_back( nMaxInd) ;
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
||||
return false ;
|
||||
vInd.push_back( vPtU.size() - 1) ;
|
||||
}
|
||||
|
||||
// ordino in senso crescente
|
||||
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[vInd.size()-2]].first).IsEpsilon( dToler)) {
|
||||
vInd.erase( vInd.begin()) ;
|
||||
vInd.back() = vInd.front() ;
|
||||
}
|
||||
}
|
||||
// se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura
|
||||
if ( IsClosed() && m_lUPoints.size() >= 4) {
|
||||
// precP e currP sono già corretti
|
||||
// il primo punto ripete l'ultimo (geometricamente coincide con currP)
|
||||
auto firstP = m_lUPoints.begin() ;
|
||||
// questo è il vero successivo
|
||||
nextP = next( firstP) ;
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
||||
double dSqDist ;
|
||||
// se da eliminare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
||||
// faccio coincidere il primo punto con il precedente
|
||||
firstP->first = precP->first ;
|
||||
// elimino il punto corrente
|
||||
m_lUPoints.erase( currP) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// rimetto in lista i soli punti rimasti
|
||||
m_lUPoints.clear() ;
|
||||
for ( auto Ind : vInd)
|
||||
m_lUPoints.push_back( vPtU[Ind]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -937,7 +977,7 @@ PolyLine::MyApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
|
||||
}
|
||||
}
|
||||
}
|
||||
// non è stato eliminato alcunché
|
||||
// non è stato eliminato alcunché
|
||||
// ripristino la tolleranza corrente
|
||||
dCurrToler = dToler ;
|
||||
// avanzo il terzetto di uno step
|
||||
@@ -978,7 +1018,7 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||
bool
|
||||
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 ;
|
||||
while ( bRemoved) {
|
||||
bRemoved = false ;
|
||||
@@ -1006,7 +1046,7 @@ PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||
bRemoved = true ;
|
||||
continue ;
|
||||
}
|
||||
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
||||
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
||||
precP = currP ;
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
@@ -1033,7 +1073,7 @@ PolyLine::Invert( bool bInvertU)
|
||||
m_lUPoints.reverse() ;
|
||||
// se richiesto, inverto anche il parametro U
|
||||
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 ;
|
||||
// ciclo su tutti gli elementi
|
||||
for ( auto& UPoint : m_lUPoints) {
|
||||
@@ -1248,7 +1288,7 @@ PolyLine::GetMinAreaRectangleXY( Point3d& ptCen, Vector3d& vtAx, double& dLen, d
|
||||
bool
|
||||
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
||||
{
|
||||
// se vuota non faccio alcunché
|
||||
// se vuota non faccio alcunché
|
||||
if ( m_lUPoints.size() == 0)
|
||||
return false ;
|
||||
|
||||
@@ -1350,7 +1390,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
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 ;
|
||||
Point3d ptMinDist ;
|
||||
auto itMinDistEnd = List.end() ;
|
||||
@@ -1439,7 +1479,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol
|
||||
// assegno nuovo inizio
|
||||
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) ;
|
||||
}
|
||||
|
||||
@@ -1452,7 +1492,7 @@ ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
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 ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
@@ -1496,7 +1536,7 @@ SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler,
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
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 ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
@@ -1560,10 +1600,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
int nLastJ = 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) {
|
||||
|
||||
double dDist = INFINITO ;
|
||||
@@ -1572,7 +1608,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine PointLineDistCalc( vPnt1[i].first, vPnt2[j-1].first, vPnt2[j].first) ;
|
||||
double dPlDist ;
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist) {
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
||||
dDist = dPlDist ;
|
||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||
dMinDistPar += j - 1 ;
|
||||
@@ -1580,14 +1616,10 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
}
|
||||
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)
|
||||
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)
|
||||
bCommonInternalPoints = true ;
|
||||
|
||||
@@ -1598,9 +1630,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// calcoli per seconda curva
|
||||
int nLastI = 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) {
|
||||
|
||||
@@ -1610,8 +1639,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine PointLineDistCalc( vPnt2[j].first, vPnt1[i-1].first, vPnt1[i].first) ;
|
||||
double dPlDist ;
|
||||
PointLineDistCalc.GetDist( dPlDist) ;
|
||||
if ( dPlDist < dDist) {
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
||||
dDist = dPlDist ;
|
||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||
dMinDistPar += i - 1 ;
|
||||
@@ -1619,10 +1647,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
}
|
||||
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)
|
||||
nMinI = nLastI ;
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ProjectCurveSurfBez.cpp Data : 07.05.24 Versione : 2.6e3
|
||||
// Contenuto : Implementazione funzioni proiezione curve su superficie Bezier.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 07.05.24 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfBez( const ICurve& crCrv, const ISurfBezier& surfBez, const Vector3d& vtDir, double dLinTol, double dMaxSegmLen,
|
||||
PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
const ISurfTriMesh* pAuxSurf = surfBez.GetAuxSurf() ;
|
||||
return ProjectCurveOnSurfTm( crCrv, *pAuxSurf, vtDir, dLinTol, dMaxSegmLen, vPt5ax) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfBez( const ICurve& crCrv, const ISurfBezier& surfBez, const IGeoPoint3d& gpRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
const ISurfTriMesh* pAuxSurf = surfBez.GetAuxSurf() ;
|
||||
return ProjectCurveOnSurfTm( crCrv, *pAuxSurf, gpRef, dLinTol, dMaxSegmLen, vPt5ax) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfBez( const ICurve& crCrv, const ISurfBezier& surfBez, const ICurve& crRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
const ISurfTriMesh* pAuxSurf = surfBez.GetAuxSurf() ;
|
||||
return ProjectCurveOnSurfTm( crCrv, *pAuxSurf, crRef, dLinTol, dMaxSegmLen, vPt5ax) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfBez( const ICurve& crCrv, const ISurfBezier& surfBez, const ISurfTriMesh& tmRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
const ISurfTriMesh* pAuxSurf = surfBez.GetAuxSurf() ;
|
||||
return ProjectCurveOnSurfTm( crCrv, *pAuxSurf, tmRef, dLinTol, dMaxSegmLen, vPt5ax) ;
|
||||
}
|
||||
+329
-57
@@ -13,13 +13,19 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Angolo limite tra normale al triangolo e direzione di proiezione 89°
|
||||
const double COS_ANG_LIM = 0.0175 ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
||||
@@ -33,63 +39,9 @@ PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext,
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vector3d& vtDir, double dLinTol, double dMaxSegmLen,
|
||||
PNT5AXVECTOR& vPt5ax)
|
||||
static bool
|
||||
RemovePointsInExcess( PNT5AXVECTOR& vMyPt5ax, double dLinTol, double dMaxSegmLen)
|
||||
{
|
||||
// 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 dU ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dU, &ptP) ;
|
||||
while ( bFound) {
|
||||
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
intPLSTM.GetInters( ptL, 1, 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, dU, 1) ;
|
||||
}
|
||||
bFound = PL.GetNextUPoint( &dU, &ptP) ;
|
||||
}
|
||||
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
||||
double dSqTol = dLinTol * dLinTol ;
|
||||
@@ -130,6 +82,326 @@ ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vec
|
||||
++ 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 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, 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) {
|
||||
// intersezione retta di proiezione con superficie
|
||||
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
intPLSTM.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) {
|
||||
// calcolo il punto
|
||||
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)) {
|
||||
// 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) {
|
||||
// calcolo il punto
|
||||
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 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, 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)) {
|
||||
// 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) {
|
||||
// calcolo il punto
|
||||
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)) {
|
||||
// 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) {
|
||||
// calcolo il punto
|
||||
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() ;
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : Quaternion.cpp Data : 13.04.24 Versione : 2.6d4
|
||||
// Contenuto : Funzioni della classe Quaternion.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 13.04.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "\EgtDev\Include\EGkQuaternion.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Lunghezza o Modulo
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
Quaternion::Len( void) const
|
||||
{
|
||||
if ( abs( x) < EPS_ZERO && abs( y) < EPS_ZERO && abs( z) < EPS_ZERO)
|
||||
return abs( w) ;
|
||||
if ( abs( w) < EPS_ZERO && abs( y) < EPS_ZERO && abs( z) < EPS_ZERO)
|
||||
return abs( x) ;
|
||||
if ( abs( w) < EPS_ZERO && abs( z) < EPS_ZERO && abs( x) < EPS_ZERO)
|
||||
return abs( y) ;
|
||||
if ( abs( w) < EPS_ZERO && abs( x) < EPS_ZERO && abs( y) < EPS_ZERO)
|
||||
return abs( z) ;
|
||||
|
||||
return sqrt( w * w + x * x + y * y + z * z) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Normalizzazione
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Quaternion::Normalize( double dEps)
|
||||
{
|
||||
// se già normalizzato, ok
|
||||
double dSqLen = w * w + x * x + y * y + z * z ;
|
||||
if ( abs( 1.0 - dSqLen) < ( 2 * 1000 * DBL_EPSILON))
|
||||
return true ;
|
||||
|
||||
// se troppo piccolo, errore
|
||||
if ( dSqLen < ( dEps * dEps))
|
||||
return false ;
|
||||
|
||||
// eseguo la normalizzazione
|
||||
double dLen = sqrt( dSqLen) ;
|
||||
*this /= dLen ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Quaternion
|
||||
FromAxisAngle( const Vector3d& vtAx, double dAngDeg)
|
||||
{
|
||||
if ( abs( dAngDeg) < EPS_ANG_ZERO)
|
||||
return Q_UNIT ;
|
||||
double dLen = vtAx.Len() ;
|
||||
if ( dLen < EPS_ZERO)
|
||||
return Q_NULL ;
|
||||
double dDenom = 1 / dLen ;
|
||||
double dHCos = cos( dAngDeg / 2 * DEGTORAD) ;
|
||||
double dHSin = sin( dAngDeg / 2 * DEGTORAD) ;
|
||||
return Quaternion( dHCos, dHSin * vtAx.x * dDenom, dHSin * vtAx.y * dDenom, dHSin * vtAx.z * dDenom) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ToAxisAngle( const Quaternion& qtQ, Vector3d& vtAx, double& dAngDeg)
|
||||
{
|
||||
if ( ! qtQ.IsNormalized())
|
||||
return false ;
|
||||
if ( qtQ.IsUnit() || (-qtQ).IsUnit()) {
|
||||
dAngDeg = 0 ;
|
||||
vtAx = Z_AX ;
|
||||
}
|
||||
else {
|
||||
dAngDeg = 2 * acos( qtQ.w) * RADTODEG ;
|
||||
double dDenom = 1 / sqrt( 1 - qtQ.w * qtQ.w) ;
|
||||
vtAx.x = qtQ.x * dDenom ;
|
||||
vtAx.y = qtQ.y * dDenom ;
|
||||
vtAx.z = qtQ.z * dDenom ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Quaternion
|
||||
FromFrame( const Frame3d& frRef)
|
||||
{
|
||||
// verifico il riferimento
|
||||
if ( ! frRef.IsValid())
|
||||
return Q_NULL ;
|
||||
// eseguo il calcolo
|
||||
Quaternion qtQ ;
|
||||
// traccia della matrice di rotazione
|
||||
double dTr = frRef.VersX().x + frRef.VersY().y + frRef.VersZ().z ;
|
||||
// se traccia positiva o nulla
|
||||
if ( dTr > - 10 * EPS_ZERO) {
|
||||
double dS = sqrt( 1 + dTr) ;
|
||||
qtQ.w = dS / 2 ;
|
||||
dS = 1 / ( 2 * dS) ;
|
||||
qtQ.x = ( frRef.VersY().z - frRef.VersZ().y) * dS ;
|
||||
qtQ.y = ( frRef.VersZ().x - frRef.VersX().z) * dS ;
|
||||
qtQ.z = ( frRef.VersX().y - frRef.VersY().x) * dS ;
|
||||
}
|
||||
// altrimenti traccia negativa
|
||||
else {
|
||||
if ( frRef.VersX().x > frRef.VersY().y - 10 * EPS_ZERO && frRef.VersX().x > frRef.VersZ().z - 10 * EPS_ZERO) {
|
||||
double dS = sqrt( 1 + frRef.VersX().x - ( frRef.VersY().y + frRef.VersZ().z)) ;
|
||||
qtQ.x = dS / 2 ;
|
||||
dS = 1 / ( 2 * dS) ;
|
||||
qtQ.y = ( frRef.VersY().x + frRef.VersX().y) * dS ;
|
||||
qtQ.z = ( frRef.VersX().z + frRef.VersZ().x) * dS ;
|
||||
qtQ.w = ( frRef.VersY().z - frRef.VersZ().y) * dS ;
|
||||
}
|
||||
else if ( frRef.VersY().y > frRef.VersZ().z - 10 * EPS_ZERO && frRef.VersY().y > frRef.VersX().x - 10 * EPS_ZERO) {
|
||||
double dS = sqrt( 1 + frRef.VersY().y - ( frRef.VersZ().z + frRef.VersX().x)) ;
|
||||
qtQ.y = dS / 2 ;
|
||||
dS = 1 / ( 2 * dS) ;
|
||||
qtQ.z = ( frRef.VersZ().y + frRef.VersY().z) * dS ;
|
||||
qtQ.x = ( frRef.VersY().x + frRef.VersX().y) * dS ;
|
||||
qtQ.w = ( frRef.VersZ().x - frRef.VersX().z) * dS ;
|
||||
}
|
||||
else {
|
||||
double dS = sqrt( 1 + frRef.VersZ().z - ( frRef.VersX().x + frRef.VersY().y)) ;
|
||||
qtQ.z = dS / 2 ;
|
||||
dS = 1 / ( 2 * dS) ;
|
||||
qtQ.x = ( frRef.VersX().z + frRef.VersZ().x) * dS ;
|
||||
qtQ.y = ( frRef.VersZ().y + frRef.VersY().z) * dS ;
|
||||
qtQ.w = ( frRef.VersX().y - frRef.VersY().x) * dS ;
|
||||
}
|
||||
}
|
||||
|
||||
return qtQ ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ToFrame( const Quaternion& qtQ, Frame3d& frRef)
|
||||
{
|
||||
double dNrm = qtQ.Len() ;
|
||||
double dS = ( dNrm > EPS_ZERO ? 2 / dNrm : 0) ;
|
||||
double dXs = qtQ.x * dS, dYs = qtQ.y * dS, dZs = qtQ.z * dS ;
|
||||
double dWx = qtQ.w * dXs, dWy = qtQ.w * dYs, dWz = qtQ.w * dZs ;
|
||||
double dXx = qtQ.x * dXs, dXy = qtQ.x * dYs, dXz = qtQ.x * dZs ;
|
||||
double dYy = qtQ.y * dYs, dYz = qtQ.y * dZs, dZz = qtQ.z * dZs ;
|
||||
Vector3d vtX( 1 - ( dYy + dZz), dXy + dWz, dXz - dWy) ;
|
||||
Vector3d vtY( dXy - dWz, 1 - ( dXx + dZz), dYz + dWx) ;
|
||||
Vector3d vtZ( dXz + dWy, dYz - dWx, 1 - ( dXx + dYy)) ;
|
||||
return frRef.Set( ORIG, vtX, vtY, vtZ) ;
|
||||
}
|
||||
@@ -15,8 +15,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : RotationMinimizingFrame.cpp Data : 05.03.24 Versione : 2.6d1
|
||||
// Contenuto : Classe per RotationMinimizeFrame
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 05.03.24 RE Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::Set( const ICurve* pCrv, const Frame3d& fr_Start)
|
||||
{
|
||||
// pulisco
|
||||
Clear() ;
|
||||
// verifico i parametri
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid() ||
|
||||
! fr_Start.IsValid())
|
||||
return false ;
|
||||
// assegno i parametri
|
||||
m_pCrv = pCrv->Clone() ;
|
||||
m_Frame0 = fr_Start ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::Clear( void)
|
||||
{
|
||||
// pulizia della curva
|
||||
if ( m_pCrv != nullptr)
|
||||
delete m_pCrv ;
|
||||
m_pCrv = nullptr ;
|
||||
// reset del frame di partenza
|
||||
m_Frame0.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::IsValid( void)
|
||||
{
|
||||
// controllo validità della curva
|
||||
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo del frame iniziale
|
||||
if ( ! m_Frame0.IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo che l'origine del frame sia sulla curva e che l'asse Z sia tangente alla curva
|
||||
Point3d ptS ;
|
||||
Vector3d vtZ ;
|
||||
if ( ! m_pCrv->GetPointD1D2( 0., ICurve::FROM_MINUS, ptS, &vtZ) ||
|
||||
! vtZ.Normalize() ||
|
||||
! AreSamePointApprox( ptS, m_Frame0.Orig()) ||
|
||||
! AreSameVectorEpsilon( vtZ, m_Frame0.VersZ(), 5 * EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::GetFrameAtParam( const Frame3d& frAct, const double dParNext, Frame3d& frNext)
|
||||
{
|
||||
/*
|
||||
Double Reflection
|
||||
Computation of Rotation Minimizing Frame in Computer Graphics
|
||||
Wenping Wang Bert Juttler Dayue Zheng Yang Liu
|
||||
*/
|
||||
|
||||
// ricavo i parametri dal frame
|
||||
if ( ! frAct.IsValid())
|
||||
return false ;
|
||||
|
||||
// origine del frame e versori ( ptCurr, [ vtCurrR, vtCurrS, vtCurrT])
|
||||
Point3d ptCurr = frAct.Orig() ;
|
||||
Vector3d vtCurrR = frAct.VersX() ;
|
||||
Vector3d vtCurrT = frAct.VersZ() ;
|
||||
|
||||
// punto i-esimo sulla curva e suo vettore tangente
|
||||
Point3d ptNext ;
|
||||
Vector3d vtNextT ;
|
||||
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNextT) ||
|
||||
! vtNextT.Normalize())
|
||||
return false ;
|
||||
|
||||
// controllo per casi degeneri
|
||||
if ( AreSamePointEpsilon( ptCurr, ptNext, EPS_ZERO) || // non esiste il piano R1
|
||||
abs( ( ptNext - ptCurr) * ( vtNextT + vtCurrT)) < EPS_ZERO) // non esiste il piano R2
|
||||
return false ;
|
||||
|
||||
// ricavo il vettore di riflessione rispetto al piano R1
|
||||
Vector3d vR1_norm = ptNext - ptCurr ;
|
||||
if ( ! vR1_norm.IsValid())
|
||||
return false ;
|
||||
|
||||
// parametro di riflessione per R1
|
||||
double dPar1 = vR1_norm * vR1_norm ;
|
||||
|
||||
// riflessione rispetto al piano R1 ( sistema sinistrorso L )
|
||||
Vector3d vt_r_L = vtCurrR - ( 2 / dPar1) * ( vR1_norm * vtCurrR) * vR1_norm ;
|
||||
Vector3d vt_t_L = vtCurrT - ( 2 / dPar1) * ( vR1_norm * vtCurrT) * vR1_norm ;
|
||||
|
||||
// ricavo il vettore di riflessione rispetto al piano R1
|
||||
Vector3d vR2_norm = vtNextT - vt_t_L ;
|
||||
if ( ! vR2_norm.IsValid())
|
||||
return false ;
|
||||
|
||||
// parametro di riflessione per R2
|
||||
double dPar2 = vR2_norm * vR2_norm ;
|
||||
// versore r del nuovo frame
|
||||
Vector3d vt_r_next = vt_r_L - ( 2 / dPar2) * ( vR2_norm * vt_r_L) * vR2_norm ;
|
||||
|
||||
// imposto il nuovo frame
|
||||
return frNext.Set( ptNext, vtNextT, vt_r_next) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::GetFramesByStep( double dStep, bool bUniform, FRAME3DVECTOR& vRMFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sullo step
|
||||
dStep = max( 10 * EPS_SMALL, dStep) ;
|
||||
|
||||
// lunghezza della curva
|
||||
double dCrvLen = 0. ;
|
||||
if ( ! m_pCrv->GetLength( dCrvLen) || dCrvLen < 10 * EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// ricavo il numero degli step
|
||||
int nStep = int( ceil( dCrvLen / dStep)) ;
|
||||
double dMyStep = ( bUniform ? dCrvLen / nStep : dStep) ;
|
||||
|
||||
// inserisco il frame iniziale nel vettore dei riferimenti
|
||||
vRMFrames.clear() ;
|
||||
vRMFrames.reserve( nStep + 1) ;
|
||||
vRMFrames.push_back( m_Frame0) ;
|
||||
|
||||
// ciclo sugli step in cui la curva è suddivisa
|
||||
for ( int i = 1 ; i <= nStep ; ++ i) {
|
||||
// ricavo il parametro della curva allo step i-esimo
|
||||
double dParNext ;
|
||||
if ( ! m_pCrv->GetParamAtLength( min( i * dMyStep, dCrvLen - EPS_SMALL), dParNext))
|
||||
return false ;
|
||||
// ricavo il frame alla posizione calcolata
|
||||
Frame3d frNext ;
|
||||
if ( ! GetFrameAtParam( vRMFrames[i-1], dParNext, frNext))
|
||||
return false ;
|
||||
// inserisco nuovo frame nel vettore dei riferimenti
|
||||
vRMFrames.push_back( frNext) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::GetFramesBySplit( int nIntervals, FRAME3DVECTOR& vRMFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sul numero di intervalli
|
||||
nIntervals = max( 1, nIntervals) ;
|
||||
|
||||
// ricavo lo step
|
||||
double dLen = 0 ;
|
||||
if ( ! m_pCrv->GetLength( dLen))
|
||||
return false ;
|
||||
double dStep = dLen / nIntervals ;
|
||||
|
||||
return GetFramesByStep( dStep, true, vRMFrames) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationMinimizingFrame::GetFramesByTolerance( double dTol, FRAME3DVECTOR& vRMFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sulla tolleranza
|
||||
dTol = max( EPS_SMALL, dTol) ;
|
||||
|
||||
// ricavo la PolyLine associata alla curva mediante tale tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return false ;
|
||||
int nStep = PL.GetLineNbr() ;
|
||||
|
||||
// inserisco il frame iniziale nel vettore dei riferimenti
|
||||
vRMFrames.clear() ;
|
||||
vRMFrames.reserve( nStep + 1) ;
|
||||
vRMFrames.push_back( m_Frame0) ;
|
||||
|
||||
// eseguo il calcolo dei frame su ogni punto ricavato dall'approssimazione
|
||||
Point3d ptCurr ;
|
||||
PL.GetFirstPoint( ptCurr) ;
|
||||
double dParNext ;
|
||||
Point3d ptNext ;
|
||||
while ( PL.GetNextUPoint( &dParNext, &ptNext)) {
|
||||
// ricavo il Frame associato a questa posizione
|
||||
Frame3d frNext ;
|
||||
if ( ! GetFrameAtParam( vRMFrames.back(), dParNext, frNext))
|
||||
return false ;
|
||||
vRMFrames.emplace_back( frNext) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : RotationXplaneFrame.cpp Data : 05.04.24 Versione : 2.6d1
|
||||
// Contenuto : Classe per RotationXplaneFrame.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 05.04.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::Set( const ICurve* pCrv, const Vector3d& vtNorm, const Vector3d& vtNearX)
|
||||
{
|
||||
// pulisco
|
||||
Clear() ;
|
||||
// verifico i parametri
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid() ||
|
||||
! vtNorm.IsValid() || vtNorm.IsSmall() || ! vtNearX.IsValid())
|
||||
return false ;
|
||||
// assegno i parametri
|
||||
m_pCrv = pCrv->Clone() ;
|
||||
m_vtNorm = vtNorm ;
|
||||
m_vtNearX = vtNearX ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::Clear( void)
|
||||
{
|
||||
// pulizia della curva
|
||||
if ( m_pCrv != nullptr)
|
||||
delete m_pCrv ;
|
||||
m_pCrv = nullptr ;
|
||||
// reset dei vettori
|
||||
m_vtNorm = V_NULL ;
|
||||
m_vtNearX = V_NULL ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::IsValid( void)
|
||||
{
|
||||
// controllo validità della curva
|
||||
if ( m_pCrv == nullptr || ! m_pCrv->IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo della normale al piano
|
||||
if ( m_vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::GetFrameAtParam( const Frame3d& frAct, const double dParNext, Frame3d& frNext)
|
||||
{
|
||||
// verifico il riferimento corrente
|
||||
if ( ! frAct.IsValid())
|
||||
return false ;
|
||||
|
||||
// recupero punto e tangente nel nuovo punto
|
||||
Point3d ptNext ;
|
||||
Vector3d vtNext ;
|
||||
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNext) ||
|
||||
! vtNext.Normalize())
|
||||
return false ;
|
||||
|
||||
// calcolo il nuovo riferimento
|
||||
Vector3d vtAxX = m_vtNorm ^ vtNext ;
|
||||
if ( vtAxX.IsSmall())
|
||||
vtAxX = frAct.VersX() ;
|
||||
else if ( vtAxX * frAct.VersX() < 0)
|
||||
vtAxX.Invert() ;
|
||||
|
||||
// lo imposto
|
||||
return frNext.Set( ptNext, vtNext, vtAxX) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::GetFramesByStep( double dStep, bool bUniform, FRAME3DVECTOR& vRXFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sullo step
|
||||
dStep = max( 10 * EPS_SMALL, dStep) ;
|
||||
|
||||
// lunghezza della curva
|
||||
double dCrvLen = 0. ;
|
||||
if ( ! m_pCrv->GetLength( dCrvLen) || dCrvLen < 10 * EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// numero e lunghezza effettiva di ogni step
|
||||
int nStep = int( ceil( dCrvLen / dStep)) ;
|
||||
double dMyStep = ( bUniform ? dCrvLen / nStep : dStep) ;
|
||||
|
||||
// calcolo il riferimento iniziale
|
||||
Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ;
|
||||
Vector3d vtAxX = m_vtNorm ^ vtStart ;
|
||||
if ( vtAxX.IsSmall()) {
|
||||
vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ;
|
||||
if ( vtAxX.IsSmall()) {
|
||||
vtAxX = FromUprightOrtho( m_vtNorm) ;
|
||||
vtAxX.Rotate( m_vtNorm, 0, 1) ;
|
||||
}
|
||||
}
|
||||
Frame3d frStart ;
|
||||
if ( ! frStart.Set( ptStart, vtStart, vtAxX))
|
||||
return false ;
|
||||
|
||||
// inserisco questo frame nel vettore dei riferimenti
|
||||
vRXFrames.clear() ;
|
||||
vRXFrames.reserve( nStep + 1) ;
|
||||
vRXFrames.push_back( frStart) ;
|
||||
|
||||
// ciclo sugli step in cui la curva è suddivisa
|
||||
for ( int i = 1 ; i <= nStep ; ++ i) {
|
||||
// ricavo il parametro della curva allo step i-esimo
|
||||
double dParNext ;
|
||||
if ( ! m_pCrv->GetParamAtLength( min( i * dMyStep, dCrvLen - EPS_SMALL), dParNext))
|
||||
return false ;
|
||||
// ricavo il frame alla posizione calcolata
|
||||
Frame3d frNext ;
|
||||
if ( ! GetFrameAtParam( vRXFrames[i-1], dParNext, frNext))
|
||||
return false ;
|
||||
// inserisco nuovo frame nel vettore dei riferimenti
|
||||
vRXFrames.push_back( frNext) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::GetFramesBySplit( int nIntervals, FRAME3DVECTOR& vRXFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sul numero di intervalli
|
||||
nIntervals = max( 1, nIntervals) ;
|
||||
|
||||
// ricavo lo step
|
||||
double dLen = 0 ;
|
||||
if ( ! m_pCrv->GetLength( dLen))
|
||||
return false ;
|
||||
double dStep = dLen / nIntervals ;
|
||||
|
||||
return GetFramesByStep( dStep, true, vRXFrames) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RotationXplaneFrame::GetFramesByTolerance( double dTol, FRAME3DVECTOR& vRXFrames)
|
||||
{
|
||||
// controllo validità
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo sulla tolleranza
|
||||
dTol = max( EPS_SMALL, dTol) ;
|
||||
|
||||
// ricavo la PolyLine associata alla curva mediante tale tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! m_pCrv->ApproxWithLines( dTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return false ;
|
||||
int nStep = PL.GetLineNbr() ;
|
||||
|
||||
// calcolo il riferimento iniziale
|
||||
Point3d ptStart ; m_pCrv->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ; m_pCrv->GetStartDir( vtStart) ;
|
||||
Vector3d vtAxX = m_vtNorm ^ vtStart ;
|
||||
if ( vtAxX.IsSmall()) {
|
||||
vtAxX = OrthoCompo( m_vtNearX, m_vtNorm) ;
|
||||
if ( vtAxX.IsSmall()) {
|
||||
vtAxX = FromUprightOrtho( m_vtNorm) ;
|
||||
vtAxX.Rotate( m_vtNorm, 0, 1) ;
|
||||
}
|
||||
}
|
||||
Frame3d frStart ;
|
||||
if ( ! frStart.Set( ptStart, vtStart, vtAxX))
|
||||
return false ;
|
||||
|
||||
// inserisco questo frame nel vettore dei riferimenti
|
||||
vRXFrames.clear() ;
|
||||
vRXFrames.reserve( nStep + 1) ;
|
||||
vRXFrames.push_back( frStart) ;
|
||||
|
||||
// eseguo il calcolo dei frame sui punti della polyline approssimante
|
||||
Point3d ptCurr ;
|
||||
PL.GetFirstPoint( ptCurr) ;
|
||||
double dParNext ;
|
||||
Point3d ptNext ;
|
||||
while ( PL.GetNextUPoint( &dParNext, &ptNext)) {
|
||||
// ricavo il Frame associato a questa posizione
|
||||
Frame3d frNext ;
|
||||
if ( ! GetFrameAtParam( vRXFrames.back(), dParNext, frNext))
|
||||
return false ;
|
||||
vRXFrames.emplace_back( frNext) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
+1407
File diff suppressed because it is too large
Load Diff
+113
@@ -0,0 +1,113 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SbzSphere.cpp Data : 14.02.2024 Versione : 2.6b2
|
||||
// Contenuto : Implementazione di funzioni per creazione di superfici Sbz
|
||||
// standard : Box, Pyramid, Cylinder, Sphere, Cone.
|
||||
//
|
||||
//
|
||||
// Modifiche : 14.02.2024 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveArc.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkSbzStandard.h"
|
||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierSphere( const Point3d& ptCenter, double dR)
|
||||
{
|
||||
// creo una superficie di Bezier di grado 2 con 45 punti di controllo
|
||||
PtrOwner<ISurfBezier> pSrfBez( CreateSurfBezier()) ;
|
||||
int nDegU = 2 ;
|
||||
int nDegV = 2 ;
|
||||
int nSpanU = 4 ; // i poli della sfera sono a coordinate ( 0,0,-R) e ( 0,0,R)
|
||||
int nSpanV = 2 ;
|
||||
bool bRat = true ;
|
||||
double dW = SQRT2 ;
|
||||
pSrfBez->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
||||
// polo inferiore // dW = 1, dW = SQRT2 / 2
|
||||
for ( int i = 0 ; i < 9; ++i) {
|
||||
if ( i % 2 == 0)
|
||||
dW = 1 ;
|
||||
else
|
||||
dW = SQRT2 / 2 ;
|
||||
pSrfBez->SetControlPoint( i, 0, ptCenter + Point3d( 0, 0, -dR), dW) ;
|
||||
}
|
||||
// definisco la gabbia esterna // dW = SQRT2 / 2, dW = 1 / 2
|
||||
// parto dal punto ( 0,-dR, -dR) e completo riga per riga
|
||||
double dH = -dR ;
|
||||
for ( int j = 1 ; j < 4 ; ++j ) {
|
||||
Vector3d vtDir ( 0, -dR, 0) ;
|
||||
Point3d pt(-dR,-dR,dH) ;
|
||||
for ( int i = 0; i < 9 ; ++i ) {
|
||||
// ogni due punti ruoto di 90 gradi a sinistra
|
||||
if ( i%2 == 0) {
|
||||
vtDir.Rotate( Z_AX, 90) ;
|
||||
if ( j%2 == 1)
|
||||
dW = SQRT2 / 2 ;
|
||||
else
|
||||
dW = 1 ;
|
||||
}
|
||||
else {
|
||||
if ( j%2 == 1)
|
||||
dW = 1. / 2. ;
|
||||
else
|
||||
dW = SQRT2 / 2 ;
|
||||
}
|
||||
pt += vtDir ;
|
||||
pSrfBez->SetControlPoint( i, j, ptCenter + pt, dW) ;
|
||||
}
|
||||
dH += dR ;
|
||||
}
|
||||
// polo superiore // dW = 1, dW = SQRT2 / 2
|
||||
for ( int i = 0 ; i < 9; ++i) {
|
||||
if ( i % 2 == 0)
|
||||
dW = 1 ;
|
||||
else
|
||||
dW = SQRT2 / 2 ;
|
||||
pSrfBez->SetControlPoint( i, 4, ptCenter + Point3d( 0, 0, dR), dW) ;
|
||||
}
|
||||
|
||||
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) ;
|
||||
//}
|
||||
@@ -88,6 +88,8 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
}
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// per curva approssimata, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
||||
|
||||
+143
-30
@@ -367,25 +367,14 @@ GetSurfFlatRegionFromTriangle( const Triangle3d& Tria)
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||
{
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( ContourPolyLine))
|
||||
return nullptr ;
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( 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) ;
|
||||
}
|
||||
|
||||
@@ -401,25 +390,17 @@ GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
||||
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( vContoursPolyLineVec[nL]))
|
||||
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
|
||||
if ( nL == 0) {
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
if ( ! pSfr->AddExtLoop( Release( pLoop)))
|
||||
return nullptr ;
|
||||
}
|
||||
// Loop interno
|
||||
else {
|
||||
pSfr->AddIntLoop( Release( pLoop)) ;
|
||||
if ( ! pSfr->AddIntLoop( Release( pLoop)))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
return Release( pSfr) ;
|
||||
@@ -590,4 +571,136 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
|
||||
vId.push_back( pCrv->GetTempProp()) ;
|
||||
}
|
||||
return ( ! vId.empty()) ;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
|
||||
{
|
||||
// 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 bool : riferito al vettore originale 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 ;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user