diff --git a/VolZmap.h b/VolZmap.h index 2be989f..b993e7e 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -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 : diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 922332f..f9e83e2 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -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 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 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 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> 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))