Compare commits

...

26 Commits

Author SHA1 Message Date
Riccardo Elitropi c0b5f38301 EgtGeomKernel :
- migliorie alle funzioni SharpRectSwept e BeveledRectSwept
- migliorie varie.
2024-05-16 13:06:55 +02:00
Riccardo Elitropi 3e6aa0d81b EgtGeomKernel :
- creazione Zmap aggiungendo TriMesh.
2024-05-15 10:57:37 +02:00
Dario Sassi 34089648b0 EgtGeomKernel 2.6e4 :
- in CalcPocketing sistemata gestione di memoria che poteva dare crash.
2024-05-14 19:18:41 +02:00
Dario Sassi 0bef1638d0 EgtGeomKernel :
- corretto controllo di curva composita chiusa per caso con un solo arco.
2024-05-13 16:26:01 +02:00
Dario Sassi 17759877d4 EgtGeomKernel 2.6e3 :
- interfaccia DistLineLine ora esportata
- in lettura Curve Composite allargata tolleranza giunzione tra componenti.
2024-05-13 07:56:42 +02:00
Dario Sassi d00064a671 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-05-08 15:08:52 +02:00
SaraP dc91f932f7 EgtGeomKernel :
- correzione nell'associazione dei punti a minima distanza delle polylines.
2024-05-08 11:15:51 +02:00
Dario Sassi d911862c84 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-05-07 19:46:02 +02:00
Dario Sassi 1b025ec60e EgtGeomKernel :
- in GeneralizedCut di SurfTriMesh migliorata gestione delle facce.
2024-05-07 19:45:50 +02:00
Daniele Bariletti 9d18e1a9ba EgtGeomKernel :
- mantenuta l'approssimazione della spirale con bezier cubiche razionali.
2024-05-07 17:34:42 +02:00
Dario Sassi 3a8900983a Merge commit '35c019a03e4662fbf0a9a402df7082d526ff42ec' 2024-05-07 11:25:34 +02:00
Dario Sassi 971a76e473 EgtGeomKernel :
- in CAvToolSurfTm corretto segno parametro spostamento della posizione
- migliorata RemoveAlignedPoints di PolyLine con controllo punto iniziale di percorsi chiusi
- modificate GetSurfTriMeshSharpRectSwept e GetSurfTriMeshBeveledRectSwept per generare superfici chiuse.
2024-05-07 11:23:49 +02:00
Daniele Bariletti 35c019a03e EgtGeomKernel :
- cambio versione.
2024-05-07 10:17:11 +02:00
Daniele Bariletti de97f249a2 Merge branch 'MoreBezier' 2024-05-07 10:06:47 +02:00
Daniele Bariletti 81f0cc23bf EgtGeomKernel :
- aggiunte le funzioni per la conversione da curva generica a curva di Bezier.
2024-05-07 10:03:03 +02:00
Dario Sassi 8a0234093e EgtGeomKernel :
- nella ricostruzione dei contorni delle superfici TriMesh (Loops) inseriti controlli per terminare cicli andati in loop
- nella funzione di taglio delle superfici TriMesh con un piano aumentata del 10% la tolleranza (1.1 * EPS_SMALL).
2024-05-03 12:00:55 +02:00
Dario Sassi 88d355f2f7 EgtGeomKernel :
- in SurfTriMesh SetTFlag e GetTFlag messe in interfaccia (inoltre corretta la prima funzione).
2024-05-02 09:29:01 +02:00
Dario Sassi 20fd06d67c EgtGeomKernel 2.6e1 :
- ricompilazione per modifiche a gestione chiave di rete.
2024-04-30 16:53:39 +02:00
Daniele Bariletti 52f2785e67 Merge branch 'master' into MoreBezier 2024-04-30 15:34:30 +02:00
Dario Sassi 2e2bd0ceec Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-04-30 08:54:52 +02:00
Daniele Bariletti e4c3c9a2a4 EgtGeomKernel :
- aumentato il grado possibile per curve/superfici di Bezier.
2024-04-30 08:53:09 +02:00
Dario Sassi 1160e3d067 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtGeomKernel 2024-04-26 11:24:44 +02:00
Dario Sassi 91d667bcfc EgtGeomKernel :
- modifiche a Zmap per virtual-additive
- modifiche a Frame3d per Set con i tre assi che ora aggiusta errori molto piccoli.
2024-04-26 11:23:56 +02:00
Dario Sassi 3dd9466938 Merge commit 'c0f7eb6727287b012402c0c52c5b50195257df83' 2024-04-24 09:32:35 +02:00
Dario Sassi 76e2843ed3 Merge commit 'faa2004c298ad6a2d3e35c61fbf893cdf7beb779' 2024-04-22 19:06:50 +02:00
Riccardo Elitropi faa2004c29 EgtGeomKernel :
- integrate modifiche vMill additivo dal ramo TempForVmill.
2024-04-22 13:21:37 +02:00
29 changed files with 2530 additions and 543 deletions
+3 -2
View File
@@ -212,8 +212,9 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
while ( itPntMCurr != lPntM.end()) {
// verifico il punto
ptCurr = itPntMCurr->first ;
itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ;
if ( itPntMCurr->second < - EPS_SMALL)
double dMove = MyTestPositionHG( itPntMCurr->first, vtDir) ;
itPntMCurr->second = - dMove ;
if ( dMove < - EPS_SMALL)
return false ;
// se esiste il punto precedente devo verificare il medio
if ( itPntMPrev != lPntM.end()) {
+1 -2
View File
@@ -12,11 +12,10 @@
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "DistLineLine.h"
#include "CDeTriaTria.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
#include <array>
#include <algorithm>
using namespace std ;
+3 -3
View File
@@ -759,7 +759,7 @@ GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICU
PtrOwner<ISurfFlatRegion> pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( Release( pCrvLink_i), s_dRad + 5 * EPS_SMALL, false, false)) ;
if ( ! IsNull( pSrfToolRegLinki)) {
if ( ! pSrfTool_Links->IsValid() || pSrfTool_Links->GetChunkCount() == 0)
pSrfTool_Links.Set( GetBasicSurfFlatRegion( pSrfToolRegLinki)) ;
pSrfTool_Links.Set( GetBasicSurfFlatRegion( Release( pSrfToolRegLinki))) ;
else
pSrfTool_Links->Add( *pSrfToolRegLinki) ;
}
@@ -2536,7 +2536,7 @@ CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpCrvs, double
vAddedLinks.emplace_back( pCrvLink->Clone()) ;
// pSeg2 ora diventa pSeg1 e il procedimento si itera per tutto il percorso
pLastSeg.Set( Release( pSeg2)) ;
pLastSeg.Set( pSeg2) ;
}
// cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno
double dUstart = Sec.dOe ;
@@ -3164,7 +3164,7 @@ AdjustLinkDifferentY( const ICurve* pCrvSegPrec, const ICurve* pCrvSegSucc, cons
if ( IsNull( pSfrTrap_c))
return false ;
if ( ! pSfrTrap->Offset( - s_dRad / 5, ICurve::OFF_CHAMFER))
pSfrTrap.Set( Release( pSfrTrap_c)) ;
pSfrTrap.Set( pSfrTrap_c) ;
// se il Link interseca questa regione, allora va eliminato
CRVCVECTOR ccClass ;
+270 -2
View File
@@ -403,9 +403,20 @@ CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv)
return true ;
}
//----------------------------------------------------------------------------
ICurveBezier*
LineToBezierCurve( const ICurveLine* pCrvLine)
{
PtrOwner<ICurveBezier> pCrvBezier( CreateCurveBezier()) ;
// rendo tutte le curve di grado 2 e razionali così posso convertire anche archi e avere tutte curve dello stesso grado e razionali
pCrvBezier->Init( 2, true) ;
pCrvBezier->FromLine( *pCrvLine) ;
return Release( pCrvBezier) ;
}
//----------------------------------------------------------------------------
ICurve*
ArcToBezierCurve( const ICurve* pCrv)
ArcToBezierCurve( const ICurve* pCrv, bool bDeg3OrDeg2)
{
// verifico sia un arco
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
@@ -413,7 +424,8 @@ ArcToBezierCurve( const ICurve* pCrv)
return nullptr ;
// se angolo al centro sotto il limite, basta una curva
if ( abs( pArc->GetAngCenter()) < BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL) {
if ( ( abs( pArc->GetAngCenter()) < BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL && abs( pArc->GetDeltaN()) < EPS_ZERO && ! bDeg3OrDeg2) ||
( abs( pArc->GetAngCenter()) < BEZARC_ANG_CEN_MAX + EPS_ANG_SMALL && bDeg3OrDeg2)) {
// creo la curva di Bezier equivalente all'arco
PtrOwner<CurveBezier> pCrvBez( CreateBasicCurveBezier()) ;
if ( IsNull( pCrvBez) || ! pCrvBez->FromArc( *pArc))
@@ -429,6 +441,8 @@ ArcToBezierCurve( const ICurve* pCrv)
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
@@ -451,6 +465,260 @@ ArcToBezierCurve( const ICurve* pCrv)
}
}
//----------------------------------------------------------------------------
ICurve*
CompositeToBezierCurve( const ICurveComposite* pCC)
{
// 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 ;
if ( pCC->GetCurve(i)->GetType() == CRV_ARC) {
const CurveArc* crArc = GetBasicCurveArc( pCC->GetCurve(i)) ;
ICurve* pCrvBezier = ArcToBezierCurve( crArc) ;
if ( pCrvBezier == nullptr)
return nullptr ;
// 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) {
const CurveLine* crLine = GetBasicCurveLine( pCC->GetCurve(i)) ;
ICurve* pCrvBezier = LineToBezierCurve( crLine) ;
if ( pCrvBezier == nullptr)
return nullptr ;
pCrvNew.Set( pCrvBezier) ;
}
else if ( pCC->GetCurve(i)->GetType() == CRV_BEZIER ) {
const CurveBezier* crvBezier = GetBasicCurveBezier( pCC->GetCurve(i)) ;
ICurve* pCrvBezier = BezierToBasicBezierCurve( crvBezier) ;
if ( pCrvBezier == nullptr)
return nullptr ;
pCrvNew.Set( pCrvBezier) ;
}
pCCBezier->AddCurve( Release( pCrvNew)) ;
}
return Release( pCCBezier) ;
}
//----------------------------------------------------------------------------
ICurve*
BezierToBasicBezierCurve( const ICurveBezier* pCrvBezier)
{
// resta da calcolare un errore sull'approssimazione oppure usare la tecnica di spezzare la curva originale in sottocurve e approssimarle con bezier cubiche
// per ridurre molto l'errore
// dovrei restituire una bezier di grado 2, razionale per poter essere uniforme con le altre curve trasmorate in bezier
PtrOwner<ICurveBezier> pCrvNew( pCrvBezier->Clone()) ;
int nDeg = pCrvBezier->GetDegree() ;
bool bRat = pCrvBezier->IsRational() ;
// se la curva è già nella forma giusta la restituisco
if ( nDeg == 2 && bRat)
return Release( pCrvNew) ;
// sennò la riduco di grado fino al 2
PtrOwner<ICurveBezier> pBasicBezier ( CreateCurveBezier()) ;
pBasicBezier->Init( 2, true) ;
double dW = 1 ;
if ( nDeg == 1) {
Point3d ptStart = pCrvBezier->GetControlPoint( 0) ;
Point3d ptEnd = pCrvBezier->GetControlPoint( 1) ;
pBasicBezier->SetControlPoint( 0, ptStart, dW) ;
pBasicBezier->SetControlPoint( 1, 0.5 * (ptStart + ptEnd), dW) ;
pBasicBezier->SetControlPoint( 2, ptEnd, dW) ;
return Release( pBasicBezier) ;
}
while ( nDeg > 2 ) {
pCrvNew.Set( BezierDecreaseDegree( pCrvNew, 1)) ;
if ( IsNull( pCrvNew) || ! pCrvNew->IsValid())
return nullptr ;
-- nDeg ;
}
for ( int i = 0 ; i < 3 ; ++i) {
Point3d ptCopy = pCrvNew->GetControlPoint( i) ;
if ( bRat)
dW = pCrvNew->GetControlWeight( i) ;
pBasicBezier->SetControlPoint( i, ptCopy, dW) ;
}
return Release( pBasicBezier) ;
}
ICurveBezier*
BezierIncreaseDegree(const ICurveBezier* pCrvBezier)
{
if ( pCrvBezier == nullptr)
return nullptr ;
// 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
Point3d ptCtrlPrev = pCrvBezier->GetControlPoint( 0) ;
double dWprev = 1 ;
if ( bRat ) {
dWprev = pCrvBezier->GetControlWeight( 0) ;
pNewBezier->SetControlPoint( 0, ptCtrlPrev, dWprev) ;
}
else
pNewBezier->SetControlPoint( 0, ptCtrlPrev) ;
// 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)) ;
Point3d ptNew = ( i / nDeg) * ptCtrlPrev + ( 1 - i / ( nDeg)) * ptCtrlCurr ;
if ( bRat) {
dWcurr = pCrvBezier->GetControlWeight( int( i)) ;
double dWnew = ( i / nDeg) * dWprev + ( 1 - i / ( nDeg)) * dWcurr ;
pNewBezier->SetControlPoint( int( i), ptNew, dWnew) ;
dWprev = dWnew ;
}
else
pNewBezier->SetControlPoint( int( i), ptNew) ;
ptCtrlPrev = ptCtrlCurr ;
}
// salvo l'ultimo punto
ptCtrlCurr = pCrvBezier->GetControlPoint( nDeg - 1) ;
if ( bRat ) {
dWcurr = pCrvBezier->GetControlWeight( nDeg - 1) ;
pNewBezier->SetControlPoint( nDeg, ptCtrlCurr, dWcurr) ;
}
else
pNewBezier->SetControlPoint( nDeg, ptCtrlCurr) ;
return Release( pNewBezier) ;
}
ICurveBezier*
BezierDecreaseDegree(const ICurveBezier* pCrvBezier, double dTol)
{
if ( pCrvBezier == nullptr)
return nullptr ;
PtrOwner<ICurveBezier> pNewBezier( CreateCurveBezier()) ;
int nDeg = pCrvBezier->GetDegree() - 1 ;
if ( nDeg == 0)
return nullptr ;
bool bRat = pCrvBezier->IsRational() ;
pNewBezier->Init( nDeg, bRat) ;
// prev e curr sono riferiti alla nuova curva
//salvo il primo punto
Point3d ptCtrlPrev = pCrvBezier->GetControlPoint( 0) ;
double dWprev = 1 ;
if ( bRat ) {
dWprev = pCrvBezier->GetControlWeight( 0) ;
pNewBezier->SetControlPoint( 0, ptCtrlPrev, dWprev) ;
}
else
pNewBezier->SetControlPoint( 0, ptCtrlPrev) ;
// ciclo sui punti intermedi per trovare i nuovi punti di controllo // equazioni da NURBS book
Point3d ptCtrlCurr ;
double dWcurr ;
int r = int (nDeg / 2) ;
// prima metà
for ( double i = 1 ; i < r ; ++i) {
double dAlpha = i / ( nDeg + 1) ;
// old è riferito alla curva originale
Point3d ptOld = pCrvBezier->GetControlPoint( int( i)) ;
ptCtrlCurr = ( ptOld + (- dAlpha * ptCtrlPrev)) / ( 1 - dAlpha) ;
if ( bRat) {
double dWold = pCrvBezier->GetControlWeight( int( i)) ;
dWcurr = ( dWold + (- dAlpha * dWprev)) / ( 1 - dAlpha) ;
pNewBezier->SetControlPoint( int( i), ptCtrlCurr, dWcurr) ;
dWprev = dWcurr ;
}
else
pNewBezier->SetControlPoint( int( i), ptCtrlCurr) ;
ptCtrlPrev = ptCtrlCurr ;
}
// risolvo il punto di mezzo per il caso nDeg pari
if ( ( nDeg + 1) % 2 == 0) { // pari
double dAlpha = r / ( nDeg + 1.) ;
Point3d ptOld = pCrvBezier->GetControlPoint( r) ;
ptCtrlCurr = ( ptOld + (- dAlpha * ptCtrlPrev)) / ( 1 - dAlpha) ;
if ( bRat) {
double dWold = pCrvBezier->GetControlWeight( r) ;
dWcurr = ( dWold + (- dAlpha * dWprev)) / ( 1 - dAlpha) ;
pNewBezier->SetControlPoint( r, ptCtrlCurr, dWcurr) ;
dWprev = dWcurr ;
}
else
pNewBezier->SetControlPoint( r, ptCtrlCurr) ;
}
// salvo l'ultimo punto
ptCtrlCurr = pCrvBezier->GetControlPoint( nDeg + 1) ;
if ( bRat ) {
dWcurr = pCrvBezier->GetControlWeight( nDeg + 1) ;
pNewBezier->SetControlPoint( nDeg, ptCtrlCurr, dWcurr) ;
}
else
pNewBezier->SetControlPoint( nDeg, ptCtrlCurr) ;
ptCtrlPrev = ptCtrlCurr ;
if ( bRat)
dWprev = dWcurr ;
// seconda metà
for ( double i = nDeg - 1 ; i > r ; --i) {
double dAlpha = ( i + 1) / ( nDeg + 1) ;
Point3d ptOld = pCrvBezier->GetControlPoint( int( i) + 1) ;
ptCtrlCurr = ( ptOld + ( - ( 1 - dAlpha) * ptCtrlPrev)) / dAlpha ;
if ( bRat) {
double dWold = pCrvBezier->GetControlWeight( int( i) + 1) ;
dWcurr = ( dWold - ( ( 1 - dAlpha) * dWprev)) / dAlpha ;
pNewBezier->SetControlPoint( int( i), ptCtrlCurr, dWcurr) ;
dWprev = dWcurr ;
}
else
pNewBezier->SetControlPoint( int( i), ptCtrlCurr) ;
ptCtrlPrev = ptCtrlCurr ;
}
// risolvo il punto di mezzo per il caso nDeg dispari
// calcolo anche l'errore di approssimazione
double dErr = 0 ;
if ( (nDeg + 1) % 2 != 0) { // dispari
// puntdo di sinistra
double dAlpha = r / ( nDeg + 1.) ;
ptCtrlPrev = pNewBezier->GetControlPoint( r - 1) ;
Point3d ptOld = pCrvBezier->GetControlPoint( r) ;
Point3d ptL = ( ptOld + ( - dAlpha * ptCtrlPrev)) / ( 1 - dAlpha) ;
double dWL = 1 ;
if ( bRat) {
dWprev = pNewBezier->GetControlWeight( r - 1) ;
double dWold =pCrvBezier->GetControlWeight( r) ;
dWL = ( dWold - ( dAlpha * dWprev)) / ( 1 - dAlpha) ;
}
// punto di destra
dAlpha = ( r + 1.) / ( nDeg + 1.) ;
ptCtrlPrev = pNewBezier->GetControlPoint( r + 1) ;
ptOld = pCrvBezier->GetControlPoint( r + 1) ;
double dWR = 1 ;
if ( bRat) {
dWprev = pNewBezier->GetControlWeight( r + 1) ;
double dWold =pCrvBezier->GetControlWeight( r + 1) ;
dWR = ( dWold - ( ( 1 - dAlpha) * dWprev)) / dAlpha ;
}
Point3d ptR = ( ptOld + ( - ( 1 - dAlpha) * ptCtrlPrev)) / dAlpha ;
// calcolo il punto di mezzo e lo aggiungo
Point3d ptNew = ( ptL + ptR) / 2 ;
double dWnew = ( dWL + dWR) / 2 ;
if ( bRat)
pNewBezier->SetControlPoint( r, ptNew, dWnew) ;
else
pNewBezier->SetControlPoint( r, ptNew) ;
dErr = Dist( ptL, ptR) ;
}
else {
ptCtrlCurr = pNewBezier->GetControlPoint( r + 1) ;
ptCtrlPrev = pNewBezier->GetControlPoint( r) ;
Point3d ptOld = pCrvBezier->GetControlPoint( r + 1) ;
dErr = Dist( ptOld, 0.5 * ( ptCtrlPrev + ptCtrlCurr)) ;
}
//// se l'approssimazione dà un errore troppo alto allora annullo tutto // da controllare
//if ( dErr > dTol)
// return nullptr ;
return Release( pNewBezier) ;
}
//----------------------------------------------------------------------------
ICurve*
CurveToNoArcsCurve( const ICurve* pCrv)
+56
View File
@@ -27,12 +27,15 @@
#include "Bernstein.h"
#include "deCasteljau.h"
#include "Voronoi.h"
#include "IntersLineLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUiUnits.h"
#include "/EgtDev/Include/ENkPolynomial.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include <array>
using namespace std ;
@@ -195,6 +198,35 @@ CurveBezier::FromArc( const ICurveArc& crArc)
SetControlPoint( 1, ptNew1, dW) ;
SetControlPoint( 2, ptNew2, dW) ;
SetControlPoint( 3, ptEnd, 1) ;
//// anziché usare una bezier cubica approssimo le eliche con più bezier quadratiche razionali.
//// più è grande l'angolo al centro dell'arco e maggiore sarà l'errore di approssimazione
//
// // quadratica razionale
// // peso del punto di controllo intermedio
// double dW = dCosAhalf ;
// // calcolo dei punti di controllo
// Point3d ptStart ;
// crArc.GetStartPoint( ptStart) ;
// Point3d ptEnd ;
// crArc.GetEndPoint( ptEnd) ;
// // Point3d ptMed = Media( ptStart, ptEnd, 0.5) ;
// //Vector3d vtDir = ptMed - crArc.GetCenter() ;
// // Point3d ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ;
// Vector3d vtStart ; crArc.GetStartDir( vtStart) ;
// Vector3d vtEnd ; crArc.GetEndDir( vtEnd) ;
// PtrOwner<CurveLine> pCrvLine1( CreateBasicCurveLine()) ;
// pCrvLine1->SetPVL( ptStart, vtStart, 10) ;
// PtrOwner<CurveLine> pCrvLine2( CreateBasicCurveLine()) ;
// pCrvLine2->SetPVL( ptEnd, vtEnd, 10) ;
// IntersLineLine ill( *pCrvLine1, *pCrvLine2, false) ;
// IntCrvCrvInfo iccInfo ; ill.GetIntCrvCrvInfo( iccInfo) ;
// Point3d ptNew = 0.5 * (iccInfo.IciA->ptI + iccInfo.IciB->ptI) ;
// // inserimento nella curva dei punti di controllo con i pesi
// Init( 2, true) ;
// SetControlPoint( 0, ptStart, 1) ;
// SetControlPoint( 1, ptNew, dW) ;
// SetControlPoint( 2, ptEnd, 1) ;
}
// copio estrusione e spessore
@@ -204,6 +236,30 @@ CurveBezier::FromArc( const ICurveArc& crArc)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveBezier::FromLine( const ICurveLine& crLine)
{
if ( ! crLine.IsValid())
return false ;
double dWeight = 1 ;
int nCount = 0 ;
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
SetControlPoint( nCount, ptStart, dWeight) ;
++nCount ;
double dPart = 1. / m_nDeg ;
for ( int i = 1 ; i < m_nDeg ; ++i) {
double dU = i * dPart ;
Point3d ptMid ; crLine.GetPointD1D2( dU, ICurve::FROM_MINUS, ptMid) ;
SetControlPoint( nCount, ptMid, dWeight) ;
++nCount ;
}
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
SetControlPoint( nCount, ptEnd, dWeight) ;
++nCount ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveBezier::IsAPoint( void) const
+2 -1
View File
@@ -138,6 +138,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ;
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
bool FromArc( const ICurveArc& crArc) override ;
bool FromLine( const ICurveLine& crLine) override ;
int GetDegree( void) const override
{ return m_nDeg ; }
bool IsRational( void) const override
@@ -190,7 +191,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
static const int MAXDEG = 11 ;
static const int MAXDEG = 21 ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
+7 -4
View File
@@ -745,7 +745,7 @@ CurveComposite::Load( NgeReader& ngeIn)
ICurve* pCrv = ::GetCurve( pGeoO) ;
bOk = bOk && ( pCrv != nullptr && pCrv->IsSimple()) ;
// aggiungo questa curva (sicuramente semplice)
bOk = bOk && AddSimpleCurve( pCrv) ;
bOk = bOk && AddSimpleCurve( pCrv, true, 10 * EPS_SMALL) ;
// se errore
if ( ! bOk)
return false ;
@@ -878,10 +878,13 @@ CurveComposite::TestClosure( void)
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
// se distanza superiore al limite ridotto forzo i punti a coincidere
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
// se un solo arco
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_ARC)
return GetBasicCurveArc( m_CrvSmplS.front())->ChangeAngCenter( ANG_FULL) ;
// caso generale
Point3d ptM = Media( ptStart, ptEnd) ;
if ( ! m_CrvSmplS.front()->ModifyStart( ptM) ||
! m_CrvSmplS.back()->ModifyEnd( ptM))
return false ;
return ( m_CrvSmplS.front()->ModifyStart( ptM) &&
m_CrvSmplS.back()->ModifyEnd( ptM)) ;
}
return true ;
}
+3 -4
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2020-2022
// EgalTech 2020-2024
//----------------------------------------------------------------------------
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1
// File : DistLineLine.cpp Data : 10.05.24 Versione : 2.6e3
// Contenuto : Implementazione della classe distanza fra elementi lineari.
//
//
@@ -12,11 +12,10 @@
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "DistLineLine.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkGeoCollection.h"
#include "/EgtDev/Include/EGkGeoConst.h"
#include <algorithm>
using namespace std ;
-53
View File
@@ -1,53 +0,0 @@
//----------------------------------------------------------------------------
// EgalTech 2020-2020
//----------------------------------------------------------------------------
// File : DistLineLine.h Data : 06.11.20 Versione : 2.2k1
// Contenuto : Dichiarazione della classe distanza fra elementi lineari.
//
//
//
// Modifiche : 06.11.20 LM Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkVector3d.h"
#include "/EgtDev/Include/EGkPoint3d.h"
//----------------------------------------------------------------------------
class DistLineLine
{
public :
DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1,
const Point3d& ptSt2, const Point3d& ptEn2,
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
public :
bool GetSqDist( double& dSqDist) const ;
bool GetDist( double& dDist) const ;
bool IsEpsilon( double dTol) const
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
bool IsSmall( void) const
{ return IsEpsilon( EPS_SMALL) ; }
bool IsZero( void) const
{ return IsEpsilon( EPS_ZERO) ; }
bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) const ;
bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) const ;
private :
void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
bool bIsSegment1, bool bIsSegment2) ;
private:
double m_dSqDist ;
mutable double m_dDist ;
double m_dPos1 ;
double m_dPos2 ;
Point3d m_ptMinDist1 ;
Point3d m_ptMinDist2 ;
} ;
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -328,6 +328,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
<ClInclude Include="..\Include\EGkDistLineLine.h" />
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
@@ -595,7 +596,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="CAvSimpleSurfFrMove.h" />
<ClInclude Include="CAvToolSurfTm.h" />
<ClInclude Include="CreateCurveAux.h" />
<ClInclude Include="DistLineLine.h" />
<ClInclude Include="DistPointArc.h" />
<ClInclude Include="DistPointCrvAux.h" />
<ClInclude Include="DistPointCrvBezier.h" />
+3 -3
View File
@@ -1118,9 +1118,6 @@
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="DistLineLine.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="CDeUtility.h">
<Filter>File di intestazione</Filter>
</ClInclude>
@@ -1214,6 +1211,9 @@
<ClInclude Include="..\Include\EGkQuaternion.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkDistLineLine.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+17
View File
@@ -37,6 +37,23 @@ Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX,
! m_vtVersZ.Normalize())
return false ;
// se ci sono errori molto piccoli di ortogonalità, li correggo
double dOrtXZ = m_vtVersX * m_vtVersZ ;
if ( dOrtXZ > EPS_ZERO && dOrtXZ < 10 * EPS_ZERO) {
m_vtVersX = OrthoCompo( m_vtVersX, m_vtVersZ) ;
m_vtVersX.Normalize() ;
}
double dOrtYX = m_vtVersY * m_vtVersX ;
if ( dOrtYX > EPS_ZERO && dOrtYX < 10 * EPS_ZERO) {
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersX) ;
m_vtVersY.Normalize() ;
}
double dOrtYZ = m_vtVersY * m_vtVersZ ;
if ( dOrtYZ > EPS_ZERO && dOrtYZ < 10 * EPS_ZERO) {
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersZ) ;
m_vtVersY.Normalize() ;
}
// verifica della ortogonalità dei versori e del senso destrorso
if ( ! Verify())
return false ;
+1 -1
View File
@@ -14,7 +14,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineCaps.h"
#include "DistLineLine.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EGkIntersLineSphere.h"
using namespace std ;
+1 -1
View File
@@ -18,7 +18,7 @@
#include "IntersLineLine.h"
#include "IntersLineTria.h"
#include "DistPointLine.h"
#include "DistLineLine.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include <array>
+37 -44
View File
@@ -1,4 +1,4 @@
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// EgalTech 2013-2013
//----------------------------------------------------------------------------
// File : PolyLine.cpp Data : 22.12.13 Versione : 1.4l3
@@ -53,7 +53,7 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
{
// se da aggiungere in coda
if ( bEndOrStart) {
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
++ m_nRejected ;
return true ;
@@ -68,7 +68,7 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
}
// altrimenti si aggiunge in testa
else {
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
++ m_nRejected ;
return true ;
@@ -92,7 +92,7 @@ PolyLine::Close( void)
// ci devono essere almeno 2 punti
if ( m_lUPoints.size() < 2)
return false ;
// verifico non sia già chiuso
// verifico non sia già chiuso
if ( AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first))
return false ;
// aggiungo un punto uguale al primo in coda
@@ -219,7 +219,7 @@ PolyLine::ToLoc( const Frame3d& frRef)
bool
PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
{
// se i due riferimenti coincidono, non devo fare alcunché
// se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest))
return true ;
// ciclo sui punti
@@ -233,7 +233,7 @@ PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
bool
PolyLine::Join( PolyLine& PL, double dOffsetPar)
{
// se l'altra polilinea non contiene alcunchè, esco con ok
// se l'altra polilinea non contiene alcunchè, esco con ok
if ( PL.m_lUPoints.size() == 0)
return true ;
// verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra
@@ -385,7 +385,7 @@ PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP, bool bNotFirst) const
bool
PolyLine::GetCurrUPoint( double* pdPar, Point3d* pptP) const
{
// verifico validità punto corrente
// verifico validità punto corrente
if ( m_iter == m_lUPoints.end())
return false ;
@@ -426,7 +426,7 @@ PolyLine::GetFirstULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d*
bool
PolyLine::GetNextULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin) const
{
// parametro e punto iniziali (è il precedente finale)
// parametro e punto iniziali (è il precedente finale)
if ( m_iter == m_lUPoints.end())
return false ;
if ( pdIni != nullptr)
@@ -510,19 +510,19 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.25), dLen / 2) ;
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.75), dLen / 2) ;
}
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
nRank = ptsPCA.GetRank() ;
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
if ( nRank == 0)
return ptsPCA.GetCenter( ptCen) ;
// se dimensione 1, allora i punti sono distribuiti su una linea
if ( nRank == 1) {
// assegno il centro e la direzione della linea (il verso è indifferente)
// assegno il centro e la direzione della linea (il verso è indifferente)
ptsPCA.GetCenter( ptCen) ;
ptsPCA.GetPrincipalComponent( 0, vtDir) ;
return true ;
}
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
// Center and normal vector
ptsPCA.GetCenter( ptCen) ;
Vector3d vtX, vtY ;
@@ -530,9 +530,9 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
ptsPCA.GetPrincipalComponent( 1, vtY) ;
vtDir = vtX ^ vtY ;
if ( ! vtDir.Normalize()) {
// riduco la dimensionalità a lineare
// riduco la dimensionalità a lineare
nRank = 1 ;
// assegno il centro e la direzione della linea (il verso è indifferente)
// assegno il centro e la direzione della linea (il verso è indifferente)
ptsPCA.GetCenter( ptCen) ;
vtDir = vtX ;
return true ;
@@ -561,12 +561,12 @@ PolyLine::IsFlat( Plane3d& plPlane, double dToler) const
plPlane.Reset() ;
return false ;
}
// recupero dati sulla planarità della polilinea
// recupero dati sulla planarità della polilinea
int nRank ;
Point3d ptCen ;
Vector3d vtDir ;
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
// imposto il piano a seconda della dimensionalità
// imposto il piano a seconda della dimensionalità
switch ( nRank) {
case 0 : // punto
plPlane.Set( ptCen, Z_AX) ;
@@ -639,13 +639,13 @@ PolyLine::GetAreaXY( double& dArea) const
// verifico sia chiusa
if ( ! IsClosed())
return false ;
// calcolo l'area considerando solo XY (è la Z di Newell)
// calcolo l'area considerando solo XY (è la Z di Newell)
dArea = 0 ;
Point3d ptIni, ptFin ;
for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) {
dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
}
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
// significativa anche se sono coincidenti per le nostre tolleranze
ptIni = ptFin ;
GetFirstPoint( ptFin) ;
@@ -746,7 +746,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
}
}
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
if ( dMaxSqDist > dSqTol) {
// inserisco il punto
@@ -789,7 +789,7 @@ PolyLine::RemoveAlignedPoints( double dToler)
}
// altrimenti chiusa
else {
// cerco il punto più distante dal primo
// cerco il punto più distante dal primo
double dMaxDist = 0. ;
int nMaxInd = 0 ;
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
@@ -812,6 +812,14 @@ PolyLine::RemoveAlignedPoints( double dToler)
// ordino in senso crescente
sort( vInd.begin(), vInd.end()) ;
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
if ( IsClosed() && vInd.size() >= 4) {
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[vInd.size()-2]].first).IsEpsilon( dToler)) {
vInd.erase( vInd.begin()) ;
vInd.back() = vInd.front() ;
}
}
// rimetto in lista i soli punti rimasti
m_lUPoints.clear() ;
for ( auto Ind : vInd)
@@ -958,7 +966,7 @@ PolyLine::MyApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
}
}
}
// non è stato eliminato alcunché
// non è stato eliminato alcunché
// ripristino la tolleranza corrente
dCurrToler = dToler ;
// avanzo il terzetto di uno step
@@ -999,7 +1007,7 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
bool
PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
{
// ciclo i controlli finchè non ci sono rimozioni
// ciclo i controlli finchè non ci sono rimozioni
bool bRemoved = true ;
while ( bRemoved) {
bRemoved = false ;
@@ -1027,7 +1035,7 @@ PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
bRemoved = true ;
continue ;
}
// non è stato eliminato alcunché : avanzo il terzetto di uno step
// non è stato eliminato alcunché : avanzo il terzetto di uno step
precP = currP ;
currP = nextP ;
++ nextP ;
@@ -1054,7 +1062,7 @@ PolyLine::Invert( bool bInvertU)
m_lUPoints.reverse() ;
// se richiesto, inverto anche il parametro U
if ( bInvertU) {
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
double dUfin = m_lUPoints.front().second ;
// ciclo su tutti gli elementi
for ( auto& UPoint : m_lUPoints) {
@@ -1269,7 +1277,7 @@ PolyLine::GetMinAreaRectangleXY( Point3d& ptCen, Vector3d& vtAx, double& dLen, d
bool
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
{
// se vuota non faccio alcunché
// se vuota non faccio alcunché
if ( m_lUPoints.size() == 0)
return false ;
@@ -1371,7 +1379,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
return false ;
// Riferimento alla lista dei punti
PNTULIST& List = const_cast<PolyLine&>( plPoly).GetUPointList() ;
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
double dMinSqDist = SQ_INFINITO ;
Point3d ptMinDist ;
auto itMinDistEnd = List.end() ;
@@ -1460,7 +1468,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol
// assegno nuovo inizio
ptStart = ptEnd ;
}
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
return ( dMinSqDist < dToler * dToler) ;
}
@@ -1473,7 +1481,7 @@ ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
return false ;
// Riferimento alla lista dei punti
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
double dMinSqDist = SQ_INFINITO ;
auto itMinDistEnd = LoopList.end() ;
auto itStart = LoopList.begin() ;
@@ -1517,7 +1525,7 @@ SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler,
return false ;
// Riferimento alla lista dei punti
const PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
double dMinSqDist = SQ_INFINITO ;
auto itMinDistEnd = LoopList.end() ;
auto itStart = LoopList.begin() ;
@@ -1581,10 +1589,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
int nLastJ = 0 ;
vPnt1[0].second = 0 ;
double dFirstDist, dFirstParMinDist ;
DistPointPolyLine( vPnt1[0].first, PL2, dFirstDist, dFirstParMinDist) ;
int nFirstMinJ = ( int)( dFirstParMinDist + 0.5) ;
for ( int i = 1 ; i < nTotP1 ; ++ i) {
double dDist = INFINITO ;
@@ -1601,14 +1605,10 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
}
int nMinJ = ( int)( dMinDistPar + 0.5) ;
// eventuale correzione per i primi punti ( da forzare nel vertice 0)
if ( nLastJ == 0 && nFirstMinJ > 0.5 * nTotP2 && nMinJ >= nFirstMinJ)
nMinJ = 0 ;
if ( nMinJ < nLastJ)
nMinJ = nLastJ ;
// verifica se è un punto interno in comune con l'altra polyline
// verifica se è un punto interno in comune con l'altra polyline
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
bCommonInternalPoints = true ;
@@ -1619,9 +1619,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
// calcoli per seconda curva
int nLastI = 0 ;
vPnt2[0].second = 0 ;
DistPointPolyLine( vPnt2[0].first, PL1, dFirstDist, dFirstParMinDist) ;
int nFirstMinI = ( int)( dFirstParMinDist + 0.5) ;
for ( int j = 1 ; j < nTotP2 ; ++ j) {
@@ -1640,10 +1637,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
}
int nMinI = ( int)( dMinDistPar + 0.5) ;
// eventuale correzione per primi punti
if ( nLastI == 0 && nFirstMinI > 0.5 * nTotP1 && nMinI >= nFirstMinI)
nMinI = 0 ;
if ( nMinI < nLastI)
nMinI = nLastI ;
+398 -92
View File
@@ -330,9 +330,11 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
{
// verifico che la linea guida sia piana
Plane3d plGuide ;
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
return nullptr ;
Vector3d vtNorm = plGuide.GetVersN() ;
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
if ( vtNorm.IsSmall())
vtNorm = Z_AX ;
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
// curve di offset
@@ -355,7 +357,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
if ( IsNull( pSrfBot))
return nullptr ;
pSrfBot->Translate( -dDimV * vtNorm) ;
pSrfBot->Translate( - dDimV * vtNorm) ;
pSrfBot->Invert() ;
PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
if ( IsNull( pSrfRgt))
@@ -365,74 +367,188 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
if ( IsNull( pSrfLft))
return nullptr ;
// unisco le parti
PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
pSTM->DoSewing( *pSrfRgt) ;
pSTM->DoSewing( *pSrfLft) ;
pSTM->DoSewing( *pSrfBot) ;
// salvo tolleranza lineare usata e imposto angolo per smooth
pSTM->SetLinearTolerance( dLinTol) ;
pSTM->SetSmoothAngle( 20) ;
int nBuckets = max( 2 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start( nBuckets))
return nullptr ;
stmSoup.AddSurfTriMesh( *pSrfTop) ;
stmSoup.AddSurfTriMesh( *pSrfRgt) ;
stmSoup.AddSurfTriMesh( *pSrfLft) ;
stmSoup.AddSurfTriMesh( *pSrfBot) ;
PtrOwner<ISurfTriMesh> pSTM ;
// se guida aperta e tappi piatti
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
// completo unione e recupero la superficie risultante
if ( ! stmSoup.End())
return nullptr ;
pSTM.Set( stmSoup.GetSurf()) ;
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
return nullptr ;
Plane3d plEnds ; double dArea ;
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
return nullptr ;
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
return nullptr ;
// aggiungo il cap sull'inizio
// calcolo il cap sull'inizio
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
return nullptr ;
pSci->Invert() ;
pSTM->DoSewing( *pSci) ;
// aggiungo il cap sulla fine
// calcolo il cap sulla fine
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
return nullptr ;
pSce->Invert() ;
pSTM->DoSewing( *pSce) ;
// cucio i tappi all'estrusione
if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
return nullptr ;
}
// se altrimenti guida aperta e tappi arrotondati
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
// step di rotazione per rispettare la tolleranza
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
// aggiungo il cap sull'inizio
Point3d ptStart ;
pGuide->GetStartPoint( ptStart) ;
Vector3d vtStart ;
pGuide->GetStartDir( vtStart) ;
vtStart.Rotate( vtNorm, 0, 1) ;
PolyLine PLStart ;
PLStart.AddUPoint( 0, ptStart) ;
PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ;
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ;
PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ;
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
// se l'offset interno alla guida è chiuso
if ( pCrvL->IsClosed()) {
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
Point3d ptCenter = Media( ptRight, ptLeft) ;
Vector3d vtRight = ptRight - ptCenter ;
Vector3d vtLeft = ptLeft - ptCenter ;
double dAng = ANG_STRAIGHT ;
vtRight.GetAngle( vtLeft, dAng) ;
vtRight.Normalize() ;
PolyLine plLoop ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptRight) ; // primo punto
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptRight ;
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
}
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
// superificie Top
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop) ;
// superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
pStmBottom->Translate( - dDimV * vtNorm) ;
pStmBottom->Invert() ;
stmSoup.AddSurfTriMesh( *pStmBottom) ;
// superificie perpendicolare
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
plLoop.EraseLastUPoint() ; // apro il loop
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp) || ! pStmPerp->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
! pStmPerp->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmPerp) ;
}
// se l'offset interno della guida è aperto...
else {
// aggiungo il cap sull'inizio
Point3d ptStart ;
pGuide->GetStartPoint( ptStart) ;
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
Vector3d vtLeft = ptSLeft - ptStart ;
Vector3d vtRight = ptSRight - ptStart ;
double dAng = ANG_STRAIGHT ;
vtLeft.GetAngle( vtRight, dAng) ;
vtLeft.Normalize() ;
PolyLine plLoop ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
double dAngStep = ceil( dAng / dStepRotDeg) ;
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSLeft ;
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ;
}
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
// creo la superficie Top
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
// superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
pStmBottom_start->Translate( - dDimV * vtNorm) ;
pStmBottom_start->Invert() ;
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
// superificie perpendicolare
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
plLoop.EraseLastUPoint() ; // apro il loop
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp_start) || ! pStmPerp_start->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
! pStmPerp_start->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
// aggiungo il cap sulla fine
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
pCrvL->GetEndPoint( ptSLeft) ;
pCrvR->GetEndPoint( ptSRight) ;
vtLeft = ptSLeft - ptEnd ;
vtRight = ptSRight - ptEnd ;
dAng = ANG_STRAIGHT ;
vtRight.GetAngle( vtLeft, dAng) ;
vtRight.Normalize() ;
plLoop.Clear() ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptSRight) ;
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSRight ;
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ;
}
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
// creo la superficie Top
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
// creo la superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom_end( CloneSurfTriMesh( pStmTop_end)) ;
pStmBottom_end->Translate( - dDimV * vtNorm) ;
pStmBottom_end->Invert() ;
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
// creo la superificie perpendicolare alla guida
plLoop.EraseLastUPoint() ; // apro il loop
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp_end) || ! pStmPerp_end->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
! pStmPerp_end->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
}
// completo unione e recupero la superficie risultante
if ( ! stmSoup.End())
return nullptr ;
pSci->Invert() ;
pSTM->DoSewing( *pSci) ;
// aggiungo il cap sulla fine
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
Vector3d vtEnd ;
pGuide->GetEndDir( vtEnd) ;
vtEnd.Rotate( vtNorm, 0, -1) ;
PolyLine PLEnd ;
PLEnd.AddUPoint( 0, ptEnd) ;
PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ;
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ;
PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ;
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
return nullptr ;
pSce->Invert() ;
pSTM->DoSewing( *pSce) ;
pSTM.Set( stmSoup.GetSurf()) ;
}
else {
// completo unione e recupero la superficie risultante
if ( ! stmSoup.End())
return nullptr ;
pSTM.Set( stmSoup.GetSurf()) ;
}
// salvo tolleranza lineare usata e imposto angolo per smooth
pSTM->SetLinearTolerance( dLinTol) ;
pSTM->SetSmoothAngle( 20) ;
// restituisco la superficie
return Release( pSTM) ;
}
@@ -445,13 +561,13 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
// verifico che la linea guida sia piana
Plane3d plGuide ;
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
return nullptr ;
// assegno la normale del piano
Vector3d vtNorm = plGuide.GetVersN() ;
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
if ( vtNorm.IsSmall())
vtNorm = Z_AX ;
// determino il punto centrale della sezione
Point3d ptCen ;
pGuide->GetStartPoint( ptCen) ;
Point3d ptCen ; pGuide->GetStartPoint( ptCen) ;
ptCen -= dDimV / 2 * vtNorm ;
// determino se la guida è chiusa
bool bGuideClosed = pGuide->IsClosed() ;
@@ -480,7 +596,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
}
if ( ! bOk ||
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
@@ -549,10 +664,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
if ( ! stmSoup.End())
return nullptr ;
pSTM.Set( stmSoup.GetSurf()) ;
// preparo seconda zuppa di triangoli per inserire i tappi
StmFromTriangleSoup stmCapSoup ;
if ( ! stmCapSoup.Start( nBuckets))
return nullptr ;
// verifico che le due estremità siano chiuse e piatte
POLYLINEVECTOR vPL ;
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
@@ -580,42 +691,236 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
// step di rotazione per rispettare il tipo o la tolleranza
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
// aggiungo il cap sull'inizio
Point3d ptStart ;
pGuide->GetStartPoint( ptStart) ;
Vector3d vtStart ;
pGuide->GetStartDir( vtStart) ;
vtStart.Rotate( vtNorm, 0, 1) ;
PolyLine PLStart ;
PLStart.AddUPoint( 0, ptStart) ;
PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ;
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ;
PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ;
PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ;
PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ;
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
// se l'offset interno della guida è chiuso...
if ( pCrvL->IsClosed()) {
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
Point3d ptCenter = Media( ptRight, ptLeft) ;
Vector3d vtRight = ptRight - ptCenter ;
Vector3d vtLeft = ptLeft - ptCenter ;
double dAng = ANG_STRAIGHT ;
vtRight.GetAngle( vtLeft, dAng) ;
vtRight.Normalize() ;
PolyLine plLoop ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptRight) ; // primo punto
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptRight ;
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
}
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
// superificie Top
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop) ;
// superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
if ( IsNull( pStmBottom) || ! pStmBottom->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmBottom) ;
// calcolo l'angolo di rotazione per la faccia Top del bevel
// NB. Questo angolo va ricalcolato, il bevel è inclinato rispetto alla normale della guida
ptCenter.Translate( - dBevelV * vtNorm) ;
Point3d ptbRight ; pCrvRb->GetEndPoint( ptbRight) ;
Point3d ptbLeft ; pCrvRb->GetStartPoint( ptbLeft) ;
Vector3d vtbLeft = ptbLeft - ptCenter ;
Vector3d vtbRight = ptbRight - ptCenter ;
dAng = ANG_STRAIGHT ;
vtbRight.GetAngle( vtbLeft, dAng) ;
vtbRight.Normalize() ;
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
plLoop.EraseLastUPoint() ; // apro il loop
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
// creo il loop defininendo i punti
PolyLine plLoopB ;
plLoopB.AddUPoint( 0, ptbRight) ;
dAngStep = ceil( dAng / dStepRotDeg) ;
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptbRight ;
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
plLoopB.AddUPoint( i, ptRot) ;
}
plLoopB.AddUPoint( dAngStep, ptbLeft) ;
// creo la superficie Top Bevel
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmbTop_start) ||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
! pStmbTop_start->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
// creo la superificie Bottom Bevel
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
// creo la superficie perpendicolare alla guida
PolyLine plLoopB1 = plLoopB ;
plLoopB1.Mirror( ptCen, vtNorm) ;
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp) ||
! pStmPerp->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
! pStmPerp->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmPerp) ;
}
// se l'offset interno della guida è aperto...
else {
// aggiungo il cap sull'inizio
Point3d ptStart ;
pGuide->GetStartPoint( ptStart) ;
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
Vector3d vtLeft = ptSLeft - ptStart ;
Vector3d vtRight = ptSRight - ptStart ;
double dAng = ANG_STRAIGHT ;
vtLeft.GetAngle( vtRight, dAng) ;
vtLeft.Normalize() ;
PolyLine plLoop ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
double dAngStep = ceil( dAng / dStepRotDeg) ;
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSLeft ;
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ;
}
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
// creo la superficie Top
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
// creo la superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
if ( IsNull( pStmBottom_start) || ! pStmBottom_start->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
// calcolo l'angolo di rotazione per la faccia Top del bevel
ptStart.Translate( - dBevelV * vtNorm) ;
Point3d ptSbLeft ; pCrvLb->GetStartPoint( ptSbLeft) ;
Point3d ptSbRight ; pCrvRb->GetStartPoint( ptSbRight) ;
Vector3d vtbLeft = ptSbLeft - ptStart ;
Vector3d vtbRight = ptSbRight - ptStart ;
dAng = ANG_STRAIGHT ;
vtbLeft.GetAngle( vtbRight, dAng) ;
vtbLeft.Normalize() ;
plLoop.EraseLastUPoint() ; // apro il loop
// creo il loop defininendo i punti
PolyLine plLoopB ;
plLoopB.AddUPoint( 0, ptSbLeft) ;
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSbLeft ;
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
plLoopB.AddUPoint( i, ptRot) ;
}
plLoopB.AddUPoint( dAngStep, ptSbRight) ; // ultimo punto
// creo la superficie Top Bevel
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmbTop_start) ||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
! pStmbTop_start->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
// creo la superificie Bottom Bevel
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
// creo la superficie perpendicolare alla guida
PolyLine plLoopB1 = plLoopB ;
plLoopB1.Mirror( ptCen, vtNorm) ;
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp_start) ||
! pStmPerp_start->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
! pStmPerp_start->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
// aggiungo il cap sulla fine
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
pCrvL->GetEndPoint( ptSLeft) ;
pCrvR->GetEndPoint( ptSRight) ;
vtLeft = ptSLeft - ptEnd ;
vtRight = ptSRight - ptEnd ;
dAng = ANG_STRAIGHT ;
vtRight.GetAngle( vtLeft, dAng) ;
vtRight.Normalize() ;
plLoop.Clear() ;
// creo il loop defininendo i punti
plLoop.AddUPoint( 0, ptSRight) ;
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSRight ;
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
plLoop.AddUPoint( i, ptRot) ;
}
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
// creo la superficie Top
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
// creo la superificie Bottom
PtrOwner<ISurfTriMesh> pStmBottom_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmBottom_end) ||
! pStmBottom_end->CopyFrom( pStmTop_end) ||
! pStmBottom_end->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
// calcolo l'angolo di rotazione per la faccia Top del bevel
ptEnd.Translate( - dBevelV * vtNorm) ;
pCrvLb->GetEndPoint( ptSbLeft) ;
pCrvRb->GetEndPoint( ptSbRight) ;
vtbLeft = ptSbLeft - ptEnd ;
vtbRight = ptSbRight - ptEnd ;
dAng = ANG_STRAIGHT ;
vtbRight.GetAngle( vtbLeft, dAng) ;
vtbRight.Normalize() ;
plLoop.EraseLastUPoint() ; // apro il loop
// creo il loop defininendo i punti
plLoopB.Clear() ;
plLoopB.AddUPoint( 0, ptSbRight) ;
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
for ( int i = 1 ; i < dAngStep ; ++ i) {
Point3d ptRot = ptSbRight ;
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
plLoopB.AddUPoint( i, ptRot) ;
}
plLoopB.AddUPoint( dAngStep, ptSbLeft) ; // ultimo punto
// creo la superficie Top Bevel
PtrOwner<ISurfTriMesh> pStmbTop_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmbTop_end) ||
! pStmbTop_end->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
! pStmbTop_end->Invert())
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbTop_end) ;
// creo la superificie Bottom Bevel
PtrOwner<ISurfTriMesh> pStmbBottom_end( CloneSurfTriMesh( pStmbTop_end)) ;
if ( IsNull( pStmbBottom_end) || ! pStmbBottom_end->Mirror( ptCen, vtNorm))
return nullptr ;
stmSoup.AddSurfTriMesh( *pStmbBottom_end) ;
// creo la superficie perpendicolare alla guida
plLoopB1 = plLoopB ;
plLoopB1.Mirror( ptCen, vtNorm) ;
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
if ( IsNull( pStmPerp_end) ||
! pStmPerp_end->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
! pStmPerp_end->Invert())
return nullptr ;
pSci->Invert() ;
stmSoup.AddSurfTriMesh( *pSci) ;
// aggiungo il cap sulla fine
Point3d ptEnd ;
pGuide->GetEndPoint( ptEnd) ;
Vector3d vtEnd ;
pGuide->GetEndDir( vtEnd) ;
vtEnd.Rotate( vtNorm, 0, -1) ;
PolyLine PLEnd ;
PLEnd.AddUPoint( 0, ptEnd) ;
PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ;
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ;
PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ;
PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ;
PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ;
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
return nullptr ;
pSce->Invert() ;
stmSoup.AddSurfTriMesh( *pSce) ;
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
}
// completo unione e recupero la superficie risultante
if ( ! stmSoup.End())
return nullptr ;
@@ -634,6 +939,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol)
+1 -1
View File
@@ -159,7 +159,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
enum ParDir { ON_U = 1, ON_V = 2} ;
static const int MAXDEG = 11 ;
static const int MAXDEG = 21 ;
private :
bool CopyFrom( const SurfBezier& sbSrc) ;
+9 -1
View File
@@ -21,9 +21,9 @@
#include "NgeReader.h"
#include "SurfFlatRegion.h"
#include "DistPointLine.h"
#include "DistLineLine.h"
#include "Triangulate.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkPointGrid3d.h"
#include "/EgtDev/Include/EGkPolyLine.h"
@@ -1048,10 +1048,16 @@ bool
SurfTriMesh::MarchAlongLoop( int nT, int nV, int nTimeStamp, PolyLine& PL) const
{
// mi muovo lungo il loop, un triangolo alla volta
int nCount = 0 ;
bool bEnd = false ;
while ( ! bEnd) {
// altro triangolo
if ( ! MarchOneTria( nT, nV, nTimeStamp, PL, bEnd))
return false ;
// per evitare loop infiniti
++ nCount ;
if ( nCount > 3 * int( m_vTria.size()) + 10)
return true ;
}
return true ;
}
@@ -3710,6 +3716,8 @@ SurfTriMesh::SetTFlag( int nId, int nTFlag)
if ( nId < 0 || nId >= GetTriangleSize() || m_vTria[nId].nIdVert[0] == SVT_DEL)
return false ;
m_vTria[nId].nTFlag = nTFlag ;
m_nMaxTFlag = max( m_nMaxTFlag, abs( nTFlag)) ;
m_OGrMgr.Clear() ;
return true ;
}
+2 -2
View File
@@ -318,6 +318,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
int GetPartCount( void) const override ;
bool RemovePart( int nPart) override ;
SurfTriMesh* ClonePart( int nPart) const override ;
bool SetTFlag( int nId, int nTFlag) override ;
bool GetTFlag( int nId, int& nFlag) const override ;
int GetMaxTFlag( void) const override
{ return m_nMaxTFlag ; }
bool ResetTFlags( void) override ;
@@ -343,10 +345,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool ExistsTriangle( int nT) const
{ return ( nT >= 0 && nT < GetTriangleSize() && m_vTria[nT].nIdVert[0] != SVT_DEL) ; }
bool GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const ;
bool GetTFlag( int nId, int& nFlag) const ;
bool GetTempInt( int nId, int& nTempInt) const ;
bool ResetTempInts( void) const ;
bool SetTFlag( int nId, int nTFlag) ;
bool SetTempInt( int nId, int nTempInt) const ;
private :
+5 -5
View File
@@ -79,7 +79,7 @@ SurfTriMesh::CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModi
if ( m_vVert[i].nIdTria == SVT_DEL)
continue ;
double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ;
if ( abs( dDist) < EPS_SMALL)
if ( abs( dDist) < 1.1 * EPS_SMALL)
m_vVert[i].nTemp = 0 ;
else if ( dDist > 0)
m_vVert[i].nTemp = +1 ;
@@ -781,14 +781,14 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
}
}
// Ripristino scala originale
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
// se superficie originale a facce, cerco di semplificarle in ogni caso
if ( nFacetOriCnt < 200 || double( nTriaOriCnt) / nFacetOriCnt > 4) {
if ( ! SimplifyFacets())
if ( ! SimplifyFacets( CUT_SCALE * MAX_EDGE_LEN_STD))
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::GeneralizedCut")
}
// Ripristino scala originale
Scale( frScalingRef, 1. / CUT_SCALE, 1. / CUT_SCALE, 1. / CUT_SCALE) ;
return true ;
}
+1 -1
View File
@@ -16,7 +16,7 @@
#include "CurveLine.h"
#include "Triangulate.h"
#include "DistPointLine.h"
#include "DistLineLine.h"
#include "/EgtDev/Include/EGkDistLineLine.h"
#include <unordered_map>
using namespace std ;
+96
View File
@@ -580,3 +580,99 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh,
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRc, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// Verifica sulle dimensioni
if ( dH < 10 * EPS_SMALL || dR < 10 * EPS_SMALL || dRc < - EPS_SMALL || dR < dRc - EPS_SMALL)
return false ;
// Assegnazione dati geometrici principali
m_dHeight = dH ;
m_dRadius = dR ;
m_dRCorner = min( dRc, dR) ;
if ( m_dRCorner < 10 * EPS_SMALL)
m_dRCorner = 0 ;
m_dTipHeight = 0 ;
m_dTipRadius = 0 ;
m_dRefRadius = 0 ;
m_dCutterHeight = dH ;
// Utensile cilindrico con eventuale raggio corner (al limite sferico)
if ( m_dRCorner <= m_dHeight / 2) {
// Se Cilindrico
if ( m_dRCorner < EPS_SMALL) {
// inizio
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
// segmento orizzontale in alto
m_Outline.AddLine( Point3d( m_dRadius, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
// segmento verticale
m_Outline.AddLine( Point3d( m_dRadius, -m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
// segmento orizzontale in basso
m_Outline.AddLine( Point3d( 0, -m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
}
// Generico
else {
// inizio
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
int nInd = -1 ;
// eventuale segmento orizzontale in alto
if ( m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)))
m_Outline.SetCurveTempProp( ++ nInd, 1, 1) ;
// raggio corner in alto
CurveArc cvArc ;
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, -m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, -m_dRCorner, 0)) ;
m_Outline.AddCurve( cvArc, true, 2 * EPS_SMALL) ;
m_Outline.SetCurveTempProp( ++ nInd, 1, 1) ;
// eventuale segmento verticale
if ( m_Outline.AddLine( Point3d( m_dRadius, -m_dHeight + m_dRCorner, 0)))
m_Outline.SetCurveTempProp( ++ nInd, 1, 1) ;
// raggio corner in basso
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, -m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, -m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, -m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc, true, 2 * EPS_SMALL) ;
m_Outline.SetCurveTempProp( ++ nInd, 1, 1) ;
// eventuale segmento orizzontale in basso
if ( m_Outline.AddLine( Point3d( 0, -m_dHeight, 0)))
m_Outline.SetCurveTempProp( ++ nInd, 1, 1) ;
}
m_Outline.SetTempProp( 1, 1) ;
if ( ! SetGenTool( sToolName, &m_Outline, nToolNum))
return false ;
}
// Utensile sfiancato
else {
double dCenX = m_dRadius - m_dRCorner ;
double dCylRad = dCenX + sqrt( m_dRCorner * m_dRCorner - m_dHeight * m_dHeight / 4) ;
// Utensile mal definito
if ( dCylRad < EPS_SMALL)
return false ;
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
CurveArc cvArc ;
cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
if ( ! SetGenTool( sToolName, &m_Outline, nToolNum))
return false ;
}
m_nType = ADDITIVE ;
return true ;
}
+3 -1
View File
@@ -33,6 +33,7 @@ class Tool
bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) ;
bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) ;
bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nToolNum) ;
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRc, int nToolNum) ;
bool SetToolNum( int nToolNum)
{ m_nCurrentNum = nToolNum ; return true ; }
int GetType() const
@@ -70,7 +71,8 @@ class Tool
BULLNOSEMILL = 4, // Naso di toro
CONEMILL = 5, // Con parte terminale conica
MORTISER = 6, // Mortasatrice
CHISEL = 7} ; // Scalpello
CHISEL = 7, // Scalpello
ADDITIVE = 8} ; // Additivo
private :
bool ModifyForCutterHeight( void) ;
+200 -2
View File
@@ -25,6 +25,7 @@
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include <thread>
#include <future>
@@ -49,7 +50,6 @@ VolZmap::VolZmap(void)
m_nFracLin[i] = 0 ;
}
m_vTool.resize( 1) ;
m_nCurrTool = 0 ;
}
//----------------------------------------------------------------------------
@@ -1501,7 +1501,187 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const
//----------------------------------------------------------------------------
bool
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
VolZmap::AddSurfTm( const ISurfTriMesh* pStm)
{
// controllo sulla superficie
double dVol ;
if ( pStm == nullptr || ! pStm->IsValid() || ! pStm->IsClosed() ||
! pStm->GetVolume( dVol) || dVol < 0)
return false ;
// controllo se il Box3d della superficie si interseca con il Box3d dello Zmap corrente
BBox3d BBox_stm, BBox_curr ;
if ( ! pStm->GetLocalBBox( BBox_stm) || ! GetLocalBBox( BBox_curr))
return false ;
BBox3d BBox_inters ;
if ( BBox_stm.FindIntersection( BBox_curr, BBox_inters) && BBox_inters.IsEmpty())
return true ; // se non ci sono intersezioni, la superficie non influenza lo Zmap
Vector3d vtLen = BBox_curr.GetMax() - BBox_curr.GetMin() ; // dimensione massima dello spillone
// ciclo sulle griglie
bool bCompleted = true ;
for ( int g = 0 ; g < m_nMapNum ; ++ g) {
// definisco dei sistemi di riferimento ausiliari
Frame3d frMapFrame ;
if ( g == 0)
frMapFrame = m_MapFrame ;
else if ( g == 1)
frMapFrame.Set( m_MapFrame.Orig(), Y_AX, Z_AX, X_AX) ;
else if ( g == 2)
frMapFrame.Set( m_MapFrame.Orig(), Z_AX, X_AX, Y_AX) ;
// oggetto per calcolo massivo intersezioni
IntersParLinesSurfTm intPLSTM( frMapFrame, *pStm) ;
// numero massimo di thread
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
vector<future<bool>> vRes ;
vRes.resize( nThreadMax) ;
// se dimensione griglia in X maggiore di dimensione Y
if ( m_nNx[g] > m_nNy[g]) {
int nDexNum = m_nNx[g] / nThreadMax ;
int nRemainder = m_nNx[g] % nThreadMax ;
int nInfI = 0 ;
int nSupI = 0 ;
// aggiungo le parti interessate alla mappa
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfI = nSupI ;
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::AddMapPart, this, g,
nInfI, nSupI, 0, m_nNy[g], ref( vtLen), ref( m_MapFrame.Orig()),
ref( *pStm), ref( intPLSTM)) ;
}
}
// se dimensione griglia in Y maggiore di dimensione X
else {
int nDexNum = m_nNy[g] / nThreadMax ;
int nRemainder = m_nNy[g] % nThreadMax ;
int nInfJ = 0 ;
int nSupJ = 0 ;
// aggiungo le parti interessate alla mappa
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfJ = nSupJ ;
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::AddMapPart, this, g,
0, m_nNx[g], nInfJ, nSupJ, ref( vtLen), ref( m_MapFrame.Orig()),
ref( *pStm), 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() ;
}
}
}
if ( ! bCompleted)
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::MakeUniform( double dToler)
{
// controllo validità dello Zmap
if ( ! IsValid())
return false ;
// la tolleranza deve essere minore dello step
dToler = min( dToler, 0.95 * m_dStep) ;
// creo lo Zmpa che andrà a sostituire il corrente
PtrOwner<VolZmap> pOldVolZmap( CloneBasicVolZmap( this)) ;
if ( IsNull( pOldVolZmap))
return false ;
// ciclo sulle griglie
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
// salvo lo Zmap prima di modificare gli spilloni
PtrOwner<VolZmap> pVolZMapCurrGrid( CloneBasicVolZmap( this)) ;
if ( IsNull( pVolZMapCurrGrid))
return false ;
// ciclo sul numero di dexel presenti
for ( int nDex = 0 ; nDex < int( m_Values[nGrid].size()) ; ++ nDex) {
// se il dexel corrente non ha sotto-intervalli passo al successivo
if ( int( m_Values[nGrid][nDex].size()) == 0)
continue ;
// indici del dexel
int nI = nDex % m_nNx[nGrid] ;
int nJ = nDex / m_nNx[nGrid] ;
// salvo le informazioni dei sotto-intervalli del dexel corrente
vector<Data> vInfo ;
for ( int nExtr = 0 ; nExtr < int( m_Values[nGrid][nDex].size()) ; ++ nExtr)
vInfo.push_back( m_Values[nGrid][nDex][nExtr]) ;
// per ogni sotto-intervallo, estendo a destra e a sinistra della tolleranza
int nSub_intervals = int( vInfo.size()) ;
// scorro gli intervalli
for ( int nInfo = 0 ; nInfo < int( pVolZMapCurrGrid->m_Values[nGrid][nDex].size()) ; ++ nInfo) {
// estremo inferiore
if ( vInfo[nInfo].dMin - dToler > m_dMinZ[nGrid]) {
AddIntervals( nGrid, nI, nJ,
vInfo[nInfo].dMin - dToler,
vInfo[nInfo].dMin + dToler,
vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN, vInfo[nInfo].nToolMin,
true) ;
// se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due
// direzioni nel voxel corrispondente
if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL &&
nSub_intervals != int( m_Values[nGrid][nDex].size())) {
nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti
// l'intervallo corrente si è unito con il precedente...
AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMin, dToler,
vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN,
vInfo[nInfo].nToolMin) ;
}
}
// estremo superiore
if ( vInfo[nInfo].dMax + dToler < m_dMaxZ[nGrid]) {
AddIntervals( nGrid, nI, nJ,
vInfo[nInfo].dMax - dToler,
vInfo[nInfo].dMax + dToler,
vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN, vInfo[nInfo].nToolMax,
true) ;
if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL &&
nSub_intervals != int( m_Values[nGrid][nDex].size())) {
nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti
AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMax, dToler,
vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN,
vInfo[nInfo].nToolMax) ;
}
}
}
// per ogni sotto-intervallo ricavato fino ad ora, restringo della tolleranza
// ( NB. avendo aggiunto intervalli, il dexel può modificare la sua struttura interna )
for ( int nInfo = 0 ; nInfo < int( m_Values[nGrid][nDex].size()) ; ++ nInfo) {
// ( NB. la rimozione di un intervallo ora va definita per intervalli a destra e a sinistra,
// altrimenti rimuovo parti in eccesso )
if ( ! pVolZMapCurrGrid->m_Values[nGrid][nDex].empty()) {
if ( nInfo != 0 ||
pVolZMapCurrGrid->m_Values[nGrid][nDex][0].dMin - dToler > m_dMinZ[nGrid])
m_Values[nGrid][nDex][nInfo].dMin += dToler ;
if ( nInfo != int( m_Values[nGrid][nDex].size()) - 1 ||
pVolZMapCurrGrid->m_Values[nGrid][nDex].back().dMax + dToler < m_dMaxZ[nGrid])
m_Values[nGrid][nDex][nInfo].dMax -= dToler ;
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
{
// Controllo sulla validità della griglia
if ( nGrid < 0 || nGrid > 2)
@@ -2172,6 +2352,24 @@ VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dT
return m_vTool[m_nCurrTool].SetChiselTool( sToolName, dH, dW, dTh, nFlag) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SetAdditiveTool( const std::string& sToolName,
double dH, double dR, double dRc, int nFlag, bool bFirst)
{
if ( bFirst) {
m_vTool.resize( 1) ;
m_vTool[0].Clear( true) ;
}
else
m_vTool.emplace_back( true) ;
m_nCurrTool = int( m_vTool.size()) - 1 ;
if ( m_nCurrTool < 0)
return false ;
m_vTool[m_nCurrTool].SetTolerances( m_dToolLinTol, m_dToolAngTolDeg) ;
return m_vTool[m_nCurrTool].SetAdditiveTool( sToolName, dH, dR, dRc, nFlag) ;
}
//----------------------------------------------------------------------------
int
VolZmap::GetToolCount( void) const
+26 -4
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2023
// EgalTech 2015-2024
//----------------------------------------------------------------------------
// File : VolZmap.h Data : 12.09.23 Versione : 2.5i1
// File : VolZmap.h Data : 22.04.24 Versione : 2.6d4
// Contenuto : Dichiarazione della classe Volume Zmap.
//
//
@@ -78,6 +78,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
bool Clear( void) override ;
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) override ;
int GetBlockCount( void) const override ;
@@ -109,6 +110,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
double dH, double dW, double dTh, double dRc, int nFlag, bool bFirst) override ;
bool SetChiselTool( const std::string& sToolName,
double dH, double dW, double dTh, int nFlag, bool bFirst) override ;
bool SetAdditiveTool( const std::string& sToolName,
double dH, double dR, double dRc, int nFlag, bool bFirst) override ;
int GetToolCount( void) const override ;
bool SetCurrTool( int nCurrTool) override ;
bool ResetTools( void) override ;
@@ -140,6 +143,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
VolZmap* ClonePart( int nPart) const override ;
bool RemovePart( int nPart) override ;
int GetPartMinDistFromPoint( const Point3d& ptP) const override ;
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
bool MakeUniform( double dToler) override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
@@ -240,9 +245,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW
INTVECTOR& vAdjBlockVoxComp, INTVECTOR& vAdjBordBlockVoxComp) const ;
// OPERAZIONI SU INTERVALLI
bool SubtractIntervals( int nGrid, int nI, int nJ,
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum) ;
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
int nToolNum, bool bSkipSwap = false) ;
bool AddIntervals( int nGrid, int nI, int nJ,
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum) ;
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
int nToolNum, bool bSkipSwap = false) ;
bool AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler,
Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum) ;
bool AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
Vector3d& vtMin, Vector3d& vtMax) ;
// Spostamenti utensile
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,
@@ -319,6 +330,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
// Generica traslazione sfera
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
// Additivi
bool AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
bool AddingCylinder( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dRad) ;
bool AddingTruncatedCone( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx,
double dMaxRad, double dMinRad, double dHei,
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ;
bool AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) ;
bool AddingGeneral( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ;
// BBox per utensili e solidi semplici con movimenti di traslazione
inline bool TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
@@ -411,6 +430,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
// Funzione per crezione solido in parallelo
bool CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
bool AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
@@ -444,6 +465,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
} ;
std::vector<std::vector<Data>> m_Values[N_MAPS] ; // dexel delle 3 griglie
int m_nShape ; // Forma : 0 generica, 1 box, 2 estrusione
int m_nVoxNumPerBlock ; // Numero di voxel per blocco
+187 -21
View File
@@ -27,13 +27,13 @@ using namespace std ;
//----------------------------------------------------------------------------
bool
VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex)
VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex)
{
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
return false ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Aggiorno la dimensione della mappa 1 o 3
@@ -47,8 +47,8 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ;
// Definisco i vettori dei limiti su indici
m_nNx[0] = max( int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNy[0] = max( int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNx[0] = max( int( ( dDimX + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNy[0] = max( int( ( dDimY + EPS_SMALL) / m_dStep + 0.5), 1) ;
// Numero di componenti connesse
m_nConnectedCompoCount = 1 ;
@@ -56,7 +56,7 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
// Se tridexel
if ( bTriDex) {
m_nNx[1] = m_nNy[0] ;
m_nNy[1] = max( int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNy[1] = max( int( ( dDimZ + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNx[2] = m_nNy[1] ;
m_nNy[2] = m_nNx[0] ;
}
@@ -97,19 +97,19 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
switch ( i) {
case 0 :
m_Values[i][j][0].vtMinN = - Z_AX ;
m_Values[i][j][0].dMax = dLengthZ ;
m_Values[i][j][0].dMax = dDimZ ;
m_Values[i][j][0].vtMaxN = Z_AX ;
m_Values[i][j][0].nToolMax = 0 ;
break ;
case 1 :
m_Values[i][j][0].vtMinN = - X_AX ;
m_Values[i][j][0].dMax = dLengthX ;
m_Values[i][j][0].dMax = dDimX ;
m_Values[i][j][0].vtMaxN = X_AX ;
m_Values[i][j][0].nToolMax = 0 ;
break ;
case 2 :
m_Values[i][j][0].vtMinN = - Y_AX ;
m_Values[i][j][0].dMax = dLengthY ;
m_Values[i][j][0].dMax = dDimY ;
m_Values[i][j][0].vtMaxN = Y_AX ;
m_Values[i][j][0].nToolMax = 0 ;
break ;
@@ -118,11 +118,11 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
// Definizione delle limitazioni iniziali in Z per ogni mappa
m_dMinZ[0] = 0 ;
m_dMaxZ[0] = dLengthZ ;
m_dMaxZ[0] = dDimZ ;
m_dMinZ[1] = 0 ;
m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ;
m_dMaxZ[1] = ( bTriDex ? dDimX : 0) ;
m_dMinZ[2] = 0 ;
m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ;
m_dMaxZ[2] = ( bTriDex ? dDimY : 0) ;
// Tipologia
m_nShape = BOX ;
@@ -133,6 +133,80 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex)
{
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
return false ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bTriDex ? 3 : 1) ;
// Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z
// di uno si ottengono da una permutazione ciclica di quelle del precedente sistema.
// es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1)
// Definisco il sistema di riferimento intrinseco
m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ;
// Definisco i vettori dei limiti su indici
m_nNx[0] = max( int( ( dDimX + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNy[0] = max( int( ( dDimY + EPS_SMALL) / m_dStep + 0.5), 1) ;
// Numero di componenti connesse
m_nConnectedCompoCount = 1 ;
// Se tridexel
if ( bTriDex) {
m_nNx[1] = m_nNy[0] ;
m_nNy[1] = max( int( ( dDimZ + EPS_SMALL) / m_dStep + 0.5), 1) ;
m_nNx[2] = m_nNy[1] ;
m_nNy[2] = m_nNx[0] ;
}
// altrimenti mono dexel
else {
m_nNx[1] = 0 ;
m_nNy[1] = 0 ;
m_nNx[2] = 0 ;
m_nNy[2] = 0 ;
}
// Definisco il numero di blocchi lungo x,y e z
if ( ! CalcBlockNum())
return false ;
// Creazione delle mappe
// Calcolo del numero di celle per ogni mappa
for ( int i = 0 ; i < m_nMapNum ; ++ i)
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
// Creazione delle celle per ogni mappa
for ( int i = 0 ; i < m_nMapNum ; ++ i)
m_Values[i].resize( m_nDim[i]) ;
// Definizione delle limitazioni iniziali in Z per ogni mappa
m_dMinZ[0] = 0 ;
m_dMaxZ[0] = dDimZ ;
m_dMinZ[1] = 0 ;
m_dMaxZ[1] = ( bTriDex ? dDimX : 0) ;
m_dMinZ[2] = 0 ;
m_dMaxZ[2] = ( bTriDex ? dDimY : 0) ;
// Tipologia
m_nShape = GENERIC ;
// Aggiornamento dello stato
m_nStatus = OK ;
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex)
@@ -140,7 +214,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
// Aggiorno la dimensione della mappa 1 o 3
m_nMapNum = ( bTriDex ? 3 : 1) ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Determino il bounding box della flat region
@@ -223,11 +297,11 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
CRVCVECTOR IntersectionResults ;
Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ;
// Analizzo le parti in cui la retta è stata divisa
// Analizzo le parti in cui la retta è stata divisa
int nPart = int( IntersectionResults.size()) ;
for ( int k = 0 ; k < nPart ; ++ k) {
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
int nType = IntersectionResults[k].nClass ;
if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) {
@@ -334,7 +408,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
int nPart = int( IntersectionResults.size()) ;
for ( int k = 0 ; k < nPart ; ++ k) {
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
// Se la retta è interna alla regione o coincidente con parte della sua frontiera
int nType = IntersectionResults[k].nClass ;
if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) {
@@ -471,7 +545,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
int nIntType = IntersectionResults[k].nILTT ;
// Se c'è intersezione
// Se c'è intersezione
if ( nIntType != ILTT_NO) {
double dCos = IntersectionResults[k].dCosDN ;
@@ -523,11 +597,103 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
return true ;
}
bool
VolZmap::AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
{
// controllo sui parametri
if ( nMap < 0 || nMap > 2 ||
nInfI < 0 || nInfI > m_nNx[nMap] ||
nSupI < 0 || nSupI > m_nNx[nMap] ||
nInfJ < 0 || nInfJ > m_nNy[nMap] ||
nSupJ < 0 || nSupJ > m_nNy[nMap])
return false ;
// determinazione e ridimensionamento dei dexel interni alla trimesh
for ( int i = nInfI ; i < nSupI ; ++ i) {
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
// definisco la retta da intersecare con la trimesh
double dX = ( i + 0.5) * m_dStep ;
double dY = ( j + 0.5) * m_dStep ;
Point3d ptP0( dX, dY, 0) ;
// intersezioni della retta con la TriMesh
ILSIVECTOR IntersectionResults ;
intPLSTM.GetInters( ptP0, vtLen.v[(nMap+2)%3], IntersectionResults) ;
// rimuovo le intersezioni in eccesso
for ( int nI = 0 ; nI < int( IntersectionResults.size()) - 3 ; ++ nI) {
int nJ = nI + 1 ; // prima successiva
int nK = nJ + 1 ; // seconda successiva
int nT = nK + 1 ; // terza successiva
// determino i segni delle 4 intersezioni tra la linea e il trangolo della TriMesh
int nSgnI = IntersectionResults[nI].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nI].dCosDN > -EPS_SMALL ? 0 : - 1 ;
int nSgnJ = IntersectionResults[nJ].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nJ].dCosDN > -EPS_SMALL ? 0 : - 1 ;
int nSgnK = IntersectionResults[nK].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nK].dCosDN > -EPS_SMALL ? 0 : - 1 ;
int nSgnT = IntersectionResults[nT].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nT].dCosDN > -EPS_SMALL ? 0 : - 1 ;
// parametri dell'intersezione sulla linea
double dUJ = IntersectionResults[nJ].dU ;
double dUK = IntersectionResults[nK].dU ;
// controllo coerenza con segni...
if ( nSgnI != 0 && nSgnI == nSgnJ &&
nSgnK != 0 && nSgnK == nSgnT &&
nSgnI == - nSgnT &&
abs( dUJ - dUK) < EPS_SMALL) {
// ... ed elimino le intersezioni in eccesso...
IntersectionResults.erase( IntersectionResults.begin() + nK) ;
IntersectionResults.erase( IntersectionResults.begin() + nJ) ;
}
}
int nInt = int( IntersectionResults.size()) ; // numero di intersezioni valide
bool bInside = false ; // Flag entrata/uscita per tratto di retta
Point3d ptIn ; Vector3d vtInN ;
// per ogni intersezione valida trovata...
for ( int k = 0 ; k < nInt ; ++ k) {
// ricavo il tipo di intersezione
int nIntType = IntersectionResults[k].nILTT ;
// se c'è intersezione
if ( nIntType != ILTT_NO) {
// ricavo il cos tra i vettori ( normale del triangolo e tangente alla retta)
double dCos = IntersectionResults[k].dCosDN ;
// se entro nella superficie trimesh...
if ( dCos < - EPS_SMALL) {
ptIn = IntersectionResults[k].ptI ; // punto di intersezione
int nT = IntersectionResults[k].nT ; // triangolo di interesse
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
Surf.GetFacetNormal( nF, vtInN) ;
bInside = true ; // entrata
}
// ...se esco dalla superficie trimesh ( prima sono per forza entrato)
else if ( dCos > EPS_SMALL && bInside) {
Point3d ptOut = IntersectionResults[k].ptI ; // punto di intersezione
int nT = IntersectionResults[k].nT ; // triangolo di interesse
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
Vector3d vtOutN ; Surf.GetFacetNormal( nF, vtOutN) ; // vettore d'uscita
// Aggiungo un tratto al dexel
AddIntervals( nMap, i, j,
ptIn.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
ptOut.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
vtInN, vtOutN, 0, true) ;
bInside = false ; // uscita
}
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex)
{
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
double dVol ;
if ( ! Surf.IsClosed() || ! Surf.GetVolume( dVol) || dVol < 0)
return false ;
@@ -543,14 +709,14 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
Point3d ptMapOrig, ptMapEnd ;
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
// quindi espandiamo il bounding box per ovviare al problema.
SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ;
// Sistema di riferimento intrinseco dello Zmap
m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ;
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
// Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
m_dStep = max( dStep, 100 * EPS_SMALL) ;
// Determino le dimensioni lineari del BBox
+22 -12
View File
@@ -3327,12 +3327,12 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
nK *= m_nDexVoxRatio ;
// Se l'indice è alla frontiera del reticolo non vi è materiale
if ( nI <= - 1 || nI >= int( m_nNx[0]) ||
if ( nI <= - 1 || nI >= int( m_nNx[0]) ||
nJ <= - 1 || nJ >= int( m_nNy[0]) ||
nK <= - 1 || nK >= int( m_nNy[1]))
nK <= - 1 || nK >= int( m_nNy[1]))
return false ;
// ciclo sulle griglie
// ciclo sulle griglie
int nCount = 0 ;
int nMinPos[3] = { -1, -1, -1} ;
int nMinIndex[3] ;
@@ -3361,18 +3361,22 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
}
// verifica spillone su vertice
double dMinDist = INFINITO ;
int nIndex = 0 ;
int nIndex = 0 ;
int nPos = nGrJ * m_nNx[nGrid] + nGrI ;
nDexSize[nGrid] = int( m_Values[nGrid][nPos].size()) ;
// scorro i sotto-interalli dello spillone
while ( nIndex < nDexSize[nGrid]) {
// distanza tra la "Z" attuale e il parametro minimo e massimo dell'intervallo nIndex-esimo
double dDistInf = dZ[nGrid] - m_Values[nGrid][nPos][nIndex].dMin + 2 * EPS_SMALL ;
double dDistSup = dZ[nGrid] - m_Values[nGrid][nPos][nIndex].dMax - 2 * EPS_SMALL ;
// se "Z" attuale a cavallo tra queste due distanze...
if ( dDistInf > 0. && dDistSup < 0.) {
nMinIndex[nGrid] = nIndex ;
nMinIndex[nGrid] = nIndex ; // aggiorno l'indice
++ nCount ;
bInterOnNode[nGrid] = true ;
bInterOnNode[nGrid] = true ; // flag T per griglia zero
break ;
}
// se "Z" attuale tutta sopra o tutta sotto
else {
double dDist = min( abs( dDistInf), abs( dDistSup)) ;
if ( dDist < dMinDist) {
@@ -3380,16 +3384,22 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
nMinIndex[nGrid] = nIndex ;
dMinDist = dDist ;
}
}
}
// sotto-intervallo successivo
nIndex += 1 ;
}
}
if ( nCount == 3)
} // fine ciclo sulle griglie
if ( nCount == 3) // ... se interno a tutte e 3 le griglie, allora c'è materiale ...
return true ;
else if ( nCount == 2) {
else if ( nCount == 2) { // ... se interno solo a 2 griglie ...
// recupero la griglia sulla quale è esterno
int nGrid = ( bInterOnNode[0] ? ( bInterOnNode[1] ? 2 : 1) : 0) ;
// se tale griglia non ha sotto-intervalli allora non c'è materiale
if ( nDexSize[nGrid] == 0)
return false ;
// se il valore in "Z" dello spillone è vicino al punto ( 1/10 dello step), aggiorno il
// parametro minimo e massimo e considero la presenza di materiale
if ( dZ[nGrid] > m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMin - 0.1 * m_dStep &&
dZ[nGrid] < m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMax + 0.1 * m_dStep) {
double dDistInf = abs( dZ[nGrid] - m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMin) ;
@@ -3401,9 +3411,9 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
return true ;
}
else
return false ;
return false ;
}
else
else // ... se invece interno a 1 o a nessuna delle griglie, allora non c'è materiale
return false ;
}
+1175 -280
View File
File diff suppressed because it is too large Load Diff