Compare commits
54 Commits
SaraP
...
TempForVmill
| Author | SHA1 | Date | |
|---|---|---|---|
| 29138a8a0b | |||
| 99b503a637 | |||
| acad826499 | |||
| 2f4d75b958 | |||
| 7e2bf848a9 | |||
| 4f62467320 | |||
| 78d4d79cbf | |||
| 1c8ee6a332 | |||
| e4b5e4c0a9 | |||
| 6f60e2d711 | |||
| 20a9efaebb | |||
| fd9a6a9847 | |||
| c773b8829e | |||
| 8710115634 | |||
| 4056be90d9 | |||
| 77640f3a6f | |||
| 9b11212d07 | |||
| 2ea8812f52 | |||
| e2ae42a045 | |||
| 41d76f0c3f | |||
| d2b77833fd | |||
| 9ac1a56535 | |||
| 9aca1f1e25 | |||
| e3c10e9bd3 | |||
| e84a34917a | |||
| 009328b31b | |||
| ca83aaa249 | |||
| 6cdfdf6db8 | |||
| 6628b1ee24 | |||
| 2d70d27d85 | |||
| 63d62fcc92 | |||
| b4303d0e0d | |||
| 9369447886 | |||
| dca713b240 | |||
| aa82c82ddc | |||
| 8a6dbf044e | |||
| 76d009ddbe | |||
| 6deff01b6e | |||
| e79bb117d2 | |||
| 2ea4b59b9b | |||
| 6e9465247f | |||
| 1d1fb41212 | |||
| add949b6a6 | |||
| 4731df3702 | |||
| e7d0b00e0f | |||
| 641708a5fa | |||
| f5b11a61a0 | |||
| a4cc43dadb | |||
| 334ce10018 | |||
| 3d233597f3 | |||
| a5fad89380 | |||
| d0f9c2fff5 | |||
| 038142a6d7 | |||
| 26424252f9 |
+2
-2
@@ -13,8 +13,8 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "\EgtDev\Include\EGkBBox3d.h"
|
||||
#include "\EgtDev\Include\EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/EGkBBox3d.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+5
-2
@@ -59,8 +59,10 @@ class ArcApproxer
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc::CurveArc( void)
|
||||
: m_nStatus( TO_VERIFY), m_PtCen(), m_VtN(), m_VtS(), m_dRad(),
|
||||
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -578,7 +580,8 @@ CurveArc::CopyFrom( const CurveArc& caSrc)
|
||||
return true ;
|
||||
m_VtExtr = caSrc.m_VtExtr ;
|
||||
m_dThick = caSrc.m_dThick ;
|
||||
m_nTempProp = caSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = caSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = caSrc.m_nTempProp[1] ;
|
||||
return Set( caSrc.m_PtCen, caSrc.m_VtN, caSrc.m_dRad,
|
||||
caSrc.m_VtS, caSrc.m_dAngCenDeg, caSrc.m_dDeltaN) ;
|
||||
}
|
||||
|
||||
+6
-5
@@ -49,10 +49,11 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -211,7 +212,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 ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+5
-2
@@ -45,8 +45,10 @@ GEOOBJ_REGISTER( CRV_BEZIER, NGE_C_BEZ, CurveBezier) ;
|
||||
//----------------------------------------------------------------------------
|
||||
CurveBezier::CurveBezier( void)
|
||||
: m_nStatus( TO_VERIFY), m_nDeg(), m_bRat( false), m_dParSing( -2),
|
||||
m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -283,7 +285,8 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
||||
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
||||
m_VtExtr = cbSrc.m_VtExtr ;
|
||||
m_dThick = cbSrc.m_dThick ;
|
||||
m_nTempProp = cbSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = cbSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = cbSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -51,10 +51,11 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override { return true ; }
|
||||
@@ -189,7 +190,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
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 ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+17
-11
@@ -30,6 +30,7 @@
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -40,8 +41,10 @@ GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveComposite::CurveComposite( void)
|
||||
: m_nStatus( TO_VERIFY), m_VtExtr(), m_dThick(), m_ptStart(), m_nTempProp(), m_Iter( m_CrvSmplS.end())
|
||||
: m_nStatus( TO_VERIFY), m_VtExtr(), m_dThick(), m_ptStart(), m_Iter( m_CrvSmplS.end())
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -63,7 +66,8 @@ CurveComposite::Clear( void)
|
||||
m_VtExtr = V_NULL ;
|
||||
m_dThick = 0 ;
|
||||
m_ptStart = ORIG ;
|
||||
m_nTempProp = 0 ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
m_Iter = m_CrvSmplS.end() ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
@@ -541,7 +545,8 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
|
||||
Clear() ;
|
||||
m_VtExtr = ccSrc.m_VtExtr ;
|
||||
m_dThick = ccSrc.m_dThick ;
|
||||
m_nTempProp = ccSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = ccSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = ccSrc.m_nTempProp[1] ;
|
||||
for ( auto& pCrv : ccSrc.m_CrvSmplS) {
|
||||
if ( ! AddCurve( *pCrv))
|
||||
return false ;
|
||||
@@ -558,7 +563,8 @@ CurveComposite::RelocateFrom( CurveComposite& ccSrc)
|
||||
Clear() ;
|
||||
m_VtExtr = ccSrc.m_VtExtr ;
|
||||
m_dThick = ccSrc.m_dThick ;
|
||||
m_nTempProp = ccSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = ccSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = ccSrc.m_nTempProp[1] ;
|
||||
for ( ICurve* pCrv = ccSrc.RemoveFirstOrLastCurve( false) ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = ccSrc.RemoveFirstOrLastCurve( false)) {
|
||||
@@ -1316,8 +1322,8 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
|
||||
// se lineare con lato obbligato...
|
||||
if ( nType == APL_LEFT || nType == APL_LEFT_CONVEX ||
|
||||
nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) {
|
||||
// prima approssimazione lineare a 10 * Epsilon
|
||||
if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
|
||||
// prima approssimazione lineare alla tolleranza minima del programma
|
||||
if ( ! ApproxWithLines( EPS_SMALL, dAngTolDeg, APL_SPECIAL, PL))
|
||||
return false ;
|
||||
// eliminazione dei punti in tolleranza andando solo dalla parte ammessa
|
||||
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
|
||||
@@ -3129,7 +3135,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg)
|
||||
pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ;
|
||||
// calcolo la classificazione della curva rispetto alla regione
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, ccClass))
|
||||
if ( ! pSfrCut->GetCurveClassification( *pOutLoop, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// determino gli intervalli di curva da conservare
|
||||
Intervals inOk ;
|
||||
@@ -3243,7 +3249,7 @@ CurveComposite::IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::SetCurveTempProp( int nCrv, int nProp)
|
||||
CurveComposite::SetCurveTempProp( int nCrv, int nProp, int nPropNum)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -3252,13 +3258,13 @@ CurveComposite::SetCurveTempProp( int nCrv, int nProp)
|
||||
if ( nCrv < 0 || nCrv >= int( m_CrvSmplS.size()))
|
||||
return false ;
|
||||
// eseguo assegnazione
|
||||
m_CrvSmplS[nCrv]->SetTempProp( nProp) ;
|
||||
m_CrvSmplS[nCrv]->SetTempProp( nProp, nPropNum) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::GetCurveTempProp( int nCrv, int& nProp) const
|
||||
CurveComposite::GetCurveTempProp( int nCrv, int& nProp, int nPropNum) const
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -3267,6 +3273,6 @@ CurveComposite::GetCurveTempProp( int nCrv, int& nProp) const
|
||||
if ( nCrv < 0 || nCrv >= int( m_CrvSmplS.size()))
|
||||
return false ;
|
||||
// eseguo recupero
|
||||
nProp = m_CrvSmplS[nCrv]->GetTempProp() ;
|
||||
nProp = m_CrvSmplS[nCrv]->GetTempProp( nPropNum) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
+8
-7
@@ -50,10 +50,11 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -158,8 +159,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool IsAPoint( void) const override ;
|
||||
bool IsALine( double dLinTol, Point3d& ptStart, Point3d& ptEnd) const override ;
|
||||
bool IsACircle( double dLinTol, Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const override ;
|
||||
bool SetCurveTempProp( int nCrv, int nProp) override ;
|
||||
bool GetCurveTempProp( int nCrv, int& nProp) const override ;
|
||||
bool SetCurveTempProp( int nCrv, int nProp, int nPropNum = 0) override ;
|
||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropNum = 0) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -202,7 +203,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 ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
mutable PCSD_CONST_ITER m_Iter ; // iteratore
|
||||
} ;
|
||||
|
||||
|
||||
+5
-2
@@ -29,8 +29,10 @@ GEOOBJ_REGISTER( CRV_LINE, NGE_C_LIN, CurveLine) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveLine::CurveLine( void)
|
||||
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick(), m_nTempProp()
|
||||
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -123,7 +125,8 @@ CurveLine::CopyFrom( const CurveLine& clSrc)
|
||||
return true ;
|
||||
m_VtExtr = clSrc.m_VtExtr ;
|
||||
m_dThick = clSrc.m_dThick ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_PtStart, clSrc.m_PtEnd) ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -49,10 +49,11 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ICurve
|
||||
bool IsSimple( void) const override
|
||||
@@ -164,7 +165,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
Point3d m_PtEnd ; // punto finale
|
||||
Vector3d m_VtExtr ; // vettore estrusione
|
||||
double m_dThick ; // spessore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+10
-11
@@ -23,33 +23,30 @@
|
||||
bool
|
||||
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
|
||||
{
|
||||
double dSqDist ;
|
||||
double dPar ;
|
||||
double dUIni ;
|
||||
double dUFin ;
|
||||
Point3d ptIni ;
|
||||
Point3d ptFin ;
|
||||
double dMinDist ;
|
||||
double dSqMinDist ;
|
||||
MinDistCalc approxMin ;
|
||||
|
||||
vApproxMin.reserve( 4) ;
|
||||
vApproxMin.clear() ;
|
||||
|
||||
bool bFound = false ;
|
||||
bool bOnEnd = false ;
|
||||
vApproxMin.reserve( 4) ;
|
||||
vApproxMin.clear() ;
|
||||
double dUIni, dUFin ;
|
||||
Point3d ptIni, ptFin ;
|
||||
double dMinDist, dSqMinDist ;
|
||||
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
|
||||
bLine ;
|
||||
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
|
||||
// calcolo la distanza del punto dal segmento
|
||||
DistPointLine dstPtLn( ptP, ptIni, ptFin) ;
|
||||
double dSqDist ;
|
||||
if ( ! dstPtLn.GetSqDist( dSqDist))
|
||||
continue ;
|
||||
// altro punto con la stessa minima distanza già trovata
|
||||
if ( bFound && abs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
|
||||
// salvo i dati nella struttura
|
||||
MinDistCalc approxMin ;
|
||||
approxMin.dDist = dMinDist ;
|
||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||
double dPar ;
|
||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||
approxMin.dParMin = dUIni ;
|
||||
@@ -66,8 +63,10 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCV
|
||||
dSqMinDist = dSqDist ;
|
||||
dMinDist = sqrt( dSqMinDist) ;
|
||||
// salvo i dati nella struttura
|
||||
MinDistCalc approxMin ;
|
||||
approxMin.dDist = dMinDist ;
|
||||
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
|
||||
double dPar ;
|
||||
dstPtLn.GetParamAtMinDistPoint( dPar) ;
|
||||
approxMin.dPar = ( 1 - dPar) * dUIni + dPar * dUFin ;
|
||||
approxMin.dParMin = dUIni ;
|
||||
|
||||
Binary file not shown.
+11
-8
@@ -51,7 +51,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
@@ -86,6 +86,7 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir>$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<IncludePath>C:\;$(IncludePath)</IncludePath>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>$(ProjectName)R$(PlatformArchitecture)</TargetName>
|
||||
@@ -101,6 +102,7 @@
|
||||
<OutDir>$(SolutionDir)$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||
<IntDir>$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||
<IncludePath>C:\;$(IncludePath)</IncludePath>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -149,6 +151,7 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -237,10 +240,11 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -364,12 +368,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersCurveCurve.cpp" />
|
||||
<ClCompile Include="IntersLineArc.cpp" />
|
||||
<ClCompile Include="IntersLineLine.cpp" />
|
||||
<ClCompile Include="IntersLinePlane.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="IntersLinePlane.cpp" />
|
||||
<ClCompile Include="IntersLineSurfTm.cpp" />
|
||||
<ClCompile Include="IntersLineTria.cpp" />
|
||||
<ClCompile Include="Intervals.cpp" />
|
||||
@@ -395,6 +394,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="SurfFlatRegionBooleans.cpp" />
|
||||
<ClCompile Include="SurfFlatRegionOffset.cpp" />
|
||||
<ClCompile Include="SurfTriMeshBooleans.cpp" />
|
||||
<ClCompile Include="SurfTriMeshCuts.cpp" />
|
||||
<ClCompile Include="SurfTriMeshUtilities.cpp" />
|
||||
<ClCompile Include="TextureData.cpp" />
|
||||
<ClCompile Include="Tool.cpp" />
|
||||
<ClCompile Include="UserObjDefault.cpp" />
|
||||
@@ -560,6 +561,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="DistPointCrvComposite.h" />
|
||||
<ClInclude Include="DistPointLine.h" />
|
||||
<ClInclude Include="DllMain.h" />
|
||||
<ClInclude Include="earcut.hpp" />
|
||||
<ClInclude Include="ExtDimension.h" />
|
||||
<ClInclude Include="ExtText.h" />
|
||||
<ClInclude Include="FontAux.h" />
|
||||
@@ -588,6 +590,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="IntersArcArc.h" />
|
||||
<ClInclude Include="IntersCrvCompoCrvCompo.h" />
|
||||
<ClInclude Include="IntersLineArc.h" />
|
||||
<ClInclude Include="IntersLineBox.h" />
|
||||
<ClInclude Include="IntersLineLine.h" />
|
||||
<ClInclude Include="IntersLineSurfStd.h" />
|
||||
<ClInclude Include="IntersLineTria.h" />
|
||||
|
||||
@@ -453,6 +453,12 @@
|
||||
<ClCompile Include="CDeRectPrismoidTria.cpp">
|
||||
<Filter>File di origine\GeoCollision</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshUtilities.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshCuts.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -1076,6 +1082,12 @@
|
||||
<ClInclude Include="CDeRectPrismoidTria.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="earcut.hpp">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IntersLineBox.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+4
-1
@@ -49,6 +49,8 @@ ExtDimension::ExtDimension( void)
|
||||
: m_dExtLineLen( STD_EXTLINELEN), m_dArrowLen( STD_ARROWLEN), m_dTextDist( STD_TEXTDIST),
|
||||
m_bLenIsMM( true), m_nDecDigit( STD_DECDIGIT), m_sFont( STD_FONT), m_dTextHeight( STD_TEXTHEIGHT)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -186,7 +188,8 @@ ExtDimension::CopyFrom( const ExtDimension& clSrc)
|
||||
m_nDecDigit = clSrc.m_nDecDigit ;
|
||||
m_sFont = clSrc.m_sFont ;
|
||||
m_dTextHeight = clSrc.m_dTextHeight ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -50,10 +50,11 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IExtDimension
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -148,5 +149,5 @@ class ExtDimension : public IExtDimension, public IGeoObjRW
|
||||
int m_nDecDigit ; // numero di cifre decimali
|
||||
std::string m_sFont ; // font del testo
|
||||
double m_dTextHeight ; // altezza del testo
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
+5
-2
@@ -35,8 +35,10 @@ GEOOBJ_REGISTER( EXT_TEXT, NGE_E_TXT, ExtText) ;
|
||||
//----------------------------------------------------------------------------
|
||||
ExtText::ExtText( void)
|
||||
: m_pSTM( nullptr), m_bNoSTM( false), m_ptP(), m_vtN( 0, 0, 1), m_vtD( 1, 0, 0), m_sFont(),
|
||||
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0), m_nTempProp()
|
||||
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -184,7 +186,8 @@ ExtText::CopyFrom( const ExtText& clSrc)
|
||||
m_dRatio = clSrc.m_dRatio ;
|
||||
m_dAddAdvance = clSrc.m_dAddAdvance ;
|
||||
m_nInsPos = clSrc.m_nInsPos ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,10 +50,11 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IExtText
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -143,5 +144,5 @@ class ExtText : public IExtText, public IGeoObjRW
|
||||
double m_dRatio ; // rapporto tra larghezza e altezza
|
||||
double m_dAddAdvance ; // avanzamento addizionale tra caratteri
|
||||
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
+118
-118
@@ -57,7 +57,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Per Id di entità
|
||||
// Per Id di entità
|
||||
static const int ID_NO = -99 ;
|
||||
// Per tipo di costruzione di poligono
|
||||
static const int POLYG_INSCR = 1 ;
|
||||
@@ -189,7 +189,7 @@ GdbExecutor::Execute( const string& sCmd1, const string& sCmd2, const STRVECTOR&
|
||||
LOG_ERROR( GetEGkLogger(), "Error : null GeomDb in GdbExecutor.")
|
||||
return ER_ERR ;
|
||||
}
|
||||
// verifico validità CmdParser
|
||||
// verifico validità CmdParser
|
||||
if ( m_pParser == nullptr) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error : null CmdParser in GdbExecutor.")
|
||||
return ER_ERR ;
|
||||
@@ -218,7 +218,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 2 o 3 parametri : Id, Id del padre[, Frame]
|
||||
if ( vsParams.size() != 2 && vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -236,7 +236,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, Id del padre, Orig
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -253,7 +253,7 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// creo il gruppo
|
||||
int nIdDest = GetIdParam( vsParams[0], true) ;
|
||||
int nIdNew = m_pGDB->AddGroup( nIdDest, GetIdParam( vsParams[1]), frFrame) ;
|
||||
// se IdDest da calcolare, può essere una variabili a cui cambiare il valore
|
||||
// se IdDest da calcolare, può essere una variabili a cui cambiare il valore
|
||||
if ( nIdDest == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( vsParams[0], nIdNew) ;
|
||||
|
||||
@@ -270,7 +270,7 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, IdParent e punto
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frPnt ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPnt))
|
||||
return false ;
|
||||
@@ -289,7 +289,7 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 4 : Id, IdParent, ptP, vtV
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frPnt ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPnt))
|
||||
return false ;
|
||||
@@ -351,7 +351,7 @@ GdbExecutor::VectorMake( const STRVECTOR& vsParams)
|
||||
// 3 o 4 parametri : Id, IdParent, Vettore [, ScaleFactor]
|
||||
if ( vsParams.size() != 3 && vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -378,7 +378,7 @@ GdbExecutor::VectorFromSpherical( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, dLen, dAngVertDeg, dAngOrizzDeg
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -386,7 +386,7 @@ GdbExecutor::VectorFromSpherical( const STRVECTOR& vsParams)
|
||||
double dLen ;
|
||||
if ( ! GetLengthParam( vsParams[2], dLen))
|
||||
return false ;
|
||||
// recupero l'angolo in verticale (non c'è metodo generale)
|
||||
// recupero l'angolo in verticale (non c'è metodo generale)
|
||||
double dAngVertDeg ;
|
||||
if ( ! FromString( vsParams[3], dAngVertDeg))
|
||||
return false ;
|
||||
@@ -410,7 +410,7 @@ GdbExecutor::VectorCrossProduct( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, vtV1, vtV2 [, bNorm]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -444,7 +444,7 @@ GdbExecutor::VectorDifference( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, ptP1, ptP2 [, bNorm]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -478,7 +478,7 @@ GdbExecutor::VectorBaseVector( const STRVECTOR& vsParams)
|
||||
// 4 o 5 parametri : Id, IdParent, PtBase, Vettore [, ScaleFactor]
|
||||
if ( vsParams.size() != 4 && vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect))
|
||||
return false ;
|
||||
@@ -512,7 +512,7 @@ GdbExecutor::VectorModifyBase( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
// indice dell'oggetto
|
||||
int nId = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frVect ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nId, frVect))
|
||||
return false ;
|
||||
@@ -537,7 +537,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 3 parametri : Id, ParentId, Frame
|
||||
if ( vsParams.size() != 3)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -557,7 +557,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptOrig, ptOnX, ptNearY
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -579,7 +579,7 @@ GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// 4 parametri
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -634,7 +634,7 @@ GdbExecutor::CurveLineMake( const STRVECTOR& vsParams)
|
||||
// 4 parametri : Id, IdParent, ptStart, ptEnd
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -664,7 +664,7 @@ GdbExecutor::CurveLineVersorLength( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, ptStart, vtDir, dLen
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -698,7 +698,7 @@ GdbExecutor::CurveLineDirLength( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, IdParent, ptStart, dAngDeg, dLen
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -863,7 +863,7 @@ GdbExecutor::CurveLineMinPointCurve( const STRVECTOR& vsParams)
|
||||
// porto il punto nel riferimento della curva
|
||||
Point3d ptSloc = ptStart ;
|
||||
ptSloc.LocToLoc( frPoint, frCurve) ;
|
||||
// recupero eventuale parametro per discriminare tra più soluzioni
|
||||
// recupero eventuale parametro per discriminare tra più soluzioni
|
||||
double dNearParam ;
|
||||
if ( vsParams.size() < 5 || ! FromString( vsParams[4], dNearParam))
|
||||
dNearParam = 0 ;
|
||||
@@ -962,7 +962,7 @@ GdbExecutor::CurveCircleMake( const STRVECTOR& vsParams)
|
||||
// 5 parametri
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -996,7 +996,7 @@ GdbExecutor::CurveCirclePlaneXY( const STRVECTOR& vsParams)
|
||||
// 4 parametri
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1026,7 +1026,7 @@ GdbExecutor::CurveArcMake( const STRVECTOR& vsParams)
|
||||
// 8 parametri
|
||||
if ( vsParams.size() != 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1072,7 +1072,7 @@ GdbExecutor::CurveArcPlaneXY( const STRVECTOR& vsParams)
|
||||
// 7 parametri
|
||||
if ( vsParams.size() != 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1114,7 +1114,7 @@ GdbExecutor::CurveArcCircle3P( const STRVECTOR& vsParams, bool bCirc)
|
||||
// 5 parametri : Id, ParentId, ptP0, ptP1, ptP2
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1148,7 +1148,7 @@ GdbExecutor::CurveArc2PDi( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptPi, ptPf, dDiri
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1164,7 +1164,7 @@ GdbExecutor::CurveArc2PDi( const STRVECTOR& vsParams)
|
||||
double dDirI ;
|
||||
if ( ! GetDirParam( vsParams[4], frRef, dDirI))
|
||||
return false ;
|
||||
// calcolo l'arco (in casi particolari può essere una retta)
|
||||
// calcolo l'arco (in casi particolari può essere una retta)
|
||||
ICurve* pCurve = GetArc2PD( ptPi, ptPf, dDirI) ;
|
||||
if ( pCurve == nullptr)
|
||||
return false ;
|
||||
@@ -1179,7 +1179,7 @@ GdbExecutor::CurveArc2PRS( const STRVECTOR& vsParams)
|
||||
// 5 o 6 parametri : Id, ParentId, ptPi, ptPf, dRad[, CCW/CW]
|
||||
if ( vsParams.size() != 5 && vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1217,7 +1217,7 @@ GdbExecutor::CurveArcC2P( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptCen, ptPi, ptNearPf
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1251,7 +1251,7 @@ GdbExecutor::CurveCircleCenterTgArc( const STRVECTOR& vsParams)
|
||||
// 5 parametri : Id, ParentId, ptCen, IdArc, ptNear
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1297,7 +1297,7 @@ GdbExecutor::CurveArcCenterTgArcP( const STRVECTOR& vsParams)
|
||||
// 6 parametri : Id, ParentId, ptCen, IdArc, ptNearTg, ptNearEnd
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1349,7 +1349,7 @@ GdbExecutor::CurveArcPDiTgArc( const STRVECTOR& vsParams)
|
||||
// 6 parametri : Id, ParentId, ptStart, dirStart, IdArc, ptNear
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frDest ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
|
||||
return false ;
|
||||
@@ -1382,7 +1382,7 @@ GdbExecutor::CurveArcPDiTgArc( const STRVECTOR& vsParams)
|
||||
return false ;
|
||||
Point3d ptNtloc = ptNear ;
|
||||
ptNtloc.LocToLoc( frDest, frTgArc) ;
|
||||
// calcolo l'arco (in casi particolari può essere una linea)
|
||||
// calcolo l'arco (in casi particolari può essere una linea)
|
||||
ICurve* pCurve = GetArcPntDirTgCurve( ptSloc, FromPolar( 1, dDirI), *pTgArc, ptNtloc, Z_AX) ;
|
||||
if ( pCurve == nullptr)
|
||||
return false ;
|
||||
@@ -1521,7 +1521,7 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// inizializzo la curva di Bezier
|
||||
if ( ! pCrvBez->Init( nDeg, false))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1547,7 +1547,7 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// inizializzo la curva di Bezier
|
||||
if ( ! pCrvBez->Init( nDeg, true))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1949,7 +1949,7 @@ GdbExecutor::CurveCompoFromPolygon( const STRVECTOR& vsParams, int nType)
|
||||
int nNumLati ;
|
||||
if ( ! FromString( vsParams[2], nNumLati))
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -1994,7 +1994,7 @@ GdbExecutor::CurveCompoFromBiarc( const STRVECTOR& vsParams)
|
||||
// 6 o 7 parametri : Id, IdParent, ptP1, Dir1, ptP2, Dir2 [, Par]
|
||||
if ( vsParams.size() != 6 && vsParams.size() != 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2074,7 +2074,7 @@ GdbExecutor::CurveCompoExtractCurve( const STRVECTOR& vsParams, bool bEndOrStart
|
||||
Frame3d frSou ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdCCompo, frSou))
|
||||
return false ;
|
||||
// estraggo la opportuna entità
|
||||
// estraggo la opportuna entità
|
||||
PtrOwner<ICurve> pCrv( pCrvCompo->RemoveFirstOrLastCurve( bEndOrStart)) ;
|
||||
// se 1 solo parametro -> cancellazione
|
||||
if ( vsParams.size() == 1)
|
||||
@@ -2161,7 +2161,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
else if ( sCmd2 == "COMP" || sCmd2 == "DOCOMPACTING") {
|
||||
return SurfTriMeshDoCompacting( vsParams) ;
|
||||
}
|
||||
// se unione di due o più superfici per cucitura
|
||||
// se unione di due o più superfici per cucitura
|
||||
else if ( sCmd2 == "SEW" || sCmd2 == "DOSEWING") {
|
||||
return SurfTriMeshDoSewing( vsParams) ;
|
||||
}
|
||||
@@ -2395,7 +2395,7 @@ GdbExecutor::SurfTriMeshByExtrusion( const STRVECTOR& vsParams)
|
||||
CurveLocal CrvLoc( m_pGDB, nCrvId, frDest) ;
|
||||
if ( CrvLoc.Get() == nullptr)
|
||||
return false ;
|
||||
// recupero il vettore di estrusione (già in locale)
|
||||
// recupero il vettore di estrusione (già in locale)
|
||||
Vector3d vtExtr ;
|
||||
if ( ! GetVectorParam( vsParams[3], frDest, vtExtr))
|
||||
return false ;
|
||||
@@ -2471,7 +2471,7 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams)
|
||||
// recupero la tolleranza lineare
|
||||
if ( vsParams.size() == 7)
|
||||
FromString( vsParams[6], dLinTol) ;
|
||||
// non c'é movimento lungo l'asse
|
||||
// non c'é movimento lungo l'asse
|
||||
}
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
@@ -2642,7 +2642,7 @@ GdbExecutor::SurfTrimeshClonePart( const STRVECTOR& vsParams)
|
||||
// Parametri : IdNew, IdOld, IdParent, nPart
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// Recupero il riferimento in cui è immerso
|
||||
// Recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[2]), frRef))
|
||||
return false ;
|
||||
@@ -2785,7 +2785,7 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptO, dLengthX, dLengthY, dLengthZ, dPrec [, bTriDexel]
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2829,7 +2829,7 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, idCurv, dPrec, dLengthZ [, bTriDexel]
|
||||
if ( vsParams.size() < 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2867,7 +2867,7 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, idSurf, dPrec, bFlag
|
||||
if ( vsParams.size() != 5)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -2900,7 +2900,7 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (dLinTol e dAngTol sono per lavo con gen tool), bType
|
||||
if ( vsParams.size() != 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3019,7 +3019,7 @@ bool GdbExecutor::VolZmapDeepnessMeasure( const STRVECTOR& vsParams) {
|
||||
VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
if ( pZmap == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3051,7 +3051,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
if ( pZmap == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
// recupero il riferimento in cui è immerso lo Zmap
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3096,7 +3096,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
// VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
// if ( pZmap == nullptr)
|
||||
// return false ;
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// Frame3d frRef ;
|
||||
// if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
// return false ;
|
||||
@@ -3143,7 +3143,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams)
|
||||
// VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ;
|
||||
// if ( pZmap == nullptr)
|
||||
// return false;
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// // recupero il riferimento in cui è immerso lo Zmap
|
||||
// Frame3d frRef ;
|
||||
// if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
// return false ;
|
||||
@@ -3213,7 +3213,7 @@ GdbExecutor::LineDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3281,7 +3281,7 @@ GdbExecutor::RayDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3349,7 +3349,7 @@ GdbExecutor::SegmentDiscInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptDisc, ptLine, vtDisc, vtLine, dRad, dLen
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3421,7 +3421,7 @@ GdbExecutor::LineSphereInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptC, ptP, vtV, dRad
|
||||
if ( vsParams.size() < 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3472,7 +3472,7 @@ GdbExecutor::RaySphereInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptC, ptP, vtV, dRad
|
||||
if ( vsParams.size() < 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3530,7 +3530,7 @@ GdbExecutor::SegmentSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtV, dRad, dLen
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3594,7 +3594,7 @@ GdbExecutor::LineSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3651,7 +3651,7 @@ GdbExecutor::RaySemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3714,7 +3714,7 @@ GdbExecutor::SegmentSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad, dLen
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3783,7 +3783,7 @@ GdbExecutor::LinCompSemiSphereInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptC, ptP, vtSphOr, vtV, dRad, dLen, nLinType
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3854,7 +3854,7 @@ GdbExecutor::LineInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3923,7 +3923,7 @@ GdbExecutor::RayInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad
|
||||
if ( vsParams.size() < 7)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -3992,7 +3992,7 @@ GdbExecutor::SegmentInfiniteCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad, dLen
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4064,7 +4064,7 @@ GdbExecutor::SegmentCylinderInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptCyl, ptLine, vtCyl, vtLine, dRad, dCylHeigth, dLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4140,7 +4140,7 @@ GdbExecutor::SegmentConeInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptVCone, ptLine, vtCone, vtLine, dRad, dCylHeigth, dLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4221,7 +4221,7 @@ GdbExecutor::LineTruncateConeInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4303,7 +4303,7 @@ GdbExecutor::RayTruncateConeInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4384,7 +4384,7 @@ GdbExecutor::SegmentTruncateConeInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptMinBase, ptLine, vtCone, vtLine, dMinRad, dMaxRad, dConeHeigth
|
||||
if ( vsParams.size() < 10)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4469,7 +4469,7 @@ GdbExecutor::LineTorusInters( const STRVECTOR& vsParams)
|
||||
{ // parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad,
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4584,7 +4584,7 @@ GdbExecutor::RayTorusInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad,
|
||||
if ( vsParams.size() < 8)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4734,7 +4734,7 @@ GdbExecutor::SegmentTorusInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad, dSgLen
|
||||
if ( vsParams.size() < 9)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -4903,7 +4903,7 @@ GdbExecutor::LinCompTorusPartInters( const STRVECTOR& vsParams)
|
||||
// parametri : Id, IdParent, ptTorus, ptLine, vtTorus, vtLine, dMinRad, dMaxRad, dSgLen, nLinType
|
||||
if ( vsParams.size() < 10)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5124,7 +5124,7 @@ GdbExecutor::ExecuteDistPointTrimesh( const std::string& sCmd2, const STRVECTOR&
|
||||
// parametri : Id, IdMovedTria, IdParent, ptP, idSurf
|
||||
if ( vsParams.size() != 4)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5228,7 +5228,7 @@ GdbExecutor::TextSimple( const STRVECTOR& vsParams)
|
||||
// parametri : Id, ParentId, Text, Point, AngDeg, H
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5266,7 +5266,7 @@ GdbExecutor::TextComplete( const STRVECTOR& vsParams)
|
||||
// parametri : Id, ParentId, Text, Point, AngDeg, Font, W, Italic, H, Rat, AddAdv, PosIns
|
||||
if ( vsParams.size() != 12)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frRef ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef))
|
||||
return false ;
|
||||
@@ -5486,7 +5486,7 @@ GdbExecutor::AddGeoObj( const string& sId, const string& sIdParent, IGeoObj* pGe
|
||||
// creo il gruppo
|
||||
int nId = GetIdParam( sId, true) ;
|
||||
int nIdNew = m_pGDB->AddGeoObj( nId, GetIdParam( sIdParent), pGeoObj) ;
|
||||
// se nId da calcolare, può essere una variabile a cui cambiare il valore
|
||||
// se nId da calcolare, può essere una variabile a cui cambiare il valore
|
||||
if ( nId == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( sId, nIdNew) ;
|
||||
|
||||
@@ -5600,9 +5600,9 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -5623,7 +5623,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se entità geometrica
|
||||
// se entità geometrica
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) {
|
||||
// se curva
|
||||
@@ -5659,7 +5659,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
return false ;
|
||||
return vtV.LocToLoc( frEnt, frVect) ;
|
||||
}
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
@@ -5669,7 +5669,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
ICurve::Side nSide = ICurve::FROM_MINUS ;
|
||||
if ( vsParams.size() >= 3 && vsParams[2] == "+")
|
||||
nSide = ICurve::FROM_PLUS ;
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
double dU ;
|
||||
@@ -5723,7 +5723,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// altrimenti nome di vettore già nel DB
|
||||
// altrimenti nome di vettore già nel DB
|
||||
else {
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
const IGeoVector3d* pV ;
|
||||
@@ -5742,7 +5742,7 @@ GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector
|
||||
bool
|
||||
GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& ptP)
|
||||
{
|
||||
// se insieme di 2 o 3 coordinate (considerate già nel riferimento frPnt)
|
||||
// se insieme di 2 o 3 coordinate (considerate già nel riferimento frPnt)
|
||||
if ( sParam[0] == '(') {
|
||||
// divido in parti
|
||||
STRVECTOR vsParams ;
|
||||
@@ -5766,7 +5766,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
// se altrimenti punto predefinito ORIG (considerato già nel riferimento frPnt)
|
||||
// se altrimenti punto predefinito ORIG (considerato già nel riferimento frPnt)
|
||||
else if ( sParam == "ORIG") {
|
||||
ptP = ORIG ;
|
||||
return true ;
|
||||
@@ -5784,9 +5784,9 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
// recupero l'indice dell'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -5801,7 +5801,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se entità geometrica
|
||||
// se entità geometrica
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) {
|
||||
// se curva
|
||||
@@ -5835,13 +5835,13 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
return false ;
|
||||
return ptP.LocToLoc( frEnt, frPnt) ;
|
||||
}
|
||||
case 'N' : // punto più vicino a punto dato
|
||||
case 'N' : // punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
if ( vsParams.size() < 2 || ! GetPointParam( vsParams[1], frEnt, ptRef))
|
||||
return false ;
|
||||
// calcolo il punto della curva più vicino al punto di riferimento
|
||||
// calcolo il punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
if ( ! dstPC.GetMinDistPoint( 0, ptP, nFlag))
|
||||
@@ -5859,11 +5859,11 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
const ICurve* pCrv2 = GetCurve( pGObj2) ;
|
||||
if ( pCrv2 == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt2 ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt2, frEnt2))
|
||||
return false ;
|
||||
// se il riferimento è diverso da quello della prima entità, devo trasformarla
|
||||
// se il riferimento è diverso da quello della prima entità, devo trasformarla
|
||||
PtrOwner<ICurve> pcrvTrans( nullptr) ;
|
||||
if ( ! AreSameFrame( frEnt, frEnt2)) {
|
||||
pcrvTrans.Set( pCrv2->Clone()) ;
|
||||
@@ -5876,7 +5876,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
Point3d ptRef ;
|
||||
if ( vsParams.size() >= 3 && ! GetPointParam( vsParams[2], frEnt, ptRef))
|
||||
return false ;
|
||||
// calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento
|
||||
// calcolo il punto di intersezione sulla prima curva più vicino al punto di riferimento
|
||||
IntersCurveCurve intCC( *pCrv, *pCrv2, true) ;
|
||||
if ( ! intCC.GetIntersPointNearTo( 0, ptRef, ptP))
|
||||
return false ;
|
||||
@@ -5938,7 +5938,7 @@ GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d&
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// altrimenti nome di punto già nel DB
|
||||
// altrimenti nome di punto già nel DB
|
||||
else {
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
const IGeoPoint3d* pPt ;
|
||||
@@ -6015,7 +6015,7 @@ GdbExecutor::GetPointWParam( const string& sParam, const Frame3d& frPnt, Point3d
|
||||
FromString( vsParams[1], ptP.y) &&
|
||||
FromString( vsParams[2], dW)) ;
|
||||
}
|
||||
// se 2 parti, nome di punto predefinito, punto notevole o già nel DB e un peso
|
||||
// se 2 parti, nome di punto predefinito, punto notevole o già nel DB e un peso
|
||||
else if ( vsParams.size() == 2) {
|
||||
// recupero il punto
|
||||
if ( ! GetPointParam( vsParams[0], frPnt, ptP))
|
||||
@@ -6065,7 +6065,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen)
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) == nullptr)
|
||||
return false ;
|
||||
@@ -6088,7 +6088,7 @@ GdbExecutor::GetLengthParam( const string& sParam, double& dLen)
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) == nullptr)
|
||||
return false ;
|
||||
@@ -6124,12 +6124,12 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
// ci deve essere almeno un parametro
|
||||
if ( vsParams.size() < 1)
|
||||
return false ;
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
// recupero l'entità indicata dal primo parametro
|
||||
int nIdEnt = GetIdParam( vsParams[0]) ;
|
||||
const IGeoObj* pGObj ;
|
||||
if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) == nullptr)
|
||||
return false ;
|
||||
// recupero il riferimento in cui è immersa
|
||||
// recupero il riferimento in cui è immersa
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -6143,7 +6143,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetStartDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6154,7 +6154,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetEndDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6165,7 +6165,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
if ( ! pCrv->GetMidDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir))
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6196,7 +6196,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
case 'N' : // versore direzione nel punto più vicino a punto dato
|
||||
{
|
||||
// secondo parametro : punto di riferimento
|
||||
Point3d ptRef ;
|
||||
@@ -6206,7 +6206,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
ICurve::Side nSide = ICurve::FROM_MINUS ;
|
||||
if ( vsParams.size() >= 3 && vsParams[2] == "+")
|
||||
nSide = ICurve::FROM_PLUS ;
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
// calcolo il parametro del punto della curva più vicino al punto di riferimento
|
||||
DistPointCurve dstPC( ptRef, *pCrv) ;
|
||||
int nFlag ;
|
||||
double dU ;
|
||||
@@ -6236,7 +6236,7 @@ GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dD
|
||||
Vector3d vtDir = pGVect->GetVector() ;
|
||||
vtDir.LocToLoc( frEnt, frDir) ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir) ;
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
// se esiste un secondo parametro è un offset di rotazione
|
||||
if ( vsParams.size() >= 2) {
|
||||
double dOffsetDeg = 0 ;
|
||||
FromString( vsParams[1], dOffsetDeg) ;
|
||||
@@ -6294,7 +6294,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
STRVECTOR::iterator Iter ;
|
||||
for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter)
|
||||
Trim( (*Iter), " \t\r\n") ;
|
||||
// se c'è un parametro è l'origine
|
||||
// se c'è un parametro è l'origine
|
||||
Point3d ptOrig ;
|
||||
if ( vsParams.size() >= 1) {
|
||||
if ( ! GetPointParam( vsParams[0], frRef, ptOrig))
|
||||
@@ -6325,11 +6325,11 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// altrimenti nome di gruppo o di frame già nel DB
|
||||
// altrimenti nome di gruppo o di frame già nel DB
|
||||
else {
|
||||
// identificativo
|
||||
int nIdEnt = GetIdParam( sParam) ;
|
||||
// recupero il riferimento in cui è immerso
|
||||
// recupero il riferimento in cui è immerso
|
||||
Frame3d frEnt ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt))
|
||||
return false ;
|
||||
@@ -6337,7 +6337,7 @@ GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d&
|
||||
if ( m_pGDB->GetGroupFrame( nIdEnt, frF)) {
|
||||
return frF.LocToLoc( frEnt, frRef) ;
|
||||
}
|
||||
// altrimenti entità geometrica
|
||||
// altrimenti entità geometrica
|
||||
else {
|
||||
// verifico se riferimento
|
||||
const IGeoFrame3d* pFr ;
|
||||
@@ -6393,7 +6393,7 @@ GdbExecutor::GetColorParam( const string& sParam, bool& bByParent, Color& cCol)
|
||||
// ci deve essere un parametro
|
||||
if ( vsParams.size() != 1)
|
||||
return false ;
|
||||
// recupero il colore dell'entità indicata dal parametro
|
||||
// recupero il colore dell'entità indicata dal parametro
|
||||
bByParent = false ;
|
||||
return m_pGDB->GetCalcMaterial( GetIdParam( vsParams[0]), cCol) ;
|
||||
}
|
||||
@@ -6427,7 +6427,7 @@ GdbExecutor::GetMaterialParam( const string& sParam, bool& bByParent, int& nMat)
|
||||
// ci deve essere un parametro
|
||||
if ( vsParams.size() != 1)
|
||||
return false ;
|
||||
// recupero il materiale dell'entità indicata dal parametro
|
||||
// recupero il materiale dell'entità indicata dal parametro
|
||||
bByParent = false ;
|
||||
return ( m_pGDB->GetCalcMaterial( GetIdParam( vsParams[0]), nMat) && nMat != GDB_MT_COLOR) ;
|
||||
}
|
||||
@@ -6975,7 +6975,7 @@ GdbExecutor::ExecuteCopy( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
nIdNew = m_pGDB->CopyGlob( GetIdParam( vsParams[0]), nIdDest, GetIdParam( vsParams[2]), nSonBeforeAfter) ;
|
||||
else
|
||||
nIdNew = m_pGDB->Copy( GetIdParam( vsParams[0]), nIdDest, GetIdParam( vsParams[2]), nSonBeforeAfter) ;
|
||||
// se IdDest da calcolare, può essere una variabile a cui cambiare il valore
|
||||
// se IdDest da calcolare, può essere una variabile a cui cambiare il valore
|
||||
if ( nIdDest == GDB_ID_NULL)
|
||||
m_pParser->SetVariable( vsParams[1], nIdNew) ;
|
||||
|
||||
@@ -7647,7 +7647,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams)
|
||||
IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ;
|
||||
// recupero la classificazione della prima curva
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! intCC.GetCurveClassification( 0, ccClass))
|
||||
if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// recupero gli indici dei gruppi destinazione e i loro riferimenti
|
||||
const int N_GRP = 4 ;
|
||||
@@ -7877,7 +7877,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// devono essere 6 parametri : IdText, IdGroup, IdEnt1, IdEnt2, ptText, hText
|
||||
if ( vsParams.size() != 6)
|
||||
return false ;
|
||||
// recupero l'indice delle entità
|
||||
// recupero l'indice delle entità
|
||||
int nIdEnt1 = GetIdParam( vsParams[2]) ;
|
||||
int nIdEnt2 = GetIdParam( vsParams[3]) ;
|
||||
// verifico siano due curve
|
||||
@@ -7894,7 +7894,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
Frame3d frEnt2 ;
|
||||
if ( ! m_pGDB->GetGlobFrame( nIdEnt2, frEnt2))
|
||||
return false ;
|
||||
// se i riferimenti sono diversi, porto la seconda entità nel riferimento della prima
|
||||
// se i riferimenti sono diversi, porto la seconda entità nel riferimento della prima
|
||||
PtrOwner<ICurve> pcrvTrans ;
|
||||
if ( ! AreSameFrame( frEnt1, frEnt2)) {
|
||||
pcrvTrans.Set( pCrv2->Clone()) ;
|
||||
@@ -7953,7 +7953,7 @@ GdbExecutor::ExecuteOutTextIcci( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
// recupero il riferimento in cui è immerso il testo
|
||||
// recupero il riferimento in cui è immerso il testo
|
||||
Frame3d frText ;
|
||||
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frText))
|
||||
return false ;
|
||||
@@ -8090,7 +8090,7 @@ bool
|
||||
GdbExecutor::OutGroupTsc( int nId, int nFlag, int nLev)
|
||||
{
|
||||
m_OutTsc.Remark( "Start Group ---") ;
|
||||
// emetto dati gruppo ( se non è radice)
|
||||
// emetto dati gruppo ( se non è radice)
|
||||
if ( nId > GDB_ID_ROOT) {
|
||||
Frame3d frFrame ;
|
||||
if ( ( nLev == 0 && m_pGDB->GetGroupGlobFrame( nId, frFrame)) ||
|
||||
@@ -8113,7 +8113,7 @@ GdbExecutor::OutGroupTsc( int nId, int nFlag, int nLev)
|
||||
}
|
||||
}
|
||||
}
|
||||
// emetto entità gruppo
|
||||
// emetto entità gruppo
|
||||
m_OutTsc.Remark( "Entities :") ;
|
||||
GdbIterator Iter( m_pGDB) ;
|
||||
bool bNext = Iter.GoToFirstInGroup( nId) ;
|
||||
|
||||
+3
-2
@@ -32,8 +32,9 @@ using namespace std ;
|
||||
//----------------------------------------------------------------------------
|
||||
GdbObj::GdbObj( void)
|
||||
: m_nId( GDB_ID_NULL), m_pAttribs( nullptr), m_pTxrData( nullptr), m_pUserObj( nullptr),
|
||||
m_pSelPrev( nullptr), m_pSelNext( nullptr),
|
||||
m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr)
|
||||
m_pGDB( nullptr), m_pNext( nullptr), m_pPrev( nullptr), m_pParent( nullptr),
|
||||
m_pSelNext( nullptr), m_pSelPrev( nullptr)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -29,8 +29,10 @@ GEOOBJ_REGISTER( GEO_FRAME3D, NGE_G_FRM, GeoFrame3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoFrame3d::GeoFrame3d( void)
|
||||
: m_frF(), m_nTempProp()
|
||||
: m_frF()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -114,7 +116,8 @@ GeoFrame3d::CopyFrom( const GeoFrame3d& gfSrc)
|
||||
{
|
||||
if ( &gfSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = gfSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = gfSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = gfSrc.m_nTempProp[1] ;
|
||||
return Set( gfSrc.m_frF) ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -57,10 +57,11 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoFrame3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -95,5 +96,5 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Frame3d m_frF ; // oggetto
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
+5
-2
@@ -28,8 +28,10 @@ GEOOBJ_REGISTER( GEO_PNT3D, NGE_G_PNT, GeoPoint3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoPoint3d::GeoPoint3d( void)
|
||||
: m_ptP(), m_nTempProp()
|
||||
: m_ptP()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -82,7 +84,8 @@ GeoPoint3d::CopyFrom( const GeoPoint3d& clSrc)
|
||||
{
|
||||
if ( &clSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_ptP) ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -57,10 +57,11 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoPoint3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -89,5 +90,5 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Point3d m_ptP ; // oggetto
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
+5
-2
@@ -29,8 +29,10 @@ GEOOBJ_REGISTER( GEO_VECT3D, NGE_G_VEC, GeoVector3d) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
GeoVector3d::GeoVector3d( void)
|
||||
: m_vtV(), m_nTempProp()
|
||||
: m_vtV()
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -98,7 +100,8 @@ GeoVector3d::CopyFrom( const GeoVector3d& clSrc)
|
||||
{
|
||||
if ( &clSrc == this)
|
||||
return true ;
|
||||
m_nTempProp = clSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = clSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = clSrc.m_nTempProp[1] ;
|
||||
return Set( clSrc.m_vtV, clSrc.m_ptBase) ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -65,10 +65,11 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IGeoVector3d
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -104,5 +105,5 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Vector3d m_vtV ; // oggetto
|
||||
Point3d m_ptBase ; // punto base da cui tracciare il vettore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
@@ -684,7 +684,6 @@ HashGrids3d::Update( void)
|
||||
double dSize = 0 ;
|
||||
Obj.box.GetDiameter( dSize) ;
|
||||
double dCellSpan = pGrid->GetCellSpan() ;
|
||||
|
||||
if ( dSize >= dCellSpan || dSize < ( dCellSpan / hierarchyFactor)) {
|
||||
pGrid->Remove( Obj) ;
|
||||
addGrid( Obj) ;
|
||||
|
||||
+10
-8
@@ -391,7 +391,7 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR& ccClass)
|
||||
{
|
||||
// pulisco vettore classificazioni
|
||||
ccClass.clear() ;
|
||||
@@ -407,7 +407,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
return false ;
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[0], m_Info, ccClass) ;
|
||||
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
||||
@@ -424,7 +424,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass)
|
||||
SwapInfoAB( InfoTmp, 1) ;
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ;
|
||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
||||
@@ -461,7 +461,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass)
|
||||
IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, double dLenMin, CRVCVECTOR& ccClass)
|
||||
{
|
||||
// numero intersezioni
|
||||
int nNumInters = int( Info.size()) ;
|
||||
@@ -471,6 +471,8 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
double dStartPar, dEndPar ;
|
||||
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||
return false ;
|
||||
// limito lunghezza minima
|
||||
dLenMin = max( dLenMin, EPS_ZERO) ;
|
||||
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
||||
ICCIVECTOR InfoCorr ;
|
||||
InfoCorr.reserve( Info.size()) ;
|
||||
@@ -527,7 +529,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||
// se è definito un tratto precedente
|
||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > EPS_SMALL) {
|
||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia omogenea e valida
|
||||
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
||||
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
||||
@@ -562,7 +564,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
}
|
||||
}
|
||||
// eventuale tratto finale rimasto
|
||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > EPS_SMALL) {
|
||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia valida
|
||||
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
||||
return false ;
|
||||
@@ -673,7 +675,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
||||
{
|
||||
// classifico la prima curva rispetto alla seconda
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! GetCurveClassification( 0, ccClass))
|
||||
if ( ! GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||
return CCREGC_NULL ;
|
||||
// derivo la classificazione delle curve come regioni
|
||||
bool bIn = false ;
|
||||
@@ -710,7 +712,7 @@ IntersCurveCurve::GetRegionCurveClassification( void)
|
||||
if ( bOnP)
|
||||
return CCREGC_IN2 ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ! GetCurveClassification( 1, ccClass2) || ccClass2.empty())
|
||||
if ( ! GetCurveClassification( 1, EPS_SMALL, ccClass2) || ccClass2.empty())
|
||||
return CCREGC_NULL ;
|
||||
if ( ccClass2[0].nClass == CRVC_OUT)
|
||||
return CCREGC_OUT ;
|
||||
|
||||
+127
-108
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
// EgalTech 2020-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// File : IntersLineBox.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
//
|
||||
//
|
||||
@@ -13,13 +13,77 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
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.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2)
|
||||
{
|
||||
// Verifico il versore
|
||||
if ( vtL.IsSmall())
|
||||
return false ;
|
||||
|
||||
// Verifico gli estremi del box
|
||||
if ( ptMin.x > ptMax.x + EPS_SMALL ||
|
||||
ptMin.y > ptMax.y + EPS_SMALL ||
|
||||
ptMin.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtL.x) < EPS_ZERO && ( ptL.x < ptMin.x - EPS_SMALL || ptL.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.y) < EPS_ZERO && ( ptL.y < ptMin.y - EPS_SMALL || ptL.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtL.z) < EPS_ZERO && ( ptL.z < ptMin.z - EPS_SMALL || ptL.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Parametri degli estremi della retta
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtL.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
else if ( vtL.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptL.x) / vtL.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptL.x) / vtL.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtL.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
else if ( vtL.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptL.y) / vtL.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptL.y) / vtL.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtL.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
else if ( vtL.z < -EPS_ZERO){
|
||||
dU1 = max( dU1, ( ptMax.z - ptL.z) / vtL.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptL.z) / vtL.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL1, const Point3d& ptL2, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
@@ -38,114 +102,69 @@ bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3d& b3Box, INTDBLVECTOR& vInters, bool bFinite)
|
||||
{
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
Point3d ptMin, ptMax ;
|
||||
if ( ! b3Box.GetMinMax( ptMin, ptMax))
|
||||
return false ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0, 0)) ;
|
||||
PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY, 0)) ;
|
||||
PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY, 0)) ;
|
||||
PL.Close() ;
|
||||
// Vettore altezza
|
||||
Vector3d vtExtr( 0, 0, dDimZ) ;
|
||||
// Creo la superficie trimesh equivalente
|
||||
SurfTriMesh Stm ;
|
||||
if ( ! Stm.CreateByExtrusion( PL, vtExtr))
|
||||
return false ;
|
||||
SurfTriMesh StmBot ;
|
||||
if ( ! StmBot.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmBot.Invert() ;
|
||||
SurfTriMesh StmTop ;
|
||||
if ( ! StmTop.CreateByFlatContour( PL))
|
||||
return false ;
|
||||
StmTop.Translate( vtExtr) ;
|
||||
if ( ! Stm.DoSewing( StmBot) || ! Stm.DoSewing( StmTop))
|
||||
return false ;
|
||||
// Calcolo l'intersezione
|
||||
ILSIVECTOR vInfo ;
|
||||
if ( ! IntersLineSurfTm( ptL, vtL, dLen, Stm, vInfo, bFinite))
|
||||
return false ;
|
||||
// ciclo sulle intersezioni
|
||||
double dUcurr = -INFINITO ;
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
int nFlag = ILBT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = ILBT_OUT ;
|
||||
else if ( Info.dCosDN < -EPS_ZERO)
|
||||
nFlag = ILBT_IN ;
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
dUcurr = Info.dU ;
|
||||
|
||||
// Pulisco vettore intersezioni
|
||||
vInters.clear() ;
|
||||
|
||||
// Eseguo intersezione della linea completa
|
||||
double dU1, dU2 ;
|
||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||
|
||||
// Se non c'è intersezione
|
||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||
return true ;
|
||||
|
||||
// Se le due intersezioni coincidono
|
||||
if ( ( dU2 - dU1) < EPS_SMALL) {
|
||||
double dU = ( dU1 + dU2) / 2 ;
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TOUCH, dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
if ( Info.dU > dUcurr - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Info.dU2) ;
|
||||
dUcurr = Info.dU2 ;
|
||||
else {
|
||||
if ( dU > - EPS_SMALL && dU < dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TOUCH, Clamp( dU, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
// elimino intersezioni ripetute
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se sono dello stesso tipo, elimino una delle due
|
||||
if ( vInters[i].first == vInters[j].first) {
|
||||
// se entranti elimino la prima
|
||||
if ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_TG_INI)
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
// altrimenti la seconda
|
||||
else
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se hanno lo stesso parametro
|
||||
else if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se una entrante e l'altra uscente, cambio in touch ed elimino la seconda
|
||||
if ( ( vInters[i].first == ILBT_IN && vInters[j].first == ILBT_OUT) ||
|
||||
( vInters[i].first == ILBT_OUT && vInters[j].first == ILBT_IN)) {
|
||||
vInters[i].first = ILBT_TOUCH ;
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima puntuale e l'altra inizio o fine di coincidenza, elimino la prima
|
||||
else if ( ( vInters[i].first == ILBT_IN || vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TOUCH) &&
|
||||
( vInters[j].first == ILBT_TG_INI || vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se prima inizio o fine di coincidenza e l'altra puntuale, elimino la seconda
|
||||
else if ( ( vInters[i].first == ILBT_TG_INI || vInters[i].first == ILBT_TG_FIN) &&
|
||||
( vInters[j].first == ILBT_IN || vInters[j].first == ILBT_OUT || vInters[j].first == ILBT_TOUCH)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
// se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe
|
||||
else if ( ( vInters[i].first == ILBT_TG_FIN && vInters[j].first == ILBT_TG_INI) ||
|
||||
( vInters[i].first == ILBT_TG_INI && vInters[j].first == ILBT_TG_FIN)) {
|
||||
vInters.erase( vInters.begin() + j) ;
|
||||
vInters.erase( vInters.begin() + i) ;
|
||||
if ( i > 0)
|
||||
-- j ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
// passo alla successiva
|
||||
++ j ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Se sono due intersezioni con la linea giacente su una faccia del box
|
||||
if ( ( abs( vtL.x) < EPS_ZERO && ( abs( ptL.x - ptMin.x) < EPS_SMALL || abs( ptL.x - ptMax.x) < EPS_SMALL)) ||
|
||||
( abs( vtL.y) < EPS_ZERO && ( abs( ptL.y - ptMin.y) < EPS_SMALL || abs( ptL.y - ptMax.y) < EPS_SMALL)) ||
|
||||
( abs( vtL.z) < EPS_ZERO && ( abs( ptL.z - ptMin.z) < EPS_SMALL || abs( ptL.z - ptMax.z) < EPS_SMALL))) {
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_TG_INI, dU1) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Altrimenti sono due intersezioni con attraversamento
|
||||
if ( ! bFinite) {
|
||||
vInters.emplace_back( ILBT_IN, dU1) ;
|
||||
vInters.emplace_back( ILBT_OUT, dU2) ;
|
||||
}
|
||||
else {
|
||||
if ( dU1 > dLen - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_IN, dLen) ;
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2022-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.h Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Dichiarazione delle funzioni base per intersezione linea/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.01.22 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Linea e box allineato agli assi sono nel medesimo riferimento.
|
||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
TestIntersLineBox( const Point3d& ptL, const Vector3d& vtL,
|
||||
const Point3d& ptMin, const Point3d& ptMax)
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineBox( ptL, vtL, ptMin, ptMax, dU1, dU2) ;
|
||||
}
|
||||
+3
-56
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2017-2018
|
||||
// EgalTech 2017-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfStd.cpp Data : 03.12.18 Versione : 1.9l1
|
||||
// File : IntersLineSurfStd.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione delle funzioni di intersezione
|
||||
// componente lineare e superficie standard.
|
||||
//
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
@@ -21,60 +22,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono essere espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di questo sistema di riferimento.
|
||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2)
|
||||
{
|
||||
// Casi di intersezione impossibile
|
||||
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.y) < EPS_ZERO && ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL))
|
||||
return false ;
|
||||
if ( abs( vtV.z) < EPS_ZERO && ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// Inizializzo parametri intersezioni
|
||||
dU1 = -INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// Confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtV.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( vtV.x < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
|
||||
// Confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtV.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( vtV.y < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
|
||||
// Confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtV.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( vtV.z < -EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine,
|
||||
|
||||
@@ -34,11 +34,6 @@
|
||||
// Costanti tipologia di componente lineare
|
||||
enum LinType { Line = 0, Ray = 1, Segment = 2} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ;
|
||||
|
||||
|
||||
// Costanti tipologia di intersezioni fra un componente lineare e un disco
|
||||
enum LinCompDiscIntersType { D_ERROR_INT = -1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1,
|
||||
D_INNER_INT_LINE_NOT_IN_PLANE = 2, D_ONE_INT_LINE_ON_PLANE = 3,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2019
|
||||
// EgalTech 2015-2022
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineSurfTm.cpp Data : 09.03.15 Versione : 2.1b6
|
||||
// File : IntersLineSurfTm.cpp Data : 08.01.22 Versione : 2.4a3
|
||||
// Contenuto : Implementazione della intersezione linea/superficie trimesh.
|
||||
//
|
||||
//
|
||||
@@ -14,8 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
|
||||
|
||||
+34
-6
@@ -1,8 +1,8 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersLineBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione linea/box.
|
||||
// File : IntersPlaneBox.cpp Data : 07.05.20 Versione : 2.2e1
|
||||
// Contenuto : Implementazione della intersezione piano/box.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -20,19 +20,47 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
|
||||
bool
|
||||
IntersPlaneBox( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box,
|
||||
TestIntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box)
|
||||
{
|
||||
// Verifica del piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Centro e estensione del box
|
||||
Point3d ptCen ;
|
||||
Vector3d vtExt ;
|
||||
if ( ! b3Box.GetCenterExtent( ptCen, vtExt))
|
||||
return false ;
|
||||
// Distanza del centro dal piano
|
||||
double dDist = DistPointPlane( ptCen, plPlane) ;
|
||||
// Proiezione dell'estensione sulla normale al piano
|
||||
Vector3d vtN = plPlane.GetVersN() ;
|
||||
double dProjExt = vtExt.x * abs( vtN.x) + vtExt.y * abs( vtN.y) + vtExt.z * abs( vtN.z) ;
|
||||
// Confronto distanza del centro con estensione proiettata
|
||||
return ( abs( dDist) < dProjExt + EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneBox( const Plane3d& plPlane, const BBox3d& b3Box,
|
||||
PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// Creo il piano
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( ptOn, vtN))
|
||||
// Verifico il piano
|
||||
if ( ! plPlane.IsValid())
|
||||
return false ;
|
||||
// Recupero i dati del Box
|
||||
Point3d ptMin ;
|
||||
double dDimX, dDimY, dDimZ ;
|
||||
if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimZ))
|
||||
return false ;
|
||||
// Pulisco vettori intersezioni
|
||||
vPnt.clear() ;
|
||||
vBpt.clear() ;
|
||||
vTria.clear() ;
|
||||
// Verifico se può esistere intersezione
|
||||
if ( ! TestIntersPlaneBox( plPlane, b3Box))
|
||||
return true ;
|
||||
// Contorno di base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ptMin) ;
|
||||
|
||||
@@ -116,7 +116,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
|
||||
}
|
||||
}
|
||||
// se altrimenti sovrapposizione
|
||||
else if ( nRes == ITTT_OVERLAPS) {
|
||||
else if ( nRes == ITTT_OVERLAPS || nRes == ITTT_COUNTER_OVERLAPS) {
|
||||
for ( const auto& Tria : vIttTria) {
|
||||
// verifico se triangolo già inserito
|
||||
bool bFound = false ;
|
||||
|
||||
+34
-5
@@ -83,8 +83,37 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
// se i triangoli sono complanari
|
||||
if ( nResPP == IPPT_OVERLAPS ||
|
||||
((( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) &&
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL))
|
||||
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL)) {
|
||||
// verifica per triangoli con normali controverse
|
||||
bool bCounter = false ;
|
||||
Triangle3d trMyTria2 = trTria2 ;
|
||||
if ( trTria1.GetN() * trTria2.GetN() < 0) {
|
||||
Point3d ptV0 = trMyTria2.GetP( 0) ;
|
||||
trMyTria2.SetP( 0, trMyTria2.GetP( 1)) ;
|
||||
trMyTria2.SetP( 1, ptV0) ;
|
||||
trMyTria2.Validate() ;
|
||||
bCounter = true ;
|
||||
}
|
||||
// verifica per triangoli coincidenti
|
||||
bool bAreSameTria = ( ( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 2))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 0))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 1)))) &&
|
||||
( AreSameVectorExact( trTria1.GetN(), trMyTria2.GetN())) ;
|
||||
if ( bAreSameTria) {
|
||||
vTria.emplace_back( trTria1) ;
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
if ( ITTT_OVERLAPS == IntersCoplanarTriaTria( trTria1, trMyTria2, vTria)) {
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
return ITTT_NO ;
|
||||
}
|
||||
|
||||
// limito la linea di intersezione con il primo triangolo
|
||||
Point3d ptSt1, ptEn1 ;
|
||||
@@ -112,7 +141,7 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
int
|
||||
IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria)
|
||||
{
|
||||
// Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c'è intersezione
|
||||
// Se i tre vertici del secondo triangolo stanno tutti a destra di almeno un lato del primo, non c'� intersezione
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
Vector3d vtSide = trTria1.GetP( ( i + 1) % 3) - trTria1.GetP( i) ;
|
||||
Vector3d vtSN = vtSide ^ trTria1.GetN() ;
|
||||
@@ -122,7 +151,7 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
|
||||
( trTria2.GetP( 2) - trTria1.GetP( i)) * vtSN > - EPS_TRIA_H)
|
||||
return ITTT_NO ;
|
||||
}
|
||||
// Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c'è intersezione
|
||||
// Se i tre vertici del primo triangolo stanno tutti a destra di almeno un lato del secondo, non c'� intersezione
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
Vector3d vtSide = trTria2.GetP( ( i + 1) % 3) - trTria2.GetP( i) ;
|
||||
Vector3d vtSN = vtSide ^ trTria2.GetN() ;
|
||||
@@ -205,7 +234,7 @@ int
|
||||
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
|
||||
{
|
||||
// Controllo su validità input
|
||||
// Controllo su validit� input
|
||||
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
|
||||
return ITTT_NO ;
|
||||
// Casi
|
||||
|
||||
+52
-15
@@ -68,18 +68,36 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
{
|
||||
// pulisco tutto
|
||||
Reset() ;
|
||||
// verifico se la curva è un segmento di retta
|
||||
bool bIsLine = false ;
|
||||
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||
if ( pLine != nullptr)
|
||||
bIsLine = true ;
|
||||
else {
|
||||
const CurveComposite* pCompo = GetBasicCurveComposite( pCrv) ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
|
||||
bIsLine = true ;
|
||||
}
|
||||
// verifico che la curva esista e sia piana
|
||||
Plane3d plPlane ;
|
||||
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane))
|
||||
if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
// se esiste estrusione, verifico sia perpendicolare al piano della curva
|
||||
// recupero o assegno estrusione
|
||||
Vector3d vtExtr ;
|
||||
if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall()) {
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtExtr))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
if ( ! pCrv->GetExtrusion( vtExtr) || vtExtr.IsSmall()) {
|
||||
vtExtr = plPlane.GetVersN() ;
|
||||
if ( vtExtr.IsZminus())
|
||||
vtExtr.Invert() ;
|
||||
}
|
||||
// recupero normale al piano della curva
|
||||
Vector3d vtNorm = plPlane.GetVersN() ;
|
||||
if ( vtNorm * vtExtr < 0)
|
||||
vtNorm.Invert() ;
|
||||
// verifico che estrusione non sia troppo vicina al piano della curva (almeno 30 gradi di angolazione)
|
||||
double dExtrOnN = vtExtr * vtNorm ;
|
||||
if ( dExtrOnN < 0.5)
|
||||
return false ;
|
||||
// recupero spessore
|
||||
double dThick ;
|
||||
pCrv->GetThickness( dThick) ;
|
||||
@@ -102,6 +120,9 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// determino se necessario cambiare riferimento ( dal vettore estrusione)
|
||||
bool bNeedRef = ( ! vtExtr.IsZplus()) ;
|
||||
|
||||
// determino se necessario effettuare scalatura
|
||||
bool bNeedScale = ( abs( dExtrOnN) < cos( 0.1 * DEGTORAD)) ;
|
||||
|
||||
// creo una copia della curva
|
||||
CurveComposite ccCopy ;
|
||||
if ( ! ccCopy.CopyFrom( pCrv))
|
||||
@@ -109,13 +130,23 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
ccCopy.SetExtrusion( vtExtr) ;
|
||||
|
||||
// se necessario cambio il riferimento
|
||||
Frame3d frExtr ;
|
||||
if ( bNeedRef) {
|
||||
Frame3d frCopy ;
|
||||
if ( bNeedScale) {
|
||||
// calcolo il riferimento con vtNorm come asse Z e componente di vtExtr perpendicolare a vtNorm come asse X
|
||||
if ( ! frCopy.Set( ORIG, vtNorm, vtExtr - dExtrOnN * vtNorm))
|
||||
return false ;
|
||||
ccCopy.SetExtrusion( vtNorm) ;
|
||||
// esprimo la curva in questo riferimento
|
||||
ccCopy.ToLoc( frCopy) ;
|
||||
// scalo lungo l'asse X locale
|
||||
ccCopy.Scale( GLOB_FRM, dExtrOnN, 1, 1) ;
|
||||
}
|
||||
else if ( bNeedRef) {
|
||||
// calcolo il riferimento OCS con VtExtr come asse Z
|
||||
if ( ! frExtr.Set( ORIG, vtExtr))
|
||||
if ( ! frCopy.Set( ORIG, vtExtr))
|
||||
return false ;
|
||||
// esprimo la curva in questo riferimento
|
||||
ccCopy.ToLoc( frExtr) ;
|
||||
ccCopy.ToLoc( frCopy) ;
|
||||
}
|
||||
|
||||
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
||||
@@ -429,7 +460,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
inOk.Set( dStart, dEnd) ;
|
||||
IntersCurveCurve ccInt( *pCrv, *pCircS) ;
|
||||
CRVCVECTOR ccPart ;
|
||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
||||
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
|
||||
return false ;
|
||||
for ( auto& ccOne : ccPart) {
|
||||
switch ( ccOne.nClass) {
|
||||
@@ -478,7 +509,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
inOk.Set( dStart, dEnd) ;
|
||||
IntersCurveCurve ccInt( *pCrv, *pCircE) ;
|
||||
CRVCVECTOR ccPart ;
|
||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
||||
if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart))
|
||||
return false ;
|
||||
for ( auto& ccOne : ccPart) {
|
||||
switch ( ccOne.nClass) {
|
||||
@@ -601,9 +632,15 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
}
|
||||
|
||||
// riporto il risultato nel riferimento originale
|
||||
if ( bNeedRef) {
|
||||
if ( bNeedScale) {
|
||||
for ( auto pCrv : m_CrvLst) {
|
||||
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
||||
pCrv->ToGlob( frCopy) ;
|
||||
}
|
||||
}
|
||||
else if ( bNeedRef) {
|
||||
for ( auto pCrv : m_CrvLst)
|
||||
pCrv->ToGlob( frExtr) ;
|
||||
pCrv->ToGlob( frCopy) ;
|
||||
}
|
||||
|
||||
// assegno estrusione e spessore come curva originale
|
||||
|
||||
+223
-5
@@ -22,6 +22,7 @@
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -829,12 +830,11 @@ PolyLine::MyChangeStart( int nPos)
|
||||
// solo per polilinee chiuse
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// cancello ultimo punto ( coincide con primo)
|
||||
// cancello l'ultimo punto ( coincide con il primo)
|
||||
m_lUPoints.pop_back() ;
|
||||
// sposto la metà iniziale dei punti alla fine
|
||||
for ( int i = 0 ; i < nPos ; ++ i)
|
||||
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin()) ;
|
||||
// aggiungo punto finale come copia dell'iniziale
|
||||
// sposto la parte iniziale dei punti alla fine
|
||||
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin(), next( m_lUPoints.begin(), nPos)) ;
|
||||
// aggiungo il punto finale come copia dell'iniziale
|
||||
m_lUPoints.push_back( m_lUPoints.front()) ;
|
||||
|
||||
return true ;
|
||||
@@ -1296,3 +1296,221 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dDist)
|
||||
{
|
||||
// La polilinea deve contenere almeno due punti
|
||||
if ( plPoly.GetPointNbr() < 2)
|
||||
return false ;
|
||||
// Ciclo sui punti della polilinea
|
||||
dDist = INFINITO ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
plPoly.GetFirstPoint( ptStart) ;
|
||||
while ( plPoly.GetNextPoint( ptEnd)) {
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine PointLineDistCalc( ptP, ptStart, ptEnd) ;
|
||||
double dPlDist ;
|
||||
PointLineDistCalc.GetDist( dPlDist) ;
|
||||
if ( dPlDist < dDist)
|
||||
dDist = dPlDist ;
|
||||
// assegno nuovo inizio
|
||||
ptStart = ptEnd ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler)
|
||||
{
|
||||
// La polilinea deve essere chiusa e piatta, altrimenti non ha senso parlare di interno
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! plPoly.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
// Impongo l'orientamento CCW
|
||||
if ( dArea < 0)
|
||||
plPlane.Invert() ;
|
||||
// Il punto deve giacere nel piano della polilinea
|
||||
if ( ! PointInPlaneEpsilon( ptP, plPlane, 10 * EPS_SMALL))
|
||||
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
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
Point3d ptMinDist ;
|
||||
auto itMinDistEnd = List.end() ;
|
||||
auto itStart = List.begin() ;
|
||||
auto itEnd = next( itStart) ;
|
||||
for ( ; itEnd != List.end() ; ++ itStart, ++ itEnd) {
|
||||
// Distanza del punto dal segmento corrente
|
||||
DistPointLine dDistCalc( ptP, itStart->first, itEnd->first) ;
|
||||
double dSqDist ;
|
||||
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
dDistCalc.GetMinDistPoint( ptMinDist) ;
|
||||
itMinDistEnd = itEnd ;
|
||||
}
|
||||
}
|
||||
// Determino tangente di riferimento
|
||||
Vector3d vtTang ;
|
||||
// se minima distanza nell'estremo iniziale del segmento
|
||||
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
||||
// direzione del segmento
|
||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
vtCurrTg.Normalize() ;
|
||||
// direzione del segmento precedente
|
||||
Vector3d vtPrevTg ;
|
||||
if ( prev( itMinDistEnd) != List.begin())
|
||||
vtPrevTg = prev( itMinDistEnd)->first - prev( itMinDistEnd, 2)->first ;
|
||||
else
|
||||
vtPrevTg = prev( itMinDistEnd)->first - prev( List.rbegin())->first ;
|
||||
vtPrevTg.Normalize() ;
|
||||
// tangente media
|
||||
vtTang = vtPrevTg + vtCurrTg ;
|
||||
vtTang.Normalize() ;
|
||||
}
|
||||
// se altrimenti minima distanza nell'estremo finale del segmento
|
||||
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
||||
// direzione del segmento
|
||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
vtCurrTg.Normalize() ;
|
||||
// direzione del segmento successivo
|
||||
Vector3d vtNextTg ;
|
||||
if ( next( itMinDistEnd) != List.end())
|
||||
vtNextTg = next( itMinDistEnd)->first - itMinDistEnd->first ;
|
||||
else
|
||||
vtNextTg = next( List.begin())->first - itMinDistEnd->first ;
|
||||
vtNextTg.Normalize() ;
|
||||
// tangente media
|
||||
vtTang = vtCurrTg + vtNextTg ;
|
||||
vtTang.Normalize() ;
|
||||
}
|
||||
// altrimenti minima distanza con l'interno
|
||||
else {
|
||||
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
}
|
||||
// Determino la posizione del punto
|
||||
Vector3d vtDiff = ptP - ptMinDist ;
|
||||
Vector3d vtOut = vtTang ^ plPlane.GetVersN() ;
|
||||
vtOut.Normalize() ;
|
||||
return ( vtDiff * vtOut < -dToler) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler, double& dPar)
|
||||
{
|
||||
// La polilinea deve contenere almeno due punti
|
||||
if ( plPoly.GetPointNbr() < 2)
|
||||
return false ;
|
||||
// Ciclo sui punti della polilinea
|
||||
int nSeg = -1 ;
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
double dMinPar = -1 ;
|
||||
Point3d ptStart, ptEnd ;
|
||||
plPoly.GetFirstPoint( ptStart) ;
|
||||
while ( plPoly.GetNextPoint( ptEnd)) {
|
||||
// aggiorno l'indice
|
||||
++ nSeg ;
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine dDistCalc( ptP, ptStart, ptEnd) ;
|
||||
double dSqDist ;
|
||||
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
double dSegPar ;
|
||||
dDistCalc.GetParamAtMinDistPoint( dSegPar) ;
|
||||
dMinPar = nSeg + dSegPar ;
|
||||
}
|
||||
// assegno nuovo inizio
|
||||
ptStart = ptEnd ;
|
||||
}
|
||||
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
||||
return ( dMinSqDist < dToler * dToler) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
||||
{
|
||||
// La polilinea deve essere chiusa
|
||||
if ( ! plPoly.IsClosed())
|
||||
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
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
auto itEnd = next( itStart) ;
|
||||
for ( ; itEnd != LoopList.end() ; ++ itStart, ++ itEnd) {
|
||||
// Distanza del punto dal segmento corrente
|
||||
DistPointLine dDistCalc( ptNewStart, itStart->first, itEnd->first) ;
|
||||
double dSqDist ;
|
||||
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
itMinDistEnd = itEnd ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sulla polilinea, non ha senso cambiare l'inizio
|
||||
if ( dMinSqDist > dToler * dToler)
|
||||
return false ;
|
||||
// Se il punto non coincide con un vertice, lo aggiungo
|
||||
auto itNewStart = LoopList.end() ;
|
||||
if ( AreSamePointApprox( ptNewStart, prev( itMinDistEnd)->first))
|
||||
itNewStart = prev( itMinDistEnd) ;
|
||||
else if ( AreSamePointApprox( ptNewStart, itMinDistEnd->first))
|
||||
itNewStart = itMinDistEnd ;
|
||||
else
|
||||
itNewStart = LoopList.emplace( itMinDistEnd, ptNewStart, 0) ;
|
||||
// Cancello l'ultimo punto ( coincide con il primo)
|
||||
LoopList.pop_back() ;
|
||||
// Sposto la parte iniziale dei punti alla fine
|
||||
LoopList.splice( LoopList.end(), LoopList, LoopList.begin(), itNewStart) ;
|
||||
// Aggiungo il punto finale come copia dell'iniziale
|
||||
LoopList.push_back( LoopList.front()) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler, PolyLine& plPoly1, PolyLine& plPoly2)
|
||||
{
|
||||
// La polilinea deve contenere almeno due punti
|
||||
if ( plPoly.GetPointNbr() < 2)
|
||||
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
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
auto itEnd = next( itStart) ;
|
||||
for ( ; itEnd != LoopList.end() ; ++ itStart, ++ itEnd) {
|
||||
// Distanza del punto dal segmento corrente
|
||||
DistPointLine dDistCalc( ptP, itStart->first, itEnd->first) ;
|
||||
double dSqDist ;
|
||||
if ( dDistCalc.GetSqDist( dSqDist) && dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
itMinDistEnd = itEnd ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sulla polilinea, non ha senso spezzare
|
||||
if ( dMinSqDist > dToler * dToler)
|
||||
return false ;
|
||||
// Copio i punti opportuni nella prima parte
|
||||
PNTULIST& LoopList1 = plPoly1.GetUPointList() ;
|
||||
for ( auto it = LoopList.begin() ; it != itMinDistEnd ; ++ it)
|
||||
LoopList1.emplace_back( it->first, it->second) ;
|
||||
plPoly1.AddUPoint( 0, ptP) ;
|
||||
// Copio i punti opportuni nella seconda parte
|
||||
PNTULIST& LoopList2 = plPoly2.GetUPointList() ;
|
||||
for ( auto it = itMinDistEnd ; it != LoopList.end() ; ++ it)
|
||||
LoopList2.emplace_back( it->first, it->second) ;
|
||||
plPoly2.AddUPoint( 0, ptP, false) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
+46
-10
@@ -17,6 +17,7 @@
|
||||
#include "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "AdjustLoops.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkPolyLine.h"
|
||||
#include "/EgtDev/Include/EgkBiArcs.h"
|
||||
@@ -278,13 +279,34 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||
GetSurfFlatRegionFromTriangle( const Triangle3d& Tria)
|
||||
{
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Creo curva composita.
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
return nullptr ;
|
||||
if ( ! pLoop->AddPoint( Tria.GetP( 0)) ||
|
||||
! pLoop->AddLine( Tria.GetP( 1)) ||
|
||||
! pLoop->AddLine( Tria.GetP( 2)) ||
|
||||
! pLoop->Close())
|
||||
return nullptr ;
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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))
|
||||
return nullptr ;
|
||||
@@ -306,13 +328,13 @@ GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
||||
{
|
||||
// Creo la regione.
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Ciclo sulle PolyLine.
|
||||
// Ciclo sulle PolyLine.
|
||||
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
||||
// Creo curva composita.
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
return nullptr ;
|
||||
@@ -326,11 +348,11 @@ GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
||||
ptSt = ptEn ;
|
||||
bContinue = vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||
}
|
||||
// Loop esterno
|
||||
// Loop esterno
|
||||
if ( nL == 0) {
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
}
|
||||
// Loop interno
|
||||
// Loop interno
|
||||
else {
|
||||
pSfr->AddIntLoop( Release( pLoop)) ;
|
||||
}
|
||||
@@ -363,8 +385,20 @@ SurfFlatRegionByContours::AddCurve( ICurve* pCrv)
|
||||
// verifico sia chiusa
|
||||
if ( ! pMyCrv->IsClosed())
|
||||
return false ;
|
||||
// la inserisco nel vettore delle curve
|
||||
m_vpCrv.push_back( Release( pMyCrv)) ;
|
||||
// verifico sia piana e imposto estrusione come normale al piano
|
||||
double dArea ;
|
||||
Plane3d plPlane ;
|
||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
pMyCrv->SetExtrusion( plPlane.GetVersN()) ;
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
return false ;
|
||||
// la/le inserisco nel vettore delle curve
|
||||
for ( auto& pSingCrv : CrvLst)
|
||||
m_vpCrv.push_back( pSingCrv) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -418,6 +452,7 @@ SurfFlatRegionByContours::GetSurf( void)
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// aggiungo le diverse curve
|
||||
bool bExtLoop = false ;
|
||||
bool bFirstCrv ;
|
||||
do {
|
||||
bFirstCrv = true ;
|
||||
@@ -436,6 +471,7 @@ SurfFlatRegionByContours::GetSurf( void)
|
||||
}
|
||||
// provo a inserirla
|
||||
if ( pSfr->AddExtLoop( Release( pCrv))) {
|
||||
bExtLoop = true ;
|
||||
bFirstCrv = false ;
|
||||
delete m_vpCrv[j] ;
|
||||
m_vpCrv[j] = nullptr ;
|
||||
@@ -460,7 +496,7 @@ SurfFlatRegionByContours::GetSurf( void)
|
||||
}
|
||||
} while ( m_bAllowedMultiChunk && ! bFirstCrv) ;
|
||||
// se non valida, errore
|
||||
if ( ! pSfr->IsValid())
|
||||
if ( ! bExtLoop || ! pSfr->IsValid())
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSfr) ;
|
||||
|
||||
+5
-2
@@ -35,8 +35,10 @@ GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
|
||||
//----------------------------------------------------------------------------
|
||||
SurfBezier::SurfBezier(void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false),
|
||||
m_bTrimmed( false), m_pTrimReg( nullptr), m_nTempProp( 0)
|
||||
m_bTrimmed( false), m_pTrimReg( nullptr)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -566,7 +568,8 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc)
|
||||
m_vPtCtrl = sbSrc.m_vPtCtrl ;
|
||||
if ( sbSrc.m_bRat)
|
||||
m_vWeCtrl = sbSrc.m_vWeCtrl ;
|
||||
m_nTempProp = sbSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = sbSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = sbSrc.m_nTempProp[1] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -53,10 +53,11 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ISurf
|
||||
bool IsSimple( void) const override
|
||||
@@ -165,7 +166,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+15
-11
@@ -33,8 +33,10 @@ GEOOBJ_REGISTER( SRF_FLATRGN, NGE_S_FRG, SurfFlatRegion) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfFlatRegion::SurfFlatRegion( void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nTempProp()
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY)
|
||||
{
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -55,7 +57,8 @@ SurfFlatRegion::Clear( void)
|
||||
delete pLoop ;
|
||||
m_vpLoop.clear() ;
|
||||
|
||||
m_nTempProp = 0 ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
@@ -162,7 +165,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
for ( auto i : m_vExtInd) {
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
@@ -175,7 +178,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
continue ;
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() == 0 &&
|
||||
ccInt.GetCurveClassification( 0, ccClass) &&
|
||||
ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) &&
|
||||
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
|
||||
bOk = true ;
|
||||
break ;
|
||||
@@ -295,7 +298,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// verifica rispetto ai loop interni
|
||||
@@ -306,7 +309,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
||||
IntersCurveCurve ccInt2( *pMyCrv, *m_vpLoop[k]) ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt2.GetCurveClassification( 0, ccClass2) ||
|
||||
! ccInt2.GetCurveClassification( 0, EPS_SMALL, ccClass2) ||
|
||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
@@ -397,7 +400,8 @@ SurfFlatRegion::CopyFrom( const SurfFlatRegion& sfrSrc)
|
||||
m_vpLoop.push_back( pCrv) ;
|
||||
}
|
||||
m_vExtInd = sfrSrc.m_vExtInd ;
|
||||
m_nTempProp = sfrSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = sfrSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = sfrSrc.m_nTempProp[1] ;
|
||||
m_nStatus = sfrSrc.m_nStatus ;
|
||||
return ( m_nStatus == OK && ! m_vpLoop.empty()) ;
|
||||
}
|
||||
@@ -1146,7 +1150,7 @@ SurfFlatRegion::CloneChunk( int nChunk) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
|
||||
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||
{
|
||||
// la curva deve già essere nel riferimento intrinseco della regione
|
||||
// verifico lo stato
|
||||
@@ -1175,7 +1179,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
|
||||
IntersCurveCurve ccInt( Crv, *pLoop) ;
|
||||
// classificazione
|
||||
CRVCVECTOR ccPart ;
|
||||
if ( ! ccInt.GetCurveClassification( 0, ccPart))
|
||||
if ( ! ccInt.GetCurveClassification( 0, dLenMin, ccPart))
|
||||
return false ;
|
||||
for ( auto& ccOne : ccPart) {
|
||||
switch ( ccOne.nClass) {
|
||||
@@ -1268,7 +1272,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
|
||||
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
@@ -1289,7 +1293,7 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
|
||||
pCrvLoc = pCopyCrv ;
|
||||
}
|
||||
// esecuzione classificazione nel riferimento intrinseco
|
||||
return MyGetCurveClassification( *pCrvLoc, ccClass) ;
|
||||
return MyGetCurveClassification( *pCrvLoc, dLenMin, ccClass) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+8
-7
@@ -51,10 +51,11 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ISurf
|
||||
bool IsSimple( void) const override
|
||||
@@ -91,7 +92,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
||||
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
||||
bool GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const override ;
|
||||
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||
|
||||
public : // IGeoObjRW
|
||||
@@ -130,7 +131,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
ICurve* GetMyLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||
void ResetAuxSurf( void) const ;
|
||||
bool ConvertArcsToBezierCurves( void) ;
|
||||
bool MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const ;
|
||||
bool MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const ;
|
||||
static bool MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion& Other,
|
||||
int nType1, bool bInvert1, int nType2, bool bInvert2, PCRV_DEQUE& vpCurve) ;
|
||||
static bool MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) ;
|
||||
@@ -144,7 +145,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
Frame3d m_frF ; // riferimento intrinseco
|
||||
PCRV_DEQUE m_vpLoop ; // deque delle curve che formano i loop
|
||||
INTVECTOR m_vExtInd ; // indice dei loop esterni nel precedente vettore
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -289,7 +289,7 @@ SurfFlatRegion::MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion&
|
||||
for ( auto& pLoop : vpLoop) {
|
||||
// eseguo classificazione
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! Other.MyGetCurveClassification( *pLoop, ccClass))
|
||||
if ( ! Other.MyGetCurveClassification( *pLoop, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// creo intervalli validi, tenendo classificazioni ricevute
|
||||
Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ;
|
||||
@@ -441,7 +441,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop)
|
||||
CRVCVECTOR ccClass ;
|
||||
IntersCurveCurve ccInt( *vpLoop[l], *pExtLoop) ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// lo inserisco
|
||||
|
||||
@@ -27,6 +27,9 @@ SurfFlatRegion::Offset( double dDist, int nType)
|
||||
int nChunk = GetChunkCount() ;
|
||||
if ( nChunk == 0)
|
||||
return false ;
|
||||
// se offset nullo, non devo fare alcunché
|
||||
if ( abs( dDist) < 10 * EPS_SMALL)
|
||||
return true ;
|
||||
// creo una nuova regione
|
||||
PtrOwner<SurfFlatRegion> pSfr( new( nothrow) SurfFlatRegion) ;
|
||||
if ( IsNull( pSfr))
|
||||
|
||||
+116
-305
@@ -18,10 +18,10 @@
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "Triangulate.h"
|
||||
#include "GeoConst.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
@@ -41,10 +41,12 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ;
|
||||
SurfTriMesh::SurfTriMesh( void)
|
||||
: m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dBoundaryAng( STM_STD_BOUNDARY_ANG),
|
||||
m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false),
|
||||
m_nTimeStamp( 0), m_nTempProp( 0), m_nMaxTFlag( 0), m_nParts( -1), m_pHGrd3d( nullptr)
|
||||
m_nTimeStamp( 0), m_nMaxTFlag( 0), m_nParts( -1), m_pHGrd3d( nullptr)
|
||||
{
|
||||
m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ;
|
||||
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -237,7 +239,7 @@ SurfTriMesh::RemoveTriangle( int nId)
|
||||
// indice vertice
|
||||
int nV = m_vTria[nId].nIdVert[i] ;
|
||||
// se vertice non c'è passo al prossimo
|
||||
if ( nV < 0 || nV >= int( m_vTria.size()))
|
||||
if ( nV < 0 || nV >= int( m_vVert.size()))
|
||||
continue ;
|
||||
if ( m_vVert[nV].nIdTria == nId) {
|
||||
int nAdjP = m_vTria[nId].nIdAdjac[i] ;
|
||||
@@ -989,7 +991,7 @@ SurfTriMesh::MarchOneTria( int& nT, int& nV, int nTimeStamp,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
|
||||
SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL) const
|
||||
{
|
||||
// Verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
@@ -1000,6 +1002,19 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
|
||||
if ( ! vtVers.Normalize())
|
||||
return false ;
|
||||
|
||||
// Controlli su tolleranza
|
||||
dTol = max( dTol, 100 * EPS_SMALL) ;
|
||||
|
||||
// Determino il riferimento di proiezione
|
||||
Frame3d frOCS ; frOCS.Set( ORIG, vtVers) ;
|
||||
Frame3d frBox = frOCS ; frBox.Invert() ;
|
||||
BBox3d b3Box ;
|
||||
GetBBox( frBox, b3Box) ;
|
||||
frOCS.Translate( b3Box.GetMin().z * frOCS.VersZ()) ;
|
||||
|
||||
#if 0
|
||||
// *** 1° Sfruttando le adiacenze ***
|
||||
// Non funziona perchè genera loop con anelli
|
||||
// Copio la superficie
|
||||
PtrOwner<SurfTriMesh> pStm( Clone()) ;
|
||||
if ( IsNull( pStm))
|
||||
@@ -1011,14 +1026,100 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const
|
||||
if ( pStm->m_vTria[i].nIdVert[0] == SVT_DEL)
|
||||
continue ;
|
||||
// verifico la normale
|
||||
if ( pStm->m_vTria[i].vtN * vtVers < - EPS_ZERO)
|
||||
if ( pStm->m_vTria[i].vtN * vtVers < EPS_ZERO)
|
||||
pStm->RemoveTriangle( i) ;
|
||||
}
|
||||
// dichiaro facce non calcolate
|
||||
pStm->m_bFaceted = false ;
|
||||
|
||||
// Proietto la superficie
|
||||
pStm->Scale( frOCS, 1, 1, 0) ;
|
||||
|
||||
// Recupero i loop della nuova superficie
|
||||
return pStm->GetLoops( vPL) ;
|
||||
POLYLINEVECTOR vMyPL ;
|
||||
if ( pStm->GetLoops( vMyPL)) {
|
||||
// calcolo la regione della superficie proiettata
|
||||
bool bOk = true ;
|
||||
PtrOwner<ISurfFlatRegion> pSfr ;
|
||||
for ( int i = 0 ; i < int( vMyPL.size()) && bOk ; ++ i) {
|
||||
// Regione di un loop
|
||||
PtrOwner<ISurfFlatRegion> pSfrPart( GetSurfFlatRegionFromPolyLine( vMyPL[i])) ;
|
||||
if ( ! IsNull( pSfrPart)) {
|
||||
pSfrPart->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||
if ( IsNull( pSfr))
|
||||
if ( pSfrPart->GetNormVersor() * vtVers > 0)
|
||||
bOk = pSfr.Set( Release( pSfrPart)) ;
|
||||
else
|
||||
bOk = false ;
|
||||
else {
|
||||
if ( pSfrPart->GetNormVersor() * vtVers > 0)
|
||||
bOk = pSfr->Add( *pSfrPart) ;
|
||||
else {
|
||||
pSfrPart->Invert() ;
|
||||
bOk = pSfr->Subtract( *pSfrPart) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
bOk = false ;
|
||||
}
|
||||
// Verifico esistenza della regione
|
||||
if ( bOk && ! IsNull( pSfr)) {
|
||||
// Effettuo contro-offset
|
||||
pSfr->Offset( -dTol, ICurve::OFF_EXTEND) ;
|
||||
// Recupero i contorni della regione
|
||||
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
||||
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
||||
PolyLine PL ;
|
||||
if ( pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
vPL.emplace_back( PL) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
vPL.clear() ;
|
||||
#endif
|
||||
|
||||
// *** 2° Mediante unione delle regioni dei triangoli proiettati ***
|
||||
// calcolo la regione dei triangoli proiettati
|
||||
PtrOwner<ISurfFlatRegion> pSfr ;
|
||||
Triangle3d Tria ;
|
||||
int nT = GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// verifico la normale e il triangolo proiettato
|
||||
if ( Tria.GetN() * vtVers > EPS_ZERO &&
|
||||
Tria.Scale( frOCS, 1, 1, 0) && Tria.GetSqMinHeight() > SQ_EPS_SMALL) {
|
||||
PtrOwner<ISurfFlatRegion> pSfrTria( GetSurfFlatRegionFromTriangle( Tria)) ;
|
||||
if ( ! IsNull( pSfrTria)) {
|
||||
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||
if ( IsNull( pSfr))
|
||||
pSfr.Set( Release( pSfrTria)) ;
|
||||
else
|
||||
pSfr->Add( *pSfrTria) ;
|
||||
}
|
||||
}
|
||||
// passo al successivo
|
||||
nT = GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
|
||||
// Se non esiste la regione
|
||||
if ( IsNull( pSfr))
|
||||
return false ;
|
||||
|
||||
// Effettuo contro-offset
|
||||
pSfr->Offset( -dTol, ICurve::OFF_EXTEND) ;
|
||||
|
||||
// Recupero i contorni della regione
|
||||
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
||||
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
||||
PolyLine PL ;
|
||||
if ( pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
vPL.emplace_back( PL) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1068,7 +1169,8 @@ SurfTriMesh::CopyFrom( const SurfTriMesh& stmSrc)
|
||||
m_vTria = stmSrc.m_vTria ;
|
||||
m_vFacet = stmSrc.m_vFacet ;
|
||||
m_nTimeStamp = stmSrc.m_nTimeStamp ;
|
||||
m_nTempProp = stmSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = stmSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = stmSrc.m_nTempProp[1] ;
|
||||
m_nMaxTFlag = stmSrc.m_nMaxTFlag ;
|
||||
m_nParts = stmSrc.m_nParts ;
|
||||
return true ;
|
||||
@@ -1593,8 +1695,10 @@ SurfTriMesh::TestSealing( void)
|
||||
// verifico le adiacenze
|
||||
if ( m_vTria[i].nIdAdjac[0] == SVT_NULL ||
|
||||
m_vTria[i].nIdAdjac[1] == SVT_NULL ||
|
||||
m_vTria[i].nIdAdjac[2] == SVT_NULL)
|
||||
m_vTria[i].nIdAdjac[2] == SVT_NULL) {
|
||||
bClosed = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// aggiorno la chiusura della superficie
|
||||
@@ -1614,7 +1718,7 @@ SurfTriMesh::AdjustTopology( void)
|
||||
return true ;
|
||||
}
|
||||
// dichiaro sfaccettatura da ricalcolare
|
||||
ResetFaceting() ;
|
||||
m_bFaceted = false ;
|
||||
// invalido calcolo connessione
|
||||
m_nParts = - 1 ;
|
||||
// verifica indici
|
||||
@@ -2828,7 +2932,7 @@ SurfTriMesh::DoCompacting( double dTol)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther)
|
||||
SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther, double dTol)
|
||||
{
|
||||
// recupero l'altra superficie
|
||||
const SurfTriMesh* pOther = dynamic_cast<const SurfTriMesh*>( &stmOther) ;
|
||||
@@ -2870,7 +2974,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther)
|
||||
ptOP.ToGlob( frOther) ;
|
||||
// se non c'è già un vertice con la stessa posizione lo inserisco
|
||||
int nNewId ;
|
||||
if ( ! VertGrid.Find( ptOP, 2 * EPS_SMALL, nNewId)) {
|
||||
if ( ! VertGrid.Find( ptOP, dTol, nNewId)) {
|
||||
if ( ( nNewId = AddVertex( ptOP)) == SVT_NULL)
|
||||
return false ;
|
||||
VertGrid.InsertPoint( ptOP, nNewId) ;
|
||||
@@ -2880,7 +2984,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther)
|
||||
}
|
||||
int nVIdSize = int( vVId.size()) ;
|
||||
|
||||
// inserisco i triangoli dell'altra trimesh
|
||||
// aggiungo i triangoli dell'altra trimesh
|
||||
for ( int nOtId = 0 ; nOtId < pOther->GetTriangleSize() ; ++ nOtId) {
|
||||
// recupero gli indici dei vertici del triangolo
|
||||
int vOId[3] ;
|
||||
@@ -3297,299 +3401,6 @@ SurfTriMesh::Invert( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
{
|
||||
#define UseTria 1
|
||||
#if UseTria
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// classifico i vertici rispetto al piano
|
||||
double dTol = max( min( 0.5 * m_dLinTol, 10 * EPS_SMALL), EPS_SMALL) ;
|
||||
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
|
||||
double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ;
|
||||
if ( abs( dDist) < dTol) {
|
||||
m_vVert[i].nTemp = 0 ;
|
||||
if ( abs( dDist) > EPS_SMALL)
|
||||
m_vVert[i].ptP -= plPlane.GetVersN() * dDist ;
|
||||
}
|
||||
else if ( dDist > 0)
|
||||
m_vVert[i].nTemp = +1 ;
|
||||
else
|
||||
m_vVert[i].nTemp = -1 ;
|
||||
}
|
||||
|
||||
// aggiorno timestamp dei triangoli
|
||||
for ( auto& Tria : m_vTria)
|
||||
Tria.nTemp = m_nTimeStamp ;
|
||||
++ m_nTimeStamp ;
|
||||
|
||||
// sistemo i triangoli (eventualmente li elimino)
|
||||
bool bModif = false ;
|
||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||
// salto i triangoli cancellati e quelli aggiunti
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
|
||||
continue ;
|
||||
// se flag abilita e giace sul piano ed equiverso, lo salvo
|
||||
if ( bSaveOnEq &&
|
||||
m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[2]].nTemp == 0 &&
|
||||
AreSameVectorApprox( m_vTria[i].vtN, plPlane.GetVersN()))
|
||||
;
|
||||
// se giace sul piano o dalla parte esterna del piano, lo cancello
|
||||
else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != -1 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[1]].nTemp != -1 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[2]].nTemp != -1) {
|
||||
bModif = true ;
|
||||
RemoveTriangle( i) ;
|
||||
}
|
||||
// se giace dalla parte interna con al massimo un lato sul piano, lo conservo
|
||||
else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != 1 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[1]].nTemp != 1 &&
|
||||
m_vVert[ m_vTria[i].nIdVert[2]].nTemp != 1)
|
||||
;
|
||||
// altrimenti attraversa il piano, devo modificarlo
|
||||
else {
|
||||
bModif = true ;
|
||||
int nDisc = m_vVert[ m_vTria[i].nIdVert[0]].nTemp +
|
||||
m_vVert[ m_vTria[i].nIdVert[1]].nTemp +
|
||||
m_vVert[ m_vTria[i].nIdVert[2]].nTemp ;
|
||||
// se ha un vertice all'interno e uno sul piano -> 1 nuovo vertice e 1 nuovo triangolo
|
||||
if ( nDisc == 0) {
|
||||
// classifico i vertici
|
||||
int nVertOn, nVertIn, nVertOut ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0) {
|
||||
nVertOn = 0 ;
|
||||
nVertIn = 1 ;
|
||||
nVertOut = 2 ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0) {
|
||||
nVertOn = 1 ;
|
||||
nVertIn = 2 ;
|
||||
nVertOut = 0 ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[2]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
else {
|
||||
nVertOn = 2 ;
|
||||
nVertIn = 0 ;
|
||||
nVertOut = 1 ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
// calcolo il punto di intersezione del lato che attraversa il piano
|
||||
double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ;
|
||||
double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ;
|
||||
Point3d ptInt = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut)) ;
|
||||
// inserisco il nuovo vertice
|
||||
int nNewV = AddVertex( ptInt) ;
|
||||
// inserisco il nuovo triangolo
|
||||
int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
|
||||
nIdVert[nVertOut] = nNewV ;
|
||||
int nIdTria = AddTriangle( nIdVert) ;
|
||||
if ( nIdTria == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria != SVT_DEL)
|
||||
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( i) ;
|
||||
}
|
||||
// se ha un vertice all'interno e due all'esterno -> 2 nuovi vertici e 1 nuovo triangolo
|
||||
else if ( nDisc == 1) {
|
||||
// classifico i vertici
|
||||
int nVertIn, nVertOut1, nVertOut2 ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == -1) {
|
||||
nVertIn = 0 ;
|
||||
nVertOut1 = 1 ;
|
||||
nVertOut2 = 2 ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == -1) {
|
||||
nVertIn = 1 ;
|
||||
nVertOut1 = 2 ;
|
||||
nVertOut2 = 0 ;
|
||||
}
|
||||
else {
|
||||
nVertIn = 2 ;
|
||||
nVertOut1 = 0 ;
|
||||
nVertOut2 = 1 ;
|
||||
}
|
||||
// calcolo i punti di intersezione dei lati che attraversano il piano
|
||||
double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ;
|
||||
double dDistOut1 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP, plPlane) ;
|
||||
double dDistOut2 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP, plPlane) ;
|
||||
Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut1)) ;
|
||||
Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut2)) ;
|
||||
// inserisco i nuovi vertici
|
||||
int nNewV1 = AddVertex( ptInt1) ;
|
||||
int nNewV2 = AddVertex( ptInt2) ;
|
||||
// inserisco il nuovo triangolo
|
||||
int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
|
||||
nIdVert[nVertOut1] = nNewV1 ;
|
||||
nIdVert[nVertOut2] = nNewV2 ;
|
||||
int nIdTria = AddTriangle( nIdVert) ;
|
||||
if ( nIdTria == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria != SVT_DEL)
|
||||
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( i) ;
|
||||
}
|
||||
// altrimenti ha due vertici all'interno e uno all'esterno -> 2 nuovi vertici e 2 nuovi triangoli
|
||||
else {
|
||||
// classifico i vertici
|
||||
int nVertIn1, nVertIn2, nVertOut ;
|
||||
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 1) {
|
||||
nVertOut = 0 ;
|
||||
nVertIn1 = 1 ;
|
||||
nVertIn2 = 2 ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 1) {
|
||||
nVertOut = 1 ;
|
||||
nVertIn1 = 2 ;
|
||||
nVertIn2 = 0 ;
|
||||
}
|
||||
else {
|
||||
nVertOut = 2 ;
|
||||
nVertIn1 = 0 ;
|
||||
nVertIn2 = 1 ;
|
||||
}
|
||||
// calcolo i punti di intersezione dei lati che attraversano il piano
|
||||
double dDistIn1 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, plPlane) ;
|
||||
double dDistIn2 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, plPlane) ;
|
||||
double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ;
|
||||
Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP,
|
||||
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
|
||||
dDistIn1 / ( dDistIn1 + dDistOut)) ;
|
||||
Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP,
|
||||
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
|
||||
dDistIn2 / ( dDistIn2 + dDistOut)) ;
|
||||
// inserisco i nuovi vertici
|
||||
int nNewV1 = AddVertex( ptInt1) ;
|
||||
int nNewV2 = AddVertex( ptInt2) ;
|
||||
// inserisco i nuovi triangoli
|
||||
int nIdVert1[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
|
||||
int nIdVert2[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
|
||||
double dSqDist1 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, ptInt2) ;
|
||||
double dSqDist2 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, ptInt1) ;
|
||||
if ( dSqDist1 <= dSqDist2) {
|
||||
nIdVert1[nVertOut] = nNewV1 ;
|
||||
nIdVert1[nVertIn2] = nNewV2 ;
|
||||
nIdVert2[nVertOut] = nNewV2 ;
|
||||
}
|
||||
else {
|
||||
nIdVert1[nVertOut] = nNewV1 ;
|
||||
nIdVert2[nVertOut] = nNewV2 ;
|
||||
nIdVert2[nVertIn1] = nNewV1 ;
|
||||
}
|
||||
int nIdTria1 = AddTriangle( nIdVert1) ;
|
||||
int nIdTria2 = AddTriangle( nIdVert2) ;
|
||||
if ( nIdTria1 == SVT_NULL || nIdTria2 == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria1 != SVT_DEL)
|
||||
m_vTria[nIdTria1].nTemp = m_nTimeStamp ;
|
||||
if ( nIdTria2 != SVT_DEL)
|
||||
m_vTria[nIdTria2].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( i) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se effettuate modifiche
|
||||
if ( bModif) {
|
||||
// aggiorno tutto
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
#else
|
||||
|
||||
bool bModif = false ;
|
||||
|
||||
// Setto i triangoli come né fuori né dentro.
|
||||
int nTriaNum = GetTriangleSize() ;
|
||||
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
|
||||
m_vTria[nT].nTempPart = 0 ;
|
||||
}
|
||||
|
||||
INTERSCHAINMAP IntersLineMap ;
|
||||
|
||||
// Ciclo su tutte le facce.
|
||||
int nFacetNum = GetFacetCount() ;
|
||||
for ( int nF = 0 ; nF < nFacetNum ; ++ nF) {
|
||||
// Dati della faccia
|
||||
POLYLINEVECTOR vLoopVec ;
|
||||
GetFacetLoops( nF, vLoopVec) ;
|
||||
if ( vLoopVec.empty())
|
||||
continue ;
|
||||
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
|
||||
if ( IsNull( pReg))
|
||||
return false ;
|
||||
LineFacetClassVector IntersLinePart ;
|
||||
int nIntType = IntersFacetPlane( *pReg, vLoopVec[0], plPlane, IntersLinePart) ;
|
||||
if ( nIntType == FacetPlaneIntersType::FPI_CUT) {
|
||||
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
|
||||
// Salvo intersezione per la faccia.
|
||||
auto it = IntersLineMap.find( nF) ;
|
||||
if ( it != IntersLineMap.end()) {
|
||||
it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ;
|
||||
}
|
||||
else {
|
||||
IntersLineMap.emplace( nF, IntersInnChain( 1, IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn))) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_ON) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = pReg->GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_INN) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = 1 ;
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_OUT) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = - 1 ;
|
||||
}
|
||||
else
|
||||
;
|
||||
}
|
||||
|
||||
// Divido le facce.
|
||||
PieceMap NewFacet ;
|
||||
SplitFacet( IntersLineMap, NewFacet) ;
|
||||
INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ;
|
||||
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
|
||||
|
||||
int nNumTria = GetTriangleSize() ;
|
||||
for ( int nT = 0 ; nT < nNumTria ; ++ nT)
|
||||
if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2))
|
||||
RemoveTriangle( nT) ;
|
||||
|
||||
return AdjustVertices() && DoCompacting() ;
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
SurfTriMesh::ResetHashGrids3d( void) const
|
||||
|
||||
+39
-48
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2019
|
||||
// EgalTech 2014-2021
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMesh.h Data : 12.02.19 Versione : 2.1b2
|
||||
// File : SurfTriMesh.h Data : 26.09.21 Versione : 2.3i2
|
||||
// Contenuto : Dichiarazione della classe Superficie TriMesh.
|
||||
//
|
||||
//
|
||||
@@ -94,34 +94,15 @@ typedef std::unordered_map< int, Chain> CHAINMAP ;
|
||||
typedef std::unordered_map< int, TRIA3DVECTOR> TRIA3DVECTORMAP ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Struttura per la ricerca delle T-Junction
|
||||
struct TEdgeId {
|
||||
int nTriaId ;
|
||||
int nEdge ;
|
||||
} ;
|
||||
// Overloading dell'operatore < per TEdgeSet
|
||||
inline bool operator<( const TEdgeId& TEdgeA, const TEdgeId& TEdgeB) {
|
||||
if ( TEdgeA.nTriaId != TEdgeB.nTriaId)
|
||||
return ( TEdgeA.nTriaId < TEdgeB.nTriaId) ;
|
||||
return ( TEdgeA.nEdge < TEdgeB.nEdge) ;
|
||||
}
|
||||
// Loop con T-Junction
|
||||
typedef std::vector<TEdgeId> TJuncLoop ;
|
||||
// Vettore di loop con T-Junction
|
||||
typedef std::vector<TJuncLoop> TJuncLoopVec ;
|
||||
// Set di TEdgeId
|
||||
typedef std::set<TEdgeId> TJEdgeSet ;
|
||||
|
||||
// Definizione strutture intersezione linea-faccia
|
||||
//----------------------------------------------------------------------------
|
||||
// Struttura intersezione linea-faccia
|
||||
struct LineFacetClass {
|
||||
Point3d ptSt, ptEn ;
|
||||
int nTypeA, nTypeB ;
|
||||
LineFacetClass() {
|
||||
LineFacetClass( void) {
|
||||
nTypeA = 0 ;
|
||||
nTypeB = 0 ;
|
||||
}
|
||||
LineFacetClass( const Point3d& ptS, const Point3d ptE, int nTpA, int nTpB) {
|
||||
LineFacetClass( const Point3d& ptS, const Point3d& ptE, int nTpA, int nTpB) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
nTypeA = nTpA ;
|
||||
@@ -131,28 +112,27 @@ struct LineFacetClass {
|
||||
typedef std::vector<LineFacetClass> LineFacetClassVector ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_INN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
||||
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_IN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione strutture e contenitori
|
||||
// Contatti interno-interno
|
||||
// Strutture e contenitori contatti interno-interno
|
||||
struct IntersInnSeg {
|
||||
Point3d ptSt ;
|
||||
Point3d ptEn ;
|
||||
Vector3d vtOuter ;
|
||||
IntersInnSeg(void) {
|
||||
IntersInnSeg( void) {
|
||||
;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
IntersInnSeg( const Point3d& ptS, const Point3d& ptE) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vtOuter = vtO;
|
||||
IntersInnSeg( const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
vtOuter = vtO ;
|
||||
}
|
||||
};
|
||||
} ;
|
||||
typedef std::vector<IntersInnSeg> IntersInnChain ;
|
||||
typedef std::vector<IntersInnChain> INNCHAINVECTOR ;
|
||||
typedef std::unordered_map<int, IntersInnChain> INTERSCHAINMAP ;
|
||||
@@ -164,7 +144,7 @@ struct IntersEdge {
|
||||
IntersEdge( const Point3d& ptS, const Point3d& ptE, const INTVECTOR& vOFI) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vOthFacetIndex = vOFI;
|
||||
vOthFacetIndex = vOFI ;
|
||||
}
|
||||
} ;
|
||||
typedef std::vector<IntersEdge> IntersEdgeVec ;
|
||||
@@ -206,10 +186,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // ISurf
|
||||
bool IsSimple( void) const override
|
||||
@@ -248,7 +229,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRot, double dStepRot, double dMove) override ;
|
||||
bool DoCompacting( double dTol = EPS_SMALL) override ;
|
||||
bool DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther = GLOB_FRM) override ;
|
||||
bool DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther = GLOB_FRM, double dTol = 2 * EPS_SMALL) override ;
|
||||
int GetVertexCount( void) const override ;
|
||||
int GetTriangleCount( void) const override ;
|
||||
int GetTriangleCount( int nTFlag) const override ;
|
||||
@@ -277,7 +258,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool GetTriangleBoundaryEdges( int nId, TriFlags3d& TFlags) const override ;
|
||||
bool GetTriangleSmoothNormals( int nId, TriNormals3d& TNrms) const override ;
|
||||
bool GetLoops( POLYLINEVECTOR& vPL) const override ;
|
||||
bool GetSilhouette( const Vector3d& vtDir, POLYLINEVECTOR& vPL) const override ;
|
||||
bool GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL) const override ;
|
||||
int GetFacetCount( void) const override ;
|
||||
int GetFacetSize( void) const override
|
||||
{ return int( m_vFacet.size()) ; }
|
||||
@@ -304,6 +285,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
||||
bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
||||
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
||||
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
||||
const BBox3d& GetAllTriaBox( void) const override ;
|
||||
int GetPartCount( void) const override ;
|
||||
@@ -369,9 +351,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
||||
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
|
||||
bool AddBiTriangle( const int nIdVert[4]) ;
|
||||
bool ResetFaceting( void) ;
|
||||
bool VerifyFaceting( void) const ;
|
||||
bool UpdateFaceting( void) ;
|
||||
bool UpdateOneFace( int nFacet, int nT) ;
|
||||
bool UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT) ;
|
||||
bool SetFacet( int nInd, int nT) ;
|
||||
bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ;
|
||||
@@ -380,16 +362,20 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
void ResetHashGrids3d( void) const ;
|
||||
bool VerifyHashGrids3d( void) const ;
|
||||
bool VerifyConnection( void) const ;
|
||||
bool CutTriangleByPlane( int nTriaId, const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||
bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||
bool CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
||||
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
||||
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||
int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
|
||||
LineFacetClassVector& IntersLinePart) ;
|
||||
int VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) ;
|
||||
int IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane,
|
||||
LineFacetClassVector& IntersLinePart) ;
|
||||
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
|
||||
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
|
||||
LineFacetClassVector& IntersLinePart) ;
|
||||
bool ItersectTriMeshFacets( SurfTriMesh& Other) ;
|
||||
bool IntersectTriMeshFacets( SurfTriMesh& Other) ;
|
||||
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
|
||||
const INTERSEDGEMAP& EdgeInterLineMap,
|
||||
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
|
||||
@@ -406,6 +392,11 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool RemoveTripleTriangles( void) ;
|
||||
bool ScanForTripleTriangles( bool& bModified) ;
|
||||
bool FlipTriangles( int nTA, int nTB) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true) ;
|
||||
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||
bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
@@ -422,7 +413,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
TRIAVECTOR m_vTria ; // vettore dei triangoli
|
||||
INTVECTOR m_vFacet ; // vettore delle sfaccettature
|
||||
mutable int m_nTimeStamp ; // orologio locale
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli
|
||||
mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare)
|
||||
mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento
|
||||
|
||||
+415
-1393
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,874 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2019-2021
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMeshCuts.cpp Data : 06.11.21 Versione : 2.3k3
|
||||
// Contenuto : Implementazione delle funzioni di taglio per SurfFTrimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 06.11.21 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "Triangulate.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const double CUT_SCALE = 1024 ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// recupero il numero originale di triangoli e di facce
|
||||
int nTriaOriCnt = GetTriangleCount() ;
|
||||
int nFacetOriCnt = GetFacetCount() ;
|
||||
|
||||
// eseguo il taglio con il metodo delle faccette o dei triangoli (per ora solo coi triangoli)
|
||||
bool bModif = false ;
|
||||
if ( true || ! CutByFacets( plPlane, bSaveOnEq, bModif)) {
|
||||
bModif = false ;
|
||||
if ( ! CutByTriangles( plPlane, bSaveOnEq, bModif))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se effettuate modifiche
|
||||
if ( bModif) {
|
||||
// aggiorno tutto
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se superficie originale a facce, cerco di semplificarle in ogni caso
|
||||
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Cut")
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// classifico i vertici rispetto al piano
|
||||
double dTol = max( min( 0.5 * m_dLinTol, 10 * EPS_SMALL), EPS_SMALL) ;
|
||||
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
|
||||
double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ;
|
||||
if ( abs( dDist) < dTol) {
|
||||
m_vVert[i].nTemp = 0 ;
|
||||
if ( abs( dDist) > EPS_SMALL)
|
||||
m_vVert[i].ptP -= plPlane.GetVersN() * dDist ;
|
||||
}
|
||||
else if ( dDist > 0)
|
||||
m_vVert[i].nTemp = +1 ;
|
||||
else
|
||||
m_vVert[i].nTemp = -1 ;
|
||||
}
|
||||
|
||||
// aggiorno timestamp dei triangoli
|
||||
for ( auto& Tria : m_vTria)
|
||||
Tria.nTemp = m_nTimeStamp ;
|
||||
++ m_nTimeStamp ;
|
||||
|
||||
// sistemo i triangoli (eventualmente li elimino)
|
||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||
// salto i triangoli cancellati e quelli aggiunti
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
|
||||
continue ;
|
||||
CutTriangleByPlane( i, plPlane, bSaveOnEq, bModif) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CutTriangleByPlane( int nT, const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
|
||||
{
|
||||
// se flag abilita e giace sul piano ed equiverso, lo salvo
|
||||
if ( bSaveOnEq &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[0]].nTemp == 0 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[1]].nTemp == 0 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[2]].nTemp == 0 &&
|
||||
AreSameVectorApprox( m_vTria[nT].vtN, plPlane.GetVersN()))
|
||||
;
|
||||
// se giace sul piano o dalla parte esterna del piano, lo cancello
|
||||
else if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp != -1 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[1]].nTemp != -1 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[2]].nTemp != -1) {
|
||||
bModif = true ;
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
// se giace dalla parte interna con al massimo un lato sul piano, lo conservo
|
||||
else if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp != 1 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[1]].nTemp != 1 &&
|
||||
m_vVert[ m_vTria[nT].nIdVert[2]].nTemp != 1)
|
||||
;
|
||||
// altrimenti attraversa il piano, devo modificarlo
|
||||
else {
|
||||
bModif = true ;
|
||||
int nDisc = m_vVert[ m_vTria[nT].nIdVert[0]].nTemp +
|
||||
m_vVert[ m_vTria[nT].nIdVert[1]].nTemp +
|
||||
m_vVert[ m_vTria[nT].nIdVert[2]].nTemp ;
|
||||
// se ha un vertice all'interno e uno sul piano -> 1 nuovo vertice e 1 nuovo triangolo
|
||||
if ( nDisc == 0) {
|
||||
// classifico i vertici
|
||||
int nVertOn, nVertIn, nVertOut ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp == 0) {
|
||||
nVertOn = 0 ;
|
||||
nVertIn = 1 ;
|
||||
nVertOut = 2 ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[1]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[nT].nIdVert[1]].nTemp == 0) {
|
||||
nVertOn = 1 ;
|
||||
nVertIn = 2 ;
|
||||
nVertOut = 0 ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[2]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
else {
|
||||
nVertOn = 2 ;
|
||||
nVertIn = 0 ;
|
||||
nVertOut = 1 ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp > 0)
|
||||
swap( nVertIn, nVertOut) ;
|
||||
}
|
||||
// calcolo il punto di intersezione del lato che attraversa il piano
|
||||
double dDistIn = - DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertIn]].ptP, plPlane) ;
|
||||
double dDistOut = DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertOut]].ptP, plPlane) ;
|
||||
Point3d ptInt = Media( m_vVert[m_vTria[nT].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[nT].nIdVert[nVertOut]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut)) ;
|
||||
// inserisco il nuovo vertice
|
||||
int nNewV = AddVertex( ptInt) ;
|
||||
// inserisco il nuovo triangolo
|
||||
int nIdVert[3] = { m_vTria[nT].nIdVert[0], m_vTria[nT].nIdVert[1], m_vTria[nT].nIdVert[2]} ;
|
||||
nIdVert[nVertOut] = nNewV ;
|
||||
int nIdTria = AddTriangle( nIdVert) ;
|
||||
if ( nIdTria == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria != SVT_DEL)
|
||||
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
// se ha un vertice all'interno e due all'esterno -> 2 nuovi vertici e 1 nuovo triangolo
|
||||
else if ( nDisc == 1) {
|
||||
// classifico i vertici
|
||||
int nVertIn, nVertOut1, nVertOut2 ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp == -1) {
|
||||
nVertIn = 0 ;
|
||||
nVertOut1 = 1 ;
|
||||
nVertOut2 = 2 ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[nT].nIdVert[1]].nTemp == -1) {
|
||||
nVertIn = 1 ;
|
||||
nVertOut1 = 2 ;
|
||||
nVertOut2 = 0 ;
|
||||
}
|
||||
else {
|
||||
nVertIn = 2 ;
|
||||
nVertOut1 = 0 ;
|
||||
nVertOut2 = 1 ;
|
||||
}
|
||||
// calcolo i punti di intersezione dei lati che attraversano il piano
|
||||
double dDistIn = - DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertIn]].ptP, plPlane) ;
|
||||
double dDistOut1 = DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertOut1]].ptP, plPlane) ;
|
||||
double dDistOut2 = DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertOut2]].ptP, plPlane) ;
|
||||
Point3d ptInt1 = Media( m_vVert[m_vTria[nT].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[nT].nIdVert[nVertOut1]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut1)) ;
|
||||
Point3d ptInt2 = Media( m_vVert[m_vTria[nT].nIdVert[nVertIn]].ptP,
|
||||
m_vVert[m_vTria[nT].nIdVert[nVertOut2]].ptP,
|
||||
dDistIn / ( dDistIn + dDistOut2)) ;
|
||||
// inserisco i nuovi vertici
|
||||
int nNewV1 = AddVertex( ptInt1) ;
|
||||
int nNewV2 = AddVertex( ptInt2) ;
|
||||
// inserisco il nuovo triangolo
|
||||
int nIdVert[3] = { m_vTria[nT].nIdVert[0], m_vTria[nT].nIdVert[1], m_vTria[nT].nIdVert[2]} ;
|
||||
nIdVert[nVertOut1] = nNewV1 ;
|
||||
nIdVert[nVertOut2] = nNewV2 ;
|
||||
int nIdTria = AddTriangle( nIdVert) ;
|
||||
if ( nIdTria == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria != SVT_DEL)
|
||||
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
// altrimenti ha due vertici all'interno e uno all'esterno -> 2 nuovi vertici e 2 nuovi triangoli
|
||||
else {
|
||||
// classifico i vertici
|
||||
int nVertIn1, nVertIn2, nVertOut ;
|
||||
if ( m_vVert[ m_vTria[nT].nIdVert[0]].nTemp == 1) {
|
||||
nVertOut = 0 ;
|
||||
nVertIn1 = 1 ;
|
||||
nVertIn2 = 2 ;
|
||||
}
|
||||
else if ( m_vVert[ m_vTria[nT].nIdVert[1]].nTemp == 1) {
|
||||
nVertOut = 1 ;
|
||||
nVertIn1 = 2 ;
|
||||
nVertIn2 = 0 ;
|
||||
}
|
||||
else {
|
||||
nVertOut = 2 ;
|
||||
nVertIn1 = 0 ;
|
||||
nVertIn2 = 1 ;
|
||||
}
|
||||
// calcolo i punti di intersezione dei lati che attraversano il piano
|
||||
double dDistIn1 = - DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertIn1]].ptP, plPlane) ;
|
||||
double dDistIn2 = - DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertIn2]].ptP, plPlane) ;
|
||||
double dDistOut = DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nVertOut]].ptP, plPlane) ;
|
||||
Point3d ptInt1 = Media( m_vVert[m_vTria[nT].nIdVert[nVertIn1]].ptP,
|
||||
m_vVert[m_vTria[nT].nIdVert[nVertOut]].ptP,
|
||||
dDistIn1 / ( dDistIn1 + dDistOut)) ;
|
||||
Point3d ptInt2 = Media( m_vVert[m_vTria[nT].nIdVert[nVertIn2]].ptP,
|
||||
m_vVert[m_vTria[nT].nIdVert[nVertOut]].ptP,
|
||||
dDistIn2 / ( dDistIn2 + dDistOut)) ;
|
||||
// inserisco i nuovi vertici
|
||||
int nNewV1 = AddVertex( ptInt1) ;
|
||||
int nNewV2 = AddVertex( ptInt2) ;
|
||||
// inserisco i nuovi triangoli
|
||||
int nIdVert1[3] = { m_vTria[nT].nIdVert[0], m_vTria[nT].nIdVert[1], m_vTria[nT].nIdVert[2]} ;
|
||||
int nIdVert2[3] = { m_vTria[nT].nIdVert[0], m_vTria[nT].nIdVert[1], m_vTria[nT].nIdVert[2]} ;
|
||||
double dSqDist1 = SqDist( m_vVert[m_vTria[nT].nIdVert[nVertIn1]].ptP, ptInt2) ;
|
||||
double dSqDist2 = SqDist( m_vVert[m_vTria[nT].nIdVert[nVertIn2]].ptP, ptInt1) ;
|
||||
if ( dSqDist1 <= dSqDist2) {
|
||||
nIdVert1[nVertOut] = nNewV1 ;
|
||||
nIdVert1[nVertIn2] = nNewV2 ;
|
||||
nIdVert2[nVertOut] = nNewV2 ;
|
||||
}
|
||||
else {
|
||||
nIdVert1[nVertOut] = nNewV1 ;
|
||||
nIdVert2[nVertOut] = nNewV2 ;
|
||||
nIdVert2[nVertIn1] = nNewV1 ;
|
||||
}
|
||||
int nIdTria1 = AddTriangle( nIdVert1) ;
|
||||
int nIdTria2 = AddTriangle( nIdVert2) ;
|
||||
if ( nIdTria1 == SVT_NULL || nIdTria2 == SVT_NULL)
|
||||
return false ;
|
||||
if ( nIdTria1 != SVT_DEL)
|
||||
m_vTria[nIdTria1].nTemp = m_nTimeStamp ;
|
||||
if ( nIdTria2 != SVT_DEL)
|
||||
m_vTria[nIdTria2].nTemp = m_nTimeStamp ;
|
||||
// cancello il vecchio triangolo
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif)
|
||||
{
|
||||
// Setto posizione triangoli non definita
|
||||
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT)
|
||||
m_vTria[nT].nTempPart = 0 ;
|
||||
|
||||
INTERSCHAINMAP IntersLineMap ;
|
||||
|
||||
// Ciclo su tutte le facce.
|
||||
for ( int nF = 0 ; nF < GetFacetCount() ; ++ nF) {
|
||||
// Dati della faccia
|
||||
POLYLINEVECTOR vLoopVec ;
|
||||
GetFacetLoops( nF, vLoopVec) ;
|
||||
if ( vLoopVec.empty())
|
||||
continue ;
|
||||
// Verifico la posizione del loop esterno
|
||||
int nIntType = VerifyLoopPlane( vLoopVec[0], plPlane) ;
|
||||
// Se interseca il piano di taglio, calcolo la divisione della faccia
|
||||
LineFacetClassVector IntersLinePart ;
|
||||
if ( nIntType == FPI_CUT) {
|
||||
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
|
||||
if ( IsNull( pReg) || ! pReg->IsValid())
|
||||
return false ;
|
||||
nIntType = IntersFacetPlane( *pReg, plPlane, IntersLinePart) ;
|
||||
}
|
||||
// Gestione dei risultati
|
||||
if ( nIntType == FPI_CUT) {
|
||||
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
|
||||
// Salvo intersezione per la faccia.
|
||||
auto it = IntersLineMap.find( nF) ;
|
||||
if ( it != IntersLineMap.end()) {
|
||||
it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ;
|
||||
}
|
||||
else {
|
||||
IntersLineMap.emplace( nF, IntersInnChain( 1, IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn))) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( nIntType == FPI_ON) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
Vector3d vtNf ;
|
||||
GetFacetNormal( nF, vtNf) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = ( vtNf * plPlane.GetVersN() > 0 ? 2 : -2) ;
|
||||
}
|
||||
else if ( nIntType == FPI_IN) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = 1 ;
|
||||
}
|
||||
else if ( nIntType == FPI_OUT) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = -1 ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Divido le facce.
|
||||
PieceMap NewFacet ;
|
||||
SplitFacet( IntersLineMap, NewFacet) ;
|
||||
INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ;
|
||||
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
|
||||
|
||||
// Elimino i triangoli superflui
|
||||
for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) {
|
||||
if ( m_vTria[nT].nTempPart == 0 ||
|
||||
m_vTria[nT].nTempPart == -1 ||
|
||||
m_vTria[nT].nTempPart == -2 ||
|
||||
( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) {
|
||||
RemoveTriangle( nT) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Risultato : 0=nessuna intersezione, 1=intersezione è un punto, 2=intersezione è un segmento
|
||||
static int
|
||||
IntersRectangleTriangle( const Point3d& ptP, const Vector3d& vtL1, const Vector3d& vtL2,
|
||||
const Triangle3d& trTria, Point3d& ptStSeg, Point3d& ptEnSeg)
|
||||
{
|
||||
// Assegno tolleranza lineare
|
||||
double dTol = EPS_SMALL ;
|
||||
// Definisco il piano del rettangolo
|
||||
Plane3d plRectanglePlane ;
|
||||
if ( ! plRectanglePlane.Set( ptP, vtL1 ^ vtL2))
|
||||
return -1 ;
|
||||
// Interseco il piano con il triangolo (recupero estremi in ordine inverso per mantenere l'esterno a destra nei loop)
|
||||
int nPlTrIntRes = IntersPlaneTria( plRectanglePlane, trTria, ptEnSeg, ptStSeg) ;
|
||||
if ( nPlTrIntRes != IntPlaneTriaType::IPTT_YES)
|
||||
return 0 ;
|
||||
// Limito il segmento col rettangolo
|
||||
Vector3d vtSegDir = ptEnSeg - ptStSeg ;
|
||||
double dSegLen = vtSegDir.Len() ;
|
||||
vtSegDir /= dSegLen ;
|
||||
// utilizzo piani ortogonali al rettangolo passanti per i suoi estremi
|
||||
Plane3d plTrim1 ; plTrim1.Set( ptP, -vtL1) ;
|
||||
Plane3d plTrim2 ; plTrim2.Set( ptP + vtL1, vtL1) ;
|
||||
if ( vtSegDir * vtL1 < 0.)
|
||||
swap( plTrim1, plTrim2) ;
|
||||
Point3d ptInt1 ;
|
||||
int nLnPl1IntRes = IntersLinePlane( ptStSeg, vtSegDir, dSegLen, plTrim1, ptInt1, false) ;
|
||||
Point3d ptInt2 ;
|
||||
int nLnPl2IntRes = IntersLinePlane( ptStSeg, vtSegDir, dSegLen, plTrim2, ptInt2, false) ;
|
||||
// Se il segmento giace in uno dei due piani
|
||||
if ( ( nLnPl1IntRes == ILPT_NO && nLnPl2IntRes == ILPT_INPLANE) ||
|
||||
( nLnPl2IntRes == ILPT_NO && nLnPl1IntRes == ILPT_INPLANE))
|
||||
return ( AreSamePointEpsilon( ptStSeg, ptEnSeg, dTol) ? 1 : 2) ;
|
||||
// Se non ci sono intersezioni
|
||||
if ( nLnPl1IntRes == ILPT_NO && nLnPl2IntRes == ILPT_NO) {
|
||||
// se è tra i due piani
|
||||
if (( ptStSeg - plTrim1.GetPoint()) * plTrim1.GetVersN() < 0. &&
|
||||
( ptStSeg - plTrim2.GetPoint()) * plTrim2.GetVersN() < 0.)
|
||||
return ( AreSamePointEpsilon( ptStSeg, ptEnSeg, dTol) ? 1 : 2) ;
|
||||
// altrimenti è esterno
|
||||
else
|
||||
return 0 ;
|
||||
}
|
||||
// Posizioni parametriche delle intersezioni sul segmento
|
||||
double dLen1 = ( ptInt1 - ptStSeg) * vtSegDir ;
|
||||
double dLen2 = ( ptInt2 - ptStSeg) * vtSegDir ;
|
||||
// Se la prima intersezione supera la fine o la seconda viene prima dell'inizio, non ci sono intersezioni
|
||||
if ( dLen1 > dSegLen + EPS_ZERO || dLen2 < -EPS_ZERO)
|
||||
return 0 ;
|
||||
// Eventuale aggiustamento inizio
|
||||
if ( dLen1 > 0.) {
|
||||
ptStSeg = ptInt1 ;
|
||||
dSegLen -= dLen1 ;
|
||||
dLen2 -= dLen1 ;
|
||||
}
|
||||
// Eventuale aggiustamento fine
|
||||
if ( dLen2 < dSegLen) {
|
||||
ptEnSeg = ptInt2 ;
|
||||
dSegLen = dLen2 ;
|
||||
}
|
||||
// Assegno il tipo di intersezione
|
||||
return ( dSegLen > dTol ? 2 : 1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
{
|
||||
// La superficie deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// La curva deve essere valida e chiusa, il vettore estrusione deve essere non nullo
|
||||
Vector3d vtExtr ;
|
||||
if ( ! cvCurve.GetExtrusion( vtExtr) || vtExtr.IsSmall() || ! cvCurve.IsClosed())
|
||||
return false ;
|
||||
|
||||
// Recupero il numero originale di triangoli e di facce
|
||||
int nTriaOriCnt = GetTriangleCount() ;
|
||||
int nFacetOriCnt = GetFacetCount() ;
|
||||
|
||||
// Approssimo la curva con segmenti
|
||||
CurveComposite cvCompo ;
|
||||
{
|
||||
PolyLine PL ;
|
||||
if ( ! cvCurve.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! cvCompo.FromPolyLine( PL))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Eseguo scalature
|
||||
Frame3d frScalingRef;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, CUT_SCALE, CUT_SCALE, CUT_SCALE) ;
|
||||
cvCompo.Scale( frScalingRef, CUT_SCALE, CUT_SCALE, CUT_SCALE) ;
|
||||
|
||||
// Appiattisco la polilinea nel piano perpendicolare all'estrusione
|
||||
Frame3d frCurve ;
|
||||
Point3d ptStart ; cvCompo.GetStartPoint( ptStart) ;
|
||||
frCurve.Set( ptStart, vtExtr) ;
|
||||
cvCompo.ToLoc( frCurve) ;
|
||||
if ( ! cvCompo.Scale( GLOB_FRM, 1, 1, 0)) {
|
||||
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
|
||||
return false ;
|
||||
}
|
||||
double dArea ;
|
||||
cvCompo.GetAreaXY( dArea) ;
|
||||
BBox3d b3Crv ;
|
||||
cvCompo.GetLocalBBox( b3Crv) ;
|
||||
cvCompo.ToGlob( frCurve) ;
|
||||
// Assegno il senso di rotazione della curva (visto dalla punta del vettore estrusione)
|
||||
bool bCCW = ( dArea > 0) ;
|
||||
|
||||
// Recupero Bounding-box della trimesh
|
||||
BBox3d b3SurfBox ;
|
||||
GetLocalBBox( b3SurfBox) ;
|
||||
// Trovo minima e massima distanza dei vertici del bounding-box della TriMesh dal piano della curva
|
||||
b3SurfBox.ToLoc( frCurve) ;
|
||||
Point3d ptMin, ptMax ;
|
||||
b3SurfBox.GetMinMax( ptMin, ptMax) ;
|
||||
Vector3d vtMax = ( ptMax.z + 10) * vtExtr ;
|
||||
Vector3d vtMin = ( ptMin.z - 10) * vtExtr ;
|
||||
|
||||
// Ciclo sui triangoli
|
||||
bool bModif = false ;
|
||||
int nNumTria = GetTriangleSize() ;
|
||||
for ( int nT = 0 ; nT < nNumTria ; ++ nT) {
|
||||
// Recupero il triangolo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria))
|
||||
continue ;
|
||||
// Box del triangolo nel riferimento locale della curva
|
||||
BBox3d b3Tria ;
|
||||
trTria.GetLocalBBox( b3Tria) ;
|
||||
b3Tria.ToLoc( frCurve) ;
|
||||
// Se il box del triangolo non interseca quello locale della curva
|
||||
if ( ! b3Crv.OverlapsXY( b3Tria)) {
|
||||
// Se la parte da conservare è quella all'interno della curva, elimino il triangolo
|
||||
if ( bCCW) {
|
||||
RemoveTriangle( nT) ;
|
||||
bModif = true ;
|
||||
}
|
||||
continue ;
|
||||
}
|
||||
// Determino se il centro del triangolo cade all'interno della curva
|
||||
bool bTriaCenIn = false ;
|
||||
{
|
||||
// centro proiettato sul piano della curva
|
||||
Point3d ptCen = trTria.GetCentroid() ;
|
||||
ptCen = ptCen - ( ptCen - ptStart) * vtExtr * vtExtr ;
|
||||
// calcolo distanza
|
||||
DistPointCurve dstPC( ptCen, cvCompo) ;
|
||||
double dDist ; dstPC.GetDist( dDist) ;
|
||||
// se maggiore oltre il limite originale
|
||||
if ( dDist > CUT_SCALE * EPS_SMALL) {
|
||||
int nSide ;
|
||||
if ( dstPC.GetSideAtMinDistPoint( 0, vtExtr, nSide))
|
||||
bTriaCenIn = ( nSide == MDS_LEFT) ;
|
||||
}
|
||||
// altrimenti ricalcolo con centro del triangolo spostato all'interno sulla normale
|
||||
else {
|
||||
Point3d ptCen2 = trTria.GetCentroid() - CUT_SCALE * EPS_SMALL * trTria.GetN() ;
|
||||
DistPointCurve dstP2C( ptCen2, cvCompo) ;
|
||||
int nSide2 ;
|
||||
if ( dstP2C.GetSideAtMinDistPoint( 0, vtExtr, nSide2))
|
||||
bTriaCenIn = ( nSide2 == MDS_LEFT && bSaveOnEq) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Vettore di catene di punti e flag sulla complanarità del triangolo con uno dei rettangoli
|
||||
CHAINVECTOR vChain ;
|
||||
bool bTriaOn = false ;
|
||||
// Segnalatore di taglio piccolo, punto e vettore per costruire il piano per eseguirlo
|
||||
int nSmallCutState = 0 ;
|
||||
Point3d ptSmallCutPnt ;
|
||||
Vector3d vtSmallCutVec ;
|
||||
// Ciclo sui segmenti
|
||||
int nChainCnt = 0 ;
|
||||
bool bChain = false ;
|
||||
Point3d ptChSt, ptChEn ;
|
||||
const ICurve* pCrv = cvCompo.GetFirstCurve() ;
|
||||
while ( pCrv != nullptr) {
|
||||
// estremi del segmento
|
||||
Point3d ptSt ; pCrv->GetStartPoint( ptSt) ;
|
||||
Point3d ptEn ; pCrv->GetEndPoint( ptEn) ;
|
||||
// Se il segmento giace sul piano del triangolo, lo segnalo.
|
||||
if ( abs( ( ptSt - trTria.GetCentroid()) * trTria.GetN()) < CUT_SCALE * EPS_SMALL &&
|
||||
abs( ( ptEn - trTria.GetCentroid()) * trTria.GetN()) < CUT_SCALE * EPS_SMALL &&
|
||||
abs( trTria.GetN() * vtExtr) < EPS_SMALL)
|
||||
bTriaOn = true ;
|
||||
// Intersezione fra il rettangolo (ottenuto dall'estrusione del segmento corrente) e il triangolo
|
||||
Point3d ptSegSt, ptSegEn ;
|
||||
int nInt = IntersRectangleTriangle( ptSt + vtMin, ptEn - ptSt, vtMax - vtMin, trTria, ptSegSt, ptSegEn) ;
|
||||
if ( nInt == 2) {
|
||||
// Creo nuova catena se non c'è già o se discontinuità
|
||||
if ( ! bChain || ( ! AreSamePointApprox( ptSegSt, ptChEn) && ! AreSamePointApprox( ptSegEn, ptChSt))) {
|
||||
++ nChainCnt ;
|
||||
vChain.resize( nChainCnt) ;
|
||||
bChain = false ;
|
||||
}
|
||||
// Assegno i dati di intersezione
|
||||
IntSegment CurInters ;
|
||||
CurInters.ptSt = ptSegSt ;
|
||||
CurInters.ptEn = ptSegEn ;
|
||||
// Inserisco nella catena
|
||||
if ( ! bChain) {
|
||||
vChain[nChainCnt - 1].emplace_back( CurInters) ;
|
||||
ptChSt = CurInters.ptSt ;
|
||||
ptChEn = CurInters.ptEn ;
|
||||
}
|
||||
else if ( AreSamePointApprox(ptSegSt, ptChEn)) {
|
||||
vChain[nChainCnt - 1].emplace_back(CurInters) ;
|
||||
ptChEn = CurInters.ptEn ;
|
||||
}
|
||||
else {
|
||||
vChain[nChainCnt - 1].insert(vChain[nChainCnt - 1].begin(), CurInters) ;
|
||||
ptChSt = CurInters.ptSt ;
|
||||
}
|
||||
bChain = true ;
|
||||
}
|
||||
else {
|
||||
// Taglio piccolo
|
||||
if ( nInt == 1) {
|
||||
if ( nSmallCutState == 0)
|
||||
nSmallCutState = 1 ;
|
||||
else
|
||||
nSmallCutState = 2 ;
|
||||
ptSmallCutPnt = ptSt ;
|
||||
vtSmallCutVec = ptEn - ptSt ;
|
||||
}
|
||||
bChain = false ;
|
||||
}
|
||||
pCrv = cvCompo.GetNextCurve() ;
|
||||
}
|
||||
// Gestisco il taglio piccolo.
|
||||
if ( nSmallCutState == 1 && int( vChain.size()) == 0) {
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( ptSmallCutPnt, vtSmallCutVec ^ ( vtMax - vtMin)) ;
|
||||
for ( int nV = 0 ; nV < 3 ; ++ nV) {
|
||||
double dDist = DistPointPlane( m_vVert[m_vTria[nT].nIdVert[nV]].ptP, plPlane) ;
|
||||
if ( abs( dDist) < EPS_SMALL) {
|
||||
m_vVert[m_vTria[nT].nIdVert[nV]].nTemp = 0 ;
|
||||
if ( abs( dDist) > EPS_SMALL)
|
||||
m_vVert[m_vTria[nT].nIdVert[nV]].ptP -= plPlane.GetVersN() * dDist ;
|
||||
}
|
||||
else if ( dDist > 0)
|
||||
m_vVert[m_vTria[nT].nIdVert[nV]].nTemp = +1 ;
|
||||
else
|
||||
m_vVert[m_vTria[nT].nIdVert[nV]].nTemp = -1 ;
|
||||
}
|
||||
CutTriangleByPlane( nT, plPlane, bSaveOnEq, bModif) ;
|
||||
continue ;
|
||||
}
|
||||
for ( auto itI = vChain.begin() ; itI != vChain.end() ; ) {
|
||||
bool bErased = false ;
|
||||
auto itJ = itI ;
|
||||
++ itJ ;
|
||||
for ( ; itJ != vChain.end() && ! bErased ; ) {
|
||||
if ( int( itI->size()) == 1 && int( itJ->size()) == 1 &&
|
||||
AreSamePointEpsilon( itI->back().ptSt, itJ->back().ptEn, 2 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( itI->back().ptEn, itJ->back().ptSt, 2 * EPS_SMALL)) {
|
||||
itJ = vChain.erase( itJ) ;
|
||||
bErased = true ;
|
||||
}
|
||||
else
|
||||
++ itJ ;
|
||||
}
|
||||
if ( bErased) {
|
||||
itI = vChain.erase( itI) ;
|
||||
bErased = false ;
|
||||
}
|
||||
else
|
||||
++ itI ;
|
||||
}
|
||||
nChainCnt = int( vChain.size()) ;
|
||||
|
||||
// unisco eventuali catene estreme che sono parte di una stessa catena
|
||||
if ( nChainCnt > 1) {
|
||||
if ( AreSamePointApprox( vChain[0].front().ptSt, vChain[nChainCnt - 1].back().ptEn)) {
|
||||
vChain[0].insert( vChain[0].begin(), vChain[nChainCnt - 1].begin(), vChain[nChainCnt - 1].end()) ;
|
||||
vChain.pop_back() ;
|
||||
-- nChainCnt ;
|
||||
}
|
||||
else if ( AreSamePointApprox( vChain[0].back().ptEn, vChain[nChainCnt - 1].front().ptSt)) {
|
||||
vChain[0].insert(vChain[0].end(), vChain[nChainCnt - 1].begin(), vChain[nChainCnt - 1].end()) ;
|
||||
vChain.pop_back() ;
|
||||
-- nChainCnt ;
|
||||
}
|
||||
}
|
||||
|
||||
// Elimino la seconda copia di catene doppie
|
||||
for ( int nI = 0 ; nI < nChainCnt ; ++ nI) {
|
||||
for ( int nJ = nI + 1 ; nJ < nChainCnt ; ++ nJ) {
|
||||
if ( vChain[nI].size() == vChain[nJ].size()) {
|
||||
bool bSame = true ;
|
||||
for ( int nK = 0 ; nK < int( vChain[nI].size()) ; ++ nK) {
|
||||
if ( ! AreSamePointApprox( vChain[nI][nK].ptSt, vChain[nJ][nK].ptSt) ||
|
||||
! AreSamePointApprox( vChain[nI][nK].ptEn, vChain[nJ][nK].ptEn)) {
|
||||
bSame = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bSame) {
|
||||
vChain.erase( vChain.begin() + nJ) ;
|
||||
-- nChainCnt ;
|
||||
-- nJ ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fra le catene trovate separo le aperte dalle chiuse
|
||||
CHAINVECTOR cvClosedChain ;
|
||||
CHAINVECTOR cvOpenChain ;
|
||||
for ( int nL = 0 ; nL < int( vChain.size()) ; ++ nL) {
|
||||
int nCurLoopLast = max( int(vChain[nL].size()) - 1, 0) ;
|
||||
if ( AreSamePointApprox( vChain[nL][0].ptSt, vChain[nL][nCurLoopLast].ptEn) && nCurLoopLast > 0)
|
||||
cvClosedChain.emplace_back( vChain[nL]) ;
|
||||
else {
|
||||
cvOpenChain.emplace_back( vChain[nL]) ;
|
||||
}
|
||||
}
|
||||
for ( auto it = cvClosedChain.begin() ; it != cvClosedChain.end() ; ) {
|
||||
if ( int( it->size()) < 3)
|
||||
it = cvClosedChain.erase( it) ;
|
||||
else
|
||||
++ it ;
|
||||
}
|
||||
// Se più di una catena chiusa oppure catene chiuse e aperte, errore
|
||||
if ( cvClosedChain.size() > 1 || ( cvClosedChain.size() > 0 && int( cvOpenChain.size()) > 0)) {
|
||||
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Se c'è una catena chiusa
|
||||
if ( cvClosedChain.size() == 1) {
|
||||
// Ne ricavo una PolyLine
|
||||
PolyLine plInLoop ;
|
||||
for ( int nLine = 0 ; nLine < int( cvClosedChain[0].size()) ; ++ nLine) {
|
||||
plInLoop.AddUPoint( 0., cvClosedChain[0][nLine].ptSt) ;
|
||||
plInLoop.AddUPoint( 0., cvClosedChain[0][nLine].ptEn) ;
|
||||
}
|
||||
// I tre vertici sono dalla parte interna della curva (triangolo con buco)
|
||||
if ( ! bCCW) {
|
||||
// Rimuovo il triangolo corrente
|
||||
RemoveTriangle( nT) ;
|
||||
// Definisco il loop esterno (è il triangolo)
|
||||
PolyLine plExtLoop ;
|
||||
plExtLoop.AddUPoint( 0., trTria.GetP( 0)) ;
|
||||
plExtLoop.AddUPoint( 0., trTria.GetP( 1)) ;
|
||||
plExtLoop.AddUPoint( 0., trTria.GetP( 2)) ;
|
||||
plExtLoop.AddUPoint( 0., trTria.GetP( 0)) ;
|
||||
// Eseguo triangolazione
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.emplace_back( plExtLoop) ;
|
||||
vPL.emplace_back( plInLoop) ;
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( vPL, vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ;
|
||||
int nNewId[3] = { AddVertex( vPt[nNewTriaVertId[0]]),
|
||||
AddVertex( vPt[nNewTriaVertId[1]]),
|
||||
AddVertex( vPt[nNewTriaVertId[2]]) } ;
|
||||
AddTriangle( nNewId) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se nessun vertice dalla parte interna della curva (rimane solo l'area della curva)
|
||||
else {
|
||||
// Rimuovo il triangolo corrente
|
||||
RemoveTriangle( nT) ;
|
||||
// Eseguo triangolazione
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( plInLoop, vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ;
|
||||
int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]),
|
||||
AddVertex(vPt[nNewTriaVertId[1]]),
|
||||
AddVertex(vPt[nNewTriaVertId[2]]) } ;
|
||||
AddTriangle( nNewId) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop aperti, devo chiuderli
|
||||
else if ( cvOpenChain.size() > 0) {
|
||||
// Creo il loop chiuso padre di tutti, il perimetro del triangolo.
|
||||
// Questo viene diviso in sotto-loop chiusi mediante quelli aperti.
|
||||
// I loop chiusi trovati precedentemente sono interni a uno dei sotto-loop
|
||||
// chiusi di cui è formato il perimetro.
|
||||
PNTVECTOR cvFirstLoop ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 0)) ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 1)) ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 2)) ;
|
||||
|
||||
PNTMATRIX cvBoundClosedLoopVec ;
|
||||
cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ;
|
||||
BOOLVECTOR vbInOut ;
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop di partenza in sotto-loop
|
||||
while ( cvOpenChain.size() > 0) {
|
||||
int nLastOpenLoopN = int( cvOpenChain.size()) - 1 ;
|
||||
for ( int nLoop = 0 ; nLoop < int( cvBoundClosedLoopVec.size()) ; ++ nLoop) {
|
||||
// Estremi del loop aperto
|
||||
int nLastOpenLoopPoint = max( int( cvOpenChain[nLastOpenLoopN].size()) - 1, 0) ;
|
||||
Point3d ptOpenLoopStP = cvOpenChain[nLastOpenLoopN][0].ptSt ;
|
||||
Point3d ptOpenLoopEnP = cvOpenChain[nLastOpenLoopN][nLastOpenLoopPoint].ptEn ;
|
||||
PNTVECTOR Loop1, Loop2 ;
|
||||
bool bChangedStart = ChangeStart( ptOpenLoopStP, cvBoundClosedLoopVec[nLoop]) ;
|
||||
bool bSplitted = SplitAtPoint( ptOpenLoopEnP, cvBoundClosedLoopVec[nLoop], Loop1, Loop2) ;
|
||||
if ( ! ( bChangedStart && bSplitted))
|
||||
continue ;
|
||||
Chain cvCounterChain ;
|
||||
for ( int nPt = int( cvOpenChain[nLastOpenLoopN].size()) - 1 ; nPt >= 0 ; -- nPt) {
|
||||
IntSegment CurSeg ;
|
||||
CurSeg.ptSt = cvOpenChain[nLastOpenLoopN][nPt].ptEn ;
|
||||
CurSeg.ptEn = cvOpenChain[nLastOpenLoopN][nPt].ptSt ;
|
||||
cvCounterChain.emplace_back( CurSeg) ;
|
||||
}
|
||||
bool bAdded1 = AddChainToChain( cvCounterChain, Loop1) ;
|
||||
bool bAdded2 = AddChainToChain( cvOpenChain[nLastOpenLoopN], Loop2) ;
|
||||
if ( ! ( bAdded1 && bAdded2))
|
||||
continue ;
|
||||
// Aggiungo i nuovi loop nel vettore
|
||||
int nCurSize = int( cvBoundClosedLoopVec.size()) ;
|
||||
cvBoundClosedLoopVec.resize( nCurSize + 1) ;
|
||||
vbInOut.resize( nCurSize + 1) ;
|
||||
for ( int nCL = nCurSize - 1 ; nCL > nLoop ; -- nCL) {
|
||||
cvBoundClosedLoopVec[nCL + 1] = cvBoundClosedLoopVec[nCL] ;
|
||||
vbInOut[nCL + 1] = vbInOut[nCL] ;
|
||||
}
|
||||
cvBoundClosedLoopVec[nLoop] = Loop1 ;
|
||||
cvBoundClosedLoopVec[nLoop + 1] = Loop2 ;
|
||||
vbInOut[nLoop] = false ;
|
||||
vbInOut[nLoop + 1] = true ;
|
||||
++ nLoop ;
|
||||
}
|
||||
cvOpenChain.resize( nLastOpenLoopN) ;
|
||||
}
|
||||
// Rimuovo il triangolo corrente
|
||||
RemoveTriangle( nT) ;
|
||||
// Se il triangolo originale aveva il centro interno alla curva oppure devo tenere le parti
|
||||
// di superficie che hanno una parte giacente sul rettangolo della superficie di taglio,
|
||||
// aggiungo i nuovi triangoli.
|
||||
if ( ! bTriaOn || bSaveOnEq) {
|
||||
// Trasformo i loop compositi in loop polyline
|
||||
POLYLINEVECTOR vplPolyVec ;
|
||||
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
|
||||
for ( int nLoop = 0 ; nLoop < int( vplPolyVec.size()) ; ++ nLoop) {
|
||||
for ( int nLine = 0 ; nLine < int( cvBoundClosedLoopVec[nLoop].size()) ; ++ nLine) {
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][nLine]) ;
|
||||
}
|
||||
vplPolyVec[nLoop].AddUPoint( 0., cvBoundClosedLoopVec[nLoop][0]) ;
|
||||
if ( vbInOut[nLoop]) {
|
||||
// Eseguo triangolazione
|
||||
Triangulate CreateTriangulation ;
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2] } ;
|
||||
int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]),
|
||||
AddVertex(vPt[nNewTriaVertId[1]]),
|
||||
AddVertex(vPt[nNewTriaVertId[2]]) } ;
|
||||
AddTriangle( nNewId) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// da eliminare
|
||||
else if ( ! bTriaCenIn) {
|
||||
RemoveTriangle( nT) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se avvenuta modifica, aggiorno tutto
|
||||
if ( bModif) {
|
||||
// aggiorno tutto
|
||||
if ( ! AdjustVertices() || ! DoCompacting()) {
|
||||
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ripristino scala originale
|
||||
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
|
||||
|
||||
// se superficie originale a facce, cerco di semplificarle in ogni caso
|
||||
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
|
||||
if ( ! SimplifyFacets())
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::GeneralizedCut")
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
+61
-37
@@ -22,15 +22,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::ResetFaceting( void)
|
||||
{
|
||||
m_bFaceted = false ;
|
||||
m_vFacet.clear() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::VerifyFaceting( void) const
|
||||
@@ -44,14 +35,36 @@ SurfTriMesh::VerifyFaceting( void) const
|
||||
bool
|
||||
SurfTriMesh::UpdateFaceting( void)
|
||||
{
|
||||
// salvo vecchio vettore facce
|
||||
INTVECTOR vOldFacet = m_vFacet ;
|
||||
|
||||
// reset faceting
|
||||
m_bFaceted = false ;
|
||||
m_vFacet.clear() ;
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i)
|
||||
m_vTria[i].nIdFacet = SVT_NULL ;
|
||||
|
||||
// ricostruisco le sfaccettature
|
||||
bool bOk = true ;
|
||||
// indice faccia corrente
|
||||
int nFacet = -1 ;
|
||||
|
||||
// ricostruisco le sfaccettature come definite in precedenza (dove possibile)
|
||||
bool bOk = true ;
|
||||
for ( int j = 0 ; j < int( vOldFacet.size()) ; ++ j) {
|
||||
int i = vOldFacet[j] ;
|
||||
// salto triangoli inesistenti o già assegnati
|
||||
if ( i >= int( m_vTria.size()) ||
|
||||
m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
m_vTria[i].nIdFacet != SVT_NULL)
|
||||
continue ;
|
||||
// assegno indice di faccia al triangolo
|
||||
m_vTria[i].nIdFacet = ++ nFacet ;
|
||||
m_vFacet.push_back( i) ;
|
||||
// aggiorno faccia
|
||||
if ( ! UpdateOneFace( nFacet, i))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
// ricostruisco le altre sfaccettature
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||
// salto triangoli cancellati o già assegnati
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
@@ -60,32 +73,9 @@ SurfTriMesh::UpdateFaceting( void)
|
||||
// assegno indice di faccia al triangolo
|
||||
m_vTria[i].nIdFacet = ++ nFacet ;
|
||||
m_vFacet.push_back( i) ;
|
||||
// piano del triangolo
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( m_vVert[m_vTria[i].nIdVert[0]].ptP, m_vTria[i].vtN)) {
|
||||
LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data")
|
||||
return false ;
|
||||
}
|
||||
// set di triangoli da aggiornare
|
||||
set<int> stTria ;
|
||||
stTria.insert( i) ;
|
||||
// finchè set non vuoto
|
||||
while ( ! stTria.empty()) {
|
||||
// tolgo un triangolo dal set
|
||||
const auto iIt = stTria.begin() ;
|
||||
int nT = *iIt ;
|
||||
stTria.erase( iIt) ;
|
||||
// aggiorno i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nIdFacet == SVT_NULL) {
|
||||
if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT))
|
||||
bOk = false ;
|
||||
if ( m_vTria[nAdjT].nIdFacet == nFacet)
|
||||
stTria.insert( nAdjT) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// aggiorno faccia
|
||||
if ( ! UpdateOneFace( nFacet, i))
|
||||
bOk = false ;
|
||||
}
|
||||
|
||||
// se ci sono stati problemi, salvo nel log
|
||||
@@ -97,6 +87,40 @@ SurfTriMesh::UpdateFaceting( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::UpdateOneFace( int nFacet, int nT)
|
||||
{
|
||||
// piano del triangolo
|
||||
Plane3d plPlane ;
|
||||
if ( ! plPlane.Set( m_vVert[m_vTria[nT].nIdVert[0]].ptP, m_vTria[nT].vtN)) {
|
||||
LOG_ERROR( GetEGkLogger(), "SurfTM : UpdateFaceting error in triangle data")
|
||||
return false ;
|
||||
}
|
||||
// set di triangoli da aggiornare
|
||||
set<int> stTria ;
|
||||
stTria.insert( nT) ;
|
||||
// finchè set non vuoto
|
||||
bool bOk = true ;
|
||||
while ( ! stTria.empty()) {
|
||||
// tolgo un triangolo dal set
|
||||
const auto iIt = stTria.begin() ;
|
||||
int nT = *iIt ;
|
||||
stTria.erase( iIt) ;
|
||||
// aggiorno i triangoli adiacenti
|
||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[j] ;
|
||||
if ( nAdjT != SVT_NULL && m_vTria[nAdjT].nIdFacet == SVT_NULL) {
|
||||
if ( ! UpdateTriaFaceting( nT, nFacet, plPlane, nAdjT))
|
||||
bOk = false ;
|
||||
if ( m_vTria[nAdjT].nIdFacet == nFacet)
|
||||
stTria.insert( nAdjT) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, int nT)
|
||||
|
||||
@@ -0,0 +1,604 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2021-2021
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMeshUtilities.cpp Data : 01.11.21 Versione : 2.3k1
|
||||
// Contenuto : Implementazione funzioni di utilità di Superfici TriMesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 25.10.21 LM Creazione modulo.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "Triangulate.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "DistPointLine.h"
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunctions(void)
|
||||
{
|
||||
// Vettore di indici dei vertici sui lati del triangolo corrente
|
||||
unordered_map< int, INTVECTOR> TriaMap ;
|
||||
|
||||
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Vettore degli altri vertici sul contorno del triangolo
|
||||
INTVECTOR vVertOtl ;
|
||||
// Box del triangolo
|
||||
BBox3d b3Tria ;
|
||||
trTria.GetLocalBBox( b3Tria) ;
|
||||
INTVECTOR vNearTria ;
|
||||
GetAllTriaOverlapBox( b3Tria, vNearTria) ;
|
||||
// Ciclo sui lati del triangolo
|
||||
for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) {
|
||||
// aggiungo al vettore il vertice iniziale del lato
|
||||
vVertOtl.emplace_back( m_vTria[nT].nIdVert[nSeg]) ;
|
||||
// Se in questo lato il triangolo è adiacente a un altro, lo salto.
|
||||
if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL && m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL)
|
||||
continue ;
|
||||
int nPrevSize = int( vVertOtl.size()) ;
|
||||
// recupero la geometria del lato
|
||||
Point3d ptSegSt = trTria.GetP( nSeg) ;
|
||||
Point3d ptSegEn = trTria.GetP( ( nSeg + 1) % 3) ;
|
||||
Vector3d vtSeg = ptSegEn - ptSegSt ;
|
||||
double dSegLen = vtSeg.Len() ;
|
||||
if ( dSegLen < EPS_SMALL)
|
||||
continue ;
|
||||
vtSeg /= dSegLen ;
|
||||
// Ciclo sui triangoli vicini
|
||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||
// Salto il triangolo se è quello di riferimento
|
||||
if ( vNearTria[nI] == nT)
|
||||
continue ;
|
||||
// Cerco i vertici che stanno sul lato del triangolo
|
||||
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
||||
Point3d ptVert ;
|
||||
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
||||
continue ;
|
||||
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
||||
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
||||
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H)
|
||||
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||
}
|
||||
}
|
||||
// Riordino i vertici sul segmento
|
||||
auto SortVerteces = [ this, &ptSegSt, &vtSeg]( const int nV1, const int nV2)
|
||||
{ Point3d ptV1, ptV2 ;
|
||||
GetVertex( nV1, ptV1) ;
|
||||
GetVertex( nV2, ptV2) ;
|
||||
return ( ( ptV1 - ptSegSt) * vtSeg < ( ptV2 - ptSegSt) * vtSeg) ;
|
||||
} ;
|
||||
sort( vVertOtl.begin() + nPrevSize, vVertOtl.end(), SortVerteces) ;
|
||||
}
|
||||
// Se ci sono più di 3 vertici
|
||||
if ( vVertOtl.size() > 3) {
|
||||
// Elimino i vertici ripetuti
|
||||
vVertOtl.erase( unique( vVertOtl.begin(), vVertOtl.end()), vVertOtl.end()) ;
|
||||
// Se ci sono ancora più di 3 vertici, inserisco nel Map
|
||||
if ( vVertOtl.size() > 3)
|
||||
TriaMap.emplace( nT, vVertOtl) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sui triangoli da sistemare
|
||||
for ( auto itT = TriaMap.begin() ; itT != TriaMap.end() ; ++ itT) {
|
||||
// Indice del triangolo
|
||||
int nT = itT->first ;
|
||||
// Vettore degli altri vertici sul perimetro
|
||||
const INTVECTOR& vVertOtl = itT->second ;
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Salvo eventuale indice di faccetta
|
||||
int nFacet = m_vTria[nT].nIdFacet ;
|
||||
if ( nFacet > int( m_vFacet.size()) || m_vFacet[nFacet] != nT)
|
||||
nFacet = SVT_NULL ;
|
||||
// Rimuovo il triangolo
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
// Aggiungo i nuovi triangoli
|
||||
int nLastNewTria = SVT_NULL ;
|
||||
// Se ci sono 4 vertici, inserisco due triangoli
|
||||
if ( vVertOtl.size() == 4) {
|
||||
// se 1-2-3 è triangolo (e quindi 0-1-3)
|
||||
int nNew1Id[3] = { vVertOtl[1], vVertOtl[2], vVertOtl[3]} ;
|
||||
int nNew1Tria = AddTriangle( nNew1Id, nTFlag) ;
|
||||
if ( nNew1Tria != SVT_NULL && nNew1Tria != SVT_DEL) {
|
||||
nLastNewTria = nNew1Tria ;
|
||||
int nNew2Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[3]} ;
|
||||
int nNew2Tria = AddTriangle( nNew2Id, nTFlag) ;
|
||||
if ( nNew2Tria != SVT_NULL && nNew2Tria != SVT_DEL)
|
||||
nLastNewTria = nNew2Tria ;
|
||||
}
|
||||
// altrimenti 0-1-2 e 2-3-0
|
||||
else {
|
||||
int nNew3Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[2]} ;
|
||||
int nNew3Tria = AddTriangle( nNew3Id, nTFlag) ;
|
||||
if ( nNew3Tria != SVT_NULL && nNew3Tria != SVT_DEL)
|
||||
nLastNewTria = nNew3Tria ;
|
||||
int nNew4Id[3] = { vVertOtl[2], vVertOtl[3], vVertOtl[0]} ;
|
||||
int nNew4Tria = AddTriangle( nNew4Id, nTFlag) ;
|
||||
if ( nNew4Tria != SVT_NULL && nNew4Tria != SVT_DEL)
|
||||
nLastNewTria = nNew4Tria ;
|
||||
}
|
||||
}
|
||||
// altrimenti inserisco un ventaglio di triangoli dal centro ai vertici
|
||||
else {
|
||||
Point3d ptTriaCen = trTria.GetCentroid() ;
|
||||
int nCenIndex = AddVertex( ptTriaCen) ;
|
||||
int nVertNum = int( vVertOtl.size()) ;
|
||||
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
|
||||
int nEnV = ( nStV + 1) % nVertNum ;
|
||||
int nNewId[3] = { nCenIndex, vVertOtl[nStV], vVertOtl[nEnV]} ;
|
||||
int nNewTria = AddTriangle( nNewId, nTFlag) ;
|
||||
if ( nNewTria != SVT_NULL && nNewTria != SVT_DEL)
|
||||
nLastNewTria = nNewTria ;
|
||||
}
|
||||
}
|
||||
// Eventuale aggiustamento per indice di faccetta
|
||||
if ( nFacet != SVT_NULL && nLastNewTria != SVT_NULL)
|
||||
m_vFacet[nFacet] = nLastNewTria ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
IsVertex( PNTULIST& PointList, PNTULIST::const_iterator itCurr)
|
||||
{
|
||||
// recupero il punto precedente
|
||||
PNTULIST::const_iterator itPrev ;
|
||||
if ( itCurr == PointList.begin())
|
||||
itPrev = prev( PointList.end(), 2) ;
|
||||
else
|
||||
itPrev = prev( itCurr) ;
|
||||
// recupero il punto successivo
|
||||
auto itNext = next( itCurr) ;
|
||||
if ( itNext == PointList.end())
|
||||
itNext = next( PointList.begin()) ;
|
||||
// se cambia faccia adiacente tra prima e dopo, va bene
|
||||
if ( itPrev->second != itCurr->second)
|
||||
return true ;
|
||||
// se lati aperti e cambia direzione tra prima e dopo, va bene
|
||||
if ( itPrev->second == -1) {
|
||||
DistPointLine PointLineDistCalc( itCurr->first, itPrev->first, itNext->first) ;
|
||||
double dDist ;
|
||||
if ( PointLineDistCalc.GetDist( dDist) && dDist > EPS_SMALL)
|
||||
return true ;
|
||||
}
|
||||
// altrimenti non va bene
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ChooseGoodStartPoint( PNTULIST& PointList)
|
||||
{
|
||||
// se il punto iniziale è un vertice, non devo fare alcunché
|
||||
if ( IsVertex( PointList, PointList.begin()))
|
||||
return true ;
|
||||
// altrimenti cerco il vertice più vicino
|
||||
for ( auto it = next( PointList.begin()) ; it != PointList.end() ; ++it) {
|
||||
if ( IsVertex( PointList, it)) {
|
||||
// se ultimo punto non devo fare alcunché
|
||||
if ( next( it) == PointList.end())
|
||||
return false ;
|
||||
// cancello ultimo punto ( coincide con primo)
|
||||
PointList.pop_back() ;
|
||||
// sposto la parte iniziale dei punti alla fine
|
||||
PointList.splice( PointList.end(), PointList, PointList.begin(), it) ;
|
||||
// aggiungo punto finale come copia dell'iniziale
|
||||
PointList.push_back( PointList.front()) ;
|
||||
// ho finito
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
||||
{
|
||||
// Ciclo sui punti del loop
|
||||
auto itLast = PointList.begin() ;
|
||||
for ( auto it = next( itLast) ; it != PointList.end() ; ++ it) {
|
||||
|
||||
// Se dal punto corrente inizia un segmento adiacente a un'altra faccia
|
||||
if ( itLast->second != it->second) {
|
||||
// Elimino i punti interni
|
||||
auto itNextToLast = next( itLast) ;
|
||||
for ( auto itInn = itNextToLast ; itInn != it ; ) {
|
||||
itInn = PointList.erase( itInn) ;
|
||||
bModif = true ;
|
||||
}
|
||||
// Se la lunghezza del segmento supera il limite imposto
|
||||
double dSegLen = Dist( it->first, itLast->first) ;
|
||||
if ( dSegLen > dMaxEdgeLen) {
|
||||
// determino il numero di step
|
||||
double dRatio = dSegLen / dMaxEdgeLen ;
|
||||
int nStepCount = int( dRatio) + 1 ;
|
||||
// inserisco i punti
|
||||
auto itAdd = it ;
|
||||
for ( int nP = 1 ; nP < nStepCount ; ++ nP) {
|
||||
double dCoeff = double( nP) / nStepCount ;
|
||||
itAdd = PointList.insert( itAdd, POINTU( Media( itLast->first, it->first, 1 - dCoeff), itLast->second)) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
// Nuovo punto di riferimento
|
||||
itLast = it ;
|
||||
}
|
||||
|
||||
// Se sono due segmenti liberi non allineati
|
||||
else if ( itLast->second == - 1) {
|
||||
// Calcolo se i punti compresi fra gli estremi sono allineati
|
||||
bool bAreAligned = true ;
|
||||
auto itNextToLast = next( itLast) ;
|
||||
for ( auto itInn = itNextToLast ; itInn != it && bAreAligned ; ++ itInn) {
|
||||
DistPointLine PointLineDistCalc( itInn->first, itLast->first, it->first) ;
|
||||
double dDist ;
|
||||
if ( PointLineDistCalc.GetDist( dDist))
|
||||
bAreAligned = ( dDist < EPS_SMALL) ;
|
||||
}
|
||||
// Se i punti sono allineati
|
||||
if ( bAreAligned) {
|
||||
// Verifico se il successivo punto non è più allineato
|
||||
auto itNextToCurr = next( it) ;
|
||||
if ( itNextToCurr != PointList.end()) {
|
||||
for ( auto itInn = itNextToLast ; itInn != itNextToCurr && bAreAligned ; ++ itInn) {
|
||||
DistPointLine PointLineDistCalc( itInn->first, itLast->first, itNextToCurr->first) ;
|
||||
double dDist ;
|
||||
if ( PointLineDistCalc.GetDist( dDist))
|
||||
bAreAligned = ( dDist < EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
// Se ho trovato un insieme massimale di punti allineati li processo
|
||||
if ( ! bAreAligned || itNextToCurr == PointList.end()) {
|
||||
// Elimino i punti interni
|
||||
for ( auto itInn = itNextToLast ; itInn != it ; ) {
|
||||
itInn = PointList.erase( itInn) ;
|
||||
bModif = true ;
|
||||
}
|
||||
// Se la lunghezza del segmento supera il limite imposto
|
||||
double dSegLen = Dist( it->first, itLast->first) ;
|
||||
if ( dSegLen > dMaxEdgeLen) {
|
||||
// determino il numero di step
|
||||
double dRatio = dSegLen / dMaxEdgeLen ;
|
||||
int nStepCount = int( dRatio) + 1 ;
|
||||
// inserisco i punti
|
||||
auto itAdd = it ;
|
||||
for ( int nP = 1 ; nP < nStepCount ; ++ nP) {
|
||||
double dCoeff = double( nP) / nStepCount ;
|
||||
itAdd = PointList.insert( itAdd, POINTU( Media( itLast->first, it->first, 1 - dCoeff), itLast->second)) ;
|
||||
bModif = true ;
|
||||
}
|
||||
}
|
||||
// Nuovo punto di riferimento
|
||||
itLast = it ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
{
|
||||
// La trimesh deve essere valida
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
// Se la lunghezza massima del lato del triangolo sul bordo della faccia è nulla e non forzata, non devo fare alcunché
|
||||
if ( dMaxEdgeLen < EPS_SMALL && ! bForced)
|
||||
return true ;
|
||||
|
||||
// Recupero il numero delle facce (esegue anche una verifica delle stesse)
|
||||
int nFacetCnt = GetFacetCount() ;
|
||||
|
||||
// Ciclo sulle facce della mesh per trovare quelle da ritriangolare
|
||||
unordered_map< int, pair< PNTVECTOR, INTVECTOR>> FacetMap ;
|
||||
for ( int nF = 0 ; nF < nFacetCnt ; ++ nF) {
|
||||
|
||||
// Recupero i loop della faccia (il parametro indica la faccia adiacente)
|
||||
POLYLINEVECTOR LoopVec ;
|
||||
GetFacetLoops( nF, LoopVec) ;
|
||||
|
||||
// Ciclo sui loop della faccia
|
||||
bool bToRetriangulate = bForced ;
|
||||
for ( int nL = 0 ; nL < int( LoopVec.size()) ; ++ nL) {
|
||||
|
||||
// Lista dei punti del loop
|
||||
PNTULIST& PointList = LoopVec[nL].GetUPointList() ;
|
||||
|
||||
// Mi assicuro che il punto iniziale/finale non sia all'interno di un possibile segmento
|
||||
if ( ! ChooseGoodStartPoint( PointList))
|
||||
continue ;
|
||||
|
||||
// Sistemo il loop
|
||||
bool bModif = false ;
|
||||
if ( ! AdjustLoop( PointList, dMaxEdgeLen, bModif))
|
||||
return false ;
|
||||
if ( bModif)
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
|
||||
// Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni (*** disabilitato ***)
|
||||
if ( false && ! bToRetriangulate) {
|
||||
// numero dei triangoli nella faccia
|
||||
INTVECTOR vFacetTria ;
|
||||
GetAllTriaInFacet( nF, vFacetTria) ;
|
||||
int nTriaCnt = int( vFacetTria.size()) ;
|
||||
// numero dei lati di contorno della faccia
|
||||
int nSideCnt = 0 ;
|
||||
for ( int nL = 0 ; nL < int( LoopVec.size()) ; ++ nL)
|
||||
nSideCnt += LoopVec[nL].GetLineNbr() ;
|
||||
// numero dei buchi della faccia
|
||||
int nHoleCnt = int( LoopVec.size()) - 1 ;
|
||||
// dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt - 1))
|
||||
if ( nTriaCnt != nSideCnt + 2 * ( nHoleCnt - 1))
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
|
||||
// Se da ritriangolare
|
||||
if ( bToRetriangulate) {
|
||||
// Eseguo la ritriangolazione della faccia
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( LoopVec, vPt, vTr)) {
|
||||
FacetMap.emplace( nF, make_pair( vPt, vTr)) ;
|
||||
}
|
||||
// Se non riesco a triangolare anche solo questa faccia, interrompo tutto
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sulle facce da ritriangolare per eliminare i triangoli (nel contempo salvo flag colore)
|
||||
INTVECTOR vDelTria ;
|
||||
unordered_map< int, int> ColorMap ;
|
||||
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||
// Recupero i triangoli della faccia
|
||||
INTVECTOR vFacetTria ;
|
||||
GetAllTriaInFacet( itF->first, vFacetTria) ;
|
||||
vDelTria.insert( vDelTria.end(), vFacetTria.begin(), vFacetTria.end()) ;
|
||||
// Salvo il colore della faccia da flag di un suo triangolo
|
||||
ColorMap.emplace( itF->first, m_vTria[m_vFacet[itF->first]].nTFlag) ;
|
||||
}
|
||||
// Cancello i triangoli
|
||||
for ( int nT : vDelTria)
|
||||
RemoveTriangle( nT) ;
|
||||
|
||||
// Applico le nuove triangolazioni delle facce
|
||||
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||
const PNTVECTOR& vPt = itF->second.first ;
|
||||
const INTVECTOR& vTr = itF->second.second ;
|
||||
// Inserisco i nuovi triangoli
|
||||
bool bFirstTria = true ;
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
||||
AddVertex( vPt[vTr[n + 1]]),
|
||||
AddVertex( vPt[vTr[n + 2]])} ;
|
||||
auto itCol = ColorMap.find( itF->first) ;
|
||||
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
||||
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
||||
if ( nNewTriaId != SVT_NULL && nNewTriaId != SVT_DEL) {
|
||||
m_vTria[nNewTriaId].nIdFacet = itF->first ;
|
||||
if ( bFirstTria) {
|
||||
m_vFacet[itF->first] = nNewTriaId ;
|
||||
bFirstTria = false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetHashGrids3d() ;
|
||||
|
||||
// Eseguo aggiustamenti
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain)
|
||||
{
|
||||
// Se la catena da aggiungere è vuota, non devo fare alcunchè
|
||||
if ( ChainToAdd.size() == 0)
|
||||
return true ;
|
||||
// Se la catena originale è vuota, non è possibile aggiungere nulla
|
||||
if ( OrigChain.size() == 0)
|
||||
return false ;
|
||||
// Se la catena originale è chiusa non posso aggiungere nulla
|
||||
int nLastOrig = max( int( OrigChain.size()) - 1, 0) ;
|
||||
if ( AreSamePointApprox( OrigChain[0], OrigChain[nLastOrig]))
|
||||
return false ;
|
||||
int nLastToAdd = max( int( ChainToAdd.size()) - 1, 0) ;
|
||||
if ( AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[0].ptSt)) {
|
||||
for ( int nPt = 1 ; nPt <= nLastToAdd ; ++ nPt) {
|
||||
if ( nPt == nLastToAdd) {
|
||||
if ( ! AreSamePointApprox(OrigChain[0], ChainToAdd[nPt].ptSt))
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
else if ( nPt == 1) {
|
||||
if ( ! AreSamePointApprox( OrigChain[nLastOrig], ChainToAdd[nPt].ptSt))
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
else
|
||||
OrigChain.emplace_back( ChainToAdd[nPt].ptSt) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Una faccia di una trimesh ha una sola componente connessa, con un loop esterno e possibili loop interni
|
||||
bool
|
||||
SurfTriMesh::DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist)
|
||||
{
|
||||
// Verifico la presenza del loop esterno
|
||||
if ( vPolyVec.size() < 1)
|
||||
return false ;
|
||||
// Proietto il punto sul piano della faccia, utilizzando il loop esterno
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPolyVec[0].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
double dDistPtPl = DistPointPlane( ptP, plPlane) ;
|
||||
Point3d ptProjP = ptP + dDistPtPl * plPlane.GetVersN() ;
|
||||
// Verifico se il punto proiettato è esterno al loop esterno
|
||||
int nPtOut = -1 ;
|
||||
if ( ! IsPointInsidePolyLine( ptProjP, vPolyVec[0], EPS_SMALL))
|
||||
nPtOut = 0 ;
|
||||
// Verifico se il punto proiettato è interno ai loop interni (quindi esterno alla faccia)
|
||||
for ( int nLoop = 1 ; nLoop < int( vPolyVec.size()) && nPtOut < 0 ; ++ nLoop) {
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPolyVec[nLoop].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
if ( IsPointInsidePolyLine( ptProjP, vPolyVec[nLoop], EPS_SMALL))
|
||||
nPtOut = nLoop ;
|
||||
}
|
||||
// Se il punto si proietta sulla faccia, la distanza dalla faccia coincide con quella dal piano
|
||||
if ( nPtOut < 0) {
|
||||
dPointFacetDist = abs( dDistPtPl) ;
|
||||
return true ;
|
||||
}
|
||||
// Altrimenti calcolo la minima distanza del punto dalla polilinea del contorno a cui è esterno
|
||||
double dDist ;
|
||||
if ( DistPointPolyLine( ptP, vPolyVec[nPtOut], dDist)) {
|
||||
dPointFacetDist = dDist ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop)
|
||||
{
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
int nMinSeg = - 1 ;
|
||||
double dMinSqDinst = DBL_MAX ;
|
||||
for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) {
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int( Loop.size())] ;
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
if ( dSqDist < dMinSqDinst) {
|
||||
dMinSqDinst = dSqDist ;
|
||||
nMinSeg = nPt ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sul loop, errore
|
||||
if ( dMinSqDinst > SQ_EPS_SMALL)
|
||||
return false ;
|
||||
// Verifico che il punto stia su un vertice, in tal caso non devo fare nulla
|
||||
bool bOnStart = AreSamePointApprox( Loop[nMinSeg], ptNewStart) ;
|
||||
bool bOnEnd = AreSamePointApprox( Loop[( nMinSeg + 1) % int( Loop.size())], ptNewStart) ;
|
||||
if ( bOnStart || bOnEnd) {
|
||||
if ( bOnEnd) {
|
||||
++ nMinSeg ;
|
||||
if ( nMinSeg % int( Loop.size()) == 0)
|
||||
return true ;
|
||||
}
|
||||
PNTVECTOR vTempVec ;
|
||||
for ( int nPt = 0 ; nPt < nMinSeg ; ++ nPt)
|
||||
vTempVec.emplace_back( Loop[nPt]) ;
|
||||
int nSize = int( Loop.size()) ;
|
||||
for ( int nPt = 0 ; nPt < nSize - nMinSeg ; ++ nPt) {
|
||||
Loop[nPt] = Loop[nPt + nMinSeg] ;
|
||||
}
|
||||
for ( int nPt = 0 ; nPt < int( vTempVec.size()) ; ++ nPt) {
|
||||
Loop[nPt + nSize - nMinSeg] = vTempVec[nPt] ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// Ridimensiono il loop
|
||||
Loop.resize( Loop.size() + 1) ;
|
||||
// Copio i primi punti
|
||||
PNTVECTOR LoopTemp ;
|
||||
for ( int nPt = 0 ; nPt <= nMinSeg ; ++ nPt)
|
||||
LoopTemp.emplace_back( Loop[nPt]) ;
|
||||
// Aggiungo il nuovo punto all'inizio
|
||||
Loop[0] = ptNewStart ;
|
||||
// Sposto gli ultimi in testa
|
||||
int nLastPointNum = int( Loop.size()) - 1 - nMinSeg ;
|
||||
for ( int nPt = 1 ; nPt <= nLastPointNum ; ++ nPt) {
|
||||
Loop[nPt] = Loop[nPt + nMinSeg] ;
|
||||
}
|
||||
// Porto i primi in fondo
|
||||
for ( int nPt = 0 ; nPt < int( LoopTemp.size()) ; ++ nPt) {
|
||||
Loop[nPt + nLastPointNum] = LoopTemp[nPt] ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2)
|
||||
{
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
int nMinSeg = -1 ;
|
||||
double dMinSqDinst = DBL_MAX ;
|
||||
for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) {
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int(Loop.size())] ;
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptStop, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
if ( dSqDist < dMinSqDinst) {
|
||||
dMinSqDinst = dSqDist ;
|
||||
nMinSeg = nPt ;
|
||||
}
|
||||
}
|
||||
// Se il punto non sta sul loop, errore
|
||||
if ( dMinSqDinst > SQ_EPS_SMALL)
|
||||
return false ;
|
||||
// Verifico che il punto stia su un vertice, in tal caso non devo aggiungerlo
|
||||
bool bFirst = AreSamePointApprox( Loop[nMinSeg], ptStop) ;
|
||||
bool bLast = AreSamePointApprox( Loop[( nMinSeg + 1) % int( Loop.size())], ptStop) ;
|
||||
// Se il punto è sul vertice finale del segmento, aggiungo il vertice alla lista da inglobare al primo loop
|
||||
if ( bLast)
|
||||
++ nMinSeg ;
|
||||
// Inglobo fino a nSeg nel primo loop
|
||||
for ( int nPt = 0 ; nPt <= nMinSeg && nPt < int( Loop.size()) ; ++ nPt)
|
||||
Loop1.emplace_back( Loop[nPt]) ;
|
||||
// Se il punto è interno al segmento, lo inglobo in entrambi i loop
|
||||
if ( ! ( bFirst || bLast)) {
|
||||
Loop1.emplace_back( ptStop) ;
|
||||
Loop2.emplace_back( ptStop) ;
|
||||
}
|
||||
else {
|
||||
if ( nMinSeg != int( Loop.size()) )
|
||||
Loop2.emplace_back( Loop[nMinSeg]) ;
|
||||
}
|
||||
// Inglobo gli ultimi vertici in Loop2
|
||||
for ( int nPt = nMinSeg + 1 ; nPt < int( Loop.size()) ; ++ nPt)
|
||||
Loop2.emplace_back( Loop[nPt]) ;
|
||||
Loop2.emplace_back( Loop[0]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -27,9 +27,9 @@ using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Tool::Tool( bool bApproxWithLines)
|
||||
: m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG), m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), m_dTipHeight( 0),
|
||||
m_dRadius( 0), m_dRCorner( 0), m_dTipRadius( 0), m_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0),
|
||||
m_bApproxWithLines( bApproxWithLines)
|
||||
: m_bApproxWithLines( bApproxWithLines), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG),
|
||||
m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), m_dTipHeight( 0), m_dRadius( 0), m_dRCorner( 0),
|
||||
m_dTipRadius( 0), m_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -100,9 +100,13 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR,
|
||||
Point3d pt3( m_dRadius, - m_dHeight, 0) ;
|
||||
Point3d pt4( 0, - m_dHeight, 0) ;
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1);
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt4) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
// utensile naso di toro
|
||||
else if ( dCornR < dR - EPS_SMALL) {
|
||||
@@ -120,10 +124,15 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR,
|
||||
Point3d pt3( m_dTipRadius, - m_dHeight, 0) ;
|
||||
Point3d pt4( 0, - m_dHeight, 0) ;
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1);
|
||||
m_Outline.AddLine( pt2);
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddLine( pt4) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
// se da approosimare
|
||||
if ( m_bApproxWithLines)
|
||||
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
|
||||
@@ -143,9 +152,13 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR,
|
||||
Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ;
|
||||
Point3d pt4( 0, - m_dHeight, 0) ;
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1);
|
||||
m_Outline.AddLine( pt2);
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt4) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
// impossibile
|
||||
else
|
||||
@@ -201,9 +214,14 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
// profilo
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( Point3d( m_dTipRadius, - m_dHeight, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
// eventuali sistemazioni per altezza tagliente
|
||||
if ( ModifyForCutterHeight())
|
||||
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
|
||||
@@ -213,7 +231,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
|
||||
// Altrimenti utensile generico
|
||||
|
||||
// se Tip a punta ( TipRadius è raggio teorico della parte finale dell'utensile senza raccordo)
|
||||
// se Tip a punta ( TipRadius � raggio teorico della parte finale dell'utensile senza raccordo)
|
||||
if ( m_dTipRadius < m_dRadius) {
|
||||
// se punta a sfera
|
||||
if ( m_dTipRadius < EPS_SMALL) {
|
||||
@@ -242,10 +260,16 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
// creazione curva composita
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddCurve( cvArc) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
// altrimenti punta a naso di toro
|
||||
else {
|
||||
@@ -271,16 +295,22 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
// creazione curva composita
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddCurve( Release( pArc)) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
}
|
||||
|
||||
// altrimenti Tip a coda di rondine ( TipRadius è raggio misurabile della parte finale dell'utensile)
|
||||
// altrimenti Tip a coda di rondine ( TipRadius � raggio misurabile della parte finale dell'utensile)
|
||||
else {
|
||||
// il raggio della punta non può essere inferiore al raggio corner
|
||||
// il raggio della punta non pu� essere inferiore al raggio corner
|
||||
if ( m_dTipRadius < m_dRCorner)
|
||||
return false ;
|
||||
// Assegno il raggio di riferimento
|
||||
@@ -305,10 +335,16 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
// creazione curva composita
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddCurve( cvArc) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
|
||||
// eventuali sistemazioni per altezza tagliente
|
||||
@@ -321,7 +357,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR,
|
||||
bool
|
||||
Tool::ModifyForCutterHeight( void)
|
||||
{
|
||||
// Se altezza tagliente non definita o superiore alla altezza utensile non devo fare alcunché
|
||||
// Se altezza tagliente non definita o superiore alla altezza utensile non devo fare alcunch�
|
||||
if ( m_dCutterHeight < EPS_SMALL || m_dCutterHeight > m_dHeight - EPS_SMALL)
|
||||
return false ;
|
||||
// quota di taglio
|
||||
@@ -340,6 +376,8 @@ Tool::ModifyForCutterHeight( void)
|
||||
m_Outline.TrimStartAtParam( dU) ;
|
||||
m_Outline.AddLine( Point3d( 0, dYtrim, 0), false) ;
|
||||
m_Outline.AddLine( ORIG, false) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
@@ -375,22 +413,36 @@ Tool::SetSawTool( const string& sToolName, double dH, double dR,
|
||||
// creazione profilo
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddLine( pt4) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
// altrimenti con raggio corner
|
||||
else {
|
||||
// creazione profilo
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt1) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt2) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( pt3 - X_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.AddLine( pt4 + Y_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt4 - X_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 5, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
}
|
||||
// altrimenti senza gambo
|
||||
@@ -405,18 +457,28 @@ Tool::SetSawTool( const string& sToolName, double dH, double dR,
|
||||
// creazione profilo
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt3) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt4) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
// altrimenti con raggio corner
|
||||
else {
|
||||
// creazione profilo
|
||||
m_Outline.AddPoint( pt0) ;
|
||||
m_Outline.AddLine( pt3 - X_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt4 + Y_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddArcTg( pt4 - X_AX * dCornR) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.AddLine( pt5) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
}
|
||||
}
|
||||
// Assegno il raggio di riferimento
|
||||
@@ -436,17 +498,30 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline,
|
||||
if ( pToolOutline != &m_Outline)
|
||||
m_Outline.Clear() ;
|
||||
m_ArcLineApprox.Clear() ;
|
||||
|
||||
|
||||
// Copio il profilo e garantisco sia di soli archi e rette (converto eventuali curve di Bezier)
|
||||
if ( ! m_Outline.CopyFrom( pToolOutline) ||
|
||||
! m_Outline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg))
|
||||
return false ;
|
||||
|
||||
// Ciclo sulle curve componenti
|
||||
// Valuto se tutte le curve tagliano
|
||||
m_ArcLineApprox.SetTempProp( 1, 1) ;
|
||||
const ICurve* pCurve = m_Outline.GetFirstCurve() ;
|
||||
while ( pCurve != nullptr && m_ArcLineApprox.GetTempProp( 1) == 1) {
|
||||
int nCutTempProp = pCurve->GetTempProp( 1) ;
|
||||
if ( nCutTempProp == 0) {
|
||||
m_ArcLineApprox.SetTempProp( 0, 1) ;
|
||||
}
|
||||
pCurve = m_Outline.GetNextCurve() ;
|
||||
}
|
||||
|
||||
// Ciclo sulle curve componenti
|
||||
pCurve = m_Outline.GetFirstCurve() ;
|
||||
while ( pCurve != nullptr) {
|
||||
|
||||
// Se la curva è un arco ed è richiesto la verifica per l'approssimazione,
|
||||
int nCutTempProp = pCurve->GetTempProp( 1) ;
|
||||
|
||||
// Se la curva � un arco ed � richiesto la verifica per l'approssimazione,
|
||||
// verifico se approssimarlo
|
||||
if ( m_bApproxWithLines && pCurve->GetType() == CRV_ARC) {
|
||||
|
||||
@@ -454,11 +529,11 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline,
|
||||
Point3d ptO = GetBasicCurveArc( pCurve)->GetCenter() ;
|
||||
double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ;
|
||||
|
||||
// Se il centro è fuori dall'asse devo approssimare
|
||||
// Se il centro � fuori dall'asse devo approssimare
|
||||
bool bCurrApprox = ( abs( ptO.x) > EPS_SMALL) ;
|
||||
|
||||
// Se una delle altre curve dista dal centro meno del raggio, devo approssimare
|
||||
for ( int nI = 0 ; ! bCurrApprox && nI < m_Outline.GetCurveCount() ; ++ nI) {
|
||||
for ( int nI = 0 ; ! bCurrApprox && nI < m_Outline.GetCurveCount() && m_ArcLineApprox.GetTempProp( 1) == 1 ; ++ nI) {
|
||||
const ICurve* pOtherCrv = m_Outline.GetCurve( nI) ;
|
||||
if ( pOtherCrv != pCurve) {
|
||||
DistPointCurve CalcDist( ptO, *pOtherCrv) ;
|
||||
@@ -493,6 +568,7 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline,
|
||||
m_vArcNormals.emplace_back( vtExtN) ;
|
||||
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
|
||||
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, int( m_vArcNormals.size()) - 1) ;
|
||||
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
|
||||
}
|
||||
}
|
||||
// altrimenti lo aggiungo semplicemente
|
||||
@@ -500,16 +576,20 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline,
|
||||
m_ArcLineApprox.AddCurve( *pCurve, true) ;
|
||||
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
|
||||
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, - 1) ;
|
||||
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
|
||||
}
|
||||
}
|
||||
// altrimenti è segmento e lo aggiungo semplicemente
|
||||
else
|
||||
// altrimenti � segmento e lo aggiungo semplicemente
|
||||
else {
|
||||
m_ArcLineApprox.AddCurve( *pCurve, true) ;
|
||||
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
|
||||
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
|
||||
}
|
||||
|
||||
pCurve = m_Outline.GetNextCurve() ;
|
||||
}
|
||||
|
||||
// Il profilo dell'utensile deve stare nel 1° e 4° quadrante del piano XY
|
||||
// Il profilo dell'utensile deve stare nel 1� e 4� quadrante del piano XY
|
||||
BBox3d Bounding ;
|
||||
m_Outline.GetLocalBBox( Bounding) ;
|
||||
if ( Bounding.GetMin().x < - 10 * EPS_SMALL)
|
||||
@@ -521,7 +601,7 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline,
|
||||
// Assegno le dimensioni dell'utensile
|
||||
m_dHeight = - Bounding.GetMin().y ;
|
||||
m_dRadius = Bounding.GetMax().x ;
|
||||
// Assegno il raggio di riferimento se non già assegnato
|
||||
// Assegno il raggio di riferimento se non gi� assegnato
|
||||
if ( m_dRefRadius < EPS_SMALL)
|
||||
m_dRefRadius = 0.25 * m_dRadius ;
|
||||
|
||||
@@ -579,3 +659,86 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh,
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum)
|
||||
{
|
||||
// Impostazioni generali
|
||||
m_sName = sToolName ;
|
||||
m_nCurrentNum = nToolNum ;
|
||||
m_nType = UNDEF ;
|
||||
m_Outline.Clear() ;
|
||||
m_ArcLineApprox.Clear() ;
|
||||
|
||||
// verifica sulle minime dimensioni globali
|
||||
if ( dH < EPS_SMALL || dR < EPS_SMALL || dRC < - EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
m_dHeight = dH ;
|
||||
m_dRadius = dR ;
|
||||
m_dRCorner = dRC ;
|
||||
m_dTipHeight = 0 ;
|
||||
m_dTipRadius = 0 ;
|
||||
m_dRefRadius = 0 ;
|
||||
m_dCutterHeight = dH ;
|
||||
|
||||
bool bToolDefined = true ;
|
||||
|
||||
double dSquareCornerRadProj = m_dRCorner * m_dRCorner - 0.25 * m_dHeight * m_dHeight ;
|
||||
// Utensile sfiancato
|
||||
if ( dSquareCornerRadProj > 0) {
|
||||
double dCenX = m_dRadius - m_dRCorner ;
|
||||
double dCylRad = dCenX + sqrt( dSquareCornerRadProj) ;
|
||||
// Utensile mal definito
|
||||
if ( dCylRad < EPS_SMALL)
|
||||
return false ;
|
||||
// Profilo
|
||||
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
|
||||
m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
CurveArc cvArc ;
|
||||
cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ;
|
||||
m_Outline.AddCurve( cvArc) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ;
|
||||
}
|
||||
// Utensile cilindrico con eventuale raggio corner
|
||||
else {
|
||||
// Utensile mal definito
|
||||
if ( m_dRadius - m_dRCorner < 0)
|
||||
return false ;
|
||||
// Utensile sferico
|
||||
else if ( m_dRadius - m_dRCorner < EPS_SMALL)
|
||||
;
|
||||
// Raggio corner nullo: cilindro
|
||||
else if ( m_dRCorner < EPS_SMALL) {
|
||||
;
|
||||
}
|
||||
else {
|
||||
// Profilo
|
||||
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
|
||||
m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 0, 1, 1) ;
|
||||
CurveArc cvArc ;
|
||||
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, - m_dRCorner, 0)) ;
|
||||
m_Outline.AddCurve( cvArc) ;
|
||||
m_Outline.SetCurveTempProp( 1, 1, 1) ;
|
||||
m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 2, 1, 1) ;
|
||||
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, - m_dHeight, 0)) ;
|
||||
m_Outline.AddCurve( cvArc) ;
|
||||
m_Outline.SetCurveTempProp( 3, 1, 1) ;
|
||||
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
|
||||
m_Outline.SetCurveTempProp( 4, 1, 1) ;
|
||||
m_Outline.SetTempProp( 1, 1) ;
|
||||
bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ;
|
||||
}
|
||||
}
|
||||
|
||||
m_nType = ADDITIVE ;
|
||||
return bToolDefined ;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "CurveComposite.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class Tool
|
||||
class Tool
|
||||
{
|
||||
public :
|
||||
Tool( bool bApproxWithLines = false) ;
|
||||
@@ -33,6 +33,7 @@ class Tool
|
||||
bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) ;
|
||||
bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) ;
|
||||
bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nToolNum) ;
|
||||
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) ;
|
||||
bool SetToolNum( int nToolNum)
|
||||
{ m_nCurrentNum = nToolNum ; return true ; }
|
||||
int GetType() const
|
||||
@@ -61,6 +62,8 @@ class Tool
|
||||
{ return ( m_ArcLineApprox.GetCurveCount() == 0 ? m_Outline : m_ArcLineApprox) ; }
|
||||
const VCT3DVECTOR& GetArcNormalVec( void) const
|
||||
{ return m_vArcNormals ; }
|
||||
bool GetCuttingFlag() const
|
||||
{ return ( m_nType == GEN ? m_ArcLineApprox.GetTempProp( 1) == 1 : true ) ; }
|
||||
|
||||
public :
|
||||
enum ToolType { UNDEF = 0, // Utensile indefinito
|
||||
@@ -70,7 +73,8 @@ class Tool
|
||||
BULLNOSEMILL = 4, // Naso di toro
|
||||
CONEMILL = 5, // Con parte terminale conica
|
||||
MORTISER = 6, // Mortasatrice
|
||||
CHISEL = 7} ; // Scalpello
|
||||
CHISEL = 7, // Scalpello
|
||||
ADDITIVE = 8} ; // Additivo
|
||||
|
||||
private :
|
||||
bool ModifyForCutterHeight( void) ;
|
||||
|
||||
+199
-61
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
// EgalTech 2014-2021
|
||||
//----------------------------------------------------------------------------
|
||||
// File : Triangulate.cpp Data : 23.06.14 Versione : 1.5f6
|
||||
// File : Triangulate.cpp Data : 18.12.21 Versione : 2.3l
|
||||
// Contenuto : Implementazione della classe Triangulate.
|
||||
//
|
||||
//
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "DllMain.h"
|
||||
#include "Triangulate.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "earcut.hpp"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
@@ -29,6 +30,9 @@ enum EarStatus{ EAS_NULL = -1, EAS_NO = 0, EAS_OK = 1} ;
|
||||
//----------------------------------------------------------------------------
|
||||
static bool ChangeStartPntVector( int nNewStart, PNTVECTOR& vPi) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool FORCE_EARCUT_HPP = false ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// In : PolyLine
|
||||
// Out : PNTVECTOR (Point3d Vector) : points of the polyline
|
||||
@@ -37,6 +41,9 @@ static bool ChangeStartPntVector( int nNewStart, PNTVECTOR& vPi) ;
|
||||
bool
|
||||
Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// pulisco i vettori di ritorno
|
||||
vPt.clear() ;
|
||||
vTr.clear() ;
|
||||
// verifico che la polilinea sia chiusa e piana e calcolo il piano medio del poligono
|
||||
double dArea ;
|
||||
Plane3d plPlane ;
|
||||
@@ -46,8 +53,13 @@ Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
bool bCCW ;
|
||||
if ( ! CalcProjPlane( plPlane.GetVersN(), m_nPlane, bCCW))
|
||||
return false ;
|
||||
|
||||
// forzo esecuzione triangolazione con earcut.hpp
|
||||
if ( FORCE_EARCUT_HPP) {
|
||||
return MakeByEC_HPP( PL, bCCW, vPt, vTr) ;
|
||||
}
|
||||
|
||||
// riempio il vettore con i vertici del poligono da triangolare
|
||||
vPt.clear() ;
|
||||
vPt.reserve( PL.GetPointNbr() - 1) ;
|
||||
// salto il primo punto (coincide con l'ultimo)
|
||||
Point3d ptP ;
|
||||
@@ -59,18 +71,12 @@ Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
// se non CCW inverto il vettore dei punti
|
||||
if ( ! bCCW)
|
||||
reverse( vPt.begin(), vPt.end()) ;
|
||||
// creo il vettore degli indici del Poligono
|
||||
INTVECTOR vPol ;
|
||||
int n = int( vPt.size()) ;
|
||||
vPol.reserve( n) ;
|
||||
for ( int i = 0 ; i < n ; ++ i)
|
||||
vPol.push_back( i) ;
|
||||
|
||||
// eseguo la triangolazione
|
||||
if ( ! MakeByEC2( vPt, vPol, vTr) &&
|
||||
! MakeByEC3( vPt, vPol, vTr)) {
|
||||
if ( ! MakeByEC2( vPt, vTr) &&
|
||||
! MakeByEC3( vPt, vTr)) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in MakeByEC23(1)")
|
||||
return false ;
|
||||
return MakeByEC_HPP( PL, bCCW, vPt, vTr) ;
|
||||
}
|
||||
|
||||
// se era CW, devo invertire il senso dei triangoli
|
||||
@@ -115,6 +121,12 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
! AreOppositeVectorApprox( plExtPlane.GetVersN(), plPlane.GetVersN()))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// forzo esecuzione triangolazione con earcut.hpp
|
||||
if ( FORCE_EARCUT_HPP) {
|
||||
return MakeByEC_HPP( vPL, bCCW, vPt, vTr) ;
|
||||
}
|
||||
|
||||
// se non CCW inverto tutte le polilinee
|
||||
if ( ! bCCW) {
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i)
|
||||
@@ -122,8 +134,7 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
}
|
||||
// calcolo ordine decrescente su Xmax o Ymax o Zmax secondo m_nPlane per le curve interne
|
||||
INTVECTOR vOrd ;
|
||||
if ( ! SortInternalLoops( vPL, vOrd))
|
||||
return false ;
|
||||
bool bOk = SortInternalLoops( vPL, vOrd) ;
|
||||
// riempio il vettore con i punti dei poligoni da triangolare
|
||||
// calcolo spazio totale e spazio massimo per un percorso interno
|
||||
int nTot = vPL[0].GetPointNbr() - 1 ;
|
||||
@@ -136,22 +147,27 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
// riservo spazio pari al totale dei punti (anche quelli ripetuti di chiusura che servono per i link)
|
||||
vPt.reserve( nTot) ;
|
||||
// inserisco i punti del contorno esterno (tranne il primo che coincide con l'ultimo)
|
||||
if ( ! GetPntVectorFromPolyline( vPL[0], false, vPt))
|
||||
return false ;
|
||||
bOk = bOk && GetPntVectorFromPolyline( vPL[0], false, vPt) ;
|
||||
// ciclo sui percorsi interni ordinati secondo Xmax decrescente
|
||||
PNTVECTOR vPi ;
|
||||
vPi.reserve( nMax) ;
|
||||
for ( int i = 1 ; i < int( vPL.size()) ; ++ i) {
|
||||
for ( int i = 1 ; bOk && i < int( vPL.size()) ; ++ i) {
|
||||
// riordino il percorso per avere punto iniziale con Xmax
|
||||
if ( ! GetPntVectorFromPolyline( vPL[vOrd[i]], true, vPi))
|
||||
return false ;
|
||||
if ( ! GetPntVectorFromPolyline( vPL[vOrd[i]], true, vPi)) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
// cerco un punto del percorso esterno visibile dal punto iniziale del precedente interno
|
||||
int nI ;
|
||||
if ( ! GetOuterPntToJoin( vPt, vPi[0], nI))
|
||||
return false ;
|
||||
if ( ! GetOuterPntToJoin( vPt, vPi[0], nI)) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
// riordino percorso esterno per avere questo punto all'inizio
|
||||
if ( ! ChangeStartPntVector( nI, vPt))
|
||||
return false ;
|
||||
if ( ! ChangeStartPntVector( nI, vPt)) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
// ripeto punto iniziale
|
||||
vPt.push_back( vPt[0]) ;
|
||||
// accodo percorso interno
|
||||
@@ -167,20 +183,14 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i)
|
||||
const_cast<PolyLine&>(vPL[i]).Invert( true) ;
|
||||
}
|
||||
|
||||
// creo il vettore degli indici del Poligono
|
||||
INTVECTOR vPol ;
|
||||
int n = int( vPt.size()) ;
|
||||
vPol.reserve( n) ;
|
||||
// non devo gestire separatamente CCW perchè ho già invertito i punti
|
||||
for ( int i = 0 ; i < n ; ++ i)
|
||||
vPol.push_back( i) ;
|
||||
if ( ! bOk)
|
||||
return MakeByEC_HPP( vPL, bCCW, vPt, vTr) ;
|
||||
|
||||
// eseguo la triangolazione
|
||||
if ( ! MakeByEC2( vPt, vPol, vTr) &&
|
||||
! MakeByEC3( vPt, vPol, vTr)) {
|
||||
if ( ! MakeByEC2( vPt, vTr) &&
|
||||
! MakeByEC3( vPt, vTr)) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in MakeByEC23(N)")
|
||||
return false ;
|
||||
return MakeByEC_HPP( vPL, bCCW, vPt, vTr) ;
|
||||
}
|
||||
|
||||
// se era CW, devo invertire il senso dei triangoli
|
||||
@@ -190,33 +200,113 @@ Triangulate::Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Triangulate the CCW n-gon specified by the vertices vPt (Pt[n] != Pt[0])
|
||||
// Ear Clipping algorithm from mapbox
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::PrepareGrid( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
const INTVECTOR& vPrev, const INTVECTOR& vNext)
|
||||
Triangulate::MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// points number
|
||||
int n = int( vPol.size()) ;
|
||||
// overall box
|
||||
BBox3d b3All ;
|
||||
for ( int j = 0 ; j < n ; ++ j)
|
||||
b3All.Add( vPt[vPol[j]]) ;
|
||||
// grid cell dimension
|
||||
double dCellDim ;
|
||||
b3All.GetRadius( dCellDim) ;
|
||||
dCellDim *= 2 / sqrt( n) ;
|
||||
// grid
|
||||
if ( ! m_VertGrid.Init( 2 * n, dCellDim))
|
||||
// pulisco i vettori di ritorno
|
||||
vPt.clear() ;
|
||||
vTr.clear() ;
|
||||
// riempio il vettore con i vertici del poligono da triangolare
|
||||
vPt.reserve( PL.GetPointNbr() - 1) ;
|
||||
// salto il primo punto (coincide con l'ultimo)
|
||||
Point3d ptP ;
|
||||
if ( ( bCCW && ! PL.GetFirstPoint( ptP)) ||
|
||||
( ! bCCW && ! PL.GetLastPoint( ptP)))
|
||||
return false ;
|
||||
for ( int j = 0 ; j < n ; ++ j) {
|
||||
// insert only reflex vertex
|
||||
if ( ! TriangleIsCCW( vPt[vPol[vPrev[j]]], vPt[vPol[j]], vPt[vPol[vNext[j]]])) {
|
||||
if ( ! m_VertGrid.InsertPoint( vPt[vPol[j]], j))
|
||||
return false ;
|
||||
// inserisco i punti
|
||||
while ( ( bCCW && PL.GetNextPoint( ptP)) ||
|
||||
( ! bCCW && PL.GetPrevPoint( ptP)))
|
||||
vPt.push_back( ptP) ;
|
||||
// Create array
|
||||
using Point = array<double, 2> ;
|
||||
vector<vector<Point>> polygon ;
|
||||
// Fill polygon structure with actual data. Any winding order works.
|
||||
// The first polyline defines the main polygon.
|
||||
polygon.resize( 1) ;
|
||||
polygon[0].reserve( vPt.size()) ;
|
||||
for ( int i = 0 ; i < int( vPt.size()) ; ++i) {
|
||||
switch ( m_nPlane) {
|
||||
default : // PL_XY
|
||||
polygon[0].push_back( { vPt[i].x, vPt[i].y}) ;
|
||||
break ;
|
||||
case PL_YZ :
|
||||
polygon[0].push_back( { vPt[i].y, vPt[i].z}) ;
|
||||
break ;
|
||||
case PL_ZX :
|
||||
polygon[0].push_back( { vPt[i].z, vPt[i].x}) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
m_vVert.reserve( n / 5) ;
|
||||
// Run tessellation
|
||||
// Returns array of indices that refer to the vertices of the input polygon.
|
||||
// Three subsequent indices form a triangle. Output triangles are counterclockwise.
|
||||
vTr = mapbox::earcut<int32_t>( polygon) ;
|
||||
if ( vTr.empty()) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in MakeByEC_HPP(1)")
|
||||
return false ;
|
||||
}
|
||||
if ( ! bCCW)
|
||||
reverse( vTr.begin(), vTr.end()) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::MakeByEC_HPP( const POLYLINEVECTOR& vPL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// pulisco i vettori di ritorno
|
||||
vPt.clear() ;
|
||||
vTr.clear() ;
|
||||
// Creo il vettore con i punti dei poligoni da triangolare
|
||||
// calcolo spazio totale e spazio massimo per un percorso interno
|
||||
int nTot = vPL[0].GetPointNbr() - 1 ;
|
||||
for ( int i = 1 ; i < int( vPL.size()) ; ++i)
|
||||
nTot += vPL[i].GetPointNbr() - 1 ;
|
||||
// riservo spazio pari al totale dei punti (esclusi quelli ripetuti)
|
||||
vPt.reserve( nTot) ;
|
||||
// Create array
|
||||
using Point = array<double, 2> ;
|
||||
vector<vector<Point>> polygon ;
|
||||
polygon.resize( vPL.size()) ;
|
||||
// Eseguo riempimento di vettore e array
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
|
||||
polygon[i].reserve( vPL[i].GetPointNbr() - 1) ;
|
||||
// salto il primo punto (coincide con l'ultimo)
|
||||
Point3d ptP ;
|
||||
if ( ( bCCW && ! vPL[i].GetFirstPoint( ptP)) ||
|
||||
( ! bCCW && ! vPL[i].GetLastPoint( ptP)))
|
||||
return false ;
|
||||
// inserisco i punti
|
||||
while ( ( bCCW && vPL[i].GetNextPoint( ptP)) ||
|
||||
( ! bCCW && vPL[i].GetPrevPoint( ptP))) {
|
||||
vPt.push_back( ptP) ;
|
||||
switch ( m_nPlane) {
|
||||
default : // PL_XY
|
||||
polygon[i].push_back( { ptP.x, ptP.y}) ;
|
||||
break ;
|
||||
case PL_YZ :
|
||||
polygon[i].push_back( { ptP.y, ptP.z}) ;
|
||||
break ;
|
||||
case PL_ZX :
|
||||
polygon[i].push_back( { ptP.z, ptP.x}) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run tessellation
|
||||
// Returns array of indices that refer to the vertices of the input polygon.
|
||||
// Three subsequent indices form a triangle. Output triangles are counterclockwise.
|
||||
vTr = mapbox::earcut<int32_t>( polygon) ;
|
||||
if ( vTr.empty()) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in MakeByEC_HPP(N)")
|
||||
return false ;
|
||||
}
|
||||
if ( ! bCCW)
|
||||
reverse( vTr.begin(), vTr.end()) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -225,16 +315,22 @@ Triangulate::PrepareGrid( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
// Ear Clipping algorithm
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::MakeByEC( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr)
|
||||
Triangulate::MakeByEC( const PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// Clear triangle vector
|
||||
vTr.clear() ;
|
||||
|
||||
// At least 3 points
|
||||
int n = int( vPol.size()) ;
|
||||
int n = int( vPt.size()) ;
|
||||
if ( n < 3)
|
||||
return false ;
|
||||
|
||||
// Creo il vettore degli indici del Poligono
|
||||
INTVECTOR vPol ;
|
||||
vPol.reserve( n) ;
|
||||
for ( int i = 0 ; i < n ; ++ i)
|
||||
vPol.push_back( i) ;
|
||||
|
||||
// Preallocate triangle vector ( #triangles = n - 2)
|
||||
vTr.reserve( 3 * ( n - 2)) ;
|
||||
|
||||
@@ -297,16 +393,22 @@ Triangulate::MakeByEC( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& v
|
||||
// Ear Clipping algorithm enhanced, choose smaller diagonal
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::MakeByEC2( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr)
|
||||
Triangulate::MakeByEC2( const PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// Clear triangle vector
|
||||
vTr.clear() ;
|
||||
|
||||
// At least 3 points
|
||||
int n = int( vPol.size()) ;
|
||||
int n = int( vPt.size()) ;
|
||||
if ( n < 3)
|
||||
return false ;
|
||||
|
||||
// Creo il vettore degli indici del Poligono
|
||||
INTVECTOR vPol ;
|
||||
vPol.reserve( n) ;
|
||||
for ( int i = 0 ; i < n ; ++ i)
|
||||
vPol.push_back( i) ;
|
||||
|
||||
// Preallocate triangle vector ( #triangles = n - 2)
|
||||
vTr.reserve( 3 * ( n - 2)) ;
|
||||
|
||||
@@ -418,16 +520,22 @@ Triangulate::MakeByEC2( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR&
|
||||
// AR = ( Lmax * Lmax) / ( 2 * Area) = SqLenMax / L1 * L2
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::MakeByEC3( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr)
|
||||
Triangulate::MakeByEC3( const PNTVECTOR& vPt, INTVECTOR& vTr)
|
||||
{
|
||||
// Clear triangle vector
|
||||
vTr.clear() ;
|
||||
|
||||
// At least 3 points
|
||||
int n = int( vPol.size()) ;
|
||||
int n = int( vPt.size()) ;
|
||||
if ( n < 3)
|
||||
return false ;
|
||||
|
||||
// Creo il vettore degli indici del Poligono
|
||||
INTVECTOR vPol ;
|
||||
vPol.reserve( n) ;
|
||||
for ( int i = 0 ; i < n ; ++ i)
|
||||
vPol.push_back( i) ;
|
||||
|
||||
// Preallocate triangle vector ( #triangles = n - 2)
|
||||
vTr.reserve( 3 * ( n - 2)) ;
|
||||
|
||||
@@ -525,6 +633,36 @@ Triangulate::MakeByEC3( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR&
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::PrepareGrid( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
const INTVECTOR& vPrev, const INTVECTOR& vNext)
|
||||
{
|
||||
// points number
|
||||
int n = int( vPol.size()) ;
|
||||
// overall box
|
||||
BBox3d b3All ;
|
||||
for ( int j = 0 ; j < n ; ++ j)
|
||||
b3All.Add( vPt[vPol[j]]) ;
|
||||
// grid cell dimension
|
||||
double dCellDim ;
|
||||
b3All.GetRadius( dCellDim) ;
|
||||
dCellDim *= 2 / sqrt( n) ;
|
||||
// grid
|
||||
if ( ! m_VertGrid.Init( 2 * n, dCellDim))
|
||||
return false ;
|
||||
for ( int j = 0 ; j < n ; ++ j) {
|
||||
// insert only reflex vertex
|
||||
if ( ! TriangleIsCCW( vPt[vPol[vPrev[j]]], vPt[vPol[j]], vPt[vPol[vNext[j]]])) {
|
||||
if ( ! m_VertGrid.InsertPoint( vPt[vPol[j]], j))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
m_vVert.reserve( n / 5) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Triangulate::TestTriangle( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
@@ -800,7 +938,7 @@ Triangulate::GetOuterPntToJoin( const PNTVECTOR& vPt, const Point3d& ptP, int& n
|
||||
// indice punto successivo
|
||||
int j = ( i + 1 < nNumPt) ? i + 1 : 0 ;
|
||||
// mi metto nel piano principale
|
||||
switch (m_nPlane) {
|
||||
switch ( m_nPlane) {
|
||||
default : // PL_XY
|
||||
// se i punti coincidono
|
||||
if ( abs( vPt[i].x - ptP.x) < EPS_SMALL && abs( vPt[i].y - ptP.y) < EPS_SMALL) {
|
||||
|
||||
+5
-3
@@ -24,11 +24,13 @@ class Triangulate
|
||||
bool Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
|
||||
private :
|
||||
bool MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool MakeByEC_HPP( const POLYLINEVECTOR& vPL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool MakeByEC( const PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool MakeByEC2( const PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool MakeByEC3( const PNTVECTOR& vPt, INTVECTOR& vTr) ;
|
||||
bool PrepareGrid( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
const INTVECTOR& vPrev, const INTVECTOR& vNext) ;
|
||||
bool MakeByEC( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr) ;
|
||||
bool MakeByEC2( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr) ;
|
||||
bool MakeByEC3( const PNTVECTOR& vPt, const INTVECTOR& vPol, INTVECTOR& vTr) ;
|
||||
bool TestTriangle( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
||||
const INTVECTOR& vPrev, INTVECTOR& vNext, int i) ;
|
||||
double CalcTriangleAspectRatio( const Point3d& ptPa, const Point3d& ptPb, const Point3d& ptPc) ;
|
||||
|
||||
+96
-18
@@ -34,8 +34,8 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VolZmap::VolZmap(void)
|
||||
: m_nStatus( TO_VERIFY), m_nMapNum( 0), m_nNumBlock( 0), m_nConnectedCompoCount( 0), m_dStep( 10.0),
|
||||
m_nVoxNumPerBlock( N_VOXBLOCK), m_nDexVoxRatio( 1), m_nShape( GENERIC), m_nTempProp( 0), m_Tool( true)
|
||||
: m_nStatus( TO_VERIFY), m_dStep( 10.0), m_nMapNum( 0), m_nShape( GENERIC), m_nVoxNumPerBlock( N_VOXBLOCK),
|
||||
m_nDexVoxRatio( 1), m_nNumBlock( 0), m_nConnectedCompoCount( 0), m_nCurrTool( - 1)
|
||||
{
|
||||
for ( int i = 0 ; i < N_MAPS ; ++ i) {
|
||||
m_nNx[i] = 0 ;
|
||||
@@ -45,7 +45,8 @@ VolZmap::VolZmap(void)
|
||||
m_dMaxZ[i] = 0 ;
|
||||
m_nFracLin[i] = 0 ;
|
||||
}
|
||||
m_Tool.SetTolerances( LIN_TOL_STD, ANG_TOL_APPROX_DEG) ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -72,8 +73,9 @@ VolZmap::Clear( void)
|
||||
m_Values[i].clear() ;
|
||||
}
|
||||
m_dStep = EPS_SMALL ;
|
||||
m_nTempProp = 0 ;
|
||||
m_Tool.Clear() ;
|
||||
m_nTempProp[0] = 0 ;
|
||||
m_nTempProp[1] = 0 ;
|
||||
ResetAllTools() ;
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
@@ -138,7 +140,8 @@ VolZmap::CopyFrom( const VolZmap& vzmSrc)
|
||||
|
||||
m_dStep = vzmSrc.m_dStep ;
|
||||
m_nStatus = vzmSrc.m_nStatus ;
|
||||
m_nTempProp = vzmSrc.m_nTempProp ;
|
||||
m_nTempProp[0] = vzmSrc.m_nTempProp[0] ;
|
||||
m_nTempProp[1] = vzmSrc.m_nTempProp[1] ;
|
||||
|
||||
// dimensiono membri legati ai blocchi
|
||||
m_BlockToUpdate = vzmSrc.m_BlockToUpdate ;
|
||||
@@ -758,7 +761,6 @@ VolZmap::CheckMapConnection( void)
|
||||
int tStopIntZ = int( m_Values[0][tDexZ].size()) ;
|
||||
// Ciclo sugli intervalli del dexel
|
||||
for ( int tIntZ = 0 ; tIntZ < tStopIntZ ; ++ tIntZ) {
|
||||
|
||||
if ( m_Values[0][tDexZ][tIntZ].nCompo == 0) {
|
||||
++ m_nConnectedCompoCount ;
|
||||
m_Values[0][tDexZ][tIntZ].nCompo = m_nConnectedCompoCount ;
|
||||
@@ -1677,8 +1679,10 @@ VolZmap::Cut( const Plane3d& plPlane)
|
||||
Plane3d plMyPlane = plPlane ;
|
||||
plMyPlane.ToLoc( m_MapFrame) ;
|
||||
// Imposto numero fittizio di utensile per avere il colore di sezione opportuno
|
||||
int nToolNumOld = m_Tool.GetCurrentToolNum() ;
|
||||
m_Tool.SetToolNum( 1) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
int nToolNumOld = m_vTool[m_nCurrTool].GetCurrentToolNum() ;
|
||||
m_vTool[m_nCurrTool].SetToolNum( 1) ;
|
||||
// Interseco lo Zmap col piano, ciclando sulle griglie
|
||||
bool bModified = false ;
|
||||
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
||||
@@ -1732,7 +1736,7 @@ VolZmap::Cut( const Plane3d& plPlane)
|
||||
}
|
||||
|
||||
// Ripristino numero utensile
|
||||
m_Tool.SetToolNum( nToolNumOld) ;
|
||||
m_vTool[m_nCurrTool].SetToolNum( nToolNumOld) ;
|
||||
|
||||
if ( bModified == true) {
|
||||
// Imposto forma generica
|
||||
@@ -1967,14 +1971,18 @@ VolZmap::CalcBlockNum( void)
|
||||
bool
|
||||
VolZmap::SetToolTolerances( double dLinTol, double dAngTolDeg)
|
||||
{
|
||||
return m_Tool.SetTolerances( dLinTol, dAngTolDeg) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetTolerances( dLinTol, dAngTolDeg) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, double dCutterH, int nFlag)
|
||||
{
|
||||
return m_Tool.SetStdTool( sToolName, dH, dR, dCornR, dCutterH, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetStdTool( sToolName, dH, dR, dCornR, dCutterH, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1982,7 +1990,9 @@ bool
|
||||
VolZmap::SetAdvTool( const string& sToolName,
|
||||
double dH, double dR, double dTipH, double dTipR, double dCornR, double dCutterH, int nFlag)
|
||||
{
|
||||
return m_Tool.SetAdvTool( sToolName, dH, dR, dTipH, dTipR, dCornR, dCutterH, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetAdvTool( sToolName, dH, dR, dTipH, dTipR, dCornR, dCutterH, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1990,33 +2000,101 @@ bool
|
||||
VolZmap::SetSawTool( const string& sToolName,
|
||||
double dH, double dR, double dThick, double dStemR, double dCornR, int nFlag)
|
||||
{
|
||||
return m_Tool.SetSawTool( sToolName, dH, dR, dThick, dStemR, dCornR, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetSawTool( sToolName, dH, dR, dThick, dStemR, dCornR, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, int nFlag)
|
||||
{
|
||||
return m_Tool.SetGenTool( sToolName, pToolOutline, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetGenTool( sToolName, pToolOutline, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetMortiserTool( const string& sToolName, double dH, double dW, double dTh, double dRc, int nFlag)
|
||||
{
|
||||
return m_Tool.SetMortiserTool( sToolName, dH, dW, dTh, dRc, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetMortiserTool( sToolName, dH, dW, dTh, dRc, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, int nFlag)
|
||||
{
|
||||
return m_Tool.SetChiselTool( sToolName, dH, dW, dTh, nFlag) ;
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetChiselTool( sToolName, dH, dW, dTh, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetAdditiveTool(const std::string& sToolName, double dH, double dR, double dRC, int nFlag)
|
||||
{
|
||||
if ( m_nCurrTool < 0)
|
||||
return false ;
|
||||
return m_vTool[m_nCurrTool].SetAdditiveTool( sToolName, dH, dR, dRC, nFlag) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetCurrTool( int nCurrTool)
|
||||
{
|
||||
if ( nCurrTool < 0 || nCurrTool >= int( m_vTool.size()))
|
||||
return false ;
|
||||
m_nCurrTool = nCurrTool ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
VolZmap::GetToolCount( void) const
|
||||
{
|
||||
return int( m_vTool.size()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddTool( void)
|
||||
{
|
||||
m_vTool.emplace_back( true) ;
|
||||
m_vTool.back().SetTolerances( LIN_TOL_STD, ANG_TOL_APPROX_DEG) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::ResetAllTools( void)
|
||||
{
|
||||
bool bOk = true ;
|
||||
for ( int n = 0 ; n < int( m_vTool.size()) ; ++ n) {
|
||||
bOk = bOk || m_vTool[n].Clear() ;
|
||||
}
|
||||
m_vTool.clear() ;
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::ResetTool( void)
|
||||
{
|
||||
return m_Tool.Clear() ;
|
||||
if ( m_vTool.empty())
|
||||
return true ;
|
||||
bool bOk = m_vTool.back().Clear() ;
|
||||
m_vTool.erase( m_vTool.begin() + int( m_vTool.size()) - 1) ;
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const ICurveComposite&
|
||||
VolZmap::GetToolOutline( bool bApprox) const
|
||||
{
|
||||
if ( m_nCurrTool < 0)
|
||||
return cvEmptyOutline ;
|
||||
return ( bApprox ? m_vTool[m_nCurrTool].GetApproxOutline() : m_vTool[m_nCurrTool].GetOutline()) ;
|
||||
}
|
||||
|
||||
@@ -60,10 +60,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
const IObjGraphics* GetObjGraphics( void) const override
|
||||
{ return m_OGrMgr.GetObjGraphics() ; }
|
||||
void SetTempProp( int nProp) override
|
||||
{ m_nTempProp = nProp ; }
|
||||
int GetTempProp( void) const override
|
||||
{ return m_nTempProp ; }
|
||||
void SetTempProp( int nProp, int nPropInd = 0) override
|
||||
{ if ( nPropInd >= 0 && nPropInd < 2)
|
||||
m_nTempProp[nPropInd] = nProp ; }
|
||||
int GetTempProp( int nPropInd = 0) const override
|
||||
{ return (( nPropInd >= 0 && nPropInd < 2) ? m_nTempProp[nPropInd] : 0) ; }
|
||||
|
||||
public : // IVolZmap
|
||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||
@@ -71,6 +72,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
|
||||
bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ;
|
||||
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) override ;
|
||||
bool CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) override ;
|
||||
int GetBlockCount( void) const override ;
|
||||
int GetBlockUpdatingCounter( int nBlock) const override ;
|
||||
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
|
||||
@@ -89,9 +91,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nFlag) override ;
|
||||
bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nFlag) override ;
|
||||
bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nFlag) override ;
|
||||
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nFlag) override ;
|
||||
bool SetCurrTool( int nCurrTool) override ;
|
||||
int GetToolCount( void) const override ;
|
||||
int GetCurrTool( void) const override
|
||||
{ return m_nCurrTool ; }
|
||||
bool AddTool( void) override ;
|
||||
bool ResetAllTools( void) override ;
|
||||
bool ResetTool( void) override ;
|
||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
||||
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override ;
|
||||
bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ;
|
||||
bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
||||
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ;
|
||||
@@ -302,10 +310,45 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
inline bool TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA,
|
||||
double dLenX, double dLenY, double dLenZ,
|
||||
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
|
||||
|
||||
// Asportazioni superfici elementari vuote
|
||||
bool SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ;
|
||||
bool SurfCircCrown_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ;
|
||||
bool SurfCircCrown_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ;
|
||||
bool SurfCircCrown_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ;
|
||||
/*bool SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
||||
double dHei, double dRad, bool bTapB, bool bTapT) ;
|
||||
bool SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
||||
double dHei, double dRad, bool bTapB, bool bTapT) ;*/
|
||||
bool SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
||||
double dHei, double dRad, bool bOuterCutter) ;
|
||||
bool SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE,
|
||||
const Vector3d& vtToolDir, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) ;
|
||||
bool SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad,
|
||||
bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
|
||||
bool SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
||||
double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT,
|
||||
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
|
||||
bool SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad,
|
||||
bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
|
||||
bool SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
|
||||
double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT,
|
||||
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
|
||||
bool SurfSphericalShellPart_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
|
||||
double dRad, double dInfH, double dSupH, bool bOuterCutter) ;
|
||||
bool SurfSphericalShell_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
|
||||
double dRad, double dHei, bool bOuterCutter) ;
|
||||
// Additivo
|
||||
bool AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
|
||||
bool AddingCylinder( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dRad) ;
|
||||
bool AddingTruncatedCone( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
|
||||
double dMaxRad, double dMinRad, double dHei,
|
||||
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
|
||||
bool AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) ;
|
||||
bool AddingGeneral( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
|
||||
|
||||
|
||||
// Intersezioni
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const ;
|
||||
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax,
|
||||
double& dU1, double& dU2) const ;
|
||||
bool IntersLineZMapLattice( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ;
|
||||
bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) const ;
|
||||
bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int nI, int nJ,
|
||||
@@ -316,7 +359,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ;
|
||||
bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2, bool bSubtracting = true) const ;
|
||||
bool IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen,
|
||||
bool bTapLow, bool bTapUp,
|
||||
@@ -326,11 +369,39 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
bool IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2, bool bSubtracting = true) const ;
|
||||
bool IntersLineTruncatedPyramid( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& frTruncPyramFrame, double dSegMin, double dSegMax, double dHeight,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ;
|
||||
|
||||
// Intersezioni per asportazioni avanzate
|
||||
int IntersLineCircCrown( const Point3d& ptLineP, const Vector3d& vtLineDir,
|
||||
const Point3d& ptCen, const Vector3d& vtAx, double dMaxRad, double dMinRad,
|
||||
Point3d& ptInt, Vector3d& vtN) const ;
|
||||
int IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir,
|
||||
const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2,
|
||||
bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const ;
|
||||
int IntersLineCylinderCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir,
|
||||
const Point3d& ptBaseCen, const Vector3d& vtAx, double dRad, double dH, bool bInOut,
|
||||
const std::vector<Plane3d>& vPlanesVec,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
int IntersLineCircSweptSurfCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir,
|
||||
const Point3d& ptCen, const Vector3d& vtAx, double dRad, const Vector3d& vtSweptVec, bool bInOut,
|
||||
const std::vector<Plane3d>& vPlanesVec,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
int IntersLineConeCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir,
|
||||
const Point3d& ptVert, const Vector3d& vtAx, double dRad, double dH, bool bInOut,
|
||||
const std::vector<Plane3d>& vPlanesVec,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
int IntersLineSphereCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineD,
|
||||
const Point3d& ptCen, double dRad, bool bInOut,
|
||||
const std::vector<Plane3d>& vPlanesVec,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
||||
int IntersLineCatTongue( const Point3d& ptLineP, const Vector3d& vtLineD,
|
||||
const Point3d& ptCenSt, const Point3d& ptCenEn, const Vector3d& vtNorm, double dRad,
|
||||
Point3d& ptInt, Vector3d& vtN) const ;
|
||||
|
||||
// Voxel: esistenza e passaggio da N a ijk per i voxel
|
||||
bool IsValidVoxel( int nN) const ;
|
||||
bool IsValidVoxel( int nI, int nJ, int nK) const ;
|
||||
@@ -401,7 +472,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Status m_nStatus ; // stato
|
||||
int m_nTempProp ; // proprietà temporanea
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dStep ; // passo delle griglie
|
||||
int m_nMapNum ; // numero di griglie ( 1 o 3)
|
||||
Frame3d m_MapFrame ; // riferimento intrinseco dello Zmap
|
||||
@@ -451,7 +522,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
mutable std::atomic<bool> m_bBreak ;
|
||||
std::atomic<bool> m_bIsBox ;
|
||||
|
||||
Tool m_Tool ;
|
||||
// Utensili
|
||||
std::vector<Tool> m_vTool ;
|
||||
int m_nCurrTool ;
|
||||
CurveComposite cvEmptyOutline ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
+30
-123
@@ -16,10 +16,12 @@
|
||||
#include "CurveLine.h"
|
||||
#include "VolZmap.h"
|
||||
#include "GeoConst.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
@@ -30,103 +32,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box e piano devono essere nello stesso riferimento. Il box deve essere axis aligned.
|
||||
static bool
|
||||
TestIntersPlaneBox( const BBox3d& b3Box, const Plane3d& plPlane)
|
||||
{
|
||||
// Calcolo le distanze con segno dei punti dal piano
|
||||
Point3d ptE0 = b3Box.GetMin() ;
|
||||
double dDist0 = DistPointPlane( ptE0, plPlane) ;
|
||||
Point3d ptE1( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMin().z) ;
|
||||
double dDist1 = DistPointPlane( ptE1, plPlane) ;
|
||||
Point3d ptE2( b3Box.GetMax().x, b3Box.GetMax().y, b3Box.GetMin().z) ;
|
||||
double dDist2 = DistPointPlane( ptE2, plPlane) ;
|
||||
Point3d ptE3( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMin().z) ;
|
||||
double dDist3 = DistPointPlane( ptE3, plPlane) ;
|
||||
Point3d ptE4( b3Box.GetMin().x, b3Box.GetMin().y, b3Box.GetMax().z) ;
|
||||
double dDist4 = DistPointPlane( ptE4, plPlane) ;
|
||||
Point3d ptE5( b3Box.GetMax().x, b3Box.GetMin().y, b3Box.GetMax().z) ;
|
||||
double dDist5 = DistPointPlane( ptE5, plPlane) ;
|
||||
Point3d ptE6 = b3Box.GetMax() ;
|
||||
double dDist6 = DistPointPlane( ptE6, plPlane) ;
|
||||
Point3d ptE7( b3Box.GetMin().x, b3Box.GetMax().y, b3Box.GetMax().z) ;
|
||||
double dDist7 = DistPointPlane( ptE7, plPlane) ;
|
||||
// Distanze tutte positive
|
||||
if ( dDist0 > EPS_SMALL && dDist1 > EPS_SMALL && dDist2 > EPS_SMALL && dDist3 > EPS_SMALL &&
|
||||
dDist4 > EPS_SMALL && dDist5 > EPS_SMALL && dDist6 > EPS_SMALL && dDist7 > EPS_SMALL)
|
||||
return false ;
|
||||
// Distanze tutte negative
|
||||
if ( dDist0 < - EPS_SMALL && dDist1 < - EPS_SMALL && dDist2 < - EPS_SMALL && dDist3 < - EPS_SMALL &&
|
||||
dDist4 < - EPS_SMALL && dDist5 < - EPS_SMALL && dDist6 < - EPS_SMALL && dDist7 < - EPS_SMALL)
|
||||
return false ;
|
||||
// Il piano interseca il box
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di tale sistema di riferimento.
|
||||
// Viene restituito true in caso di intersezione, false altrimenti.
|
||||
bool
|
||||
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const
|
||||
{
|
||||
double dU1, dU2 ;
|
||||
return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Punti e vettore devono esse espressi nel medesimo sistema di riferimento.
|
||||
// Il box è allineato con gli assi di tale sistema di riferimento.
|
||||
// In dU1, dU2 vengono restituiti i parametri a cui si trovano le intersezioni.
|
||||
// Viene restituito true in caso di intersezione, false altrimenti.
|
||||
bool
|
||||
VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
|
||||
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) const
|
||||
{
|
||||
// Il box è allineato agli assi
|
||||
dU1 = - INFINITO ;
|
||||
dU2 = INFINITO ;
|
||||
|
||||
// confronto con piani YZ (perpendicolari ad asse X)
|
||||
if ( vtV.x > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( vtV.x < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ;
|
||||
dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ;
|
||||
}
|
||||
else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// confronto con piani ZX (perpendicolari ad asse Y)
|
||||
if ( vtV.y > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( vtV.y < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ;
|
||||
dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ;
|
||||
}
|
||||
else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// confronto con piani XY (perpendicolari ad asse Z)
|
||||
if ( vtV.z > EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( vtV.z < - EPS_ZERO) {
|
||||
dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ;
|
||||
dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ;
|
||||
}
|
||||
else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
return ( dU2 >= dU1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// La retta è rappresentata da un punto e dal versore espressi nel riferimento dello Zmap.
|
||||
// Se non vi è intersezione, viene restituito falso
|
||||
@@ -249,7 +154,7 @@ VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, int nGrid, int
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Calcola la profondità del materiale lungo un raggio, identificato da un punto e un versoreore.
|
||||
// Calcola la profondità del materiale lungo un raggio, identificato da un punto e un versore.
|
||||
// Punto e versore devono essere espressi nel sistema di riferimento locale, in cui è immerso quello dello Zmap.
|
||||
// InLength = distanza di ingresso (se -1 il punto è interno, se -2 il punto è esterno e il raggio non interseca lo Zmap)
|
||||
// OutLength = distanza di uscita
|
||||
@@ -293,7 +198,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptPLoc, const Vector3d& vtDLoc, doubl
|
||||
double dOutLen[N_MAPS] ;
|
||||
|
||||
// Ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
|
||||
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
|
||||
|
||||
Point3d ptP0 = ptP ;
|
||||
Vector3d vtV0 = vtD ;
|
||||
@@ -417,7 +322,7 @@ VolZmap::GetDepthWithDexel( const Point3d& ptPLoc, const Vector3d& vtDLoc, doubl
|
||||
else {
|
||||
dInLength = INFINITO ;
|
||||
dOutLength = - INFINITO ;
|
||||
for ( int nGr = 0 ; nGr < 3 ; ++ nGr) {
|
||||
for ( int nGr = 0 ; nGr < m_nMapNum ; ++ nGr) {
|
||||
if ( dInLen[nGr] > -2 && dInLen[nGr] < dInLength)
|
||||
dInLength = dInLen[nGr] ;
|
||||
if ( dOutLen[nGr] > -2 && dOutLen[nGr] > dOutLength)
|
||||
@@ -2376,7 +2281,7 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
|
||||
bool
|
||||
VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2, bool bSubtracting) const
|
||||
{
|
||||
// Porto la linea nel riferimento del cilindro
|
||||
Point3d ptP = ptLineSt ; ptP.ToLoc( CylFrame) ;
|
||||
@@ -2386,14 +2291,14 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
int nBasInt = 0 ;
|
||||
if ( abs( vtV.z) > EPS_ZERO) {
|
||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
||||
double EpsRad = ( vtV.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
||||
double dEpsRad = ( bSubtracting ? ( vtV.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) : EPS_SMALL) ;
|
||||
ptInt1 = ptP + ( ( 0 - ptP.z) / vtV.z) * vtV ;
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||
nBasInt += 1 ;
|
||||
vtN1 = Z_AX ;
|
||||
}
|
||||
ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ;
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
|
||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||
nBasInt += 2 ;
|
||||
vtN2 = - Z_AX ;
|
||||
}
|
||||
@@ -2776,7 +2681,7 @@ VolZmap::IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d&
|
||||
bool
|
||||
VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaZ,
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
|
||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2, bool bSubtracting) const
|
||||
{
|
||||
// Controllo sulle dimensioni lineari affinché sia valido il poliedro
|
||||
if ( dLenX <= EPS_SMALL || dLenY <= EPS_SMALL || dLenZ <= EPS_SMALL)
|
||||
@@ -2800,17 +2705,19 @@ VolZmap::IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLine
|
||||
|
||||
// Controlli affinché non vengano tagliati dexel a filo
|
||||
// con il passaggio dell'utensile:
|
||||
// Controllo sulle facce 1 e 2
|
||||
if ( abs( vtV.y) < EPS_ZERO && abs( ptP.y) > ptFacet135.y)
|
||||
return false ;
|
||||
// Controllo sulle facce 3 e 4
|
||||
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptFacet135.x || ptP.x > ptFacet246.x))
|
||||
return false ;
|
||||
// Controllo sulle facce 5 e 6
|
||||
double dP1 = abs ( ( ptFacet135 - ptP) * vtOb) ;
|
||||
double dP2 = abs ( ( ptFacet246 - ptP) * vtOb) ;
|
||||
if ( abs( vtV * vtOb) < EPS_ZERO && ( dP1 < EPS_SMALL || dP2 < EPS_SMALL))
|
||||
return false ;
|
||||
if ( bSubtracting) {
|
||||
// Controllo sulle facce 1 e 2
|
||||
if ( abs( vtV.y) < EPS_ZERO && abs( ptP.y) > ptFacet135.y)
|
||||
return false ;
|
||||
// Controllo sulle facce 3 e 4
|
||||
if ( abs( vtV.x) < EPS_ZERO && ( ptP.x < ptFacet135.x || ptP.x > ptFacet246.x))
|
||||
return false ;
|
||||
// Controllo sulle facce 5 e 6
|
||||
double dP1 = abs ( ( ptFacet135 - ptP) * vtOb) ;
|
||||
double dP2 = abs ( ( ptFacet246 - ptP) * vtOb) ;
|
||||
if ( abs( vtV * vtOb) < EPS_ZERO && ( dP1 < EPS_SMALL || dP2 < EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// Punti notevoli
|
||||
Point3d ptI1 = ptP + ( ( ptFacet135.y - ptP.y) / vtV.y) * vtV ;
|
||||
@@ -3130,8 +3037,8 @@ VolZmap::GetPartVolume( int nPart, double& dVol) const
|
||||
|
||||
// Eseguo il calcolo della lunghezza totale degli spilloni
|
||||
double dLen = 0 ;
|
||||
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
||||
for ( int nDex = 0 ; nDex < int( m_Values[nMap].size()) ; ++ nDex) {
|
||||
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
|
||||
for ( int nDex = 0 ; nDex < m_nDim[nMap] ; ++ nDex) {
|
||||
for ( int nInt = 0 ; nInt < int( m_Values[nMap][nDex].size()) ; ++ nInt) {
|
||||
// se il pezzo di spillone appartiene alla parte, ne aggiungo la lunghezza
|
||||
if ( m_Values[nMap][nDex][nInt].nCompo == nPart + 1) {
|
||||
@@ -3188,7 +3095,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
||||
if ( ! GetBlockBox( nBlockIJK, b3BlockBox))
|
||||
return false ;
|
||||
// Se c'è intersezione valuto tutti i voxel interni
|
||||
if ( IntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) {
|
||||
if ( TestIntersLineBox( ptLocP, vtDirL, b3BlockBox.GetMin(), b3BlockBox.GetMax())) {
|
||||
// Ciclo sui voxel del blocco.
|
||||
// Triangoli smooth
|
||||
for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) {
|
||||
@@ -3199,7 +3106,7 @@ VolZmap::GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTO
|
||||
m_BlockSmoothTria[nB][nV].k } ;
|
||||
GetVoxelBox( nCurVoxIJK[0], nCurVoxIJK[1], nCurVoxIJK[2], b3Vox) ;
|
||||
// Se non c'è intersezione col voxel, passo al successivo.
|
||||
if ( ! IntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax()))
|
||||
if ( ! TestIntersLineBox( ptLocP, vtDirL, b3Vox.GetMin(), b3Vox.GetMax()))
|
||||
continue ;
|
||||
for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) {
|
||||
Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
||||
@@ -3374,7 +3281,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
||||
if ( ! GetBlockBox( nBlockIJK, b3BlockBox))
|
||||
return false ;
|
||||
// Se c'è intersezione valuto tutti i voxel interni
|
||||
if ( TestIntersPlaneBox( b3BlockBox, plPlaneLoc)) {
|
||||
if ( TestIntersPlaneBox( plPlaneLoc, b3BlockBox)) {
|
||||
// Ciclo sui voxel del blocco.
|
||||
// Triangoli smooth
|
||||
for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) {
|
||||
@@ -3382,7 +3289,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
||||
BBox3d b3Vox ;
|
||||
GetVoxelBox( m_BlockSmoothTria[nB][nV].i, m_BlockSmoothTria[nB][nV].j, m_BlockSmoothTria[nB][nV].k, b3Vox) ;
|
||||
// Se non c'è intersezione col voxel, passo al successivo.
|
||||
if ( ! TestIntersPlaneBox(b3Vox, plPlaneLoc))
|
||||
if ( ! TestIntersPlaneBox( plPlaneLoc, b3Vox))
|
||||
continue ;
|
||||
for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) {
|
||||
Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
||||
@@ -3486,5 +3393,5 @@ bool
|
||||
VolZmap::TestIntersPlaneZmapBBox( const Plane3d& plPlane) const
|
||||
{
|
||||
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
|
||||
return TestIntersPlaneBox( b3Zmap, plPlane) ;
|
||||
return TestIntersPlaneBox( plPlane, b3Zmap) ;
|
||||
}
|
||||
|
||||
+76
-2
@@ -220,7 +220,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
|
||||
|
||||
// Determino le intersezioni della retta con la regione
|
||||
CRVCVECTOR IntersectionResults ;
|
||||
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
|
||||
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
|
||||
|
||||
// Analizzo le parti in cui la retta è stata divisa
|
||||
int nPart = int( IntersectionResults.size()) ;
|
||||
@@ -327,7 +327,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
|
||||
|
||||
// Determino le intersezioni della retta con la regione
|
||||
CRVCVECTOR IntersectionResults ;
|
||||
Surf.GetCurveClassification( GridLine, IntersectionResults) ;
|
||||
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
|
||||
|
||||
// Analizzo le parti
|
||||
int nPart = int( IntersectionResults.size()) ;
|
||||
@@ -665,3 +665,77 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
||||
|
||||
return bCompleted ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex)
|
||||
{
|
||||
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
|
||||
if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
|
||||
return false ;
|
||||
|
||||
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
|
||||
m_dStep = max( dStep, 100 * EPS_SMALL) ;
|
||||
|
||||
// Aggiorno la dimensione della mappa 1 o 3
|
||||
m_nMapNum = ( bTriDex ? 3 : 1) ;
|
||||
|
||||
// Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z
|
||||
// di uno si ottengono da una permutazione ciclica di quelle del precedente sistema.
|
||||
// es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1)
|
||||
|
||||
// Definisco il sistema di riferimento intrinseco
|
||||
m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ;
|
||||
|
||||
// Definisco i vettori dei limiti su indici
|
||||
m_nNx[0] = max( int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
||||
m_nNy[0] = max( int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
||||
|
||||
// Numero di componenti connesse
|
||||
m_nConnectedCompoCount = 1 ;
|
||||
|
||||
// Se tridexel
|
||||
if ( bTriDex) {
|
||||
m_nNx[1] = m_nNy[0] ;
|
||||
m_nNy[1] = max( int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
||||
m_nNx[2] = m_nNy[1] ;
|
||||
m_nNy[2] = m_nNx[0] ;
|
||||
}
|
||||
|
||||
// altrimenti mono dexel
|
||||
else {
|
||||
m_nNx[1] = 0 ;
|
||||
m_nNy[1] = 0 ;
|
||||
m_nNx[2] = 0 ;
|
||||
m_nNy[2] = 0 ;
|
||||
}
|
||||
|
||||
// Definisco il numero di blocchi lungo x,y e z
|
||||
if ( ! CalcBlockNum())
|
||||
return false ;
|
||||
|
||||
// Creazione delle mappe
|
||||
// Calcolo del numero di celle per ogni mappa
|
||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
||||
|
||||
// Creazione delle celle per ogni mappa
|
||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||
m_Values[i].resize( m_nDim[i]) ;
|
||||
|
||||
// Definizione delle limitazioni iniziali in Z per ogni mappa
|
||||
m_dMinZ[0] = 0 ;
|
||||
m_dMaxZ[0] = dLengthZ ;
|
||||
m_dMinZ[1] = 0 ;
|
||||
m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ;
|
||||
m_dMinZ[2] = 0 ;
|
||||
m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ;
|
||||
|
||||
// Tipologia
|
||||
m_nShape = GENERIC ;
|
||||
|
||||
// Aggiornamento dello stato
|
||||
m_nStatus = OK ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
+10
-9
@@ -1,13 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2019
|
||||
// EgalTech 2015-2021
|
||||
//----------------------------------------------------------------------------
|
||||
// File : VolZmap.cpp Data : 07.03.19 Versione : 2.1c2
|
||||
// File : VolZmap.cpp Data : 13.09.21 Versione : 2.3i1
|
||||
// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 22.01.15 DS Creazione modulo.
|
||||
//
|
||||
// 13.09.21 LM Correzione funzione che determina se voxel su frontiera di un blocco.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "MC_Tables.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "IntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
@@ -844,7 +845,7 @@ VolZmap::UpdateTripleMapGraphics( void) const
|
||||
VecTriHold.resize( m_nNumBlock) ;
|
||||
|
||||
// Ciclo sui blocchi per eliminare le slice fra blocchi da aggiornare
|
||||
for ( int t = 0 ; t < m_nNumBlock ; ++ t) {
|
||||
for ( int t = 0 ; t < m_nNumBlock ; ++ t) {
|
||||
for ( auto it = m_SliceXY[t].begin() ; it != m_SliceXY[t].end() ;) {
|
||||
int nSlIJK[3] ;
|
||||
if ( GetVoxIJKFromN( it->first, nSlIJK[0], nSlIJK[1], nSlIJK[2])) {
|
||||
@@ -1083,7 +1084,7 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
||||
|
||||
// Flag di regolarità dei campi scalare e vettoriale
|
||||
bool bReg = true ;
|
||||
|
||||
|
||||
// Ciclo sui segmenti
|
||||
for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) {
|
||||
// Se il segmento non attraversa la superficie passo al successivo
|
||||
@@ -3984,13 +3985,13 @@ VolZmap::IsAVoxelOnBoundary( const int nLimits[], const int nIJK[], int nDeltaIn
|
||||
-- nDeltaIndex[0] ;
|
||||
else if ( nIJK[0] == nLimits[1] - 1)
|
||||
++ nDeltaIndex[0] ;
|
||||
if ( nIJK[0] == nLimits[0])
|
||||
if ( nIJK[1] == nLimits[2])
|
||||
-- nDeltaIndex[1];
|
||||
else if ( nIJK[0] == nLimits[1] - 1)
|
||||
else if ( nIJK[1] == nLimits[3] - 1)
|
||||
++ nDeltaIndex[1];
|
||||
if ( nIJK[0] == nLimits[0])
|
||||
if ( nIJK[2] == nLimits[4])
|
||||
-- nDeltaIndex[2];
|
||||
else if ( nIJK[0] == nLimits[1] - 1)
|
||||
else if ( nIJK[2] == nLimits[5] - 1)
|
||||
++ nDeltaIndex[2];
|
||||
return ( nDeltaIndex[0] != 0 || nDeltaIndex[1] != 0 || nDeltaIndex[2] != 0) ;
|
||||
}
|
||||
|
||||
+4037
-547
File diff suppressed because it is too large
Load Diff
+823
@@ -0,0 +1,823 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace mapbox {
|
||||
|
||||
namespace util {
|
||||
|
||||
template <std::size_t I, typename T> struct nth {
|
||||
inline static typename std::tuple_element<I, T>::type
|
||||
get(const T& t) { return std::get<I>(t); };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename N = uint32_t>
|
||||
class Earcut {
|
||||
public:
|
||||
std::vector<N> indices;
|
||||
std::size_t vertices = 0;
|
||||
|
||||
template <typename Polygon>
|
||||
void operator()(const Polygon& points);
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Node(N index, double x_, double y_) : i(index), x(x_), y(y_) {}
|
||||
Node(const Node&) = delete;
|
||||
Node& operator=(const Node&) = delete;
|
||||
Node(Node&&) = delete;
|
||||
Node& operator=(Node&&) = delete;
|
||||
|
||||
const N i;
|
||||
const double x;
|
||||
const double y;
|
||||
|
||||
// previous and next vertice nodes in a polygon ring
|
||||
Node* prev = nullptr;
|
||||
Node* next = nullptr;
|
||||
|
||||
// z-order curve value
|
||||
int32_t z = 0;
|
||||
|
||||
// previous and next nodes in z-order
|
||||
Node* prevZ = nullptr;
|
||||
Node* nextZ = nullptr;
|
||||
|
||||
// indicates whether this is a steiner point
|
||||
bool steiner = false;
|
||||
};
|
||||
|
||||
template <typename Ring> Node* linkedList(const Ring& points, const bool clockwise);
|
||||
Node* filterPoints(Node* start, Node* end = nullptr);
|
||||
void earcutLinked(Node* ear, int pass = 0);
|
||||
bool isEar(Node* ear);
|
||||
bool isEarHashed(Node* ear);
|
||||
Node* cureLocalIntersections(Node* start);
|
||||
void splitEarcut(Node* start);
|
||||
template <typename Polygon> Node* eliminateHoles(const Polygon& points, Node* outerNode);
|
||||
Node* eliminateHole(Node* hole, Node* outerNode);
|
||||
Node* findHoleBridge(Node* hole, Node* outerNode);
|
||||
bool sectorContainsSector(const Node* m, const Node* p);
|
||||
void indexCurve(Node* start);
|
||||
Node* sortLinked(Node* list);
|
||||
int32_t zOrder(const double x_, const double y_);
|
||||
Node* getLeftmost(Node* start);
|
||||
bool pointInTriangle(double ax, double ay, double bx, double by, double cx, double cy, double px, double py) const;
|
||||
bool isValidDiagonal(Node* a, Node* b);
|
||||
double area(const Node* p, const Node* q, const Node* r) const;
|
||||
bool equals(const Node* p1, const Node* p2);
|
||||
bool intersects(const Node* p1, const Node* q1, const Node* p2, const Node* q2);
|
||||
bool onSegment(const Node* p, const Node* q, const Node* r);
|
||||
int sign(double val);
|
||||
bool intersectsPolygon(const Node* a, const Node* b);
|
||||
bool locallyInside(const Node* a, const Node* b);
|
||||
bool middleInside(const Node* a, const Node* b);
|
||||
Node* splitPolygon(Node* a, Node* b);
|
||||
template <typename Point> Node* insertNode(std::size_t i, const Point& p, Node* last);
|
||||
void removeNode(Node* p);
|
||||
|
||||
bool hashing;
|
||||
double minX, maxX;
|
||||
double minY, maxY;
|
||||
double inv_size = 0;
|
||||
|
||||
template <typename T, typename Alloc = std::allocator<T>>
|
||||
class ObjectPool {
|
||||
public:
|
||||
ObjectPool() { }
|
||||
ObjectPool(std::size_t blockSize_) {
|
||||
reset(blockSize_);
|
||||
}
|
||||
~ObjectPool() {
|
||||
clear();
|
||||
}
|
||||
template <typename... Args>
|
||||
T* construct(Args&&... args) {
|
||||
if (currentIndex >= blockSize) {
|
||||
currentBlock = alloc_traits::allocate(alloc, blockSize);
|
||||
allocations.emplace_back(currentBlock);
|
||||
currentIndex = 0;
|
||||
}
|
||||
T* object = ¤tBlock[currentIndex++];
|
||||
alloc_traits::construct(alloc, object, std::forward<Args>(args)...);
|
||||
return object;
|
||||
}
|
||||
void reset(std::size_t newBlockSize) {
|
||||
for (auto allocation : allocations) {
|
||||
alloc_traits::deallocate(alloc, allocation, blockSize);
|
||||
}
|
||||
allocations.clear();
|
||||
blockSize = std::max<std::size_t>(1, newBlockSize);
|
||||
currentBlock = nullptr;
|
||||
currentIndex = blockSize;
|
||||
}
|
||||
void clear() { reset(blockSize); }
|
||||
private:
|
||||
T* currentBlock = nullptr;
|
||||
std::size_t currentIndex = 1;
|
||||
std::size_t blockSize = 1;
|
||||
std::vector<T*> allocations;
|
||||
Alloc alloc;
|
||||
typedef typename std::allocator_traits<Alloc> alloc_traits;
|
||||
};
|
||||
ObjectPool<Node> nodes;
|
||||
};
|
||||
|
||||
template <typename N> template <typename Polygon>
|
||||
void Earcut<N>::operator()(const Polygon& points) {
|
||||
// reset
|
||||
indices.clear();
|
||||
vertices = 0;
|
||||
|
||||
if (points.empty()) return;
|
||||
|
||||
double x;
|
||||
double y;
|
||||
int threshold = 80;
|
||||
std::size_t len = 0;
|
||||
|
||||
for (size_t i = 0; threshold >= 0 && i < points.size(); i++) {
|
||||
threshold -= static_cast<int>(points[i].size());
|
||||
len += points[i].size();
|
||||
}
|
||||
|
||||
//estimate size of nodes and indices
|
||||
nodes.reset(len * 3 / 2);
|
||||
indices.reserve(len + points[0].size());
|
||||
|
||||
Node* outerNode = linkedList(points[0], true);
|
||||
if (!outerNode || outerNode->prev == outerNode->next) return;
|
||||
|
||||
if (points.size() > 1) outerNode = eliminateHoles(points, outerNode);
|
||||
|
||||
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
|
||||
hashing = threshold < 0;
|
||||
if (hashing) {
|
||||
Node* p = outerNode->next;
|
||||
minX = maxX = outerNode->x;
|
||||
minY = maxY = outerNode->y;
|
||||
do {
|
||||
x = p->x;
|
||||
y = p->y;
|
||||
minX = std::min<double>(minX, x);
|
||||
minY = std::min<double>(minY, y);
|
||||
maxX = std::max<double>(maxX, x);
|
||||
maxY = std::max<double>(maxY, y);
|
||||
p = p->next;
|
||||
} while (p != outerNode);
|
||||
|
||||
// minX, minY and size are later used to transform coords into integers for z-order calculation
|
||||
inv_size = std::max<double>(maxX - minX, maxY - minY);
|
||||
inv_size = inv_size != .0 ? (1. / inv_size) : .0;
|
||||
}
|
||||
|
||||
earcutLinked(outerNode);
|
||||
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
// create a circular doubly linked list from polygon points in the specified winding order
|
||||
template <typename N> template <typename Ring>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::linkedList(const Ring& points, const bool clockwise) {
|
||||
using Point = typename Ring::value_type;
|
||||
double sum = 0;
|
||||
const std::size_t len = points.size();
|
||||
std::size_t i, j;
|
||||
Node* last = nullptr;
|
||||
|
||||
// calculate original winding order of a polygon ring
|
||||
for (i = 0, j = len > 0 ? len - 1 : 0; i < len; j = i++) {
|
||||
const auto& p1 = points[i];
|
||||
const auto& p2 = points[j];
|
||||
const double p20 = util::nth<0, Point>::get(p2);
|
||||
const double p10 = util::nth<0, Point>::get(p1);
|
||||
const double p11 = util::nth<1, Point>::get(p1);
|
||||
const double p21 = util::nth<1, Point>::get(p2);
|
||||
sum += (p20 - p10) * (p11 + p21);
|
||||
}
|
||||
|
||||
// link points into circular doubly-linked list in the specified winding order
|
||||
if (clockwise == (sum > 0)) {
|
||||
for (i = 0; i < len; i++) last = insertNode(vertices + i, points[i], last);
|
||||
} else {
|
||||
for (i = len; i-- > 0;) last = insertNode(vertices + i, points[i], last);
|
||||
}
|
||||
|
||||
if (last && equals(last, last->next)) {
|
||||
removeNode(last);
|
||||
last = last->next;
|
||||
}
|
||||
|
||||
vertices += len;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
// eliminate colinear or duplicate points
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::filterPoints(Node* start, Node* end) {
|
||||
if (!end) end = start;
|
||||
|
||||
Node* p = start;
|
||||
bool again;
|
||||
do {
|
||||
again = false;
|
||||
|
||||
if (!p->steiner && (equals(p, p->next) || area(p->prev, p, p->next) == 0)) {
|
||||
removeNode(p);
|
||||
p = end = p->prev;
|
||||
|
||||
if (p == p->next) break;
|
||||
again = true;
|
||||
|
||||
} else {
|
||||
p = p->next;
|
||||
}
|
||||
} while (again || p != end);
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
// main ear slicing loop which triangulates a polygon (given as a linked list)
|
||||
template <typename N>
|
||||
void Earcut<N>::earcutLinked(Node* ear, int pass) {
|
||||
if (!ear) return;
|
||||
|
||||
// interlink polygon nodes in z-order
|
||||
if (!pass && hashing) indexCurve(ear);
|
||||
|
||||
Node* stop = ear;
|
||||
Node* prev;
|
||||
Node* next;
|
||||
|
||||
int iterations = 0;
|
||||
|
||||
// iterate through ears, slicing them one by one
|
||||
while (ear->prev != ear->next) {
|
||||
iterations++;
|
||||
prev = ear->prev;
|
||||
next = ear->next;
|
||||
|
||||
if (hashing ? isEarHashed(ear) : isEar(ear)) {
|
||||
// cut off the triangle
|
||||
indices.emplace_back(prev->i);
|
||||
indices.emplace_back(ear->i);
|
||||
indices.emplace_back(next->i);
|
||||
|
||||
removeNode(ear);
|
||||
|
||||
// skipping the next vertice leads to less sliver triangles
|
||||
ear = next->next;
|
||||
stop = next->next;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ear = next;
|
||||
|
||||
// if we looped through the whole remaining polygon and can't find any more ears
|
||||
if (ear == stop) {
|
||||
// try filtering points and slicing again
|
||||
if (!pass) earcutLinked(filterPoints(ear), 1);
|
||||
|
||||
// if this didn't work, try curing all small self-intersections locally
|
||||
else if (pass == 1) {
|
||||
ear = cureLocalIntersections(filterPoints(ear));
|
||||
earcutLinked(ear, 2);
|
||||
|
||||
// as a last resort, try splitting the remaining polygon into two
|
||||
} else if (pass == 2) splitEarcut(ear);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check whether a polygon node forms a valid ear with adjacent nodes
|
||||
template <typename N>
|
||||
bool Earcut<N>::isEar(Node* ear) {
|
||||
const Node* a = ear->prev;
|
||||
const Node* b = ear;
|
||||
const Node* c = ear->next;
|
||||
|
||||
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
|
||||
|
||||
// now make sure we don't have other points inside the potential ear
|
||||
Node* p = ear->next->next;
|
||||
|
||||
while (p != ear->prev) {
|
||||
if (pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
|
||||
area(p->prev, p, p->next) >= 0) return false;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename N>
|
||||
bool Earcut<N>::isEarHashed(Node* ear) {
|
||||
const Node* a = ear->prev;
|
||||
const Node* b = ear;
|
||||
const Node* c = ear->next;
|
||||
|
||||
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
|
||||
|
||||
// triangle bbox; min & max are calculated like this for speed
|
||||
const double minTX = std::min<double>(a->x, std::min<double>(b->x, c->x));
|
||||
const double minTY = std::min<double>(a->y, std::min<double>(b->y, c->y));
|
||||
const double maxTX = std::max<double>(a->x, std::max<double>(b->x, c->x));
|
||||
const double maxTY = std::max<double>(a->y, std::max<double>(b->y, c->y));
|
||||
|
||||
// z-order range for the current triangle bbox;
|
||||
const int32_t minZ = zOrder(minTX, minTY);
|
||||
const int32_t maxZ = zOrder(maxTX, maxTY);
|
||||
|
||||
// first look for points inside the triangle in increasing z-order
|
||||
Node* p = ear->nextZ;
|
||||
|
||||
while (p && p->z <= maxZ) {
|
||||
if (p != ear->prev && p != ear->next &&
|
||||
pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
|
||||
area(p->prev, p, p->next) >= 0) return false;
|
||||
p = p->nextZ;
|
||||
}
|
||||
|
||||
// then look for points in decreasing z-order
|
||||
p = ear->prevZ;
|
||||
|
||||
while (p && p->z >= minZ) {
|
||||
if (p != ear->prev && p != ear->next &&
|
||||
pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
|
||||
area(p->prev, p, p->next) >= 0) return false;
|
||||
p = p->prevZ;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// go through all polygon nodes and cure small local self-intersections
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::cureLocalIntersections(Node* start) {
|
||||
Node* p = start;
|
||||
do {
|
||||
Node* a = p->prev;
|
||||
Node* b = p->next->next;
|
||||
|
||||
// a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2])
|
||||
if (!equals(a, b) && intersects(a, p, p->next, b) && locallyInside(a, b) && locallyInside(b, a)) {
|
||||
indices.emplace_back(a->i);
|
||||
indices.emplace_back(p->i);
|
||||
indices.emplace_back(b->i);
|
||||
|
||||
// remove two nodes involved
|
||||
removeNode(p);
|
||||
removeNode(p->next);
|
||||
|
||||
p = start = b;
|
||||
}
|
||||
p = p->next;
|
||||
} while (p != start);
|
||||
|
||||
return filterPoints(p);
|
||||
}
|
||||
|
||||
// try splitting polygon into two and triangulate them independently
|
||||
template <typename N>
|
||||
void Earcut<N>::splitEarcut(Node* start) {
|
||||
// look for a valid diagonal that divides the polygon into two
|
||||
Node* a = start;
|
||||
do {
|
||||
Node* b = a->next->next;
|
||||
while (b != a->prev) {
|
||||
if (a->i != b->i && isValidDiagonal(a, b)) {
|
||||
// split the polygon in two by the diagonal
|
||||
Node* c = splitPolygon(a, b);
|
||||
|
||||
// filter colinear points around the cuts
|
||||
a = filterPoints(a, a->next);
|
||||
c = filterPoints(c, c->next);
|
||||
|
||||
// run earcut on each half
|
||||
earcutLinked(a);
|
||||
earcutLinked(c);
|
||||
return;
|
||||
}
|
||||
b = b->next;
|
||||
}
|
||||
a = a->next;
|
||||
} while (a != start);
|
||||
}
|
||||
|
||||
// link every hole into the outer loop, producing a single-ring polygon without holes
|
||||
template <typename N> template <typename Polygon>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::eliminateHoles(const Polygon& points, Node* outerNode) {
|
||||
const size_t len = points.size();
|
||||
|
||||
std::vector<Node*> queue;
|
||||
for (size_t i = 1; i < len; i++) {
|
||||
Node* list = linkedList(points[i], false);
|
||||
if (list) {
|
||||
if (list == list->next) list->steiner = true;
|
||||
queue.push_back(getLeftmost(list));
|
||||
}
|
||||
}
|
||||
std::sort(queue.begin(), queue.end(), [](const Node* a, const Node* b) {
|
||||
return a->x < b->x;
|
||||
});
|
||||
|
||||
// process holes from left to right
|
||||
for (size_t i = 0; i < queue.size(); i++) {
|
||||
outerNode = eliminateHole(queue[i], outerNode);
|
||||
outerNode = filterPoints(outerNode, outerNode->next);
|
||||
}
|
||||
|
||||
return outerNode;
|
||||
}
|
||||
|
||||
// find a bridge between vertices that connects hole with an outer ring and and link it
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::eliminateHole(Node* hole, Node* outerNode) {
|
||||
Node* bridge = findHoleBridge(hole, outerNode);
|
||||
if (!bridge) {
|
||||
return outerNode;
|
||||
}
|
||||
|
||||
Node* bridgeReverse = splitPolygon(bridge, hole);
|
||||
|
||||
// filter collinear points around the cuts
|
||||
Node* filteredBridge = filterPoints(bridge, bridge->next);
|
||||
filterPoints(bridgeReverse, bridgeReverse->next);
|
||||
|
||||
// Check if input node was removed by the filtering
|
||||
return outerNode == bridge ? filteredBridge : outerNode;
|
||||
}
|
||||
|
||||
// David Eberly's algorithm for finding a bridge between hole and outer polygon
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::findHoleBridge(Node* hole, Node* outerNode) {
|
||||
Node* p = outerNode;
|
||||
double hx = hole->x;
|
||||
double hy = hole->y;
|
||||
double qx = -std::numeric_limits<double>::infinity();
|
||||
Node* m = nullptr;
|
||||
|
||||
// find a segment intersected by a ray from the hole's leftmost Vertex to the left;
|
||||
// segment's endpoint with lesser x will be potential connection Vertex
|
||||
do {
|
||||
if (hy <= p->y && hy >= p->next->y && p->next->y != p->y) {
|
||||
double x = p->x + (hy - p->y) * (p->next->x - p->x) / (p->next->y - p->y);
|
||||
if (x <= hx && x > qx) {
|
||||
qx = x;
|
||||
if (x == hx) {
|
||||
if (hy == p->y) return p;
|
||||
if (hy == p->next->y) return p->next;
|
||||
}
|
||||
m = p->x < p->next->x ? p : p->next;
|
||||
}
|
||||
}
|
||||
p = p->next;
|
||||
} while (p != outerNode);
|
||||
|
||||
if (!m) return 0;
|
||||
|
||||
if (hx == qx) return m; // hole touches outer segment; pick leftmost endpoint
|
||||
|
||||
// look for points inside the triangle of hole Vertex, segment intersection and endpoint;
|
||||
// if there are no points found, we have a valid connection;
|
||||
// otherwise choose the Vertex of the minimum angle with the ray as connection Vertex
|
||||
|
||||
const Node* stop = m;
|
||||
double tanMin = std::numeric_limits<double>::infinity();
|
||||
double tanCur = 0;
|
||||
|
||||
p = m;
|
||||
double mx = m->x;
|
||||
double my = m->y;
|
||||
|
||||
do {
|
||||
if (hx >= p->x && p->x >= mx && hx != p->x &&
|
||||
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p->x, p->y)) {
|
||||
|
||||
tanCur = std::abs(hy - p->y) / (hx - p->x); // tangential
|
||||
|
||||
if (locallyInside(p, hole) &&
|
||||
(tanCur < tanMin || (tanCur == tanMin && (p->x > m->x || sectorContainsSector(m, p))))) {
|
||||
m = p;
|
||||
tanMin = tanCur;
|
||||
}
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
} while (p != stop);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
// whether sector in vertex m contains sector in vertex p in the same coordinates
|
||||
template <typename N>
|
||||
bool Earcut<N>::sectorContainsSector(const Node* m, const Node* p) {
|
||||
return area(m->prev, m, p->prev) < 0 && area(p->next, m, m->next) < 0;
|
||||
}
|
||||
|
||||
// interlink polygon nodes in z-order
|
||||
template <typename N>
|
||||
void Earcut<N>::indexCurve(Node* start) {
|
||||
assert(start);
|
||||
Node* p = start;
|
||||
|
||||
do {
|
||||
p->z = p->z ? p->z : zOrder(p->x, p->y);
|
||||
p->prevZ = p->prev;
|
||||
p->nextZ = p->next;
|
||||
p = p->next;
|
||||
} while (p != start);
|
||||
|
||||
p->prevZ->nextZ = nullptr;
|
||||
p->prevZ = nullptr;
|
||||
|
||||
sortLinked(p);
|
||||
}
|
||||
|
||||
// Simon Tatham's linked list merge sort algorithm
|
||||
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::sortLinked(Node* list) {
|
||||
assert(list);
|
||||
Node* p;
|
||||
Node* q;
|
||||
Node* e;
|
||||
Node* tail;
|
||||
int i, numMerges, pSize, qSize;
|
||||
int inSize = 1;
|
||||
|
||||
for (;;) {
|
||||
p = list;
|
||||
list = nullptr;
|
||||
tail = nullptr;
|
||||
numMerges = 0;
|
||||
|
||||
while (p) {
|
||||
numMerges++;
|
||||
q = p;
|
||||
pSize = 0;
|
||||
for (i = 0; i < inSize; i++) {
|
||||
pSize++;
|
||||
q = q->nextZ;
|
||||
if (!q) break;
|
||||
}
|
||||
|
||||
qSize = inSize;
|
||||
|
||||
while (pSize > 0 || (qSize > 0 && q)) {
|
||||
|
||||
if (pSize == 0) {
|
||||
e = q;
|
||||
q = q->nextZ;
|
||||
qSize--;
|
||||
} else if (qSize == 0 || !q) {
|
||||
e = p;
|
||||
p = p->nextZ;
|
||||
pSize--;
|
||||
} else if (p->z <= q->z) {
|
||||
e = p;
|
||||
p = p->nextZ;
|
||||
pSize--;
|
||||
} else {
|
||||
e = q;
|
||||
q = q->nextZ;
|
||||
qSize--;
|
||||
}
|
||||
|
||||
if (tail) tail->nextZ = e;
|
||||
else list = e;
|
||||
|
||||
e->prevZ = tail;
|
||||
tail = e;
|
||||
}
|
||||
|
||||
p = q;
|
||||
}
|
||||
|
||||
tail->nextZ = nullptr;
|
||||
|
||||
if (numMerges <= 1) return list;
|
||||
|
||||
inSize *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// z-order of a Vertex given coords and size of the data bounding box
|
||||
template <typename N>
|
||||
int32_t Earcut<N>::zOrder(const double x_, const double y_) {
|
||||
// coords are transformed into non-negative 15-bit integer range
|
||||
int32_t x = static_cast<int32_t>(32767.0 * (x_ - minX) * inv_size);
|
||||
int32_t y = static_cast<int32_t>(32767.0 * (y_ - minY) * inv_size);
|
||||
|
||||
x = (x | (x << 8)) & 0x00FF00FF;
|
||||
x = (x | (x << 4)) & 0x0F0F0F0F;
|
||||
x = (x | (x << 2)) & 0x33333333;
|
||||
x = (x | (x << 1)) & 0x55555555;
|
||||
|
||||
y = (y | (y << 8)) & 0x00FF00FF;
|
||||
y = (y | (y << 4)) & 0x0F0F0F0F;
|
||||
y = (y | (y << 2)) & 0x33333333;
|
||||
y = (y | (y << 1)) & 0x55555555;
|
||||
|
||||
return x | (y << 1);
|
||||
}
|
||||
|
||||
// find the leftmost node of a polygon ring
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::getLeftmost(Node* start) {
|
||||
Node* p = start;
|
||||
Node* leftmost = start;
|
||||
do {
|
||||
if (p->x < leftmost->x || (p->x == leftmost->x && p->y < leftmost->y))
|
||||
leftmost = p;
|
||||
p = p->next;
|
||||
} while (p != start);
|
||||
|
||||
return leftmost;
|
||||
}
|
||||
|
||||
// check if a point lies within a convex triangle
|
||||
template <typename N>
|
||||
bool Earcut<N>::pointInTriangle(double ax, double ay, double bx, double by, double cx, double cy, double px, double py) const {
|
||||
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
|
||||
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
|
||||
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
|
||||
}
|
||||
|
||||
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
|
||||
template <typename N>
|
||||
bool Earcut<N>::isValidDiagonal(Node* a, Node* b) {
|
||||
return a->next->i != b->i && a->prev->i != b->i && !intersectsPolygon(a, b) && // dones't intersect other edges
|
||||
((locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
|
||||
(area(a->prev, a, b->prev) != 0.0 || area(a, b->prev, b) != 0.0)) || // does not create opposite-facing sectors
|
||||
(equals(a, b) && area(a->prev, a, a->next) > 0 && area(b->prev, b, b->next) > 0)); // special zero-length case
|
||||
}
|
||||
|
||||
// signed area of a triangle
|
||||
template <typename N>
|
||||
double Earcut<N>::area(const Node* p, const Node* q, const Node* r) const {
|
||||
return (q->y - p->y) * (r->x - q->x) - (q->x - p->x) * (r->y - q->y);
|
||||
}
|
||||
|
||||
// check if two points are equal
|
||||
template <typename N>
|
||||
bool Earcut<N>::equals(const Node* p1, const Node* p2) {
|
||||
return p1->x == p2->x && p1->y == p2->y;
|
||||
}
|
||||
|
||||
// check if two segments intersect
|
||||
template <typename N>
|
||||
bool Earcut<N>::intersects(const Node* p1, const Node* q1, const Node* p2, const Node* q2) {
|
||||
int o1 = sign(area(p1, q1, p2));
|
||||
int o2 = sign(area(p1, q1, q2));
|
||||
int o3 = sign(area(p2, q2, p1));
|
||||
int o4 = sign(area(p2, q2, q1));
|
||||
|
||||
if (o1 != o2 && o3 != o4) return true; // general case
|
||||
|
||||
if (o1 == 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
|
||||
if (o2 == 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
|
||||
if (o3 == 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
|
||||
if (o4 == 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// for collinear points p, q, r, check if point q lies on segment pr
|
||||
template <typename N>
|
||||
bool Earcut<N>::onSegment(const Node* p, const Node* q, const Node* r) {
|
||||
return q->x <= std::max<double>(p->x, r->x) &&
|
||||
q->x >= std::min<double>(p->x, r->x) &&
|
||||
q->y <= std::max<double>(p->y, r->y) &&
|
||||
q->y >= std::min<double>(p->y, r->y);
|
||||
}
|
||||
|
||||
template <typename N>
|
||||
int Earcut<N>::sign(double val) {
|
||||
return (0.0 < val) - (val < 0.0);
|
||||
}
|
||||
|
||||
// check if a polygon diagonal intersects any polygon segments
|
||||
template <typename N>
|
||||
bool Earcut<N>::intersectsPolygon(const Node* a, const Node* b) {
|
||||
const Node* p = a;
|
||||
do {
|
||||
if (p->i != a->i && p->next->i != a->i && p->i != b->i && p->next->i != b->i &&
|
||||
intersects(p, p->next, a, b)) return true;
|
||||
p = p->next;
|
||||
} while (p != a);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if a polygon diagonal is locally inside the polygon
|
||||
template <typename N>
|
||||
bool Earcut<N>::locallyInside(const Node* a, const Node* b) {
|
||||
return area(a->prev, a, a->next) < 0 ?
|
||||
area(a, b, a->next) >= 0 && area(a, a->prev, b) >= 0 :
|
||||
area(a, b, a->prev) < 0 || area(a, a->next, b) < 0;
|
||||
}
|
||||
|
||||
// check if the middle Vertex of a polygon diagonal is inside the polygon
|
||||
template <typename N>
|
||||
bool Earcut<N>::middleInside(const Node* a, const Node* b) {
|
||||
const Node* p = a;
|
||||
bool inside = false;
|
||||
double px = (a->x + b->x) / 2;
|
||||
double py = (a->y + b->y) / 2;
|
||||
do {
|
||||
if (((p->y > py) != (p->next->y > py)) && p->next->y != p->y &&
|
||||
(px < (p->next->x - p->x) * (py - p->y) / (p->next->y - p->y) + p->x))
|
||||
inside = !inside;
|
||||
p = p->next;
|
||||
} while (p != a);
|
||||
|
||||
return inside;
|
||||
}
|
||||
|
||||
// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits
|
||||
// polygon into two; if one belongs to the outer ring and another to a hole, it merges it into a
|
||||
// single ring
|
||||
template <typename N>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::splitPolygon(Node* a, Node* b) {
|
||||
Node* a2 = nodes.construct(a->i, a->x, a->y);
|
||||
Node* b2 = nodes.construct(b->i, b->x, b->y);
|
||||
Node* an = a->next;
|
||||
Node* bp = b->prev;
|
||||
|
||||
a->next = b;
|
||||
b->prev = a;
|
||||
|
||||
a2->next = an;
|
||||
an->prev = a2;
|
||||
|
||||
b2->next = a2;
|
||||
a2->prev = b2;
|
||||
|
||||
bp->next = b2;
|
||||
b2->prev = bp;
|
||||
|
||||
return b2;
|
||||
}
|
||||
|
||||
// create a node and util::optionally link it with previous one (in a circular doubly linked list)
|
||||
template <typename N> template <typename Point>
|
||||
typename Earcut<N>::Node*
|
||||
Earcut<N>::insertNode(std::size_t i, const Point& pt, Node* last) {
|
||||
Node* p = nodes.construct(static_cast<N>(i), util::nth<0, Point>::get(pt), util::nth<1, Point>::get(pt));
|
||||
|
||||
if (!last) {
|
||||
p->prev = p;
|
||||
p->next = p;
|
||||
|
||||
} else {
|
||||
assert(last);
|
||||
p->next = last->next;
|
||||
p->prev = last;
|
||||
last->next->prev = p;
|
||||
last->next = p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename N>
|
||||
void Earcut<N>::removeNode(Node* p) {
|
||||
p->next->prev = p->prev;
|
||||
p->prev->next = p->next;
|
||||
|
||||
if (p->prevZ) p->prevZ->nextZ = p->nextZ;
|
||||
if (p->nextZ) p->nextZ->prevZ = p->prevZ;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename N = uint32_t, typename Polygon>
|
||||
std::vector<N> earcut(const Polygon& poly) {
|
||||
mapbox::detail::Earcut<N> earcut;
|
||||
earcut(poly);
|
||||
return std::move(earcut.indices);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user