EgtGeomKernel :

- correzione e miglioramento del VM 5 assi per il caso lama e lavorazione 3 assi.
This commit is contained in:
Daniele Bariletti
2025-05-28 17:57:03 +02:00
parent 0247fe5e7c
commit acb0a5bd5e
+477 -424
View File
@@ -23,6 +23,7 @@
#include "/EgtDev/Include/EgtPerfCounter.h"
#include "/EgtDev/Include/EGkSurfBezier.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
#include "/EgtDev/Include/EGkGeoObjSave.h"
#include <future>
using namespace std ;
@@ -815,6 +816,216 @@ VolZmap::AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int
}
// ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline BBox3d
GetCylMoveBBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, double dRad, double dH)
{
// Determinazione delle posizioni della punta del componente nelle posizioni iniziale e finale
Point3d ptP1T = ptP1 - dH * vtV ;
Point3d ptP2T = ptP2 - dH * vtV ;
// Calcolo del box del movimento dell'asse
BBox3d b3Box ;
b3Box.Add( ptP1) ;
b3Box.Add( ptP1T) ;
b3Box.Add( ptP2) ;
b3Box.Add( ptP2T) ;
// Aggiungo ingombro raggio
if ( AreSameOrOppositeVectorApprox( vtV, X_AX))
b3Box.Expand( 0, dRad, dRad) ;
else if ( AreSameOrOppositeVectorApprox( vtV, Y_AX))
b3Box.Expand( dRad, 0, dRad) ;
else if ( AreSameOrOppositeVectorApprox( vtV, Z_AX))
b3Box.Expand( dRad, dRad, 0) ;
else {
double dExpandX = dRad * sqrt( 1 - vtV.x * vtV.x) ;
double dExpandY = dRad * sqrt( 1 - vtV.y * vtV.y) ;
double dExpandZ = dRad * sqrt( 1 - vtV.z * vtV.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline BBox3d
GetCylMoveRotBBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, double dRad, double dH)
{
// Determinazione dei punti più laterali del tool, rispetto alla direzione di movimento
// per la testa e per la punta del tool
Point3d ptP1T = ptP1 - dH * vtV1 ;
Point3d ptP2T = ptP2 - dH * vtV2 ;
Vector3d vtDirTop = ptP2 - ptP1 ;
Vector3d vtDirTip = ptP2T - ptP1T ;
// determino i punti laterali del top e del bottom(tip), nella posizione di partenza
Vector3d vtAuxTopS = vtV1 ^ vtDirTop ;
vtAuxTopS.Normalize() ;
vtAuxTopS *= dRad ;
Point3d ptPTop1 = ptP1 + vtAuxTopS ;
Point3d ptPTop2 = ptP1 - vtAuxTopS ;
Vector3d vtAuxBottomS = vtV1 ^ vtDirTip ;
vtAuxBottomS.Normalize() ;
vtAuxBottomS *= dRad ;
Point3d ptPBottom1 = ptP1T + vtAuxBottomS ;
Point3d ptPBottom2 = ptP1T - vtAuxBottomS ;
// determino i punti laterali del top e del bottom(tip), nella posizione di arrivo
Vector3d vtAuxTopE = vtV2 ^ vtDirTop ;
vtAuxTopE.Normalize() ;
vtAuxTopE *= dRad ;
Point3d ptPTop3 = ptP2 + vtAuxTopE ;
Point3d ptPTop4 = ptP2 - vtAuxTopE ;
Vector3d vtAuxBottomE = vtV2 ^ vtDirTip ;
vtAuxBottomE.Normalize() ;
vtAuxBottomE *= dRad ;
Point3d ptPBottom3 = ptP2T + vtAuxBottomE ;
Point3d ptPBottom4 = ptP2T - vtAuxBottomE ;
// calcolo anche i punti estremi iniziali e finali dei cilindri
Point3d ptTopEnd, ptBottomEnd, ptTopStart, ptBottomStart ;
ptTopEnd = ptP2 + vtDirTop * dRad ;
ptBottomEnd = ptP2T + vtDirTip * dRad ;
ptTopStart = ptP1 - vtDirTop * dRad ;
ptBottomStart = ptP1T - vtDirTip * dRad ;
// Calcolo del box del volume spazzato dal tool
BBox3d b3Box ;
b3Box.Add( ptPTop1) ;
b3Box.Add( ptPTop2) ;
b3Box.Add( ptPBottom1) ;
b3Box.Add( ptPBottom2) ;
b3Box.Add( ptPTop3) ;
b3Box.Add( ptPTop4) ;
b3Box.Add( ptPBottom3) ;
b3Box.Add( ptPBottom4) ;
b3Box.Add( ptTopEnd) ;
b3Box.Add( ptBottomEnd) ;
b3Box.Add( ptTopStart) ;
b3Box.Add( ptBottomStart) ;
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline BBox3d
GetSphereMoveBBox( const Point3d& ptP1, const Point3d& ptP2, double dRad)
{
// Calcolo del box del movimento del centro
BBox3d b3Box ;
b3Box.Add( ptP1) ;
b3Box.Add( ptP2) ;
// Aggiungo ingombro raggio
b3Box.Expand( dRad) ;
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
return TestCompoBBox( nGrid, ptP1, ptP2, vtV, V_NULL, CurrTool.GetRadius(), CurrTool.GetTipRadius(), CurrTool.GetHeigth(),
nStI, nStJ, nEnI, nEnJ) ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, const Vector3d& vtV2,
double dRad, double dTipRad, double dHei,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// I punti e i vettori devono essere nel sistema di riferimento opportuno
// Controllo sull'ammissibilità del numero di griglia
if ( nGrid < 0 || nGrid > 2)
return false ;
// BBox dello Zmap
BBox3d b3Zmap( 0, 0, m_dMinZ[nGrid], m_nNx[nGrid] * m_dStep, m_nNy[nGrid] * m_dStep, m_dMaxZ[nGrid]) ;
// BBox dell'utensile nel suo movimento
double dMaxRad = max( dRad, dTipRad) ;
BBox3d b3Box ;
if ( vtV.IsSmall())
b3Box = GetSphereMoveBBox( ptP1, ptP2, dRad) ;
else if( AreSameVectorExact(vtV2, V_NULL))
b3Box = GetCylMoveBBox( ptP1, ptP2, vtV, dMaxRad, dHei) ;
else
b3Box = GetCylMoveRotBBox( ptP1, ptP2, vtV, vtV2, dRad, dHei) ;
// Verifica dell'interferenza dell'utensile con lo Zmap
if ( ! b3Zmap.FindIntersection( b3Box, b3Box))
return false ;
// Limiti su indici
nStI = max( 0, int( b3Box.GetMin().x / m_dStep)) ;
nEnI = min( m_nNx[nGrid] - 1, int( b3Box.GetMax().x / m_dStep)) ;
nStJ = max( 0, int( b3Box.GetMin().y / m_dStep)) ;
nEnJ = min( m_nNy[nGrid] - 1, int( b3Box.GetMax().y / m_dStep)) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA,
double dLenX, double dLenY, double dLenZ,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// I punti e i vettori devono essere nel sistema di riferimento opportuno
// Determino le posizioni iniziale e
// finale della punta dell'utensile.
Point3d ptSTip = ptS - vtD * dLenZ ;
Point3d ptETip = ptE - vtD * dLenZ ;
double dSemiDiag = sqrt( dLenX * dLenX + dLenY * dLenY) / 2 ;
// Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento
double dMinX = min( min( ptS.x, ptSTip.x), min( ptE.x, ptETip.x)) - dSemiDiag ;
double dMinY = min( min( ptS.y, ptSTip.y), min( ptE.y, ptETip.y)) - dSemiDiag ;
double dMinZ = min( min( ptS.z, ptSTip.z), min( ptE.z, ptETip.z)) - dSemiDiag ;
double dMaxX = max( max( ptS.x, ptSTip.x), max( ptE.x, ptETip.x)) + dSemiDiag ;
double dMaxY = max( max( ptS.y, ptSTip.y), max( ptE.y, ptETip.y)) + dSemiDiag ;
double dMaxZ = max( max( ptS.z, ptSTip.z), max( ptE.z, ptETip.z)) + dSemiDiag ;
int nMaxNx = m_nNx[nGrid] ;
int nMaxNy = m_nNy[nGrid] ;
double dMaxXValue = nMaxNx * m_dStep ;
double dMaxYValue = nMaxNy * m_dStep ;
double dMinZValue = m_dMinZ[nGrid] ;
double dMaxZValue = m_dMaxZ[nGrid] ;
// Verifica dell'interferenza dell'utensile con lo Zmap
if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL)
return false ;
if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL)
return false ;
if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL)
return false ;
// Limiti su indici
nStI = ( dMinX < EPS_SMALL ? 0 : int( dMinX / m_dStep)) ;
nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : int( dMaxX / m_dStep)) ;
nStJ = ( dMinY < EPS_SMALL ? 0 : int( dMinY / m_dStep)) ;
nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : int ( dMaxY / m_dStep)) ;
return true ;
}
// ------------------------- LAVORAZIONI --------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
@@ -1084,6 +1295,12 @@ bool
VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
double dHeight, double dMaxRad, double dMinRad, int nToolNum)
{
// tolgo il volume spazzato dal tool durante il movimento
// Verifica sull'interferenza con lo Zmap
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( nGrid, ptS, ptE, vtLs, vtLe, dMaxRad, dMinRad, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
Point3d ptTop1s ;
Point3d ptTop1e ;
Point3d ptTop2s ;
@@ -1126,38 +1343,105 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
ptBottom1e = ptP2T + vtAuxBottomE ;
ptBottom2e = ptP2T - vtAuxBottomE ;
int nSub = 4 ;
PNTVECTOR vPntTipStart ;
PNTVECTOR vPntTipEnd ;
PNTVECTOR vPntTopStart ;
PNTVECTOR vPntTopEnd ;
if ( nSub > 1) {
// determino in che modo collegare il cilindro iniziale con quello finale
Vector3d vtTopBaseEnd = vtDirTop - ( (vtDirTop * vtLe) * vtLe) ;
vtTopBaseEnd.Normalize() ;
vtTopBaseEnd *= dMaxRad ;
Point3d ptRefEnd = ptE - vtTopBaseEnd ;
Vector3d vtTopBaseStart = vtDirTop - ( ( vtDirTop * vtLs) * vtLs) ;
vtTopBaseStart.Normalize() ;
vtTopBaseStart *= dMaxRad ;
Point3d ptRefStart = ptS + vtTopBaseStart ;
double dSide = (ptRefEnd - ptRefStart) * vtLs ;
// calcolo anche i vettori per le basi inferiori
Vector3d vtTipBaseStart = - (vtLs ^ vtDirTip) ;
vtTipBaseStart.Normalize() ;
vtTipBaseStart *= dMinRad ;
Vector3d vtTipBaseEnd = - (vtLe ^ vtDirTip) ;
vtTipBaseEnd.Normalize() ;
vtTipBaseEnd *= dMinRad ;
// aggiungo il primo punto per ognuno dei gruppi
vtTopBaseStart.Rotate( vtLs, 90) ;
vtTopBaseEnd.Rotate( vtLe, 90) ;
vPntTopStart.emplace_back( ptS + vtTopBaseStart) ;
vPntTopEnd.emplace_back( ptE + vtTopBaseEnd) ;
vPntTipStart.emplace_back( ptP1T + vtTipBaseStart) ;
vPntTipEnd.emplace_back( ptP2T + vtTipBaseEnd) ;
double dSubAng = 180. / nSub ;
// se dSide si discosta da zero allora devo usare più di una superficie per definire la parte superiore e inferiore del volume spazzata dal tool
for ( int i = 0 ; i < nSub ; ++i) {
// punti sulla base superiore dei cilindri
vPntTopStart.emplace_back( vPntTopStart.back()) ;
if ( dSide > 0)
vPntTopStart.back().Rotate(ptS, vtLs, dSubAng) ;
else
vPntTopStart.back().Rotate(ptS, vtLs, -dSubAng) ;
vPntTopEnd.emplace_back( vPntTopEnd.back()) ;
if ( dSide > 0)
vPntTopEnd.back().Rotate(ptE, vtLe, dSubAng) ;
else
vPntTopEnd.back().Rotate(ptE, vtLe, -dSubAng) ;
// tolgo il volume spazzato dal tool durante il movimento
// Verifica sull'interferenza con lo Zmap
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( nGrid, ptS, ptE, vtLs, vtLe, dMaxRad, dMinRad, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
// punti sulla base inferiore dei cilindri
vPntTipStart.emplace_back( vPntTipStart.back()) ;
if ( dSide > 0)
vPntTipStart.back().Rotate(ptP1T, vtLs, dSubAng) ;
else
vPntTipStart.back().Rotate(ptP1T, vtLs, -dSubAng) ;
vPntTipEnd.emplace_back( vPntTipEnd.back()) ;
if ( dSide > 0)
vPntTipEnd.back().Rotate(ptP2T, vtLe, dSubAng) ;
else
vPntTipEnd.back().Rotate(ptP2T, vtLe, -dSubAng) ;
}
}
int nDegU = 1 ; int nDegV = 1 ;
int nSpanU = 1 ; int nSpanV = 1 ;
bool bRat = false ;
vector<PNTVECTOR> vvPtCtrl ;
PNTVECTOR vPtCtrl0 = { ptBottom1s, ptTop1s, ptBottom1e, ptTop1e} ;
vvPtCtrl.push_back( std::move( vPtCtrl0)) ;
PNTVECTOR vPtCtrl1 = { ptBottom2s, ptBottom1s, ptBottom2e, ptBottom1e} ;
vvPtCtrl.push_back( std::move( vPtCtrl1)) ;
PNTVECTOR vPtCtrl2 = { ptTop2s, ptBottom2s, ptTop2e, ptBottom2e} ;
vvPtCtrl.push_back( std::move( vPtCtrl2)) ;
PNTVECTOR vPtCtrl3 = { ptTop1s, ptTop2s, ptTop1e, ptTop2e} ;
vvPtCtrl.push_back( std::move( vPtCtrl3)) ;
PNTVECTOR vPtCtrl4 = { ptBottom1s, ptBottom2s, ptTop1s, ptTop2s} ;
vvPtCtrl.push_back( std::move( vPtCtrl4)) ;
PNTVECTOR vPtCtrl5 = { ptBottom2e, ptBottom1e, ptTop2e, ptTop1e} ;
vvPtCtrl.push_back( std::move( vPtCtrl5)) ;
// superficie laterale sinistra
vvPtCtrl.emplace_back( PNTVECTOR({ ptBottom1s, ptTop1s, ptBottom1e, ptTop1e})) ;
// superficie laterale destra
vvPtCtrl.emplace_back( PNTVECTOR({ ptTop2s, ptBottom2s, ptTop2e, ptBottom2e})) ;
if ( nSub == 1) {
// superficie inferiore
vvPtCtrl.emplace_back( PNTVECTOR({ ptBottom2s, ptBottom1s, ptBottom2e, ptBottom1e})) ;
// superficie superiore
vvPtCtrl.emplace_back( PNTVECTOR({ ptTop1s, ptTop2s, ptTop1e, ptTop2e})) ;
}
else {
// superfici superiori
for ( int i = 0 ; i < nSub ; ++i) {
vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i], vPntTipStart[i+1], vPntTipEnd[i], vPntTipEnd[i+1]})) ;
}
// superficie inferiori
for ( int i = 0 ; i < nSub ; ++i) {
vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart[i], vPntTopStart[i+1], vPntTopEnd[i], vPntTopEnd[i+1]})) ;
}
}
BOXVECTOR vSurfBox(6) ;
// inizializzo le 6 superfici bilineari e i parametri per le intersezioni
ISURFBEZPOVECTOR vSurfBez ;
PNTVECTOR d ;
Vector3d q = Z_AX ;
DBLVECTOR A1, B1, C1, A2, B2, C2 ;
for( int s = 0 ; s < 6 ; ++s) {
int nTotSurf = 2 + nSub * 2 ;
BOXVECTOR vSurfBox( nTotSurf) ;
////debug
//vector<IGeoObj*> vGeo ;
////debug
for( int s = 0 ; s < nTotSurf ; ++s) {
vSurfBez.emplace_back( CreateSurfBezier()) ;
vSurfBez.back()->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
vSurfBez.back()->SetControlPoint( 0, vvPtCtrl[s][0]) ;
@@ -1177,8 +1461,36 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
A2.push_back( a.y * q.z - a.z * q.y) ;
B2.push_back( b.y * q.z - b.z * q.y) ;
C2.push_back( c.y * q.z - c.z * q.y) ;
//vGeo.push_back( vSurfBez[s]) ;
}
////debug
//SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ;
//return true ;
////debug
BBox3d bbStartCyl = GetCylMoveBBox( ptS, ptS, vtLs, dMaxRad, dHeight) ;
BBox3d bbEndCyl = GetCylMoveBBox( ptE, ptE, vtLe, dMaxRad, dHeight) ;
// se sono nel caso di un cono calcolo già i parametri utili
Point3d ptVS, ptVE ;
double dTan = 0, dMinH, dMaxH ;
if ( dMinRad < EPS_SMALL) {
ptVS = ptP1T ;
ptVE = ptP2T ;
dMinH = 0 ;
dMaxH = dHeight ;
dTan = dMaxRad / dHeight ;
}
else {
dTan = (dMaxRad - dMinRad) / dHeight ;
dMaxH = dMaxRad * dTan ;
dMinH = dMaxH - dHeight ;
ptVS = ptS - vtLs * dMaxH ;
ptVE = ptE - vtLe * dMaxH ;
}
// scorro tutti gli spilloni interessati
for ( int i = nStartI ; i <= nEndI ; ++ i) {
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
@@ -1188,7 +1500,62 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c
Point3d ptMin, ptMax ;
double dMin = INFINITO, dMax = -10 ;
Vector3d vtMin, vtMax ;
for( int s = 0 ; s < 6 ; ++s) {
// interseco con i cilindri di inizio e fine moto
// se sto trattando un cilindro
if ( dMaxRad - dMinRad < EPS_SMALL) {
// prima di calcolare l'intersezione verifico che ci sia interferenza con i box
if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) {
Frame3d frStartCyl ;
frStartCyl.Set( ptP1T, vtLs) ;
Point3d pt1, pt2 ;
Vector3d vt1, vt2 ;
IntersLineCylinder( r, Z_AX, frStartCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2) ;
if ( ! AreSameVectorExact( vt1, V_NULL))
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
if ( ! AreSameVectorExact( vt2, V_NULL))
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
}
if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) {
Frame3d frEndCyl ;
frEndCyl.Set( ptP2T, vtLe) ;
Point3d pt1, pt2 ;
Vector3d vt1, vt2 ;
IntersLineCylinder( r, Z_AX, frEndCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2) ;
if ( ! AreSameVectorExact( vt1, V_NULL))
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
if ( ! AreSameVectorExact( vt2, V_NULL))
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
}
}
// se sto trattando un cono
else {
if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) {
Frame3d frStartCon ;
frStartCon.Set( ptVS, vtLs) ;
Point3d pt1, pt2 ;
Vector3d vt1, vt2 ;
IntersLineConus( r, Z_AX, frStartCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2) ;
if ( ! AreSameVectorExact( vt1, V_NULL))
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
if ( ! AreSameVectorExact( vt2, V_NULL))
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
}
if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) {
Frame3d frEndCon ;
frEndCon.Set( ptVE, vtLe) ;
Point3d pt1, pt2 ;
Vector3d vt1, vt2 ;
IntersLineConus( r, Z_AX, frEndCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2) ;
if ( ! AreSameVectorExact( vt1, V_NULL))
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
if ( ! AreSameVectorExact( vt2, V_NULL))
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
}
}
// interseco con le bilineari
for( int s = 0 ; s < nTotSurf ; ++s) {
// verifico che lo spillone faccia interferenza con il box della superficie
if ( vSurfBox[s].SqDistFromPointXY( r) < EPS_ZERO) {
double D1 = ( d[s].x - r.x) * q.z - ( d[s].z - r.z) * q.x ;
@@ -1237,20 +1604,20 @@ VolZmap::CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE
double dHeight, double dRadius, int nToolNum, const int nPhase)
{
bool bOk = true ;
// tolgo il volume del cilindro iniziale e finale del moto
if ( nPhase == VolZmap::MillingPhase::COUNT_START_VOL) {
// in base all'orientamento del tool scelgo la funzione adatta
if ( vtLs.SqLenXY() < EPS_SMALL * EPS_SMALL)
bOk = bOk && CompCyl_ZDrilling( nGrid, ptS, ptS, vtLs, dHeight, dRadius, nToolNum) ;
else
bOk = bOk && CompCyl_Drilling( nGrid, ptS, ptS, vtLs, dHeight, dRadius, false, false, nToolNum) ;
}
if ( nPhase == VolZmap::MillingPhase::COUNT_END_VOL) {
if ( vtLe.SqLenXY() < EPS_SMALL * EPS_SMALL)
bOk = bOk && CompCyl_ZDrilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, nToolNum) ;
else
bOk = bOk && CompCyl_Drilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, false, false, nToolNum) ;
}
//// tolgo il volume del cilindro iniziale e finale del moto
//if ( nPhase == VolZmap::MillingPhase::COUNT_START_VOL) {
// // in base all'orientamento del tool scelgo la funzione adatta
// if ( vtLs.SqLenXY() < EPS_SMALL * EPS_SMALL)
// bOk = bOk && CompCyl_ZDrilling( nGrid, ptS, ptS, vtLs, dHeight, dRadius, nToolNum) ;
// else
// bOk = bOk && CompCyl_Drilling( nGrid, ptS, ptS, vtLs, dHeight, dRadius, false, false, nToolNum) ;
//}
//if ( nPhase == VolZmap::MillingPhase::COUNT_END_VOL) {
// if ( vtLe.SqLenXY() < EPS_SMALL * EPS_SMALL)
// bOk = bOk && CompCyl_ZDrilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, nToolNum) ;
// else
// bOk = bOk && CompCyl_Drilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, false, false, nToolNum) ;
//}
// tolgo il valume spazzato dal tool durante il movimento
bOk = bOk && Comp_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHeight, dRadius, dRadius, nToolNum) ;
@@ -1328,152 +1695,6 @@ VolZmap::CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& p
bOk = bOk && Comp_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHei, dMaxRad, dMinRad, nToolNum) ;
return bOk ;
//// elimino la parte spazzata dal cono
//Point3d ptTop1s ;
//Point3d ptTop1e ;
//Point3d ptTop2s ;
//Point3d ptTop2e ;
//// per la parte bassa del cono mi servono due punti perché se ho un tronco di cono, non ho la punta ma i due punti a distansa dMinR dall'asse di simmetria
//Point3d ptBottom1s ;
//Point3d ptBottom1e ;
//Point3d ptBottom2s ;
//Point3d ptBottom2e ;
//// determino la posizione della punta del tool nella posizione iniziale e in quella finale
//Point3d ptP1T = ptS - dHei * vtLs ;
//Point3d ptP2T = ptE - dHei * vtLe ;
//// determino la direzione di movimento del top del tool e della punta del tool
//Vector3d vtDirTop = ptE - ptS ;
//Vector3d vtDirTip = ptP2T - ptP1T ;
//// determino i punti laterali del top e del bottom(tip), nella posizione di partenza
//Vector3d vtAuxTopS = vtLs ^ vtDirTop ;
//vtAuxTopS.Normalize() ;
//vtAuxTopS *= dMaxRad ;
//ptTop1s = ptS + vtAuxTopS ;
//ptTop2s = ptS - vtAuxTopS ;
//Vector3d vtAuxBottomS = vtLs ^ vtDirTip ;
//vtAuxBottomS.Normalize() ;
//vtAuxBottomS *= dMinRad ;
//ptBottom1s = ptP1T + vtAuxBottomS ;
//ptBottom2s = ptP1T - vtAuxBottomS ;
//// determino i punti laterali del top e del bottom(tip), nella posizione di arrivo
//Vector3d vtAuxTopE = vtLe ^ vtDirTop ;
//vtAuxTopE.Normalize() ;
//vtAuxTopE *= dMaxRad ;
//ptTop1e = ptE + vtAuxTopE ;
//ptTop2e = ptE - vtAuxTopE ;
//Vector3d vtAuxBottomE = vtLe ^ vtDirTip ;
//vtAuxBottomE.Normalize() ;
//vtAuxBottomE *= dMinRad ;
//ptBottom1e = ptP2T + vtAuxBottomE ;
//ptBottom2e = ptP2T - vtAuxBottomE ;
//// tolgo il volume spazzato dal tool durante il movimento
//// Verifica sull'interferenza con lo Zmap
//int nStartI, nStartJ, nEndI, nEndJ ;
//if ( ! TestCompoBBox( nGrid, ptS, ptE, vtLs, vtLe, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ))
// return true ;
//int nDegU = 1 ; int nDegV = 1 ;
//int nSpanU = 1 ; int nSpanV = 1 ;
//bool bRat = false ;
//vector<PNTVECTOR> vvPtCtrl ;
//PNTVECTOR vPtCtrl0 = { ptBottom1s, ptTop1s, ptBottom1e, ptTop1e} ;
//vvPtCtrl.push_back( std::move( vPtCtrl0)) ;
//PNTVECTOR vPtCtrl1 = { ptBottom2s, ptBottom1s, ptBottom2e, ptBottom1e} ;
//vvPtCtrl.push_back( std::move( vPtCtrl1)) ;
//PNTVECTOR vPtCtrl2 = { ptTop2s, ptBottom2s, ptTop2e, ptBottom2e} ;
//vvPtCtrl.push_back( std::move( vPtCtrl2)) ;
//PNTVECTOR vPtCtrl3 = { ptTop1s, ptTop2s, ptTop1e, ptTop2e} ;
//vvPtCtrl.push_back( std::move( vPtCtrl3)) ;
//PNTVECTOR vPtCtrl4 = { ptBottom1s, ptBottom2s, ptTop1s, ptTop2s} ;
//vvPtCtrl.push_back( std::move( vPtCtrl4)) ;
//PNTVECTOR vPtCtrl5 = { ptBottom2e, ptBottom1e, ptTop2e, ptTop1e} ;
//vvPtCtrl.push_back( std::move( vPtCtrl5)) ;
//BOXVECTOR vSurfBox(6) ;
//// inizializzo le 6 superfici bilineari e i parametri per le intersezioni
//ISURFBEZPOVECTOR vSurfBez ;
//PNTVECTOR d ;
//Vector3d q = Z_AX ;
//DBLVECTOR A1, B1, C1, A2, B2, C2 ;
//for( int s = 0 ; s < 6 ; ++s) {
// vSurfBez.emplace_back( CreateSurfBezier()) ;
// vSurfBez.back()->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
// vSurfBez.back()->SetControlPoint( 0, vvPtCtrl[s][0]) ;
// vSurfBez.back()->SetControlPoint( 1, vvPtCtrl[s][1]) ;
// vSurfBez.back()->SetControlPoint( 2, vvPtCtrl[s][2]) ;
// vSurfBez.back()->SetControlPoint( 3, vvPtCtrl[s][3]) ;
// vSurfBox[s].Add( vvPtCtrl[s]) ;
// Vector3d a = vvPtCtrl[s][3] - vvPtCtrl[s][1] + ( vvPtCtrl[s][0] - vvPtCtrl[s][2]) ;
// Vector3d b = vvPtCtrl[s][1] - vvPtCtrl[s][0] ;
// Vector3d c = vvPtCtrl[s][2] - vvPtCtrl[s][0] ;
// d.push_back( vvPtCtrl[s][0]) ;
// A1.push_back( a.x * q.z - a.z * q.x) ;
// B1.push_back( b.x * q.z - b.z * q.x) ;
// C1.push_back( c.x * q.z - c.z * q.x) ;
// A2.push_back( a.y * q.z - a.z * q.y) ;
// B2.push_back( b.y * q.z - b.z * q.y) ;
// C2.push_back( c.y * q.z - c.z * q.y) ;
//}
//// scorro tutti gli spilloni interessati
//for ( int i = nStartI ; i <= nEndI ; ++ i) {
// for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
// double dX = ( i + 0.5) * m_dStep ;
// double dY = ( j + 0.5) * m_dStep ;
// Point3d r( dX, dY, 0) ;
// Point3d ptMin, ptMax ;
// double dMin = INFINITO, dMax = -10 ;
// Vector3d vtMin, vtMax ;
// for( int s = 0 ; s < 6 ; ++s) {
// // verifico che lo spillone faccia interferenza con il box della superficie
// if ( vSurfBox[s].SqDistFromPointXY( r) < EPS_ZERO) {
// double D1 = ( d[s].x - r.x) * q.z - ( d[s].z - r.z) * q.x ;
// double D2 = ( d[s].y - r.y) * q.z - ( d[s].z - r.z) * q.y ;
// DBLVECTOR vdCoeff, vdRoots ;
// vdCoeff = { (B2[s] * D1 - B1[s] * D2), ( A2[s] * D1 - A1[s] * D2 + B2[s] * C1[s] - B1[s] * C2[s]), ( A2[s] * C1[s] - A1[s] * C2[s])} ;
// int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ;
// if ( nRoots != 0) {
// double dU1 = 0, dV1 = 0 ;
// double dU2 = 0, dV2 = 0 ;
// if ( vdRoots[0] > 0 - EPS_ZERO && vdRoots[0] < 1 + EPS_ZERO) {
// dV1 = vdRoots[0] ;
// dU1 = (dV1 * (C1[s] - C2[s]) + ( D1 - D2)) / ( dV1 * ( A2[s] - A1[s]) + ( B2[s] - B1[s])) ;
// if ( dU1 > - EPS_ZERO && dU1 < 1 + EPS_ZERO) {
// Point3d ptBez1 ;
// Vector3d vtN1 ;
// vSurfBez[s]->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez1, vtN1) ;
// UpdateMaxMin( ptBez1, vtN1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
// }
// }
// if ( nRoots > 1 && vdRoots[1] > 0 - EPS_ZERO && vdRoots[1] < 1 + EPS_ZERO) {
// dV2 = vdRoots[1] ;
// dU2 = (dV2 * (C1[s] - C2[s]) + ( D1 - D2)) / ( dV2 * ( A2[s] - A1[s]) + ( B2[s] - B1[s])) ;
// if ( dU2 > - EPS_ZERO && dU2 < 1 + EPS_ZERO) {
// Point3d ptBez2 ;
// Vector3d vtN2 ;
// vSurfBez[s]->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez2, vtN2) ;
// UpdateMaxMin( ptBez2, vtN2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
// }
// }
// }
// }
// }
// if ( dMax > 0 && dMin < dMax)
// SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, CurrTool.GetToolNum()) ;
// }
//}
//return true ;
}
//----------------------------------------------------------------------------
@@ -1548,15 +1769,42 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
double dAlongAngDeg, dAcrossAngDeg ;
GetAlongAcrossRotation( vtDs, vtDe, ptPe - ptPs, dAlongAngDeg, dAcrossAngDeg) ;
// Divido il movimento in tratti con direzione utensile costante
const double ANG_ACROSS_STEP = 4 ;
const double ANG_ACROSS_STEP = 1.0 ;
const double ANG_ALONG_STEP = 1.0 ;
int nStepCnt = int( max( { abs( dAlongAngDeg) / ANG_ALONG_STEP, abs( dAcrossAngDeg) / ANG_ACROSS_STEP, 1.})) ;
bool bOk = true ;
//////// debug - vecchia modalità
Point3d ptSt = ptPs ;
//////// debug - vecchia modalità
Point3d ptSti = ptPs ;
Vector3d vtDSi = vtDs ;
double dCorr = 0.05 * 1. / nStepCnt ; // creo una sovrapposizone tra uno step e il successivo
for ( int i = 0 ; i <= nStepCnt && bOk ; ++ i) {
////////// debug - vecchia modalità
// double dPosCoeff, dDirCoeff ;
// if ( i < nStepCnt) {
// dPosCoeff = ( i + 0.5) / nStepCnt ;
// dDirCoeff = double( i) / nStepCnt ;
// }
// else {
// dPosCoeff = 1 ;
// dDirCoeff = 1 ;
// }
// Point3d ptEn = Media( ptPs, ptPe, dPosCoeff) ;
// Vector3d vtD = Media( vtDs, vtDe, dDirCoeff) ; vtD.Normalize() ;
// Vector3d vtA = Media( vtAs, vtAe, dDirCoeff) ; vtA.Normalize() ;
// bOk = bOk && MillingTranslationStep( ptSt, ptEn, vtD, vtA) ;
//// aggiorno prossimo inizio
// ptSt = ptEn ;
////////// debug - vecchia modalità
//// replico il tutto ma tenendo degli step più ampi e usando i veri vettori di start e end del tratto
double dPosCoeffE, dDirCoeffE, dPosCoeffS, dDirCoeffS ;
dPosCoeffS = double( i) / (nStepCnt + 1) ;
@@ -1582,26 +1830,31 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
Vector3d vtLe[N_MAPS] ;
InitializePointsAndVectors( ptSti, ptEni, vtDSi, vtDEi, ptLs, ptLe, vtLs, vtLe) ;
/////// decommentare solo per debug
//for( int i = 0 ; i < N_MAPS; ++i)
// SelectGeneralMotion( i, ptLs[i], ptLe[i], vtLs[i],vtLe[i], nPhase) ;
///// decommentare solo per debug
for( int i = 0 ; i < N_MAPS; ++i)
SelectGeneralMotion( i, ptLs[i], ptLe[i], vtLs[i],vtLe[i], nPhase) ;
// Ciclo sulle mappe
vector< future<bool>> vRes ;
vRes.resize( m_nMapNum) ;
for ( int i = 0 ; i < m_nMapNum ; ++ i) {
vRes[i] = async( launch::async, &VolZmap::SelectGeneralMotion, this, i, cref( ptLs[i]), cref( ptLe[i]), cref( vtLs[i]), cref( vtLe[i]), nPhase) ;
}
bool bOk = true ;
int nTerminated = 0 ;
while ( nTerminated < m_nMapNum) {
for ( int i = 0 ; i < m_nMapNum ; ++ i) {
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
bOk = vRes[i].get() && bOk ;
++ nTerminated ;
}
}
}
//// Ciclo sulle mappe
//vector< future<bool>> vRes ;
//vRes.resize( m_nMapNum) ;
//for ( int i = 0 ; i < m_nMapNum ; ++ i) {
// vRes[i] = async( launch::async, &VolZmap::SelectGeneralMotion, this, i, cref( ptLs[i]), cref( ptLe[i]), cref( vtLs[i]), cref( vtLe[i]), nPhase) ;
//}
//bool bOk = true ;
//int nTerminated = 0 ;
//while ( nTerminated < m_nMapNum) {
// for ( int i = 0 ; i < m_nMapNum ; ++ i) {
// if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
// bOk = vRes[i].get() && bOk ;
// ++ nTerminated ;
// }
// }
//}
////debug
//if ( i == 0)
// return true ;
////debug
}
return bOk ;
@@ -1616,32 +1869,32 @@ VolZmap::MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const
Vector3d vtLs[N_MAPS] ;
Vector3d vtALs[N_MAPS] ;
InitializePointsAndVectors( ptPs, ptPe, vtD, vtA, ptLs, ptLe, vtLs, vtALs) ;
//// Ciclo sulle mappe (scommentare solo per DEBUG)
// {
// bool bOk = true ;
// for ( int i = 0 ; i < m_nMapNum ; ++ i) {
// bOk = SelectMotion( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) && bOk ;
// }
// return true ;
// }
// Ciclo sulle mappe
vector< future<bool>> vRes ;
vRes.resize( m_nMapNum) ;
for ( int i = 0 ; i < m_nMapNum ; ++ i) {
vRes[i] = async( launch::async, &VolZmap::SelectMotion, this, i, cref( ptLs[i]), cref( ptLe[i]), cref( vtLs[i]), cref( vtALs[i])) ;
}
bool bOk = true ;
int nTerminated = 0 ;
while ( nTerminated < m_nMapNum) {
// Ciclo sulle mappe (scommentare solo per DEBUG)
{
bool bOk = true ;
for ( int i = 0 ; i < m_nMapNum ; ++ i) {
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
bOk = vRes[i].get() && bOk ;
++ nTerminated ;
}
bOk = SelectMotion( i, ptLs[i], ptLe[i], vtLs[i], vtALs[i]) && bOk ;
}
return true ;
}
return bOk ;
//// Ciclo sulle mappe
// vector< future<bool>> vRes ;
// vRes.resize( m_nMapNum) ;
// for ( int i = 0 ; i < m_nMapNum ; ++ i) {
// vRes[i] = async( launch::async, &VolZmap::SelectMotion, this, i, cref( ptLs[i]), cref( ptLe[i]), cref( vtLs[i]), cref( vtALs[i])) ;
// }
// bool bOk = true ;
// int nTerminated = 0 ;
// while ( nTerminated < m_nMapNum) {
// for ( int i = 0 ; i < m_nMapNum ; ++ i) {
// if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
// bOk = vRes[i].get() && bOk ;
// ++ nTerminated ;
// }
// }
// }
// return bOk ;
}
//----------------------------------------------------------------------------
@@ -6435,203 +6688,3 @@ VolZmap::AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double
return true ;
}
// ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline BBox3d
GetCylMoveBBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, double dRad, double dH)
{
// Determinazione delle posizioni della punta del componente nelle posizioni iniziale e finale
Point3d ptP1T = ptP1 - dH * vtV ;
Point3d ptP2T = ptP2 - dH * vtV ;
// Calcolo del box del movimento dell'asse
BBox3d b3Box ;
b3Box.Add( ptP1) ;
b3Box.Add( ptP1T) ;
b3Box.Add( ptP2) ;
b3Box.Add( ptP2T) ;
// Aggiungo ingombro raggio
if ( AreSameOrOppositeVectorApprox( vtV, X_AX))
b3Box.Expand( 0, dRad, dRad) ;
else if ( AreSameOrOppositeVectorApprox( vtV, Y_AX))
b3Box.Expand( dRad, 0, dRad) ;
else if ( AreSameOrOppositeVectorApprox( vtV, Z_AX))
b3Box.Expand( dRad, dRad, 0) ;
else {
double dExpandX = dRad * sqrt( 1 - vtV.x * vtV.x) ;
double dExpandY = dRad * sqrt( 1 - vtV.y * vtV.y) ;
double dExpandZ = dRad * sqrt( 1 - vtV.z * vtV.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline BBox3d
GetCylMoveRotBBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, double dRad, double dH)
{
// Determinazione dei punti più laterali del tool, rispetto alla direzione di movimento
// per la testa e per la punta del tool
Point3d ptP1T = ptP1 - dH * vtV1 ;
Point3d ptP2T = ptP2 - dH * vtV2 ;
Vector3d vtDirTop = ptP2 - ptP1 ;
Vector3d vtDirTip = ptP2T - ptP1T ;
// determino i punti laterali del top e del bottom(tip), nella posizione di partenza
Vector3d vtAuxTopS = vtV1 ^ vtDirTop ;
vtAuxTopS.Normalize() ;
vtAuxTopS *= dRad ;
Point3d ptPTop1 = ptP1 + vtAuxTopS ;
Point3d ptPTop2 = ptP1 - vtAuxTopS ;
Vector3d vtAuxBottomS = vtV1 ^ vtDirTip ;
vtAuxBottomS.Normalize() ;
vtAuxBottomS *= dRad ;
Point3d ptPBottom1 = ptP1T + vtAuxBottomS ;
Point3d ptPBottom2 = ptP1T - vtAuxBottomS ;
// determino i punti laterali del top e del bottom(tip), nella posizione di arrivo
Vector3d vtAuxTopE = vtV2 ^ vtDirTop ;
vtAuxTopE.Normalize() ;
vtAuxTopE *= dRad ;
Point3d ptPTop3 = ptP2 + vtAuxTopE ;
Point3d ptPTop4 = ptP2 - vtAuxTopE ;
Vector3d vtAuxBottomE = vtV2 ^ vtDirTip ;
vtAuxBottomE.Normalize() ;
vtAuxBottomE *= dRad ;
Point3d ptPBottom3 = ptP2T + vtAuxBottomE ;
Point3d ptPBottom4 = ptP2T - vtAuxBottomE ;
// Calcolo del box del volume spazzato dal tool
BBox3d b3Box ;
b3Box.Add( ptPTop1) ;
b3Box.Add( ptPTop2) ;
b3Box.Add( ptPBottom1) ;
b3Box.Add( ptPBottom2) ;
b3Box.Add( ptPTop3) ;
b3Box.Add( ptPTop4) ;
b3Box.Add( ptPBottom3) ;
b3Box.Add( ptPBottom4) ;
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline BBox3d
GetSphereMoveBBox( const Point3d& ptP1, const Point3d& ptP2, double dRad)
{
// Calcolo del box del movimento del centro
BBox3d b3Box ;
b3Box.Add( ptP1) ;
b3Box.Add( ptP2) ;
// Aggiungo ingombro raggio
b3Box.Expand( dRad) ;
// Restituisco il box calcolato
return b3Box ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
return TestCompoBBox( nGrid, ptP1, ptP2, vtV, V_NULL, CurrTool.GetRadius(), CurrTool.GetTipRadius(), CurrTool.GetHeigth(),
nStI, nStJ, nEnI, nEnJ) ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, const Vector3d& vtV2,
double dRad, double dTipRad, double dHei,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// I punti e i vettori devono essere nel sistema di riferimento opportuno
// Controllo sull'ammissibilità del numero di griglia
if ( nGrid < 0 || nGrid > 2)
return false ;
// BBox dello Zmap
BBox3d b3Zmap( 0, 0, m_dMinZ[nGrid], m_nNx[nGrid] * m_dStep, m_nNy[nGrid] * m_dStep, m_dMaxZ[nGrid]) ;
// BBox dell'utensile nel suo movimento
double dMaxRad = max( dRad, dTipRad) ;
BBox3d b3Box ;
if ( vtV.IsSmall())
b3Box = GetSphereMoveBBox( ptP1, ptP2, dRad) ;
else if( AreSameVectorExact(vtV2, V_NULL))
b3Box = GetCylMoveBBox( ptP1, ptP2, vtV, dMaxRad, dHei) ;
else
b3Box = GetCylMoveRotBBox( ptP1, ptP2, vtV, vtV2, dRad, dHei) ;
// Verifica dell'interferenza dell'utensile con lo Zmap
if ( ! b3Zmap.FindIntersection( b3Box, b3Box))
return false ;
// Limiti su indici
nStI = max( 0, int( b3Box.GetMin().x / m_dStep)) ;
nEnI = min( m_nNx[nGrid] - 1, int( b3Box.GetMax().x / m_dStep)) ;
nStJ = max( 0, int( b3Box.GetMin().y / m_dStep)) ;
nEnJ = min( m_nNy[nGrid] - 1, int( b3Box.GetMax().y / m_dStep)) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
VolZmap::TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA,
double dLenX, double dLenY, double dLenZ,
int& nStI, int& nStJ, int& nEnI, int& nEnJ)
{
// I punti e i vettori devono essere nel sistema di riferimento opportuno
// Determino le posizioni iniziale e
// finale della punta dell'utensile.
Point3d ptSTip = ptS - vtD * dLenZ ;
Point3d ptETip = ptE - vtD * dLenZ ;
double dSemiDiag = sqrt( dLenX * dLenX + dLenY * dLenY) / 2 ;
// Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento
double dMinX = min( min( ptS.x, ptSTip.x), min( ptE.x, ptETip.x)) - dSemiDiag ;
double dMinY = min( min( ptS.y, ptSTip.y), min( ptE.y, ptETip.y)) - dSemiDiag ;
double dMinZ = min( min( ptS.z, ptSTip.z), min( ptE.z, ptETip.z)) - dSemiDiag ;
double dMaxX = max( max( ptS.x, ptSTip.x), max( ptE.x, ptETip.x)) + dSemiDiag ;
double dMaxY = max( max( ptS.y, ptSTip.y), max( ptE.y, ptETip.y)) + dSemiDiag ;
double dMaxZ = max( max( ptS.z, ptSTip.z), max( ptE.z, ptETip.z)) + dSemiDiag ;
int nMaxNx = m_nNx[nGrid] ;
int nMaxNy = m_nNy[nGrid] ;
double dMaxXValue = nMaxNx * m_dStep ;
double dMaxYValue = nMaxNy * m_dStep ;
double dMinZValue = m_dMinZ[nGrid] ;
double dMaxZValue = m_dMaxZ[nGrid] ;
// Verifica dell'interferenza dell'utensile con lo Zmap
if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL)
return false ;
if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL)
return false ;
if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL)
return false ;
// Limiti su indici
nStI = ( dMinX < EPS_SMALL ? 0 : int( dMinX / m_dStep)) ;
nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : int( dMaxX / m_dStep)) ;
nStJ = ( dMinY < EPS_SMALL ? 0 : int( dMinY / m_dStep)) ;
nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : int ( dMaxY / m_dStep)) ;
return true ;
}