Compare commits

..

72 Commits

Author SHA1 Message Date
Daniele Bariletti 466f92384b EgtGeomKernel :
- aggiunta dipendenza header
- aggiornata cartella header.
2025-09-29 09:17:20 +02:00
Daniele Bariletti 326f85c3d2 Merge branch 'master' into abseil 2025-09-26 12:56:07 +02:00
Daniele Bariletti 00b6f8583a EgtGeomKernel :
- piccola correzione.
2025-09-26 12:48:48 +02:00
Daniele Bariletti 4cf4a99107 EgtGeomKernel :
- puliza codice.
2025-09-26 12:10:18 +02:00
Daniele Bariletti 137289e843 EgtGeomKernel :
- correzione del merge.
2025-09-26 11:00:20 +02:00
Daniele Bariletti e7b066e75e Merge branch 'FasterVMill5Axis_Bez3x1' 2025-09-26 10:49:41 +02:00
Daniele Bariletti cd0828f3e0 Merge branch 'master' into FasterVMill5Axis_Bez3x1 2025-09-26 10:49:25 +02:00
Daniele Bariletti 563697f840 EgtGeomKernel :
- correzione al box del volume spazzato VM 5assi
- modificata gestione conversione curve a bezier.
2025-09-26 10:47:06 +02:00
Dario Sassi 61fc814528 EgtGeomKernel :
- piccola modifica per migliorare ricerca di inizio con stringa (starts_with).
2025-09-24 17:19:37 +02:00
Dario Sassi 7c90dbabea EgtGeomKernel 2.7i6 :
- ricompilazione con cambio versione (e abilitato multithread in MillingGeneralMotionStep).
2025-09-24 10:38:35 +02:00
Daniele Bariletti 5ee0f3c373 Merge branch 'master' into FasterVMill5Axis_Bez3x1 2025-09-24 10:30:21 +02:00
Daniele Bariletti 098bdd0076 EgtGeomKernel :
- semplificazione VM5assi.
2025-09-24 10:29:57 +02:00
Daniele Bariletti 40b6da6b44 EgtGeomKernel :
- correzione selezione caso VM5assi.
2025-09-24 09:46:02 +02:00
Daniele Bariletti b083dabc6b EgtGeomKernel :
- correzione piccolo errore
2025-09-24 09:35:52 +02:00
Daniele Bariletti 7fcc3ed42d Merge branch 'master' into FasterVMill5Axis_Bez3x1 2025-09-24 09:10:54 +02:00
Daniele Bariletti ccefe1314f EgtGeomKernel :
- aggiunta libreria abseil.
2025-09-23 09:47:38 +02:00
Dario Sassi 4ed362f226 EgtGeomKernel 2.7i5 :
- ritorno alla vecchia modalità per virtual milling a 5 assi
- piccoli aggiustamenti soprattutto estetici.
2025-09-22 18:59:27 +02:00
Dario Sassi 39d98f79fb EgtGeomKernel :
- migliorie e correzioni per creazione Zmap da trimesh e riconoscimento box.
2025-09-19 11:13:22 +02:00
Dario Sassi c79f7ba245 EgtGeomKernel 2.7i4 :
- eliminato memory leak in ArcToBezierCurve
- altre piccole modifiche stilistiche.
2025-09-18 19:11:59 +02:00
Dario Sassi 16354ff435 EgtGeomKernel :
- piccola correzione (seno non coseno).
2025-09-18 08:43:22 +02:00
Daniele Bariletti f3a191dd62 EgtGeomKernel :
- modificato valore di soglia per angolo di intersezione tra spillone e trimesh nella costruzione di una Zmap.
2025-09-17 15:38:44 +02:00
Daniele Bariletti cb0a5092fb Merge branch 'master' of https://gitlab.steamware.net/egalware-cadcam/libreriebase/EgtGeomKernel 2025-09-16 14:35:53 +02:00
Daniele Bariletti 8730f55308 EgtGeomKernel :
- correzione valore di default   di ingrandimento box per la costruzione VolZmap da trimesh.
2025-09-16 14:35:47 +02:00
Daniele Bariletti 932e98d19c EgtGeomKernel :
- correzione alla creazione di un VolZmap da trimesh.
2025-09-16 14:32:36 +02:00
Riccardo Elitropi 3a69dcfa79 EgtGeomKernel (2.7i3) :
- Aggiunta funzione in DistPointSurfTm per ottenere i triangoli a minima distanza
- Aggiunte funzioni per Offset Fillet di VolZmap e per Offset generici di superfici TriMesh aperte.
2025-09-12 17:01:14 +02:00
Daniele Bariletti 5930674d4a EgtGeomKernel :
- correzione alla chiamata della ArcToBezierCurve.
2025-09-12 16:12:43 +02:00
Daniele Bariletti df6b20d97f EgtGeomKernel :
- correzioni alle chiamate della ArcToBezierCurve.
2025-09-12 16:02:55 +02:00
Daniele Bariletti 4200af5296 Merge branch 'FasterVMill5Axis_Bez3x1' 2025-09-12 15:42:44 +02:00
Daniele Bariletti b0c9c5be2e EgtGeomKernel :
- aggiornate le funzioni per la conversione di curve in/da bezier.
2025-09-12 15:40:39 +02:00
Daniele Bariletti f2bb1deac4 Merge branch 'master' into FasterVMill5Axis_Bez3x1 2025-09-12 15:12:05 +02:00
Daniele Bariletti 94ec83aa60 EgtGeomKernel :
- pulizia avvisi compilatore.
2025-09-12 15:11:30 +02:00
Daniele Bariletti e183eec3ea EgtGeomKernel :
- puliza codice.
2025-09-12 15:07:18 +02:00
Daniele Bariletti b179771ec9 EgtGeomKernel :
- pulizia codice.
2025-09-12 15:02:15 +02:00
Daniele Bariletti d7380a09c1 EgtGeomKernel :
- correzioni e ottimizzazioni al VM 5 assi 3x1.
2025-09-12 09:02:39 +02:00
Dario Sassi afc316cd1d EgtGeomKernel 2.7i2 :
- aggiunta funzione globale SetDefaultFont.
2025-09-11 15:21:51 +02:00
Riccardo Elitropi b6f820258a EgtGeomKernel :
- piccola correzione In Invert per SurfTriMesh.
2025-09-11 09:30:08 +02:00
Daniele Bariletti 116b605cb1 EgtGeomKernel :
- correzioni e migliorie al VM 5 assi 3x1.
2025-09-10 17:59:43 +02:00
Daniele Bariletti 9f5ce42393 EgtGeomKernel :
- aggiornamento dell'enum per le intersezioni linea bezier.
2025-09-10 09:48:36 +02:00
Daniele Bariletti 9716d93c15 Merge branch 'master' into FasterVMill5Axis_Bez3x1. 2025-09-09 14:58:35 +02:00
Daniele Bariletti 3465179379 EgtGeomKernel :
- debug.
2025-09-09 14:47:37 +02:00
Dario Sassi c7aad8d917 EgtGeomKernel :
- piccole migliorie e correzioni.
2025-09-09 09:12:53 +02:00
SaraP 8ddc1c70e1 EgtGeomKernel :
- ripristinata AssociatePolyLinesMinDistPoints ( la modifica è stata spostata nell'executor solo per associazione nel caso di spiralize della curva).
2025-09-08 17:32:46 +02:00
Daniele Bariletti 5230261be8 EgtGeomKernel :
- aggiunta funzione per l'accoppiamento di punti di due polyline.
2025-09-08 17:21:16 +02:00
Daniele Bariletti 8cc8d6eb03 EgtGeomKernel :
- aggiunta funzione per l'accoppiamento di punti di due polyline.
2025-09-08 17:19:23 +02:00
Riccardo Elitropi 7a95e4c5a3 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2025-09-08 16:51:20 +02:00
Riccardo Elitropi 1c0f182bbc EgtGeomKernel :
- correzione controllo indici per AddIntervals su VolZmap.
2025-09-08 16:51:11 +02:00
SaraP 736e20e599 EgtGeomKernel :
- nell'associare i punti a minima distanza delle polylines aggiuta gestione speciale per gli spigoli.
2025-09-08 15:21:27 +02:00
Daniele Bariletti c71c8e8c12 EgtGeomKernel :
- miglioria per il VM 5 assi: riduco i tagli inutili.
2025-09-08 12:25:54 +02:00
Dario Sassi 9c7a29f939 EgtGeomKernel :
- piccola miglioria.
2025-09-08 11:02:08 +02:00
Riccardo Elitropi 40bb15e46b EgtGeomKernel :
- Aggiunta gestione Offset Thickening per superfici TriMesh
- Aggiunta gestione Offset Chamfer ed Extend per superfici TriMesh.
2025-09-05 17:01:59 +02:00
Daniele Bariletti fb957b61d2 Merge branch 'master' of https://gitlab.steamware.net/egalware-cadcam/libreriebase/EgtGeomKernel 2025-09-05 10:03:31 +02:00
Daniele Bariletti 4da9dcb062 EgtGeomKernel :
- aggiunto limite per la divisione del parametrico di una bezier.
2025-09-05 10:03:25 +02:00
Dario Sassi 60f9302c3f EgtGeomKernel 2.7i1 :
- ricompilazione con cambio versione.
2025-09-04 19:35:29 +02:00
Daniele Bariletti 2553f15e7b EgtGeomKernel :
- uniformazione delle funzioni per l'approssimazione curve con bezier.

(cherry picked from commit 05c0b0a18b)
(cherry picked from commit 6f1f3441ea)
2025-09-04 15:08:52 +02:00
Daniele Bariletti e8d31f2020 EgtGeomKernel :
- piccola correzione.
2025-09-04 12:55:54 +02:00
Daniele Bariletti 4c693ccd60 EgtGeomkernel :
- aggiunta intersezione linea - superficie bezier bilineare.
2025-09-04 12:43:50 +02:00
Daniele Bariletti c550fb1848 EgtGeomKernel :
- piccoli aggiustamenti.
2025-09-04 12:43:16 +02:00
Daniele Bariletti e49bd5a2a0 EgtGeonKernel :
- correzioni a VM5 assi con bezier 3x1.
2025-09-02 12:51:39 +02:00
Daniele Bariletti 81be6ce7b9 EgtGeomKernel :
- correzioni al VM 5 assi con bezier 3x1.
2025-09-01 14:54:30 +02:00
Dario Sassi 2d6bf3d9dc EgtGeomKernel :
- piccole migliorie a curve e superfici di Bezier.
2025-08-30 10:51:48 +02:00
Dario Sassi b2244b7f43 EgtGeomKernel :
- ricuperate correzioni di Daniele sugli include.
2025-08-29 20:14:27 +02:00
Dario Sassi 53dcd9c863 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2025-08-29 19:53:34 +02:00
Dario Sassi 75f70d2b30 EgtGeomKernel 2.7h2 :
- piccola miglioria in proiezione curve su superfici di Bezier.
2025-08-29 19:52:13 +02:00
Daniele Bariletti 36b1df1a27 EgtGeomKernel :
- correzione al merge.
2025-08-29 08:50:00 +02:00
Daniele Bariletti 5a445c5c0b Merge remote-tracking branch 'origin/master' into FasterVMill5Axis_Bez3x1 2025-08-28 16:12:59 +02:00
Daniele Bariletti db855ca99b EgtGeomKernel :
- correzione per il caso no_base_inters in VM5 assi 3x1.
2025-08-28 13:04:10 +02:00
Daniele Bariletti d79cb50aca EgtGeomKernel :
- tolto l'uso di namespace std dagli header.

(cherry picked from commit 704a977475)
2025-08-28 10:12:17 +02:00
Daniele Bariletti df7b4ff81f EgtGeomKernel :
- correzioni e miglioramenti per il VM5assi con superfici bezier di grado 3x1.
2025-08-22 12:34:52 +02:00
Daniele Bariletti 574041cf18 EgtGeomKernel :
- aggiunta funzione per restituire tutti i punti di controllo di una surf di bezier.
2025-08-22 09:41:13 +02:00
Daniele Bariletti ff2cc4f999 EgtGeomKernel :
- prima versione del VM5 assi con superfici di bezier 3x1.
2025-08-07 11:22:43 +02:00
Daniele Bariletti 05c0b0a18b EgtGeomKernel :
- uniformazione delle funzioni per l'approssimazione curve con bezier.
2025-08-07 11:22:20 +02:00
Daniele Bariletti 8ee5bc74d5 EgtGeomKernel :
- aggiunta e miglioramento funzioni per la gesitone di curve bezier.
2025-08-04 09:56:48 +02:00
27 changed files with 3955 additions and 1752 deletions
+71 -61
View File
@@ -513,10 +513,9 @@ CurveToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
//----------------------------------------------------------------------------
ICurveBezier*
LineToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
LineToBezierCurve( const ICurveLine* pCrvLine, int nDeg, bool bMakeRatOrNot)
{
// verifico sia una linea
const CurveLine* pCrvLine = GetBasicCurveLine( pCrv) ;
// verifico che esista la linea
if ( pCrvLine == nullptr)
return nullptr ;
@@ -531,12 +530,11 @@ LineToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
//----------------------------------------------------------------------------
ICurve*
ArcToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
ArcToBezierCurve( const ICurveArc* pArc, int nDeg, bool bMakeRatOrNot)
{
// una spirale non può essere forzata al grado 2
// verifico sia un arco
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
// verifico che esista l'arco
if ( pArc == nullptr)
return nullptr ;
@@ -546,8 +544,15 @@ ArcToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
PtrOwner<ICurveBezier> pCrvBez( CreateBasicCurveBezier()) ;
if ( IsNull( pCrvBez) || ! pCrvBez->FromArc( *pArc))
return nullptr ;
if ( ! bMakeRatOrNot) {
Point3d ptCen = pArc->GetCenter() ;
Vector3d vtN = pArc->GetNormVersor() ;
pCrvBez.Set( ApproxArcCurveBezierWithSingleCubic( pCrvBez, ptCen, vtN)) ;
}
if ( IsNull( pCrvBez))
return nullptr ;
// aumento il grado della curva come richiesto
while( pCrvBez->GetDegree() < nDeg)
while ( pCrvBez->GetDegree() < nDeg)
pCrvBez.Set( BezierIncreaseDegree( pCrvBez)) ;
// restituisco la curva
return Release( pCrvBez) ;
@@ -560,20 +565,18 @@ ArcToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
return nullptr ;
// inserisco nella CC le curve di Bezier equivalenti alle parti dell'arco
int nParts = (int) ceil( abs( pArc->GetAngCenter()) / ( BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL)) ;
//if ( ! bDeg3OrDeg2 && abs( pArc->GetDeltaN()) > EPS_ZERO)
// nParts *= 2 ;
nParts = max( nParts, 2) ;
for ( int i = 0 ; i < nParts ; ++ i) {
// copio l'arco originale
CurveArc cArc = *GetBasicCurveArc(pArc->Clone()) ;
CurveArc cArc = *GetBasicCurveArc( pArc) ;
// lo limito alla parte di interesse
cArc.TrimStartEndAtParam( i / double( nParts), ( i + 1) / double( nParts)) ;
cArc.TrimStartEndAtParam( double( i) / nParts, double( i + 1) / nParts) ;
// creo la curva di Bezier equivalente
PtrOwner<ICurveBezier> pCrvBez( CreateBasicCurveBezier()) ;
if ( IsNull( pCrvBez) || ! pCrvBez->FromArc( cArc))
return nullptr ;
// aumento il grado della curva come richiesto
while( pCrvBez->GetDegree() < nDeg)
while ( pCrvBez->GetDegree() < nDeg)
pCrvBez.Set( BezierIncreaseDegree( pCrvBez)) ;
// aggiungo la curva di Bezier a quella composita
if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
@@ -589,14 +592,13 @@ ArcToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
//----------------------------------------------------------------------------
ICurve*
CompositeToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
CompositeToBezierCurve( const ICurveComposite* pCC, int nDeg, bool bMakeRatOrNot)
{
// verifico sia una composita
const CurveComposite* pCC = GetBasicCurveComposite( pCrv) ;
// verifico che esista la curva
if ( pCC == nullptr)
return nullptr ;
// converto tutte le curve in bezier razionali di grado 2
// converto tutte le curve in bezier razionali di grado 2
PtrOwner<ICurveComposite> pCCBezier( CreateCurveComposite()) ;
for ( int i = 0 ; i < int( pCC->GetCurveCount()) ; ++i) {
PtrOwner<ICurve> pCrvNew ;
@@ -605,7 +607,7 @@ CompositeToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
ICurve* pCrvBezier = ArcToBezierCurve( crArc) ;
if ( pCrvBezier == nullptr)
return nullptr ;
// se la curva è di grado superiore al secondo allora devo ricondurla al secondo grado
// se la curva è di grado superiore al secondo allora devo ricondurla al secondo grado
pCrvNew.Set( pCrvBezier) ;
}
else if ( pCC->GetCurve(i)->GetType() == CRV_LINE) {
@@ -630,34 +632,32 @@ CompositeToBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot)
//----------------------------------------------------------------------------
ICurve*
EditBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot, double dTol)
EditBezierCurve( const ICurveBezier* pCrvBezier, int nDeg, bool bMakeRatOrNot, double dTol)
{
// se nDeg == -1 allora viene mantenuto il grado della curva originale
// verifico sia una bezier
const CurveBezier* pCrvBezier = GetBasicCurveBezier( pCrv) ;
// verifico sia una bezier
if ( pCrvBezier == nullptr)
return nullptr ;
if( nDeg == 2 || nDeg == 1)
if ( nDeg == 2 || nDeg == 1)
return nullptr ;
PtrOwner<ICurveBezier> pCrvNew( pCrvBezier->Clone()) ;
int nDegCurr = pCrvNew->GetDegree() ;
bool bRat = pCrvNew->IsRational() ;
int nDegWanted = nDeg == -1 ? nDegCurr : nDeg ;
if( ! bMakeRatOrNot) {
if( ! pCrvNew->MakeNonRational( dTol)) {
if ( ! bMakeRatOrNot) {
if ( ! pCrvNew->MakeNonRational( dTol)) {
// se ho fallito la conversione diretta in curva non razionale allora la spezzo in bezier cubiche
PtrOwner<ICurveComposite> pBezCubics( CreateCurveComposite()) ;
pBezCubics->AddCurve( ApproxBezierWithCubics(pCrvBezier, dTol)) ;
if( IsNull( pBezCubics))
if ( IsNull( pBezCubics))
return nullptr ;
// adatto ogni sottocurva cubica
PtrOwner<ICurveComposite> pCCEdited( CreateCurveComposite()) ;
for ( int i = 0 ; i < pBezCubics->GetCurveCount() ; ++i) {
if( ! pCCEdited->AddCurve( EditBezierCurve( GetCurveBezier( pBezCubics->GetCurve( i)), nDegWanted, bMakeRatOrNot, dTol)) )
if ( ! pCCEdited->AddCurve( EditBezierCurve( GetCurveBezier( pBezCubics->GetCurve( i)), nDegWanted, bMakeRatOrNot, dTol)) )
return nullptr ;
}
return Release( pCCEdited) ;
@@ -676,7 +676,7 @@ EditBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot, double dTol)
else if ( nDegCurr > nDegWanted) {
while ( nDegCurr > nDegWanted) {
ICurveBezier* pCrvDec = BezierDecreaseDegree( pCrvNew, dTol) ;
if( pCrvDec == nullptr || ! pCrvDec->IsValid()) {
if ( pCrvDec == nullptr || ! pCrvDec->IsValid()) {
// se ho fallito la riduzione di grado entro la tolleranza richiesta allora la spezzo in bezier cubiche prima di adattare
PtrOwner<ICurveComposite> pBezCubics( CreateCurveComposite()) ;
pBezCubics->AddCurve( ApproxBezierWithCubics(pCrvBezier, dTol)) ;
@@ -702,20 +702,22 @@ EditBezierCurve( const ICurve* pCrv, int nDeg, bool bMakeRatOrNot, double dTol)
//----------------------------------------------------------------------------
ICurveBezier*
BezierIncreaseDegree(const ICurveBezier* pCrvBezier)
BezierIncreaseDegree( const ICurveBezier* pCrvBezier)
{
if ( pCrvBezier == nullptr)
return nullptr ;
// creo la versione con grado aumentato
// creo la versione con grado aumentato
PtrOwner<ICurveBezier> pNewBezier( CreateCurveBezier()) ;
int nDeg = pCrvBezier->GetDegree() + 1;
bool bRat = pCrvBezier->IsRational();
pNewBezier->Init( nDeg , bRat) ;
// prev e curr sono riferiti alla curva di partenza
// salvo il primo punto
if ( IsNull( pNewBezier))
return nullptr ;
int nDeg = pCrvBezier->GetDegree() + 1 ;
bool bRat = pCrvBezier->IsRational() ;
pNewBezier->Init( nDeg, bRat) ;
// prev e curr sono riferiti alla curva di partenza
// salvo il primo punto
Point3d ptCtrlPrev = pCrvBezier->GetControlPoint( 0) ;
double dWprev = 1 ;
if ( bRat ) {
if ( bRat) {
dWprev = pCrvBezier->GetControlWeight( 0) ;
pNewBezier->SetControlPoint( 0, ptCtrlPrev, dWprev) ;
}
@@ -724,26 +726,26 @@ BezierIncreaseDegree(const ICurveBezier* pCrvBezier)
// ciclo sui punti di controllo intermedi per calcolare quelli nuovi
Point3d ptCtrlCurr ;
double dWcurr ;
for ( double i = 1 ; i < nDeg ; ++i) {
ptCtrlCurr = pCrvBezier->GetControlPoint( int( i)) ;
double dAlpha = i / nDeg ;
for ( int i = 1 ; i < nDeg ; ++i) {
ptCtrlCurr = pCrvBezier->GetControlPoint( i) ;
double dAlpha = double( i) / nDeg ;
if ( bRat) {
dWcurr = pCrvBezier->GetControlWeight( int( i)) ;
dWcurr = pCrvBezier->GetControlWeight( i) ;
double dWnew = dAlpha * dWprev + ( 1 - dAlpha) * dWcurr ;
Point3d ptNew = dAlpha * ptCtrlPrev * dWprev + ( 1 - dAlpha) * ptCtrlCurr * dWcurr;
ptNew /= dWnew ;
pNewBezier->SetControlPoint( int( i), ptNew, dWnew) ;
pNewBezier->SetControlPoint( i, ptNew, dWnew) ;
dWprev = dWcurr ;
}
else {
Point3d ptNew = dAlpha * ptCtrlPrev + ( 1 - dAlpha) * ptCtrlCurr ;
pNewBezier->SetControlPoint( int( i), ptNew) ;
pNewBezier->SetControlPoint( i, ptNew) ;
}
ptCtrlPrev = ptCtrlCurr ;
}
// salvo l'ultimo punto
ptCtrlCurr = pCrvBezier->GetControlPoint( nDeg - 1) ;
if ( bRat ) {
if ( bRat) {
dWcurr = pCrvBezier->GetControlWeight( nDeg - 1) ;
pNewBezier->SetControlPoint( nDeg, ptCtrlCurr, dWcurr) ;
}
@@ -931,10 +933,8 @@ ApproxBezierWithCubics(const ICurve* pCrv, double dTol)
Vector3d vtStartDir, vtEndDir ;
pCrvBezier->GetPointD1D2( 0, ICurve::FROM_MINUS, ptStart, &vtStartDir) ;
pCrvBezier->GetPointD1D2( 1, ICurve::FROM_PLUS, ptEnd, &vtEndDir) ;
Plane3d plPLane ;
plPLane.Set( ptStart, ptCtrl, ptEnd) ;
vtStartDir.Rotate( plPLane.GetVersN(), 90) ;
vtEndDir.Rotate( plPLane.GetVersN(), 90) ;
vtStartDir.Rotate( vtN, 90) ;
vtEndDir.Rotate( vtN, 90) ;
Point3d ptAux1 = ptStart + vtStartDir ;
Point3d ptAux2 = ptEnd + vtEndDir ;
PtrOwner<CurveLine> pCL1( CreateBasicCurveLine()) ;
@@ -949,7 +949,7 @@ ApproxBezierWithCubics(const ICurve* pCrv, double dTol)
double dDist2 = Dist( ptEnd, ptCen) ;
if ( abs(dDist1 - dDist2) < EPS_SMALL ) {
CurveArc cArc ;
cArc.SetC2PN( ptCen, ptStart, ptEnd, plPLane.GetVersN()) ;
cArc.SetC2PN( ptCen, ptStart, ptEnd, vtN) ;
// controllo se il raggio della circonferenza risultante coincide con quello calcolato prima
// impongo inoltre che l'angolo al centro sia minore di 90 gradi
if ( abs( cArc.GetRadius() - dDist1) < EPS_SMALL && cArc.GetAngCenter() < 90 + EPS_SMALL)
@@ -993,7 +993,7 @@ ApproxBezierWithCubics(const ICurve* pCrv, double dTol)
if ( ! bIsArc)
pCrvCubic.Set( ApproxCurveBezierWithSingleCubic( pCrvPart)) ;
else {
pCrvCubic.Set( ApproxArcCurveBezierWithSingleCubic( pCrvPart, ptCen)) ;
pCrvCubic.Set( ApproxArcCurveBezierWithSingleCubic( pCrvPart, ptCen, vtN)) ;
if ( IsNull( pCrvCubic)) {
// se fallisce allora riprovo usando più di una bezier
bIsArc = false ;
@@ -1067,12 +1067,21 @@ ApproxCurveBezierWithSingleCubic( const ICurve* pCrv)
//----------------------------------------------------------------------------
ICurveBezier*
ApproxArcCurveBezierWithSingleCubic( const ICurve* pCrv, const Point3d& ptCen)
ApproxArcCurveBezierWithSingleCubic( const ICurve* pCrv, const Point3d& ptCen, const Vector3d& vtN)
{
// verifico sia una bezier
const CurveBezier* pCrvBez = GetBasicCurveBezier( pCrv) ;
if ( pCrvBez == nullptr)
return nullptr ;
// verifico sia una bezier
const CurveBezier* pCrvBez = GetBasicCurveBezier( pCrv) ;
if ( pCrvBez == nullptr)
return nullptr ;
// mi metto nel frame della curva ( lavoro nel piano XY)
Point3d ptStart = pCrvBez->GetControlPoint( 0) ;
Point3d ptEnd = pCrvBez->GetControlPoint( 2) ;
Frame3d frCrv; frCrv.Set( ptStart, vtN) ;
ptStart = ORIG ;
ptEnd.ToLoc( frCrv) ;
Point3d ptCenLoc = ptCen ;
ptCenLoc.ToLoc( frCrv) ;
// converto una curva di bezier che definisce un arco perfetto di circonferenza
// dato il centro( della circonferenza), inizio e fine
@@ -1082,9 +1091,7 @@ ApproxArcCurveBezierWithSingleCubic( const ICurve* pCrv, const Point3d& ptCen)
bool bRat = pCrvBez->IsRational() ;
if ( nDeg != 2 || ! bRat)
return nullptr ;
Point3d ptStart = pCrvBez->GetControlPoint( 0) ;
Point3d ptEnd = pCrvBez->GetControlPoint( 2) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, EPS_SMALL * 50))
return nullptr ;
nDeg = 3 ;
@@ -1094,10 +1101,10 @@ ApproxArcCurveBezierWithSingleCubic( const ICurve* pCrv, const Point3d& ptCen)
pCrvCubic->SetControlPoint( 3, ptEnd) ;
// from the article of Aleksas Riškus "Approximation of a cubic bezier curve by circular arcs and vice versa"
// with corrections from "Hans Muller's Flex Blog", page "More About Approximating Circular Arcs With a Cubic Bezier Path"
double ax = ptStart.x - ptCen.x ;
double ay = ptStart.y - ptCen.y ;
double bx = ptEnd.x - ptCen.x ;
double by = ptEnd.y - ptCen.y ;
double ax = ptStart.x - ptCenLoc.x ;
double ay = ptStart.y - ptCenLoc.y ;
double bx = ptEnd.x - ptCenLoc.x ;
double by = ptEnd.y - ptCenLoc.y ;
double q1 = ax * ax + ay * ay ;
double q2 = q1 + ax * bx + ay * by ;
double k2 = 4. / 3 * ( sqrt( 2 * q1 * q2) - q2) / ( ax * by - ay * bx) ;
@@ -1109,6 +1116,9 @@ ApproxArcCurveBezierWithSingleCubic( const ICurve* pCrv, const Point3d& ptCen)
pCrvCubic->SetControlPoint( 1, ptCtrl1) ;
pCrvCubic->SetControlPoint( 2, ptCtrl2) ;
// ritorno nel frame originale
pCrvCubic->ToGlob( frCrv) ;
return Release( pCrvCubic) ;
}
@@ -1294,7 +1304,7 @@ CurveToNoArcsCurve( const ICurve* pCrv)
return nullptr ;
// se arco, devo trasformarlo in curva di Bezier (semplice o composta)
if ( pCrv->GetType() == CRV_ARC) {
return ArcToBezierCurve( GetCurveArc(pCrv)) ;
return ArcToBezierCurve( GetCurveArc( pCrv)) ;
}
// se curva composita, devo trasformarla in composita senza archi
else if ( pCrv->GetType() == CRV_COMPO) {
+1
View File
@@ -369,6 +369,7 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
return true ;
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
return false ;
m_dParSing = cbSrc.m_dParSing ;
m_vPtCtrl = cbSrc.m_vPtCtrl ;
if ( cbSrc.m_bRat)
m_vWeCtrl = cbSrc.m_vWeCtrl ;
+1 -1
View File
@@ -3046,7 +3046,7 @@ CurveComposite::ArcsToBezierCurves( void)
// se arco, devo trasformare in una o più curve di Bezier
if ( (*Iter)->GetType() == CRV_ARC) {
// eseguo trasformazione
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( (*Iter))) ;
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( GetCurveArc( *Iter))) ;
if ( IsNull( pNewCrv))
return false ;
// se risultato è singola curva
+18
View File
@@ -94,6 +94,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
{
// Inizializzo distanza non calcolata
m_dDist = - 1. ;
// Vettore di indici dei triangoli più vicini inizialmente vuoto
m_vnMinDistTriaIndex.clear() ;
// Controllo se la superficie è chiusa
m_bIsSurfClosed = tmSurf.IsClosed() ;
@@ -184,6 +186,10 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
if ( nMinDistTriaIndex == SVT_NULL)
return ;
// Inizializzo il vettore dei triangoli a minima distanza
for ( auto& Tria : vTria)
m_vnMinDistTriaIndex.emplace_back( Tria.first) ;
// salvo la distanza minima
m_dDist = dMinDist ;
// salvo il punto a distanza minima
@@ -279,6 +285,18 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) const
return true ;
}
//----------------------------------------------------------------------------
bool
DistPointSurfTm::GetMinDistTriaIndices( INTVECTOR& vMinDistTriaIndex) const
{
// Distanza non valida
if ( m_dDist < - EPS_ZERO)
return false ;
// Distanza valida
vMinDistTriaIndex = m_vnMinDistTriaIndex ;
return true ;
}
//----------------------------------------------------------------------------
int
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
+10 -1
View File
@@ -159,11 +159,20 @@ InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
{
// recupero il font manager
FontManager& fntMgr = FontManager::GetFontManager() ;
// lo inizializzo
fntMgr.Init( sNfeFontDir, sDefaultFont) ;
}
//-----------------------------------------------------------------------------
void
SetDefaultFont( const string& sDefaultFont)
{
// recupero il font manager
FontManager& fntMgr = FontManager::GetFontManager() ;
// imposto il dato
fntMgr.SetDefaultFont( sDefaultFont) ;
}
//-----------------------------------------------------------------------------
const string&
GetNfeFontDir( void)
BIN
View File
Binary file not shown.
+1
View File
@@ -117,6 +117,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>false</EnablePREfast>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>C:\EgtDev\Extern\abseil\Include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
+3 -1
View File
@@ -29,6 +29,8 @@ class FontManager
public :
bool Init( const std::string& sNfeFontDir, const std::string& sDefaultFont) ;
bool SetDefaultFont( const std::string& sDefaultFont)
{ m_sDefaultFont = sDefaultFont ; return true ; }
bool SetCurrFont( const std::string& sFont, int nWeight, bool bItalic,
double dHeight, double dRatio, double dAddAdvance) ;
const std::string& GetNfeFontDir( void) const
@@ -54,7 +56,7 @@ class FontManager
OsFont m_OsFont ;
private :
FontManager( void) {}
FontManager( void) : m_bCurrNfeFont( false) {}
FontManager( FontManager const& copy) = delete ;
FontManager& operator=( FontManager const& copy) = delete ;
} ;
+2 -2
View File
@@ -336,7 +336,7 @@ GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe
// curva originale
ICurve* pCrv = GetCurve( m_pGeoObj) ;
// trasformo in curva di Bezier (semplice o composta)
ICurve* pCrvNew = ArcToBezierCurve( pCrv) ;
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( pCrv)) ;
if ( pCrvNew == nullptr)
return false ;
// assegno alla nuova curva estrusione e spessore di quella originale
@@ -389,7 +389,7 @@ GdbGeo::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDi
if ( ! pArc->IsPlane() ||
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
// trasformo in curva di Bezier (semplice o composta)
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( m_pGeoObj)) ;
if ( pCrvNew == nullptr)
return false ;
// assegno alla nuova curva estrusione e spessore di quella originale
+4 -4
View File
@@ -877,7 +877,7 @@ GeomDB::GetFirstNameInGroup( int nGroupId, const string& sName) const
// se ha il nome o la parte iniziale di nome cercato
string sObjName ;
if ( pGdbO->GetName( sObjName) &&
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
return ( pGdbO->m_nId) ;
// passo al successivo
pGdbO = pGdbO->GetNext() ;
@@ -905,7 +905,7 @@ GeomDB::GetNextName( int nId, const string& sName) const
// se ha il nome o la parte iniziale di nome cercato
string sObjName ;
if ( pGdbNext->GetName( sObjName) &&
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
return ( pGdbNext->m_nId) ;
// passo al successivo
pGdbNext = pGdbNext->GetNext() ;
@@ -933,7 +933,7 @@ GeomDB::GetLastNameInGroup( int nGroupId, const string& sName) const
// se ha il nome o la parte iniziale di nome cercato
string sObjName ;
if ( pGdbO->GetName( sObjName) &&
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
return ( pGdbO->m_nId) ;
// passo al precedente
pGdbO = pGdbO->GetPrev() ;
@@ -961,7 +961,7 @@ GeomDB::GetPrevName( int nId, const string& sName) const
// se ha il nome o la parte iniziale di nome cercato
string sObjName ;
if ( pGdbPrev->GetName( sObjName) &&
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
return ( pGdbPrev->m_nId) ;
// passo al precedente
pGdbPrev = pGdbPrev->GetPrev() ;
+265 -7
View File
@@ -14,11 +14,17 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveLine.h"
#include "CurveBezier.h"
#include "CurveComposite.h"
#include "SurfFlatRegion.h"
#include "/EgtDev/Include/EGkDistPointLine.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
#include "/EgtDev/Include/EGkSurfBezier.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
using namespace std ;
@@ -67,11 +73,11 @@ static void
UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos,
const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo)
{
if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) {
if ( nILT == ILTA_IN || nILT == ILTA_EDGE || nILT == ILTA_VERT || nILT == ILTA_NO_TRIA) {
double dU = ( ptIBz - ptL) * vtDir ;
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
}
else if ( nILT == ILTT_SEGM || nILT == ILTT_SEGM_ON_EDGE) {
else if ( nILT == ILTA_SEGM || nILT == ILTA_SEGM_ON_EDGE) {
double dU = ( ptIBz - ptL) * vtDir ;
double dU2 = ( ptIBz2 - ptL) * vtDir ;
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
@@ -88,8 +94,8 @@ OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
sort( vInfo.begin(), vInfo.end(),
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
{ double dUa = ( ( a.nILTA == ILTA_SEGM || a.nILTA == ILTA_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
double dUb = ( ( b.nILTA == ILTA_SEGM || b.nILTA == ILTA_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
return ( dUa < dUb) ; }) ;
}
@@ -146,7 +152,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
double dCos = vtN * vtL ;
double dCos2 = 0 ;
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
if ( InfoTm.nILTT == ILTT_SEGM || InfoTm.nILTT == ILTT_SEGM_ON_EDGE ) {
if ( InfoTm.nILTT == ILTA_SEGM || InfoTm.nILTT == ILTA_SEGM_ON_EDGE ) {
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
int nVert[3] ;
@@ -176,7 +182,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
// ciclo sulle intersezioni
for ( const auto& Info : vInfo) {
// se intersezione puntuale
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
if ( Info.nILTA == ILTA_VERT || Info.nILTA == ILTA_EDGE || Info.nILTA == ILTA_IN) {
int nFlag = LSBT_TOUCH ;
if ( Info.dCosDN > EPS_ZERO)
nFlag = LSBT_OUT ;
@@ -185,7 +191,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
vInters.emplace_back( nFlag, Info.dU) ;
}
// se altrimenti intersezione con coincidenza
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
else if ( Info.nILTA == ILTA_SEGM || Info.nILTA == ILTA_SEGM_ON_EDGE) {
vInters.emplace_back( LSBT_TG_INI, Info.dU) ;
vInters.emplace_back( LSBT_TG_FIN, Info.dU2) ;
}
@@ -232,3 +238,255 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
}
return true ;
}
//----------------------------------------------------------------------------
// Intersezione di una linea con una superficie di Bezier
//----------------------------------------------------------------------------
bool
IntersLineSurfBzBilinear( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz,
ILSBIVECTOR& vInfo, bool bFinite)
{
int nDegU, nDegV, nSpanU, nSpanV ;
bool bRat, bTrimmed ;
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
// funzione pensata per funzionare solo con una monopatch bilineare
if( nDegU > 1 || nDegV > 1 || nSpanU > 1 || nSpanV > 1 || bRat)
return false ;
int nInters = int( vInfo.size()) ;
PNTVECTOR vPntCtrl ;
for( int p = 0 ; p < 4 ; ++p) {
bool bOk = false ;
vPntCtrl.push_back( pSurfBz->GetControlPoint( p, &bOk)) ;
}
Vector3d a = vPntCtrl[3] - vPntCtrl[1] + ( vPntCtrl[0] - vPntCtrl[2]) ;
Vector3d b = vPntCtrl[1] - vPntCtrl[0] ;
Vector3d c = vPntCtrl[2] - vPntCtrl[0] ;
Vector3d d = vPntCtrl[0] - ORIG ;
double A1 = a.x * vtL.z - a.z * vtL.x ;
double B1 = b.x * vtL.z - b.z * vtL.x ;
double C1 = c.x * vtL.z - c.z * vtL.x ;
double A2 = a.y * vtL.z - a.z * vtL.y ;
double B2 = b.y * vtL.z - b.z * vtL.y ;
double C2 = c.y * vtL.z - c.z * vtL.y ;
double D1 = ( d.x - ptL.x) * vtL.z - ( d.z - ptL.z) * vtL.x ;
double D2 = ( d.y - ptL.y) * vtL.z - ( d.z - ptL.z) * vtL.y ;
DBLVECTOR vdCoeff, vdRoots ;
vdCoeff = { (B2 * D1 - B1 * D2), ( A2 * D1 - A1 * D2 + B2 * C1 - B1 * C2), ( A2 * C1 - A1 * C2)} ;
int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ;
bool bFound = false ;
for( int w = 0 ; w < nRoots ; ++w) {
if ( vdRoots[w] > 0 - EPS_ZERO && vdRoots[w] < 1 + EPS_ZERO ) {
double dU = 0, dV = vdRoots[w] ;
// verifico che non sia una soluzione con molteplicità > 1
bool bAlreadyFound = false ;
for ( int k = w - 1 ; k >= 0 && ! bAlreadyFound ; --k)
bAlreadyFound = abs( dV - vdRoots[k]) < EPS_PARAM ;
if( ! bAlreadyFound) {
dU = (dV * (C1 - C2) + ( D1 - D2)) / ( dV * ( A2 - A1) + ( B2 - B1)) ;
if ( dU > - EPS_ZERO && dU < 1 + EPS_ZERO) {
Point3d ptIBez, ptIBez2 ;
Vector3d vtN ;
pSurfBz->GetPointNrmD1D2(dU, dV, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez, vtN) ;
Point3d ptSP( dU, dV, 0), ptSP2 ;
double dCos = vtN * vtL, dCos2 = 0 ;
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP, ptIBez, dCos, ptSP2, ptIBez2, dCos2, vInfo) ;
bFound = true ;
}
}
}
}
// se tutti i coefficienti sono zero allora potrei avere una linea che giace sulla superficie
// per trovare i punti di inizio e fine sovrapposizione trovo i punti a minima distanza tra la linea e gli edge della superficie
if( ! bFound && abs( vdCoeff[0]) < EPS_ZERO && abs( vdCoeff[1]) < EPS_ZERO && abs( vdCoeff[2]) < EPS_ZERO) {
ICRVCOMPOPOVECTOR vCrvEdge( 4) ;
vCrvEdge[0].Set(pSurfBz->GetCurveOnU( 0)) ;
vCrvEdge[1].Set(pSurfBz->GetCurveOnV( 1)) ;
vCrvEdge[2].Set(pSurfBz->GetCurveOnU( 1)) ;
vCrvEdge[3].Set(pSurfBz->GetCurveOnV( 0)) ;
double dAngTolDeg = 5 ;
for( int i = 0 ; i < 4 ; ++i) {
PolyLine plApprox ; vCrvEdge[0]->ApproxWithLines( EPS_SMALL, dAngTolDeg, ICurve::ApprLineType::APL_STD, plApprox) ;
//CurveComposite cCC ;
//cCC.FromPolyLine( plApprox) ;
int nClosestLine = -1 ;
double dMinDist = INFINITO ;
Point3d pt ; plApprox.GetFirstPoint( pt) ;
Point3d ptClosest ;
int c = 0 ;
int nTot = plApprox.GetPointNbr() ;
for( int j = 0 ; j < nTot ; ++j) {
DistPointLine dpl( pt, ptL, vtL, dLen, bFinite) ;
double dDist = INFINITO ;
dpl.GetDist( dDist) ;
if ( dDist < dMinDist) {
nClosestLine = c ;
dMinDist = dDist ;
}
plApprox.GetNextPoint( pt) ;
++ c ;
}
Point3d ptInt1, ptInt2 ;
if ( nClosestLine < nTot - 1 && nClosestLine > 0) {
// tra i due tratti dell'approssimazione che arrivano al punto selezionato come più vicino, devo trovare quale si avvicina di più
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
Point3d ptEnd ;
for( int z = 1 ; z < nClosestLine - 1 ; ++z)
plApprox.GetNextPoint( ptStart) ;
plApprox.GetNextPoint( ptEnd) ;
// linea precedente al punto
Vector3d vtLinePre = ptEnd - ptStart ;
double dLenPre = vtLinePre.Len() ;
DistLineLine dllPre( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
double dDistPre = INFINITO ;
dllPre.GetDist( dDistPre) ;
// linea che inzia con quel punto
ptStart = ptEnd ;
plApprox.GetNextPoint( ptEnd) ;
Vector3d vtLineCurr = ptEnd - ptStart ;
double dLenCurr = vtLineCurr.Len() ;
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
double dDistCurr = INFINITO ;
dllCurr.GetDist( dDistCurr) ;
if( dDistPre < dDistCurr)
dllPre.GetMinDistPoints( ptInt1, ptInt2) ;
else
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
}
else if ( nClosestLine == 0){
// il punto più vicino è sulla prima linea
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
Point3d ptEnd ; plApprox.GetNextPoint( ptEnd) ;
Vector3d vtLineCurr = ptEnd - ptStart ;
double dLenCurr = vtLineCurr.Len() ;
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
}
else if ( nClosestLine == nTot- 1) {
// il punto più vicino è sull'ultima linea
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
Point3d ptEnd ;
for( int z = 1 ; z < nClosestLine - 1 ; ++z)
plApprox.GetNextPoint( ptStart) ;
plApprox.GetNextPoint( ptEnd) ;
Vector3d vtLinePre = ptEnd - ptStart ;
double dLenPre = vtLinePre.Len() ;
DistLineLine dllCurr( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
}
double dU1 = 0, dV1 = 0, dU2 = 0, dV2 = 0 ;
// se ho trovato due punti vuol dire che la linea coincide con un edge e ho trovato tutto quello che serve
if( ! AreSamePointExact( ptInt2, ORIG)) {
if( i == 0) {
//dV1 = 0 ; dV2 = 0 ;
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
vCrvEdge[0]->GetParamAtPoint( ptInt2, dU2) ;
}
else if( i == 1) {
//dU1 = 1 ; dU2 = 1 ;
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
vCrvEdge[1]->GetParamAtPoint( ptInt2, dV2) ;
}
else if( i == 2){
//dV1 = 1 ; dV2 = 1 ;
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
vCrvEdge[2]->GetParamAtPoint( ptInt2, dU2) ;
}
else if( i == 3){
//dU1 = 0 ; dU2 = 0 ;
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
vCrvEdge[3]->GetParamAtPoint( ptInt2, dV2) ;
}
Point3d ptIBez1, ptIBez2 ;
Vector3d vtN1, vtN2 ;
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
pSurfBz->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez2, vtN2) ;
Point3d ptSP1( dU1, dV1, 0) ;
double dCos1 = vtN1 * vtL ;
Point3d ptSP2( dU2, dV2, 0) ;
double dCos2 = vtN2 * vtL ;
// se avevo già trovato un punto singolo che coincide col primo punto di questa intersezione sovrapposta, allora cancello l'intersezione singola che
// avevo salvato e aggiungo quella sovrapposto che ho trovato ora
if( bFound) {
int nNewTot = int(vInfo.size()) ;
int nNewInters = nNewTot - nInters ;
bool bAlreadyFound = false ;
for( int i = 0 ; i < nNewInters ; ++i) {
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) || AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP2) ;
if ( bAlreadyFound) {
vInfo.erase( vInfo.begin() + nNewTot - i) ;
break ;
}
}
}
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
bFound = true ;
break ;
}
// se ho trovato un punto a distanza zero dalla linea allora ho trovato l'intersezione
else if( dMinDist < EPS_SMALL) {
if( i == 0) {
//dV1 = 0 ;
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
}
else if( i == 1) {
//dU1 = 1 ;
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
}
else if( i == 2){
//dV1 = 1 ;
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
}
else if( i == 3){
//dU1 = 0 ;
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
}
Point3d ptSP1( dU1, dV1, 0), ptSP2 ;
// se avevo trovato già altri punti controllo di non essere esattamente su una diagonale ( e quindi avere un'intersezione con ogni edge, ma due sono doppie)
if( bFound) {
int nNewTot = int(vInfo.size()) ;
int nNewInters = nNewTot - nInters ;
bool bAlreadyFound = false ;
for( int i = 0 ; i < nNewInters ; ++i)
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) ;
if( bAlreadyFound)
continue ;
}
Point3d ptIBez1, ptIBez2 ;
Vector3d vtN1, vtN2 ;
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
double dCos1 = vtN1 * vtL, dCos2 = 0 ;
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
bFound = true ;
}
}
}
// se la superficie è trimmed verifico che i punti trovati siano all'interno del parametrico trimmato
if( bTrimmed && bFound) {
int nNewTot = int(vInfo.size()) ;
int nNewInters = nNewTot - nInters ;
const ISurfFlatRegion* pFRTrim = pSurfBz->GetTrimRegion() ;
for( int i = 0 ; i < nNewInters ; ++i) {
Point3d ptTest = vInfo[nNewTot - i].ptUV * SBZ_TREG_COEFF ;
bool bInside = false ;
double dDist = INFINITO ;
IsPointInsideSurfFr( ptTest, pFRTrim, dDist, bInside) ;
if( ! bInside)
vInfo.erase( vInfo.begin() + nNewTot - i) ;
}
}
return true ;
}
+330 -11
View File
@@ -18,6 +18,8 @@
#include "PolygonPlane.h"
#include "PointsPCA.h"
#include "GeoConst.h"
#include "CurveComposite.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkPlane3d.h"
#include "/EgtDev/Include/EGkDistPointLine.h"
@@ -796,7 +798,7 @@ PolyLine::RemoveAlignedPoints( double dToler)
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( vPtU.size() - 1) ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
// altrimenti chiusa
else {
@@ -817,7 +819,7 @@ PolyLine::RemoveAlignedPoints( double dToler)
vInd.push_back( nMaxInd) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( vPtU.size() - 1) ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
// ordino in senso crescente
@@ -825,7 +827,7 @@ PolyLine::RemoveAlignedPoints( double dToler)
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
if ( IsClosed() && vInd.size() >= 4) {
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[vInd.size()-2]].first).IsEpsilon( dToler)) {
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[int(vInd.size())-2]].first).IsEpsilon( dToler)) {
vInd.erase( vInd.begin()) ;
vInd.back() = vInd.front() ;
}
@@ -1445,7 +1447,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
}
// Determino tangente di riferimento
Vector3d vtTang ;
// se minima distanza nell'estremo iniziale del segmento
// se minima distanza nell'estremo iniziale del segmento
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
// direzione del segmento
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
@@ -1461,7 +1463,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
vtTang = vtPrevTg + vtCurrTg ;
vtTang.Normalize() ;
}
// se altrimenti minima distanza nell'estremo finale del segmento
// se altrimenti minima distanza nell'estremo finale del segmento
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
// direzione del segmento
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
@@ -1477,7 +1479,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
vtTang = vtCurrTg + vtNextTg ;
vtTang.Normalize() ;
}
// altrimenti minima distanza con l'interno
// altrimenti minima distanza con l'interno
else {
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
}
@@ -1612,8 +1614,9 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
int nPnt2 = PL2.GetPointNbr() ;
if ( nPnt1 == 0 || nPnt2 == 0)
return false ;
bCommonInternalPoints = false ; // indica la presenza di punti interni in comune tra le due polylines
// indica la presenza di punti interni in comune tra le due polylines
bCommonInternalPoints = false ;
vPnt1.reserve( PL1.GetPointNbr()) ;
Point3d ptP1 ;
@@ -1657,7 +1660,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
nMinJ = nLastJ ;
// verifica se è un punto interno in comune con l'altra polyline
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
bCommonInternalPoints = true ;
vPnt1[i].second = nMinJ ;
@@ -1687,12 +1690,328 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
if ( nMinI < nLastI)
nMinI = nLastI ;
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
bCommonInternalPoints = true ;
vPnt2[j].second = nMinI ;
nLastI = nMinI ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
MatchPolyLinesAddingPoints( const PolyLine& PL1, const PolyLine& PL2, int nType, PNTIVECTOR& vPnt1, PNTIVECTOR& vPnt2)
{
// prima trovo le associazioni senza aggiunte di punti
Point3d ptP2 ;
CurveComposite cc1, cc2 ;
cc1.FromPolyLine( PL1) ;
cc2.FromPolyLine( PL2) ;
int nPnt1 = PL1.GetPointNbr() ;
int nPnt2 = PL2.GetPointNbr() ;
vector<POINTU> vMatch2 ;
PL2.GetFirstPoint( ptP2) ;
while ( PL2.GetNextPoint( ptP2, true)) {
DistPointCurve dpc( ptP2, cc1, false) ;
int nFlag = 0 ;
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
vMatch2.emplace_back( ptJoint, dParam) ;
}
int nAtStart2 = 0 ; // match ripetuti dalla curva U0 allo start della curva U1
int nAtEnd2 = 0 ;
Point3d ptP1 ; PL1.GetFirstPoint( ptP1) ;
int c = 0 ;
int nRep1 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1
int nRep2 = 0 ;
double dLastParamMatch = 0 ;
Point3d ptLastPointMatch = ptP1 ;
BOOLVECTOR vbRep1( nPnt1) ;
INTVECTOR vnAddedOrNextIsRep1 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
DBLVECTOR vdSplit1 ;
DBLVECTOR vdMatch1 ;
fill( vbRep1.begin(), vbRep1.end(), false) ;
while ( PL1.GetNextPoint( ptP1, true)) {
// devo salvarmi se matcho più punti con lo start o l'end della curva totale
DistPointCurve dpc( ptP1, cc2, false) ;
int nFlag = 0 ;
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
vdMatch1.push_back( dParam) ;
if ( dParam < EPS_SMALL ) {
++nAtStart2 ;
vbRep1[c] = true ;
++c ;
continue ;
}
else if ( dParam > nPnt2 - EPS_SMALL ) {
vbRep1[c] = nAtEnd2 == 0 ? false : true ;
vbRep1.back() = true ;
++ nAtEnd2 ;
++c ;
continue ;
}
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
dParam = dLastParamMatch ;
vbRep1[c] = true ;
++ nRep1 ;
++c ;
continue ;
}
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
// se sono già troppo vicino ad un split esistente allora non faccio nulla
if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
continue ;
}
vdSplit1.push_back( dParam) ;
// verifico se ho un match per questo punto
// in tal caso vuol dire che sto creando una ripetizione nRep1
int nCase = 0 ;
for ( int j = 0 ; j < int( vMatch2.size()) ; ++j) {
if ( abs(vMatch2[j].second - (c + 1)) < EPS_SMALL) {
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
bool bFoundMatch = false ;
for ( int z = int( vMatch2[j].second) ; z < int( vdMatch1.size()) ; ++z) {
if ( abs( vdMatch1[z] - ( j + 1 )) < EPS_SMALL ) {
bFoundMatch = true ;
break ;
}
}
if ( ! bFoundMatch) {
++ nRep2 ;
// capisco se il punto è rep o se lo è il suo successivo
if ( j + 1 < dParam)
nCase = 1 ;
else
nCase = 2 ;
}
break ;
}
}
vnAddedOrNextIsRep1.push_back( nCase) ;
}
++c ;
}
int nAtStart1 = 0 ;
int nAtEnd1 = 0 ;
PL2.GetFirstPoint( ptP2) ;
c = 0 ;
dLastParamMatch = 0 ;
ptLastPointMatch = ptP2 ;
INTVECTOR vnAddedOrNextIsRep2 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
DBLVECTOR vdSplit2 ;
BOOLVECTOR vbRep2( nPnt2) ;
fill( vbRep2.begin(), vbRep2.end(), false) ;
while ( PL2.GetNextPoint( ptP2, true)) {
DistPointCurve dpc( ptP2, cc1, false) ;
int nFlag = 0 ;
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
if ( dParam < EPS_SMALL ) {
++nAtStart1 ;
vbRep2[c] = true ;
++c ;
continue ;
}
else if ( dParam > nPnt1 - EPS_SMALL ) {
vbRep2[c] = ( nAtEnd1 == 0 ? false : true) ;
vbRep2.back() = true ;
++ nAtEnd1 ;
++c ;
continue ;
}
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
dParam = dLastParamMatch ;
vbRep2[c] = true ;
++ nRep2 ;
++c ;
continue ;
}
else {
dLastParamMatch = dParam ;
ptLastPointMatch = ptJoint ;
// se sono troppo vicino ad uno split esistente allora non faccio nulla
if ( abs( dParam - round( dParam)) < 100 * EPS_PARAM) {
++c ;
continue ;
}
vdSplit2.push_back( dParam) ;
// verifico se ho un match per questo punto
// in tal caso vuol dire che sto creando una ripetizione nRep0
int nCase = 0 ;
for ( int j = 0 ; j < int( vdMatch1.size()) ; ++j) {
if ( abs( vdMatch1[j] - (c + 1)) < EPS_SMALL) {
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
bool bFoundMatch = false ;
for ( int z = int( vdMatch1[j]) ; z < int( vMatch2.size()) ; ++z) {
if ( abs( vMatch2[z].second - ( j + 1 )) < EPS_SMALL) {
bFoundMatch = true ;
break ;
}
}
if ( ! bFoundMatch) {
++nRep1 ;
// capisco se il punto è rep o se lo è il suo successivo
if ( j + 1 < dParam)
nCase = 1 ;
else
nCase = 2 ;
}
break ;
}
}
vnAddedOrNextIsRep2.push_back( nCase) ;
}
++c ;
}
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
int nUnit = 0 ;
if ( ! vdSplit1.empty())
nUnit = int( vdSplit1.back()) ;
for ( int z = int( vdSplit1.size()) - 1 ; z >= 0 ; --z) {
double dSplit = vdSplit1[z] ;
int nSplit = int( dSplit) ;
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
// riscalare
if ( nSplit == nUnit && z < int( vdSplit1.size()) - 1) {
dSplit = nSplit + ( dSplit - nSplit) / ( vdSplit1[z+1] - nSplit) ;
}
nUnit = nSplit ;
cc2.AddJoint( dSplit) ;
switch ( vnAddedOrNextIsRep1[z]) {
case 0 :
if ( vbRep2[nSplit])
++ nRep2 ;
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
vbRep2.insert( vbRep2.begin() + nSplit, vbRep2[nSplit]) ;
break ;
case 1 :
vbRep2.insert( vbRep2.begin() + nSplit, true) ;
break ;
case 2 :
if ( vbRep2[nSplit])
--nRep2 ;
else
vbRep2[nSplit] = true ;
vbRep2.insert( vbRep2.begin() + nSplit, false) ;
break ;
}
}
if ( ! vdSplit2.empty())
nUnit = int( vdSplit2.back()) ;
for ( int z = int( vdSplit2.size()) - 1 ; z >= 0 ; --z) {
double dSplit = vdSplit2[z] ;
int nSplit = int( dSplit) ;
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
// riscalare
if ( nSplit == nUnit && z < int( vdSplit2.size()) - 1) {
dSplit = nSplit + ( dSplit - nSplit) / (vdSplit2[z+1] - nSplit) ;
}
nUnit = nSplit ;
cc1.AddJoint( dSplit) ;
switch ( vnAddedOrNextIsRep2[z]) {
case 0 :
if ( vbRep1[nSplit])
++ nRep1 ;
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ;
break ;
case 1 :
vbRep1.insert( vbRep1.begin() + nSplit, true) ;
break ;
case 2 :
if ( vbRep1[nSplit])
-- nRep1 ;
else
vbRep1[nSplit] = true ;
vbRep1.insert( vbRep1.begin() + nSplit, false) ;
break ;
}
}
nPnt1 = cc1.GetCurveCount() ;
nPnt2 = cc2.GetCurveCount() ;
//aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true
int nAddedSpan = 0 ;
int nCrv1 = 0 ;
int nCrv2 = 0 ;
while ( nAddedSpan < nPnt1 + nAtStart1 + nAtEnd1 + nRep2) {
if ( nCrv1 >= nPnt1)
nCrv1 = nPnt1 - 1 ;
if ( nCrv2 >= nPnt2)
nCrv2 = nPnt2 - 1 ;
bool bRep1 = vbRep1[nCrv1] ;
bool bRep2 = vbRep2[nCrv2] ;
if ( bRep1 && bRep2) {
vbRep1[nCrv1] = false ;
bRep1 = false ;
vbRep2[nCrv2] = false ;
bRep2 = false ;
-- nRep1 ;
-- nRep2 ;
}
if ( ! bRep1 || nCrv2 == nPnt2 - 1)
++ nCrv2 ;
if ( ! bRep2 || nCrv1 == nPnt1 - 1)
++ nCrv1 ;
++ nAddedSpan ;
}
// se non sono arrivato all'ultima curva su U0 o U1 vuol dire che ho creato delle ripetizioni che non ho contato prima
if ( nCrv2 < nPnt2) {
nRep2 += nPnt2 - nCrv2 ;
for ( int z = int( vbRep2.size()) - 1 ; z >= nCrv2 ; --z)
vbRep2[z] = true ;
}
if( nCrv1 < nPnt1) {
nRep1 += nPnt1 - nCrv1 ;
for ( int z = int( vbRep1.size()) - 1 ; z >= nCrv1 ; --z)
vbRep1[z] = true ;
}
// trovo il numero di span che dovrà avere la superficie
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
int nPnt = nPnt1 + nAtStart1 + nAtEnd1 + nRep2 ;
if ( nPnt != nPnt2 + nAtStart2 + nAtEnd2 + nRep1)
LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ;
// aggiungo i punti di controllo scorrendo in contemporanea le due curve
nAddedSpan = 0 ;
nCrv1 = 0 ;
nCrv2 = 0 ;
bool bLast1 = false ;
bool bLast2 = false ;
while ( nAddedSpan < nPnt) {
if ( nCrv1 >= nPnt1) {
nCrv1 = nPnt1 - 1 ;
bLast1 = true ;
}
if ( nCrv2 >= nPnt2) {
nCrv2 = nPnt2 - 1 ;
bLast2 = true ;
}
bool bRep1 = vbRep1[nCrv1] ;
bool bRep2 = vbRep2[nCrv2] ;
const ICurve* pSubCrv1 = cc1.GetCurve( nCrv1) ;
Point3d ptStart1 ; pSubCrv1->GetStartPoint( ptStart1) ;
vPnt1.emplace_back( ptStart1, nAddedSpan) ;
const ICurve* pSubCrv2 = cc2.GetCurve( nCrv2) ;
Point3d ptStart2 ; pSubCrv2->GetStartPoint( ptStart2) ;
vPnt2.emplace_back( ptStart2, nAddedSpan) ;
if ( ! bRep2)
++ nCrv1 ;
if ( ! bRep1)
++ nCrv2 ;
++ nAddedSpan ;
}
return true ;
}
}
+36 -13
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2023-2023
// EgalTech 2023-2025
//----------------------------------------------------------------------------
// File : ProjectCurveSurfTm.cpp Data : 16.11.23 Versione : 2.5kh3
// File : ProjectCurveSurfTm.cpp Data : 29.08.25 Versione : 2.7h2
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
//
//
@@ -40,6 +40,13 @@ const int P5AX_CONC = 3 ; // in angolo concavo
const int P5AX_BEFORE_CONC = 4 ; // adiacente ad angolo concavo
const int P5AX_AFTER_CONC = 5 ; // adiacente ad angolo concavo
//----------------------------------------------------------------------------
static double
GetSurfBezierTol( double dLinTol)
{
return max( dLinTol / 10, EPS_SMALL) ;
}
//----------------------------------------------------------------------------
static bool
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
@@ -154,7 +161,8 @@ RemovePointsInExcess( PNT5AXVECTOR& vPt5ax, double dLinTol, double dMaxSegmLen,
return true ;
}
typedef std::vector<IntersParLinesSurfTm*> INTPARLINESTMPVECTOR ; // vettore di oggetti intersezione massiva rette parallele SurfTM
// --- vettore di oggetti intersezione massiva rette parallele SurfTM --------
typedef std::vector<IntersParLinesSurfTm*> INTPARLINESTMPVECTOR ;
//----------------------------------------------------------------------------
static bool
@@ -230,8 +238,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const Vect
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
break ;
case SRF_BEZIER :
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurf() ;
break ;
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
} break ;
case SRF_FLATRGN :
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
break ;
@@ -440,8 +451,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const IGeo
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
break ;
case SRF_BEZIER :
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurf() ;
break ;
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
} break ;
case SRF_FLATRGN :
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
break ;
@@ -593,8 +607,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ICur
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
break ;
case SRF_BEZIER :
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurf() ;
break ;
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
} break ;
case SRF_FLATRGN :
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
break ;
@@ -804,8 +821,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ISur
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
break ;
case SRF_BEZIER :
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurf() ;
break ;
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
} break ;
case SRF_FLATRGN :
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
break ;
@@ -824,8 +844,11 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ISur
pRefTm = GetBasicSurfTriMesh( &sfRef) ;
break ;
case SRF_BEZIER :
pRefTm = GetBasicSurfBezier( &sfRef)->GetAuxSurf() ;
break ;
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
pRefTm = GetBasicSurfBezier( &sfRef)->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
} break ;
case SRF_FLATRGN :
pRefTm = GetBasicSurfFlatRegion( &sfRef)->GetAuxSurf() ;
break ;
+28 -10
View File
@@ -41,6 +41,7 @@
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Extern/Eigen/Dense"
#include "/EgtDev/Include/EgtPerfCounter.h"
using namespace std ;
@@ -48,7 +49,16 @@ using namespace std ;
GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
//----------------------------------------------------------------------------
struct PairHashIntInt {
size_t operator()(const pair<int, int>& key) const {
size_t h1 = hash<int>{}( key.first) ;
size_t h2 = hash<int>{}( key.second) ;
return h1 ^ ( h2 << 1) ; // Combine hashes
}
};
static unordered_map<INTINT, DBLVECTOR, PairHashIntInt> s_mBernCache ; // mappa dei polinomi di bernstein
//----------------------------------------------------------------------------
static double s_dAuxSurfTol = 200 * EPS_SMALL ;
static double s_dAuxSurfRefinedTol = 50 * EPS_SMALL ;
@@ -1788,13 +1798,18 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
// resetto il vettore degli edge
m_mCCEdge.clear() ;
m_vCCLoop.clear() ;
//debug
static PerformanceCounter Counter;
static double dTotCount = 0. ;
Counter.Start();
//debug
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
Point3d ptMin = get<0>( vTrees[i]) ;
Point3d ptMax = get<1>( vTrees[i]) ;
Tree.SetSurf( this, ptMin, ptMax) ;
Tree.BuildTree( dTol, dSideMin) ;
if ( ! Tree.GetPolygons( vvPL, vvPL3d, m_mCCEdge, m_vCCLoop))
continue ;
if ( ! Tree.GetPolygons(vvPL, vvPL3d, m_mCCEdge, m_vCCLoop))
continue ;
//Tree.GetPolygonsBasic( vPL, true) ; // per usare i polygon basic
// aggiorno la chiusura della superficie
@@ -1804,6 +1819,12 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
// UpdateEdgesFromTree( Tree) ; // ora viene fatto nella GetPolygons
}
//debug
dTotCount += Counter.Stop() ;
string sOut = "CalcTree=" + ToString( dTotCount, 3) ;
LOG_INFO( GetEGkLogger(), sOut.c_str())
//debug
//// per usare i polygon basic//////////////////////
//for (int k = 0 ; k < (int)vPL.size(); ++k) {
// vvPL.emplace_back() ;
@@ -2162,7 +2183,7 @@ bool
SurfBezier::IncreaseUV( double& dUV, double dxy, bool bUOrV, double* dUVCopy, bool bModifyOrig) const
{
double dUVTest ;
if (dUVCopy == nullptr && !bModifyOrig)
if ( dUVCopy == nullptr && ! bModifyOrig)
return false ;
if ( dUVCopy != nullptr) {
*dUVCopy = dUV + dxy ;
@@ -2175,15 +2196,15 @@ SurfBezier::IncreaseUV( double& dUV, double dxy, bool bUOrV, double* dUVCopy, bo
if ( bUOrV) {
if ( dUVTest < 0)
dUVTest = 0 ;
dUVTest = 0 ;
else if ( dUVTest > m_nSpanU * SBZ_TREG_COEFF )
dUVTest = m_nSpanU * SBZ_TREG_COEFF ;
dUVTest = m_nSpanU * SBZ_TREG_COEFF ;
}
else {
if ( dUVTest < 0)
dUVTest = 0 ;
dUVTest = 0 ;
else if ( dUVTest > m_nSpanV * SBZ_TREG_COEFF )
dUVTest = m_nSpanV * SBZ_TREG_COEFF ;
dUVTest = m_nSpanV * SBZ_TREG_COEFF ;
}
if ( bModifyOrig)
dUV = dUVTest ;
@@ -2849,7 +2870,6 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
// se sono in polo e mi hanno passato un punto precedente allora devo prendere il triangolo di quel punto
bool bIsPole = false ;
bool bNearPole = false ; // devo capire se il triangolo di riferimento ha un vertice in un polo
int nInters = 0 ;
INTVECTOR vInters(4) ;
fill( vInters.begin(), vInters.end(), 0) ;
// se il vettore dei poli non è stato riempito vuol dire che quando è stata creata la superficie non è stata chiamata la funzione CalcPoles
@@ -2867,11 +2887,9 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
vInters[c] = AreSamePointApprox( pt, ptI) ? 1 : 0 ;
if ( vInters[c] == 1)
bIsPole = true ;
nInters += vInters[c] ;
}
else {
vInters[c] = m_mCCEdge[c][i]->IsPointOn(ptI) ? 1 : 0 ;
nInters += vInters[c] ;
}
}
}
-10
View File
@@ -22,16 +22,6 @@
#include "/EgtDev/Include/EGkSurfBezier.h"
#include "/EgtDev/Include/EGkGeoCollection.h"
class Tree ;
struct PairHashIntInt {
std::size_t operator()(const std::pair<int, int>& key) const {
std::size_t h1 = std::hash<int>{}(key.first);
std::size_t h2 = std::hash<int>{}(key.second);
return h1 ^ (h2 << 1); // Combine hashes
}
};
//----------------------------------------------------------------------------
class SurfBezier : public ISurfBezier, public IGeoObjRW
{
+1 -1
View File
@@ -827,7 +827,7 @@ SurfFlatRegion::ConvertArcsToBezierCurves( void)
// ciclo sui loop
for ( auto& pLoop : m_vpLoop) {
if ( pLoop->GetType() == CRV_ARC) {
ICurve* pCrvNew = ArcToBezierCurve( pLoop) ;
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc(pLoop)) ;
if ( pCrvNew == nullptr)
return false ;
delete pLoop ;
+12
View File
@@ -3637,6 +3637,18 @@ SurfTriMesh::Invert( void)
for ( int i = 0 ; i < GetTriangleSize() ; ++ i)
InvertTriangle( i) ;
// se bordi della sfaccettatura validi
if ( m_bFacEdged) {
for ( int nE = 0 ; nE < GetEdgeCount() ; ++ nE) {
// inversione dei vertici nel vettore delle sfaccettature
swap( m_vFacEdge[nE].nIdVert[0], m_vFacEdge[nE].nIdVert[1]) ;
// inversione delle adiacenze nel vettore delle sfaccettature
swap( m_vFacEdge[nE].nIdFacAdj[0], m_vFacEdge[nE].nIdFacAdj[1]) ;
// inversione dell'angolo interno
m_vFacEdge[nE].dIntAng *= -1. ;
}
}
return true ;
}
+135 -9
View File
@@ -15,8 +15,21 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "VolZmap.h"
#include "SurfTriMesh.h"
#include "EgtDev/Include/EGkDistPointSurfTm.h"
#include "\EgtDev\Include\EGkSurfTriMeshAux.h"
#define DEBUG 0
#if DEBUG
#include "/EgtDev/Include/EGkGeoObjSave.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkStmStandard.h"
#include "/EgtDev/Include/EgtPerfCounter.h"
std::vector<IGeoObj*> VT ;
std::vector<Color> VC ;
#endif
using namespace std ;
//----------------------------------------------------------------------------
@@ -73,20 +86,131 @@ CreateSurfTriMeshesOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dPr
if ( vStm.empty())
return nullptr ;
// controllo sul valore di tolleranza lineare
double dMyPrec = max( dPrec, 100 * EPS_SMALL) ;
double dMyPrec = max( dPrec, 100. * EPS_SMALL) ;
// --- NB. ( Il valore di Offset deve essere maggiore di 10 * EPS_SMALL in valore assoluto)
// Nel caso sia minore, restituisco semplicemente la somma delle superfici
// ( questo valore serve per rimanere coerente con l'Offset delle curve)
if ( abs( dOffs) < 10 * EPS_SMALL)
if ( abs( dOffs) < 10. * EPS_SMALL)
return SumStm( vStm) ;
// creo lo Zmap associato alle superfici TriMesh
PtrOwner<IVolZmap> pVolZmap( CreateVolZmap()) ;
if ( IsNull( pVolZmap) || ! pVolZmap->CreateFromTriMeshOffset( vStm, dOffs, dMyPrec, nType))
VolZmap OneVolZmap ;
if ( ! OneVolZmap.CreateFromTriMeshOffset( vStm, dOffs, dMyPrec, nType))
return nullptr ;
if ( ! OneVolZmap.IsValid())
return nullptr ;
// restituisco la superficie TriMesh
return ( pVolZmap->GetSurfTriMesh()) ;
// recupero le superfici aperte
CISURFTMPVECTOR vStmOpen ;
for ( const ISurfTriMesh* pStm : vStm) {
if ( pStm != nullptr && pStm->IsValid() && ! pStm->IsClosed())
vStmOpen.emplace_back( pStm) ;
}
// --- se non ho superfici aperte
if ( vStmOpen.empty()) {
// restituisco la superficie TriMesh di Offset
return ( OneVolZmap.GetSurfTriMesh()) ;
}
// --- se ho delle superfici aperte
// lo Zmap creato è orientato e definisce una superficie chiusa; devo rimuovere i triangoli in eccesso
// anzitutto controllo che lo Zmap sia valido
if ( ! OneVolZmap.IsValid())
return nullptr ;
// inzializzo la superficie TriMesh da restituire
PtrOwner<SurfTriMesh> pStm( CreateBasicSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->Init( 3, 1))
return nullptr ;
PointGrid3d VertGrid ; VertGrid.Init( 50000) ;
// tolleranza di vicinanza alla superficie
double dTolDist = 30. * EPS_SMALL ;
#if DEBUG
VT.emplace_back( OneVolZmap.Clone()) ;
VC.emplace_back( BLACK) ;
#endif
// ciclo lungo i blocchi dello ZMap
for ( int nB = 0 ; nB < OneVolZmap.GetBlockCount() ; ++ nB) {
// recupero i triangoli
TRIA3DEXVECTOR vTria, vTriaSafe ;
OneVolZmap.GetBlockTriangles( nB, vTria) ;
// un triangolo viene ritenuto valido se è non è troppo vicino ( dOffs) alle superfici aperte
for ( int nT = 0 ; nT < int( vTria.size()) ; ++ nT) {
// recupero il triangolo
Triangle3dEx& Tria = vTria[nT] ;
// scorro le superficie aperte
bool bInsert = true ;
for ( int nS = 0 ; bInsert && nS < int( vStm.size()) ; ++ nS) {
// controllo se posso inserirlo
vector<DistPointSurfTm> vDistPtStm ;
for ( int i = 0 ; i < 3 && bInsert ; ++ i) {
double dDist = 0. ;
vDistPtStm.emplace_back( DistPointSurfTm( Tria.GetP( i), *vStm[nS])) ;
bInsert = ( vDistPtStm.back().GetDist( dDist) && dDist > abs( dOffs) - dTolDist) ;
}
// se il triangolo è al più a distanza di |dOffs| - dTolDist
if ( bInsert) {
// recupero i triangoli a distanza minima dai vertici del triangolo corrente
bool bPerp = true ;
for ( int i = 0 ; i < 3 && bPerp ; ++ i) {
INTVECTOR vTria ;
vDistPtStm[i].GetMinDistTriaIndices( vTria) ;
for ( int j = 0 ; j < int( vTria.size()) && bPerp ; ++ j) {
Triangle3d TriaCloser ;
vStm[nS]->GetTriangle( vTria[j], TriaCloser) ;
bPerp = ( abs( Tria.GetN() * TriaCloser.GetN()) < dTolDist) ;
}
}
// se tutti i triangoli a distanza minima sono perpendicolari, allora non lo inserisco
bInsert = ( ! bPerp) ;
}
}
// se triangolo da inserire
if ( bInsert)
vTriaSafe.emplace_back( Tria) ;
#if DEBUG
ICurveComposite* pCompo = CreateCurveComposite() ;
pCompo->AddPoint( Tria.GetP( 0)) ;
pCompo->AddLine( Tria.GetP( 1)) ;
pCompo->AddLine( Tria.GetP( 2)) ;
pCompo->Close() ;
Color myCol = ( bInsert ? Color( 0., 1., 0., .5) : Color( 1., 0., 0., .5)) ;
VT.emplace_back( CloneCurveComposite( pCompo)) ;
VC.emplace_back( myCol) ;
ISurfFlatRegion* pSfrTria = CreateSurfFlatRegion() ;
pSfrTria->AddExtLoop( pCompo) ;
VT.emplace_back( pSfrTria) ;
VC.emplace_back( myCol) ;
#endif
}
// inserisco tutti i triangoli validi
if ( ! pStm->AddTriaFromZMap( vTriaSafe, VertGrid))
return nullptr ;
}
#if DEBUG
SaveGeoObj( VT, VC, "C:\\Temp\\TriangleSelection.nge") ;
#endif
// sistemo la topologia
if ( ! pStm->AdjustTopologyFromZMap())
return nullptr ;
return ( Release( pStm)) ;
}
//----------------------------------------------------------------------------
@@ -107,10 +231,12 @@ CreateSurfTriMeshesThickeningOffset( const CISURFTMPVECTOR& vStm, double dOffs,
return SumStm( vStm) ;
// creo lo Zmap associato alle superfici TriMesh
PtrOwner<IVolZmap> pVolZmap( CreateVolZmap()) ;
if ( IsNull( pVolZmap) || ! pVolZmap->CreateFromTriMeshThickeningOffset( vStm, dOffs, dMyPrec, nType))
VolZmap OneVolZmap ;
if ( ! OneVolZmap.CreateFromTriMeshThickeningOffset( vStm, dOffs, dMyPrec, nType))
return nullptr ;
if ( ! OneVolZmap.IsValid())
return nullptr ;
// restituisco la superficie TriMesh
return ( pVolZmap->GetSurfTriMesh()) ;
return ( OneVolZmap.GetSurfTriMesh()) ;
}
+7 -2
View File
@@ -125,7 +125,7 @@ Tree::GetPoint( double dU, double dV, Point3d& ptP) const
//----------------------------------------------------------------------------
bool
Tree::SavePoint( double dU, double dV, Point3d& ptP)
Tree::SavePoint( double dU, double dV, const Point3d& ptP)
{
pair<int64_t, int64_t> key( int64_t( GetHalfKey( dU)), int64_t( GetHalfKey( dV))) ;
if ( m_mPt3d.find( key) == m_mPt3d.end())
@@ -727,7 +727,12 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
// se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione
// ( dSideMinVal è zero se entrambi i lati da splittare sono collassati in un punto, controllo dLengMinVal)
bool bSplit = false ;
bool bDimOk = ( dSideMinVal / 2 >= dSideMin || ( dSideMinVal < EPS_SMALL && dLengMinVal / 2 >= dSideMin)) ;
bool bParamDimOk = false ;
if( bVert)
bParamDimOk = ( pcToSplit->GetTopRight().x - pcToSplit->GetBottomLeft().x) / 2 > 100 * EPS_PARAM ;
else
bParamDimOk = ( pcToSplit->GetTopRight().y - pcToSplit->GetBottomLeft().y) / 2 > 100 * EPS_PARAM ;
bool bDimOk = ( dSideMinVal / 2 >= dSideMin || ( dSideMinVal < EPS_SMALL && dLengMinVal / 2 >= dSideMin)) && bParamDimOk ;
if ( dSideMaxVal > dSideMax) {
bSplit = true ;
//LOG_DBG_INFO( GetEGkLogger(), " Split by SideMax")
+14 -10
View File
@@ -20,6 +20,8 @@
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include <map>
#include "/EgtDev/Extern/abseil/Include/absl/algorithm/container.h"
#include "/EgtDev/Extern/abseil/Include/absl/container/flat_hash_map.h"
#include <utility>
struct PairHashInt64 {
@@ -255,10 +257,12 @@ class Tree
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
// ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
bool GetEdges3D ( std::vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i) vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ; return true ; };
bool GetLeaves( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
bool GetEdges3D( std::vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // restituisce i loop splitatti ai confini delle celle
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i)
vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ;
return true ; }
// funzioni da usare per ricostruire tagli che vanno aggiunti allo spazio parametrico
bool AddCutsToRoot( POLYLINEVECTOR& vCuts) ; // aggiunge i tagli al tree
bool CreateCellContour( POLYLINEMATRIX& vPolygons) ; // crea il nuovo contorno esterno, tenendo conto dei tagli
@@ -304,14 +308,14 @@ class Tree
bool UpdateSplitLoop( ICurveComposite* pCC, Point3d& pt) ;
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ;
bool GetPoint(double dU, double dV, Point3d& pt) const ;
bool SavePoint( double dU, double dV, Point3d& pt) ;
bool GetPoint(double dU, double dV, Point3d& ptP) const ;
bool SavePoint( double dU, double dV, const Point3d& ptP) ;
private :
const SurfBezier* m_pSrfBz ; // superficie di bezier
bool m_bTrimmed ; // superficie trimmata
std::unordered_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
absl::flat_hash_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
bool m_bBilinear ; // superficie bilineare
bool m_bMulti ; // superficie multi-patch
bool m_bClosedU ; // superficie chiusa lungo il parametro U
@@ -321,8 +325,8 @@ class Tree
int m_nDegV ; // grado della superficie nel parametro V
int m_nSpanU ; // numero di span lungo il parametro U
int m_nSpanV ; // numero di span lungo il parametro V
std::unordered_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
mutable std::unordered_map<std::pair<int64_t, int64_t>,Point3d, PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int)
absl::flat_hash_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
mutable absl::flat_hash_map<std::pair<int64_t,int64_t>,Point3d,PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int)
INTVECTOR m_vnLeaves ; // vettore delle foglie
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
ICRVCOMPOPOVECTOR m_vCCLoop2D ; // vettore che contiene le CurveCompo che rappresentano i loop di trim tenendo conto della divisione in celle
+9 -6
View File
@@ -1929,8 +1929,6 @@ VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
bool
VolZmap::IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, double& dMinZ, double& dMaxZ)
{
if ( ! m_bIsBox)
return true ;
dMinZ = m_dMaxZ[nMap] ;
dMaxZ = m_dMinZ[nMap] ;
for ( int i = nInfI ; i < nSupI ; ++ i) {
@@ -1960,6 +1958,7 @@ bool
VolZmap::IsBox( void)
{
// Se non tridexel, non posso stabilire con il metodo seguente se è un box
// Verifico solo che gli spilloni di una mappa o sono nulli o hanno gli stessi estremi
if ( m_nMapNum == 1)
return false ;
// Numero massimo di thread per il calcolo parallelo.
@@ -1968,9 +1967,12 @@ VolZmap::IsBox( void)
if ( nThreadMax == 1) {
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
double dMinZ, dMaxZ ;
if ( ! IsMapPartABox( nMap, 0, m_nNx[nMap], 0, m_nNy[nMap], dMinZ, dMaxZ))
if ( ! IsMapPartABox( nMap, 0, m_nNx[nMap], 0, m_nNy[nMap], dMinZ, dMaxZ)) {
m_bIsBox = false ;
return false ;
}
}
m_bIsBox = true ;
return true ;
}
@@ -2024,10 +2026,11 @@ VolZmap::IsBox( void)
return false ;
// Controllo che gli estremi Z siano uguali.
for ( int nT = 1 ; nT < nThreadMax ; ++ nT) {
if ( abs( vMinZ[nT] - vMinZ[0]) > EPS_SMALL)
return false ;
if ( abs( vMaxZ[nT] - vMaxZ[0]) > EPS_SMALL)
if ( abs( vMinZ[nT] - vMinZ[0]) > EPS_SMALL ||
abs( vMaxZ[nT] - vMaxZ[0]) > EPS_SMALL) {
m_bIsBox = false ;
return false ;
}
}
}
+52 -100
View File
@@ -16,7 +16,6 @@
#include "ObjGraphicsMgr.h"
#include "GeoObjRW.h"
#include "Tool.h"
#include "SurfBezier.h"
#include "/EgtDev/Include/EGkVolZmap.h"
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
@@ -31,8 +30,6 @@ typedef std::vector<PNTVEC3D> PNTVEC3DVECTOR ; // vettore di intersezion
// ------------------------- FORWARD -------------------------------------------------------------
class IntersParLinesSurfTm ;
class BBox3d ;
class Frame3d ;
// ------------------------- STRUTTURE -----------------------------------------------------------
struct AppliedVector {
@@ -41,55 +38,6 @@ struct AppliedVector {
int nPropIndex ;
} ;
struct MachInfo {
int n5AxisType ;
int nSub ;
int nStepCnt ;
double dSide ;
Vector3d vtDirTipStartEx ;
Vector3d vtDirTipEndEx ;
Vector3d vtDirTopStartEx ;
Vector3d vtDirTopEndEx ;
VCT3DVECTOR vvtTipStartAux ;
VCT3DVECTOR vvtTipEndAux ;
VCT3DVECTOR vvtTopStartAux ;
VCT3DVECTOR vvtTopEndAux ;
Vector3d vtDirTip ;
Vector3d vtDirTop ;
MachInfo( int n5AxisType_, int nSub_, int nStepCnt_, double dSide_, Vector3d vtDirTipStartEx_, Vector3d vtDirTipEndEx_, Vector3d vtDirTopStartEx_, Vector3d vtDirTopEndEx_,
VCT3DVECTOR vvtTipStartAux_, VCT3DVECTOR vvtTipEndAux_, VCT3DVECTOR vvtTopStartAux_, VCT3DVECTOR vvtTopEndAux_, Vector3d vtDirTip_, Vector3d vtDirTop_) :
n5AxisType( n5AxisType_), nSub( nSub_), nStepCnt( nStepCnt_), dSide( dSide_), vtDirTipStartEx( vtDirTipStartEx_), vtDirTipEndEx( vtDirTipEndEx_), vtDirTopStartEx( vtDirTopStartEx_), vtDirTopEndEx( vtDirTopEndEx_),
vvtTipStartAux( vvtTipStartAux_), vvtTipEndAux( vvtTipEndAux_), vvtTopStartAux( vvtTopStartAux_), vvtTopEndAux( vvtTopEndAux_), vtDirTip( vtDirTip_), vtDirTop( vtDirTop_) {}
};
struct ToolInfo {
double dHeight ;
double dMaxRad ;
double dMinRad ;
double dTan ;
double dMaxH ;
double dMinH ;
double dMaxRadApprox ;
double dMinRadApprox ;
BBox3d bbStartCyl ;
BBox3d bbEndCyl ;
Frame3d frToolStart ;
Frame3d frToolEnd ;
//Vector3d vtDirTip ;
//Vector3d vtDirTop ;
ToolInfo( double dHeight_, double dMaxRad_, double dMinRad_, double dTan_, double dMaxH_, double dMinH_, double dMaxRadApprox_, double dMinRadApprox_,
BBox3d bbStartCyl_, BBox3d bbEndCyl_, Frame3d frToolStart_, Frame3d frToolEnd_) :
dHeight ( dHeight_), dMaxRad( dMaxRad_), dMinRad( dMinRad_), dTan( dTan_), dMaxH( dMaxH_), dMinH( dMinH_), dMaxRadApprox( dMaxRadApprox_), dMinRadApprox( dMinRadApprox_),
bbStartCyl( bbStartCyl_), bbEndCyl( bbEndCyl_), frToolStart( frToolStart_), frToolEnd( frToolEnd_) {}
};
struct SurfBezForInters {
SurfBezier sBez ;
BBox3d bbSurf ;
double A1, A2, B1, B2, C1, C2 ;
Vector3d d ;
};
//----------------------------------------------------------------------------
class VolZmap : public IVolZmap, public IGeoObjRW
{
@@ -137,9 +85,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
bool CreateEmpty( 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, double dExtraBox = 0.) override ;
bool CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) override ;
bool CreateFromTriMeshThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) override ;
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox = 0) override ;
int GetBlockCount( void) const override ;
int GetBlockUpdatingCounter( int nBlock) const override ;
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
@@ -153,7 +99,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
{ return m_nDexVoxRatio ; }
bool ChangeResolution( int nDexVoxRatio) override ;
void SetShowEdges( bool bShow) override
{ m_bShowEdges = bShow ; // qui necessario far ricreare la grafica
{ m_bShowEdges = bShow ; // qui è necessario far ricreare la grafica
m_OGrMgr.Clear() ; }
bool GetShowEdges( void) const override
{ return m_bShowEdges ; }
@@ -206,6 +152,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
bool SubtractSurfTm( const ISurfTriMesh* pStm) override ;
bool MakeUniform( double dToler) override ;
bool Offset( double dOffs, int nType) override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
@@ -226,6 +173,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
return *this ; }
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const ;
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const ;
bool CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) ;
bool CreateFromTriMeshThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) ;
private :
enum CubeType { VOX_EXTERN = 1,
@@ -319,7 +268,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ;
bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) ;
bool SelectGeneralMotion( int nGrid, const PNTVECTOR& ptPs, const PNTVECTOR& ptPe, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, int n5AxisType) ;
bool SelectGeneralMotion( int nGrid, const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtLs, const Vector3d& vtLe, int n5AxisType) ;
bool SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtL, const Vector3d& vtAL) ;
bool InitializePointsAndVectors( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtAs,
Point3d ptLs[3], Point3d ptLe[3], Vector3d vtLs[3], Vector3d vtALs[3]) ;
@@ -358,10 +307,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
bool GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
// lavorazioni a 5 assi
bool GenTool_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, int nToolNum, int n5AxisType = VolZmap::Move5Axis::ACROSS) ;
bool Cyl_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, int nToolNum, double dHeightCorr = 0, int n5AxisType = VolZmap::Move5Axis::ACROSS) ;
bool CylBall_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, int nToolNum, int n5AxisType = VolZmap::Move5Axis::ACROSS) ;
bool Conus_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, int nToolNum, int n5AxisType = VolZmap::Move5Axis::ACROSS) ;
bool GenTool_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
bool Cyl_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, double dHeightCorr = 0, int n5AxisType = ACROSS) ;
bool CylBall_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
bool Conus_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
// COMPONENTI
// Asse di simmetria diretto come l'asse Z
@@ -397,13 +346,13 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ,
const Point3d& ptS, const Point3d& ptE,
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
// lavorazioni a 5 assi
bool Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe,
// lavorazioni a 5 assi
bool Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
double dHeight, double dMaxRad, double dMinRad, int nToolNum, int n5AxisType) ;
bool CompCyl_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe,
double dHeight, double dRadius, int nToolNum,int n5AxisType) ;
bool CompConus_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtToolDirS, const VCT3DVECTOR& vtToolDirE, double dHei, double dMaxRad, double dMinRad,
bool bTapB, bool bTapT,const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum, int n5AxisType) ;
bool CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
double dHeight, double dRadius, int nToolNum, int n5AxisType) ;
bool CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDirS, const Vector3d& vtToolDirE, double dHei, double dMaxRad, double dMinRad,
bool bTapB, bool bTapT, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum, int n5AxisType) ;
// Generica traslazione sfera
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
@@ -449,8 +398,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
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 IntersToolLine( const Point3d& ptLineStart, const Vector3d& vtLineDir, const MachInfo& mi, const ToolInfo& ti,
const std::vector<SurfBezForInters>& vSurfBez,PNTVEC3DVECTOR& vInters, INTVECTOR& vSurfInters) const ;
bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ;
// Voxel: esistenza e passaggio da N a ijk per i voxel
bool IsValidVoxel( int nN) const ;
@@ -514,52 +461,51 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool SubtractMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
// Funzioni per Offset di superfici
bool InitVolZMapOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
bool InitVolZMapThickeningOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
bool InitVolZMapOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
bool InitVolZMapThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
bool UpdateVolZMapByOpenSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
bool UpdateVolZMapByOpenSurfSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
bool UpdateVolZMapByClosedSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
bool UpdateVolZMapByClosedSurfSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
bool UpdateVolZMapBySurfThickeningFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
bool CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid, int nVertexType = 0) ;
bool CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid, int nVertexType = 0) ;
bool UpdateVolZMapBySurfThickeningSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
bool CreateOffsetSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid, int nVertexType = 0) ;
bool CreateOffsetCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid, int nVertexType = 0) ;
bool CreateFatOffsetExtrusionFace( const ISurfTriMesh* Surf, double dOffs, bool bThickle) ;
bool CreateOrientedOffsetExtrusionFace( const ISurfTriMesh* Surf, double dOffs) ;
bool SubtractIntervalsForOffset( int nGrid, int nI, int nJ,
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
int nToolNum, bool bSkipSwap = false) ;
bool AddIntervalsForOffset( int nGrid, int nI, int nJ,
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
int nToolNum, bool bSkipSwap = false) ;
public :
// ------------------------- ENUM ----------------------------------------------------------------
enum MillingPhase {
COUNT_START_VOL = 0 ,
ONLY_LATERAL_SURF = 1 ,
COUNT_END_VOL = 2 ,
COUNT_START_END = 3
} ;
enum Move5Axis{
ALONG_CONVEX = 0 ,
ALONG_CONCAVE = 1 ,
ACROSS = 2 ,
NO_BASE_INTERS = 3
} ;
enum CuttingSurface {
NONE = -1,
TOOL = 0 ,
BZ = 1 ,
LATERAL = 2
} ;
bool CutByPlaneForOffset( const Plane3d& plCut) ;
// Funzioni per Offset di Zmap
bool OffsetFillet( double dOffs) ;
bool OffsetSharped( double dOffs, int nType) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
enum Shape { GENERIC = 0, BOX = 1, EXTRUSION = 2, OFFSET = 3} ;
enum Move5Axis {
ALONG_CONVEX = 0 ,
ALONG_CONCAVE = 1 ,
ACROSS = 2 ,
NO_BASE_INTERS = 3} ;
enum Status {
ERR = 0,
OK = 1,
TO_VERIFY = 2} ;
enum Shape {
GENERIC = 0,
BOX = 1,
EXTRUSION = 2,
OFFSET = 3} ;
static const int N_MAPS = 3 ;
static const int N_VOXBLOCK = 32 ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
int m_nTempProp[2] ; // vettore propriet temporanee
int m_nTempProp[2] ; // vettore proprietà temporanee
double m_dTempParam[2] ; // vettore parametri temporanei
bool m_bShowEdges ; // flag di visualizzazione spigoli vivi
Frame3d m_MapFrame ; // riferimento intrinseco dello Zmap
@@ -593,8 +539,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
mutable BOOLVECTOR m_BlockToUpdate ;
mutable INTVECTOR m_BlockUpdatingCounter ;
int m_nConnectedCompoCount ; // Se == - 1 il numero di componenti non noto
// Se >= 0 il numero di componenti connesse
int m_nConnectedCompoCount ; // Se == - 1 il numero di componenti non è noto
// Se >= 0 è il numero di componenti connesse
mutable std::vector<VoxelContainer> m_InterBlockVox ;
mutable SharpTriaMatrix m_InterBlockOriginalSharpTria ;
@@ -617,6 +563,12 @@ class VolZmap : public IVolZmap, public IGeoObjRW
double m_dToolAngTolDeg ;
} ;
// Offset
enum {
VOLZMAP_OFFS_FILLET = 0,
VOLZMAP_OFFS_CHANFER = 1,
VOLZMAP_OFFS_EXTENDED = 2
} ;
//-----------------------------------------------------------------------------
inline VolZmap* CreateBasicVolZmap( void)
+62 -47
View File
@@ -505,6 +505,8 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
nSupJ < 0 || nSupJ > m_nNy[nMap])
return false ;
double dCosSmall = sin( EPS_ANG_SMALL * DEGTORAD) ;
// Determinazione e ridimensionamento dei dexel interni alla trimesh
for ( int i = nInfI ; i < nSupI ; ++ i) {
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
@@ -552,7 +554,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
double dCos = IntersectionResults[k].dCosDN ;
// entro nella superficie trimesh
if ( dCos < - EPS_SMALL) {
if ( dCos < - dCosSmall) {
ptIn = IntersectionResults[k].ptI ;
@@ -565,7 +567,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
}
// esco dalla superficie trimesh
else if ( dCos > EPS_SMALL && bInside) {
else if ( dCos > dCosSmall && bInside) {
Point3d ptOut = IntersectionResults[k].ptI ;
@@ -804,7 +806,9 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
// quindi espandiamo il bounding box per ovviare al problema.
if ( dExtraBox > EPS_ZERO)
SurfBBox.Expand( dExtraBox) ;
else
dExtraBox = 0 ;
// Determino i punti estremi del bounding box
Point3d ptMapOrig, ptMapEnd ;
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
@@ -870,58 +874,69 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
// Oggetto per calcolo massivo intersezioni
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
// Numero massimo di thread
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
vector< future<bool>> vRes ;
vRes.resize( nThreadMax) ;
if ( m_nNx[nG] > m_nNy[nG]) {
int nDexNum = m_nNx[nG] / nThreadMax ;
int nRemainder = m_nNx[nG] % nThreadMax ;
int nInfI = 0 ;
int nSupI = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfI = nSupI ;
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
}
}
else {
int nDexNum = m_nNy[nG] / nThreadMax ;
int nRemainder = m_nNy[nG] % nThreadMax ;
int nInfJ = 0 ;
int nSupJ = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfJ = nSupJ ;
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
}
}
// Ciclo per attendere che tutti gli async abbiano terminato.
int nTerminated = 0 ;
while ( nTerminated < nThreadMax) {
for ( int nL = 0 ; nL < nThreadMax ; ++ nL) {
// Async terminato
if ( vRes[nL].valid() && vRes[nL].wait_for( chrono::microseconds{ 1}) == future_status::ready) {
++ nTerminated ;
bCompleted = bCompleted && vRes[nL].get() ;
// Standarda è multithread
constexpr bool MULTITHREAD = true ;
if ( MULTITHREAD) {
// Numero massimo di thread
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
vector< future<bool>> vRes ;
vRes.resize( nThreadMax) ;
if ( m_nNx[nG] > m_nNy[nG]) {
int nDexNum = m_nNx[nG] / nThreadMax ;
int nRemainder = m_nNx[nG] % nThreadMax ;
int nInfI = 0 ;
int nSupI = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfI = nSupI ;
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
}
}
else {
int nDexNum = m_nNy[nG] / nThreadMax ;
int nRemainder = m_nNy[nG] % nThreadMax ;
int nInfJ = 0 ;
int nSupJ = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfJ = nSupJ ;
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
}
}
// Ciclo per attendere che tutti gli async abbiano terminato.
int nTerminated = 0 ;
while ( nTerminated < nThreadMax) {
for ( int nL = 0 ; nL < nThreadMax ; ++ nL) {
// Async terminato
if ( vRes[nL].valid() && vRes[nL].wait_for( chrono::microseconds{ 1}) == future_status::ready) {
++ nTerminated ;
bCompleted = bCompleted && vRes[nL].get() ;
}
}
}
}
// !!!! NON MULTITHREAD : SOLO PER DEBUG !!!!
else {
CreateMapPart( nG, 0, m_nNx[nG], 0, m_nNy[nG], vtLen, ptMapOrig, Surf, intPLSTM) ;
}
}
// Assegno il minimo e massimo valore di Z della mappa
m_dMinZ[0] = 0 ;
m_dMaxZ[0] = vtLen.z ;
m_dMinZ[1] = 0 ;
m_dMaxZ[1] = ( bTriDex ? vtLen.x : 0) ;
m_dMinZ[2] = 0 ;
m_dMaxZ[2] = ( bTriDex ? vtLen.y : 0) ;
m_dMinZ[0] = dExtraBox ;
m_dMaxZ[0] = vtLen.z - dExtraBox ;
m_dMinZ[1] = ( bTriDex ? dExtraBox : 0) ;
m_dMaxZ[1] = ( bTriDex ? vtLen.x - dExtraBox : 0) ;
m_dMinZ[2] = ( bTriDex ? dExtraBox : 0) ;
m_dMaxZ[2] = ( bTriDex ? vtLen.y - dExtraBox : 0) ;
// Tipologia
m_nShape = ( dExtraBox > EPS_ZERO && IsBox() ? BOX : GENERIC) ;
// Con espansione non va considerato box (calcolo trimesh va in crash)
m_nShape = ( dExtraBox <= EPS_ZERO && IsBox() ? BOX : GENERIC) ;
// Aggiornamento dello stato
m_nStatus = OK ;
+32 -16
View File
@@ -950,25 +950,41 @@ VolZmap::UpdateTripleMapGraphics( void) const
}
}
// Calcolo i triangoli sui blocchi
int nBlockUpdated = 0 ;
vector< future<bool>> vRes ;
vRes.resize( m_nNumBlock) ;
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
// Se il blocco deve essere processato
if ( m_BlockToUpdate[i]) {
// processo ...
++ nBlockUpdated ;
vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ;
// Standarda è multithread
constexpr bool MULTITHREAD = true ;
if ( MULTITHREAD) {
// Calcolo i triangoli sui blocchi
int nBlockUpdated = 0 ;
vector< future<bool>> vRes ;
vRes.resize( m_nNumBlock) ;
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
// Se il blocco deve essere processato
if ( m_BlockToUpdate[i]) {
// processo ...
++ nBlockUpdated ;
vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ;
}
}
bool bOk = true ;
int nTerminated = 0 ;
while ( nTerminated < nBlockUpdated) {
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
bOk = vRes[i].get() && bOk ;
++ nTerminated ;
}
}
}
}
bool bOk = true ;
int nTerminated = 0 ;
while ( nTerminated < nBlockUpdated) {
else {
// Calcolo i triangoli sui blocchi
bool bOk = true ;
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
bOk = vRes[i].get() && bOk ;
++ nTerminated ;
// Se il blocco deve essere processato
if ( m_BlockToUpdate[i]) {
// processo ...
bOk = ExtMarchingCubes( i, vVoxContainerVec[i]) && bOk ;
}
}
}
+1797 -110
View File
File diff suppressed because it is too large Load Diff
+1063 -1330
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -34,3 +34,4 @@
#pragma comment(lib, EGTLIBDIR "EgtGeneral" EGTLIBVER ".lib")
#pragma comment(lib, EGTLIBDIR "EgtNumKernel" EGTLIBVER ".lib")
#pragma comment(lib, EGTLIBDIR "SEgtLock" EGTLIBVER ".lib")
#pragma comment(lib, EGTLIBDIR "abseil" EGTLIBVER ".lib")