EgtGeomKernel :

- aggiunte funzioni per le lavorazioni generiche a 5 assi.
This commit is contained in:
Daniele Bariletti
2025-05-20 10:14:39 +02:00
parent 59755ec8a5
commit 9c93d6c2f3
2 changed files with 585 additions and 175 deletions
+15 -3
View File
@@ -258,7 +258,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ;
bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) ;
bool SelectGeneralMotion( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtDe, const int nPhase = VolZmap::MillingPhase::ONLY_LATERAL_SURF) ;
bool SelectGeneralMotion( int nGrid, const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtLs, const Vector3d& vtLe, const int nPhase) ;
bool SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtL, const Vector3d& vtAL) ;
bool InitializePointsAndVectors( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtAs,
Point3d ptLs[3], Point3d ptLe[3], Vector3d vtLs[3], Vector3d vtALs[3]) ;
@@ -296,6 +296,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool Chs_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ; // E' in realtà un Perp
bool GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
bool GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
// lavorazioni a 5 assi
bool GenTool_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase) ;
bool Cyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase, double dHeightCorr = 0) ;
bool CylBall_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase) ;
bool Conus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase) ;
// COMPONENTI
// Asse di simmetria diretto come l'asse Z
@@ -331,6 +336,12 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ,
const Point3d& ptS, const Point3d& ptE,
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
// lavorazioni a 5 assi
bool CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
double dHeight, double dRadius, int nToolNum, const int nPhase) ;
bool CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDirS, const Vector3d& vtToolDirE, double dHei, double dMaxRad, double dMinRad,
bool bTapB, bool bTapT,const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum, int nPhase) ;
// Generica traslazione sfera
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
// Additivi
@@ -438,9 +449,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW
public :
// ------------------------- ENUM ----------------------------------------------------------------
enum MillingPhase {
COUNT_START_CYL = 0 ,
COUNT_START_VOL = 0 ,
ONLY_LATERAL_SURF = 1 ,
COUNT_END_CYL = 2
COUNT_END_VOL = 2 ,
COUNT_START_END = 3
} ;
private :
+570 -172
View File
@@ -952,191 +952,582 @@ VolZmap::InitializeAuxPoints( Point3d ptTop1s[3], Point3d ptTop1e[3], Point3d pt
//----------------------------------------------------------------------------
bool
VolZmap::SelectGeneralMotion( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtDe, const int nPhase)
VolZmap::GenTool_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase)
{
///////////////////////////////////////////////////////////////////////////////////////////
// qui al momento gestisco solo il caso del cilindro, ma dovrò gestire anche gli altri casi
///////////////////////////////////////////////////////////////////////////////////////////
// tolgo il volume dei cilindri all'inizio e alla fine del tratto e poi uso delle bilineari per approssimare il volume spazzato
Point3d ptLs[N_MAPS] ;
Point3d ptLe[N_MAPS] ;
Vector3d vtLs[N_MAPS] ;
Vector3d vtLe[N_MAPS] ;
InitializePointsAndVectors( ptPs, ptPe, vtDs, vtDe, ptLs, ptLe, vtLs, vtLe) ;
// recupero le info del tool
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
double dHeight = CurrTool.GetHeigth() ;
double dRadius = CurrTool.GetRadius() ;
Point3d ptTop1s[N_MAPS] ;
Point3d ptTop1e[N_MAPS] ;
Point3d ptTop2s[N_MAPS] ;
Point3d ptTop2e[N_MAPS] ;
Point3d ptBottom1s[N_MAPS] ;
Point3d ptBottom1e[N_MAPS] ;
Point3d ptBottom2s[N_MAPS] ;
Point3d ptBottom2e[N_MAPS] ;
// Descrizione geometrica del moto
Point3d ptI = ptS ;
Point3d ptF = ptE ;
Vector3d vtMove = ptE - ptS ;
// Vettore delle normali agli archi
const VCT3DVECTOR& vArcNorm = CurrTool.GetArcNormalVec() ;
// Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di
// riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ.
Frame3d frNormFrame ;
frNormFrame.Set( ORIG, X_AX, -Z_AX, Y_AX) ;
// Ciclo sulle curve del profilo
const CurveComposite& ToolProfile = CurrTool.GetApproxOutline() ;
int i = - 1 ;
const ICurve* pPrevCurve = nullptr ;
const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ;
double dCumHeight = 0 ; // altezza cumulativa dei tratti già considerati
while ( pCurve != nullptr) {
// determino la posizone della punta del tool nella posizone inizale e in quella finale
Point3d ptP1T = ptPs - dHeight * vtDs ;
Point3d ptP2T = ptPe - dHeight * vtDe ;
double dHeight = 0 ;
// Se segmento
if ( pCurve->GetType() == CRV_LINE) {
// Recupero gli estremi
const ICurveLine* pLine = GetCurveLine( pCurve) ;
Point3d ptStart = pLine->GetStart() ;
Point3d ptEnd = pLine->GetEnd() ;
int nNormNum = pLine->GetTempProp() ;
Vector3d vtNormSt, vtNormEn ;
if ( nNormNum != 0) {
vtNormSt = vArcNorm[nNormNum - 1] ;
vtNormEn = vArcNorm[nNormNum] ;
vtNormSt.ToLoc( frNormFrame) ;
vtNormEn.ToLoc( frNormFrame) ;
}
// Ne determino l'altezza
dHeight = abs( ptStart.y - ptEnd.y) ;
if ( dHeight > EPS_SMALL) {
// verifiche curva precedente per eventuale tappo sopra
bool bTapT = true ;
if ( pPrevCurve != nullptr && pPrevCurve->GetType() == CRV_LINE) {
const ICurveLine* pOthLine = GetCurveLine( pPrevCurve) ;
Point3d ptOthStart = pOthLine->GetStart() ;
Point3d ptOthEnd = pOthLine->GetEnd() ;
if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x < ptOthEnd.x)
bTapT = false ;
}
// verifiche curva successiva per eventuale tappo sotto
bool bTapB = true ;
const ICurve* pNextCurve = ToolProfile.GetCurve( ++ i) ;
if ( pNextCurve != nullptr && pNextCurve->GetType() == CRV_LINE) {
const ICurveLine* pOthLine = GetCurveLine( pNextCurve) ;
Point3d ptOthStart = pOthLine->GetStart() ;
Point3d ptOthEnd = pOthLine->GetEnd() ;
if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x)
bTapB = false ;
}
// Se X costante, è un cilindro
if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) {
double dRadius = ptStart.x ;
if ( dRadius > 10 * EPS_SMALL)
CompCyl_5AxisMilling( nGrid, ptI, ptF, vtLs, vtLe, dHeight, dRadius, nToolNum, nPhase) ;
}
// se altrimenti X decrescente, è un cono con vettore equiverso a quello dell'utensile
else if ( ptStart.x > ptEnd.x) {
double dMaxRad = ptStart.x ;
double dMinRad = ptEnd.x ;
CompConus_5AxisMilling( nGrid, ptI, ptF, vtLs, vtLe, dHeight, dMaxRad, dMinRad,
bTapB, bTapT, vtNormSt, vtNormEn, nToolNum, nPhase) ;
}
// altrimenti X crescente, è un cono con vettore opposto a quello dell'utensile
else {
double dMaxRad = ptEnd.x ;
double dMinRad = ptStart.x ;
Point3d ptIn = ptI - vtLs * dHeight ;
Point3d ptFn = ptF - vtLe * dHeight ;
vtNormEn.z = -vtNormEn.z ;
vtNormSt.z = -vtNormSt.z ;
CompConus_5AxisMilling( nGrid, ptIn, ptFn, - vtLs, -vtLe, dHeight, dMaxRad, dMinRad,
bTapT, bTapB, vtNormEn, vtNormSt, nToolNum, nPhase) ;
}
// Passo alla curva successiva
pPrevCurve = pCurve ;
pCurve = pNextCurve ;
}
else {
// Passo alla curva successiva
pPrevCurve = pCurve ;
pCurve = ToolProfile.GetCurve( ++ i) ;
}
}
// Se arco
else if ( pCurve->GetType() == CRV_ARC) {
// Recupero estremi, centro e raggio
const ICurveArc* pArc = GetCurveArc( pCurve) ;
Point3d ptStart ; pArc->GetStartPoint( ptStart) ;
Point3d ptEnd ; pArc->GetEndPoint( ptEnd) ;
Point3d ptCen = pArc->GetCenter() ;
double dRadius = pArc->GetRadius() ;
// Determino le posizioni iniziale e finale del centro della sfera
Point3d ptCenS = ptI - vtLs * ( ptStart.y - ptCen.y) ;
Point3d ptCenE = ptF - vtLe * ( ptStart.y - ptCen.y) ;
// Eseguo l'asportazione del materiale
CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius, nToolNum) ;
// aggiorno l'altezza
dHeight = abs( ptStart.y - ptEnd.y) ;
// Passo alla curva successiva
pPrevCurve = pCurve ;
pCurve = ToolProfile.GetCurve( ++ i) ;
}
// Determino le posizioni iniziale e finale del componente successivo
dCumHeight += dHeight ;
ptI = ptS - vtLs * dCumHeight ;
ptF = ptE - vtLe * dCumHeight ;
}
return true ;
}
////----------------------------------------------------------------------------
//bool
//VolZmap::Comp_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
// double dHeight, double dRadius, int nToolNum, const int nPhase)
//{
//
// return true ;
//}
//----------------------------------------------------------------------------
bool
VolZmap::CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
double dHeight, double dRadius, int nToolNum, const int nPhase)
{
Point3d ptTop1s ;
Point3d ptTop1e ;
Point3d ptTop2s ;
Point3d ptTop2e ;
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 - dHeight * vtLs ;
Point3d ptP2T = ptE - dHeight * vtLe ;
// determino la direzione di movimento del top del tool e della punta del tool
Vector3d vtDirTop = ptPe - ptPs ;
Vector3d vtDirTop = ptE - ptS ;
Vector3d vtDirTip = ptP2T - ptP1T ;
// determino i punti laterali del top e del bottom(tip), nella posizione di partenza
Vector3d vtAuxTopS = vtDs ^ vtDirTop ;
Vector3d vtAuxTopS = vtLs ^ vtDirTop ;
vtAuxTopS.Normalize() ;
vtAuxTopS *= dRadius ;
ptTop1s[0] = ptPs + vtAuxTopS ;
ptTop2s[0] = ptPs - vtAuxTopS ;
ptTop1s = ptS + vtAuxTopS ;
ptTop2s = ptS - vtAuxTopS ;
Vector3d vtAuxBottomS = vtDs ^ vtDirTip ;
Vector3d vtAuxBottomS = vtLs ^ vtDirTip ;
vtAuxBottomS.Normalize() ;
vtAuxBottomS *= dRadius ;
ptBottom1s[0] = ptP1T + vtAuxBottomS ;
ptBottom2s[0] = ptP1T - vtAuxBottomS ;
ptBottom1s = ptP1T + vtAuxBottomS ;
ptBottom2s = ptP1T - vtAuxBottomS ;
// determino i punti laterali del top e del bottom(tip), nella posizione di arrivo
Vector3d vtAuxTopE = vtDe ^ vtDirTop ;
Vector3d vtAuxTopE = vtLe ^ vtDirTop ;
vtAuxTopE.Normalize() ;
vtAuxTopE *= dRadius ;
ptTop1e[0] = ptPe + vtAuxTopE ;
ptTop2e[0] = ptPe - vtAuxTopE ;
ptTop1e = ptE + vtAuxTopE ;
ptTop2e = ptE - vtAuxTopE ;
Vector3d vtAuxBottomE = vtDe ^ vtDirTip ;
Vector3d vtAuxBottomE = vtLe ^ vtDirTip ;
vtAuxBottomE.Normalize() ;
vtAuxBottomE *= dRadius ;
ptBottom1e[0] = ptP2T + vtAuxBottomE ;
ptBottom2e[0] = ptP2T - vtAuxBottomE ;
ptBottom1e = ptP2T + vtAuxBottomE ;
ptBottom2e = ptP2T - vtAuxBottomE ;
InitializeAuxPoints( ptTop1s, ptTop1e, ptTop2s, ptTop2e, ptBottom1s, ptBottom1e, ptBottom2s, ptBottom2e) ;
// 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)
CompCyl_ZDrilling( nGrid, ptS, ptS, vtLs, dHeight, dRadius, nToolNum) ;
else
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)
CompCyl_ZDrilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, nToolNum) ;
else
CompCyl_Drilling( nGrid, ptE, ptE, vtLe, dHeight, dRadius, false, false, nToolNum) ;
}
for ( int z = 0 ; z < m_nMapNum ; ++z) {
// 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, dRadius, dRadius, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
//CompCyl_AcrossMilling() // questa potrebbe essere la funzione che raccoglie tutto quello che ci sarà in questo for
// tolgo il volume del cilindro iniziale e finale del moto
if ( nPhase == VolZmap::MillingPhase::COUNT_START_CYL) {
// in base all'orientamento del tool scelgo la funzione adatta
if ( vtLs[z].SqLenXY() < EPS_SMALL * EPS_SMALL)
CompCyl_ZDrilling( z, ptLs[z], ptLs[z], vtLs[z], dHeight, dRadius, CurrTool.GetToolNum()) ;
else
CompCyl_Drilling( z, ptLs[z], ptLs[z], vtLs[z], dHeight, dRadius, false, false, CurrTool.GetToolNum()) ;
}
if ( nPhase == VolZmap::MillingPhase::COUNT_END_CYL) {
if ( vtLs[z].SqLenXY() < EPS_SMALL * EPS_SMALL)
CompCyl_ZDrilling( z, ptLe[z], ptLe[z], vtLe[z], dHeight, dRadius, CurrTool.GetToolNum()) ;
else
CompCyl_Drilling( z, ptLe[z], ptLe[z], vtLe[z], dHeight, dRadius, false, false, CurrTool.GetToolNum()) ;
}
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)) ;
// tolgo il volume spazzato dal tool durante il movimento
// Verifica sull'interferenza con lo Zmap
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( z, ptLs[z], ptLe[z], vtLs[z], vtLe[z], dRadius, dRadius, dHeight, nStartI, nStartJ, nEndI, nEndJ))
return true ;
BOXVECTOR vSurfBox(6) ;
int nDegU = 1 ; int nDegV = 1 ;
int nSpanU = 1 ; int nSpanV = 1 ;
bool bRat = false ;
vector<PNTVECTOR> vvPtCtrl ;
PNTVECTOR vPtCtrl0 = { ptBottom1s[z], ptTop1s[z], ptBottom1e[z], ptTop1e[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl0)) ;
PNTVECTOR vPtCtrl1 = { ptBottom2s[z], ptBottom1s[z], ptBottom2e[z], ptBottom1e[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl1)) ;
PNTVECTOR vPtCtrl2 = { ptTop2s[z], ptBottom2s[z], ptTop2e[z], ptBottom2e[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl2)) ;
PNTVECTOR vPtCtrl3 = { ptTop1s[z], ptTop2s[z], ptTop1e[z], ptTop2e[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl3)) ;
PNTVECTOR vPtCtrl4 = { ptBottom1s[z], ptBottom2s[z], ptTop1s[z], ptTop2s[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl4)) ;
PNTVECTOR vPtCtrl5 = { ptBottom2e[z], ptBottom1e[z], ptTop2e[z], ptTop1e[z]} ;
vvPtCtrl.push_back( std::move( vPtCtrl5)) ;
// 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]) ;
BOXVECTOR vSurfBox(6) ;
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]) ;
// 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]) ;
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) ;
}
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]) ;
// 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 ;
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) ;
}
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 ( 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( z, i, j, dMin, dMax, vtMin, vtMax, CurrTool.GetToolNum()) ;
}
if ( dMax > 0 && dMin < dMax)
SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, nToolNum) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::Cyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase, double dHeightCorr)
{
// tolgo il volume dei cilindri all'inizio e alla fine del tratto e poi uso delle bilineari per approssimare il volume spazzato
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
// recupero le info del tool
Tool& CurrTool = m_vTool[m_nCurrTool] ;
double dHeight = CurrTool.GetHeigth() - dHeightCorr ;
double dRadius = CurrTool.GetRadius() ;
return CompCyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHeight, dRadius, nToolNum, nPhase) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CylBall_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase)
{
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
double dHeight = CurrTool.GetHeigth() - CurrTool.GetTipRadius() ;
double dRadius = CurrTool.GetRadius() ;
CompCyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dRadius, dHeight, nToolNum, nPhase) ;
// devo poi togliere la sfera tip iniziale, la sfera tip finale e il cilindro del volume spazzato
Point3d ptTipS = ptS - vtLs * ( CurrTool.GetHeigth()) ;
Point3d ptTipE = ptE - vtLe * ( CurrTool.GetHeigth()) ;
CompBall_Milling( nGrid, ptTipS, ptTipE, CurrTool.GetRadius(), CurrTool.GetToolNum()) ;
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, double dHei, double dMaxRad, double dMinRad,
bool bTapB, bool bTapT, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum, int nPhase)
{
// come per le altre funzioni che lavorano con i coni, se il cono è inverso ( che va allargandosi andando verso il fondo del tool), allora i vtL passati sono invertiti rispetto a quelli
// reali del tool e i punti ptS e ptE sono invertiti( così come dMaxRad e dMinRad)
// al momento i bool bTapB e bTapT vengono ignorati e di default si crea un volume chiuso con anche le superfici superiore e inferiore.
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
// elimino la parte occupata dal tool all'inizio e alla fine del tratto lavorato
if ( nPhase == VolZmap::MillingPhase::COUNT_START_VOL) {
// in base all'orientamento del tool scelgo la funzione adatta
if ( vtLs.SqLenXY() < EPS_SMALL * EPS_SMALL)
CompConus_ZDrilling( nGrid, ptS, ptS, vtLs, dHei, dMaxRad, dMinRad, V_NULL, V_NULL, CurrTool.GetToolNum()) ;
else
CompConus_Drilling( nGrid, ptS, ptS, vtLs, dHei, dMaxRad, dMinRad, false, false, V_NULL, V_NULL, CurrTool.GetToolNum()) ;
}
if ( nPhase == VolZmap::MillingPhase::COUNT_END_VOL) {
if ( vtLe.SqLenXY() < EPS_SMALL * EPS_SMALL)
CompConus_ZDrilling( nGrid, ptE, ptE, vtLe, dHei, dMaxRad, dMinRad, V_NULL, V_NULL, CurrTool.GetToolNum()) ;
else
CompConus_Drilling( nGrid, ptE, ptE, vtLe, dHei, dMaxRad, dMinRad, false, false, V_NULL, V_NULL, CurrTool.GetToolNum()) ;
}
// 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 ;
}
//----------------------------------------------------------------------------
bool
VolZmap::Conus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase)
{
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
// recupero le info del tool
Tool& CurrTool = m_vTool[m_nCurrTool] ;
double dHeight = CurrTool.GetHeigth() ;
double dRadius = CurrTool.GetRadius() ;
double dTipRadius = CurrTool.GetTipRadius() ;
double dStemHeigth = dHeight - CurrTool.GetTipHeigth() ;
// elimino la parte del volume spazzato dalla parte cilindrica del tool
Cyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, nToolNum, nPhase, CurrTool.GetTipHeigth()) ;
// elimino la parte spazzata dalla punta conica del tool
if ( CurrTool.GetTipRadius() < dRadius) {
// Trapano
Point3d ptSConus = ptS - dStemHeigth * vtLs ;
Point3d ptEConus = ptE - dStemHeigth * vtLe ;
CompConus_5AxisMilling( nGrid, ptSConus, ptEConus, vtLs, vtLe, dHeight,
dRadius, dTipRadius, true, false, V_NULL, V_NULL, CurrTool.GetToolNum(), nPhase) ;
}
else {
Point3d ptSInvertedConus = ptS - CurrTool.GetHeigth() * vtLs ;
Point3d ptEInvertedConus = ptE - CurrTool.GetHeigth() * vtLe ;
CompConus_5AxisMilling( nGrid, ptSInvertedConus, ptEInvertedConus, - vtLs, - vtLe, dHeight,
dTipRadius, dRadius, false, true, V_NULL, V_NULL, CurrTool.GetToolNum(), nPhase) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SelectGeneralMotion( int nGrid, const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtLs, const Vector3d& vtLe, const int nPhase)
{
// Controllo utensile
if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size()))
return false ;
Tool& CurrTool = m_vTool[m_nCurrTool] ;
switch ( CurrTool.GetType()) {
case Tool::GEN :
return GenTool_5AxisMilling( nGrid, ptPs, ptPe, vtLs, vtLe, CurrTool.GetToolNum(), nPhase) ;
case Tool::CYLMILL :
return Cyl_5AxisMilling( nGrid, ptPs, ptPe, vtLs, vtLe, CurrTool.GetToolNum(), nPhase) ;
case Tool::BALLMILL :
return CylBall_5AxisMilling( nGrid, ptPs, ptPe, vtLs, vtLe, CurrTool.GetToolNum(), nPhase) ;
case Tool::CONEMILL :
return Conus_5AxisMilling( nGrid, ptPs, ptPe, vtLs, vtLe, CurrTool.GetToolNum(), nPhase) ;
case Tool::MORTISER :
return false ; // in realtà potremmo accettare un moto con un angolo solo along
case Tool::CHISEL :
return false ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
@@ -1151,34 +1542,10 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
int nStepCnt = int( max( { abs( dAlongAngDeg) / ANG_ALONG_STEP, abs( dAcrossAngDeg) / ANG_ACROSS_STEP, 1.})) ;
bool bOk = true ;
// valori allo step i-esimo
//Point3d ptSt = ptPs ; ///////////////////// commentato per debug
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) {
//////////////////////////////////////////////// commentato per debug
// 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 ;
//// 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) ;
@@ -1194,10 +1561,37 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
int nPhase = VolZmap::MillingPhase::ONLY_LATERAL_SURF ;
if ( i == 0)
nPhase = VolZmap::MillingPhase::COUNT_START_CYL ;
nPhase = VolZmap::MillingPhase::COUNT_START_VOL ;
if ( i == nStepCnt)
nPhase = VolZmap::MillingPhase::COUNT_END_CYL ;
bOk = bOk && SelectGeneralMotion( ptSti, ptEni, vtDSi, vtDEi,nPhase) ;
nPhase = VolZmap::MillingPhase::COUNT_END_VOL ;
Point3d ptLs[N_MAPS] ;
Point3d ptLe[N_MAPS] ;
Vector3d vtLs[N_MAPS] ;
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) ;
// 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 ;
}
}
}
}
return bOk ;
}
@@ -3960,6 +4354,10 @@ VolZmap::CompConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE,
double dHei, double dMaxRad, double dMinRad,
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum)
{
// i vettori vtArcNormMaxR e vtArcNormMinR servono nel caso in cui un tratto del tool sia identificato da un arco, ma si decida di approssimarlo con un cono
// in quel caso per il calcolo corretto della normale viene fatta una somma pesata tra le normali alla superficie nei punti estremi dell'arco
// i pesi sono riferiti alla posizione relativa dell'intersezione spillone-superficie e questi due punti estremi
// Verifica sull'interferenza con lo Zmap
int nStartI, nStartJ, nEndI, nEndJ ;
if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, V_NULL, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ))