From bdbd3583b82804e47ca82b110b5ac48d7fc62868 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 16 Jun 2025 15:10:10 +0200 Subject: [PATCH] EgtGeomKernel : - versione temporanea per VM5assi per caso lama e 3 assi. --- VolZmap.h | 4 +- VolZmapVolume.cpp | 554 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 394 insertions(+), 164 deletions(-) diff --git a/VolZmap.h b/VolZmap.h index e807d10..0b047d5 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -297,7 +297,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ; bool GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ; // lavorazioni a 5 assi - bool GenTool_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, const int nPhase) ; + bool GenTool_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& 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) ; @@ -339,7 +339,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW // lavorazioni a 5 assi bool Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& vtLe, double dHeight, double dMaxRad, double dMinRad, int nToolNum) ; - bool CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, + bool CompCyl_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& ptE, const VCT3DVECTOR& vtLs, const VCT3DVECTOR& 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) ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 667f79c..b04339e 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1308,167 +1308,202 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt // 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)) + if ( ! TestCompoBBox( nGrid, ptS[0], ptE.back(), vtLs[0], vtLe.back(), dMaxRad, dMinRad, dHeight, nStartI, nStartJ, nEndI, nEndJ) ) return true ; - 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 = 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 ; - - 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) ; - - // 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 nStepCnt = int( ptS.size()) ; + + + // vettori di riferimento per trovare i punti ausiliari int nDegU = 1 ; int nDegV = 1 ; int nSpanU = 1 ; int nSpanV = 1 ; bool bRat = false ; - vector vvPtCtrl ; - // 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 inferiori - for ( int i = 0 ; i < nSub ; ++i) { - vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i], vPntTipStart[i+1], vPntTipEnd[i], vPntTipEnd[i+1]})) ; - } - // superficie superiori - for ( int i = 0 ; i < nSub ; ++i) { - vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart[i], vPntTopStart[i+1], vPntTopEnd[i], vPntTopEnd[i+1]})) ; - } - } - - - // inizializzo le 6 superfici bilineari e i parametri per le intersezioni + int nSub = 4 ; // numero di bilineari con cui approssimare il (quasi) semi-cilindro ellissoide che descrive il volume della punta e della cima del tool ISURFBEZPOVECTOR vSurfBez ; PNTVECTOR d ; Vector3d q = Z_AX ; DBLVECTOR A1, B1, C1, A2, B2, C2 ; int nTotSurf = 2 + nSub * 2 ; BOXVECTOR vSurfBox( nTotSurf) ; + double dSide = 0 ; + // punti per le bilineari, sulle posizioni del tool alle estremità del movimento + PNTVECTOR vPntTipStartEx ; + PNTVECTOR vPntTipEndEx ; + PNTVECTOR vPntTopStartEx ; + PNTVECTOR vPntTopEndEx ; + Vector3d vtDirTopStartEx ; + Vector3d vtDirTopEndEx ; + Vector3d vtDirTipStartEx ; + Vector3d vtDirTipEndEx ; + for ( int s = 0 ; s < nStepCnt ; ++s) { + // punti d riferimento sul tool + Point3d ptTop1s ; + Point3d ptTop1e ; + Point3d ptTop2s ; + Point3d ptTop2e ; + Point3d ptBottom1s ; + Point3d ptBottom1e ; + Point3d ptBottom2s ; + Point3d ptBottom2e ; + // tip del tool + Point3d ptP1T ; + Point3d ptP2T ; + // determino la posizione della punta del tool nella posizione iniziale e in quella finale + ptP1T = ptS[s] - dHeight * vtLs[s] ; + ptP2T = ptE[s] - dHeight * vtLe[s] ; + // determino la direzione di movimento del top del tool e della punta del tool + Vector3d vtDirTop = ptE[s] - ptS[s] ; + Vector3d vtDirTip = ptP2T - ptP1T ; - 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]) ; - 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]) ; + // determino i punti laterali del top e del bottom(tip), nella posizione di partenza + Vector3d vtAuxTopS = vtLs[s] ^ vtDirTop ; + vtAuxTopS.Normalize() ; + vtAuxTopS *= dMaxRad ; + ptTop1s = ptS[s] + vtAuxTopS ; + ptTop2s = ptS[s] - vtAuxTopS ; - 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]) ; + Vector3d vtAuxBottomS = vtLs[s] ^ vtDirTip ; + vtAuxBottomS.Normalize() ; + vtAuxBottomS *= dMinRad ; + ptBottom1s = ptP1T + vtAuxBottomS ; + ptBottom2s = ptP1T - vtAuxBottomS ; - 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) ; - if ( nGrid == 0) - vGeo.push_back( vSurfBez[s]->Clone()) ; + // determino i punti laterali del top e del bottom(tip), nella posizione di arrivo + Vector3d vtAuxTopE = vtLe[s] ^ vtDirTop ; + vtAuxTopE.Normalize() ; + vtAuxTopE *= dMaxRad ; + ptTop1e = ptE[s] + vtAuxTopE ; + ptTop2e = ptE[s] - vtAuxTopE ; + + Vector3d vtAuxBottomE = vtLe[s] ^ vtDirTip ; + vtAuxBottomE.Normalize() ; + vtAuxBottomE *= dMinRad ; + ptBottom1e = ptP2T + vtAuxBottomE ; + ptBottom2e = ptP2T - vtAuxBottomE ; + + 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[s]) * vtLe[s]) ; + vtTopBaseEnd.Normalize() ; + vtTopBaseEnd *= dMaxRad ; + if ( s == nStepCnt) + vtDirTopEndEx = vtTopBaseEnd ; + Point3d ptRefEnd = ptE[s] - vtTopBaseEnd ; + Vector3d vtTopBaseStart = vtDirTop - ( ( vtDirTop * vtLs[s]) * vtLs[s]) ; + vtTopBaseStart.Normalize() ; + vtTopBaseStart *= dMaxRad ; + if ( s == 0) + vtDirTopStartEx = vtTopBaseStart ; + Point3d ptRefStart = ptS[s] + vtTopBaseStart ; + dSide = (ptRefEnd - ptRefStart) * vtLs[s] ; + // calcolo anche i vettori per le basi inferiori + Vector3d vtTipBaseStart = - (vtLs[s] ^ vtDirTip) ; + vtTipBaseStart.Normalize() ; + vtTipBaseStart *= dMinRad ; + if ( s == 0) + vtDirTipStartEx = vtTipBaseStart ; + Vector3d vtTipBaseEnd = - (vtLe[s] ^ vtDirTip) ; + vtTipBaseEnd.Normalize() ; + vtTipBaseEnd *= dMinRad ; + if ( s == nStepCnt) + vtDirTipEndEx = vtTipBaseEnd ; + // aggiungo il primo punto per ognuno dei gruppi + vtTopBaseStart.Rotate( vtLs[s], 90) ; + vtTopBaseEnd.Rotate( vtLe[s], 90) ; + vPntTopStart.emplace_back( ptS[s] + vtTopBaseStart) ; + vPntTopEnd.emplace_back( ptE[s] + 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[s], vtLs[s], dSubAng) ; + else + vPntTopStart.back().Rotate(ptS[s], vtLs[s], -dSubAng) ; + vPntTopEnd.emplace_back( vPntTopEnd.back()) ; + if ( dSide > 0) + vPntTopEnd.back().Rotate(ptE[s], vtLe[s], dSubAng) ; + else + vPntTopEnd.back().Rotate(ptE[s], vtLe[s], -dSubAng) ; + + // punti sulla base inferiore dei cilindri + vPntTipStart.emplace_back( vPntTipStart.back()) ; + if ( dSide > 0) + vPntTipStart.back().Rotate(ptP1T, vtLs[s], dSubAng) ; + else + vPntTipStart.back().Rotate(ptP1T, vtLs[s], -dSubAng) ; + vPntTipEnd.emplace_back( vPntTipEnd.back()) ; + if ( dSide > 0) + vPntTipEnd.back().Rotate(ptP2T, vtLe[s], dSubAng) ; + else + vPntTipEnd.back().Rotate(ptP2T, vtLe[s], -dSubAng) ; + } + } + // mi salvo i punti ausiliari per la posizione iniziale e finale del tool + if ( s == 0) { + vPntTipStartEx = vPntTipStart ; + vPntTopStartEx = vPntTopStart ; + } + else if ( s == nStepCnt - 1) { + vPntTipEndEx = vPntTipEnd ; + vPntTopEndEx = vPntTopEnd ; + } + + vector vvPtCtrl ; + // 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 inferiori + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i], vPntTipStart[i+1], vPntTipEnd[i], vPntTipEnd[i+1]})) ; + } + // superficie superiori + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart[i], vPntTopStart[i+1], vPntTopEnd[i], vPntTopEnd[i+1]})) ; + } + } + + // inizializzo le superfici bilineari e i parametri per le intersezioni + for( int z = 0 ; z < nTotSurf ; ++z) { + vSurfBez.emplace_back( CreateSurfBezier()) ; + vSurfBez.back()->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ; + vSurfBez.back()->SetControlPoint( 0, vvPtCtrl[z][0]) ; + vSurfBez.back()->SetControlPoint( 1, vvPtCtrl[z][1]) ; + vSurfBez.back()->SetControlPoint( 2, vvPtCtrl[z][2]) ; + vSurfBez.back()->SetControlPoint( 3, vvPtCtrl[z][3]) ; + vSurfBox[z].Add( vvPtCtrl[z]) ; + + Vector3d a = vvPtCtrl[z][3] - vvPtCtrl[z][1] + ( vvPtCtrl[z][0] - vvPtCtrl[z][2]) ; + Vector3d b = vvPtCtrl[z][1] - vvPtCtrl[z][0] ; + Vector3d c = vvPtCtrl[z][2] - vvPtCtrl[z][0] ; + d.push_back( vvPtCtrl[z][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) ; + if ( nGrid == 0) + vGeo.push_back( vSurfBez[z]->Clone()) ; + } } ////debug @@ -1479,12 +1514,14 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt //} ////debug - BBox3d bbStartCyl = GetCylMoveBBox( ptS, ptS, vtLs, dMaxRad, dHeight) ; - BBox3d bbEndCyl = GetCylMoveBBox( ptE, ptE, vtLe, dMaxRad, dHeight) ; + BBox3d bbStartCyl = GetCylMoveBBox( ptS[0], ptS[0], vtLs[0], dMaxRad, dHeight) ; + BBox3d bbEndCyl = GetCylMoveBBox( ptE.back(), ptE.back(), vtLe.back(), dMaxRad, dHeight) ; // se sono nel caso di un cono calcolo già i parametri utili Point3d ptVS, ptVE ; double dTan = 0, dMinH, dMaxH ; + Point3d ptP1T = ptS[0] - vtLs[0] * dHeight ; + Point3d ptP2T = ptE.back() - vtLe.back() * dHeight ; if ( dMinRad < EPS_SMALL) { ptVS = ptP1T ; ptVE = ptP2T ; @@ -1496,10 +1533,71 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt dTan = (dMaxRad - dMinRad) / dHeight ; dMaxH = dMaxRad * dTan ; dMinH = dMaxH - dHeight ; - ptVS = ptS - vtLs * dMaxH ; - ptVE = ptE - vtLe * dMaxH ; + ptVS = ptS[0] - vtLs[0] * dMaxH ; + ptVE = ptE.back() - vtLe.back() * dMaxH ; } - + + Vector3d vtDirTop = ptE.back() - ptS.front() ; + Vector3d vtDirTip = ptP2T - ptP1T ; + VCT3DVECTOR vvtTipStartAux( nSub + 1) ; + VCT3DVECTOR vvtTipEndAux( nSub + 1) ; + VCT3DVECTOR vvtTopStartAux( nSub + 1) ; + VCT3DVECTOR vvtTopEndAux( nSub + 1) ; + vvtTipStartAux.front() = vPntTipStartEx.front() - ptP1T ; + vvtTipEndAux.front() = vPntTipEndEx.front() - ptP2T ; + vvtTopStartAux.front() = vPntTopStartEx.front() - ptS.front() ; + vvtTopEndAux.front() = vPntTopEndEx.front() - ptE.back() ; + + //Frame3d frTipStart, frTipEnd, frTopStart, frTopEnd ; + //if ( dSide > 0) { + // frTipStart.Set( ptP1T, ) ; + // frTipEnd.Set( ptP2T, ) ; + // frTopStart.Set( ptS[0], ) ; + // frTopEnd.Set( ptE.back(), ) ; + //} + //else if( dSide < 0) { + // frTipStart.Set( ptP1T, ) ; + // frTipEnd.Set( ptP2T, ) ; + // frTopStart.Set( ptS[0], ) ; + // frTopEnd.Set( ptE.back(), ) ; + //} + for ( int i = 1 ; i <= nSub ; ++i) { + vvtTipStartAux[i] = Media( vPntTipStartEx[i-1],vPntTipStartEx[i]) - ptP1T; + vvtTipEndAux[i] = Media( vPntTipEndEx[i-1],vPntTipEndEx[i]) - ptP2T ; + vvtTopStartAux[i] = Media( vPntTopStartEx[i-1],vPntTopStartEx[i]) - ptS[0] ; + vvtTopEndAux[i] = Media( vPntTopEndEx[i-1],vPntTopEndEx[i]) - ptE.back() ; + } + + double dRadApprox = vvtTipStartAux.back().Len() ; + + //// creo le quattro superficie quadrate per fare i cap della giunzione tra cilindri e bilineari + //PNTMATRIX vvPntSq( 4) ; + //double dAng = 90 ; + //if ( dSide < 0) + // dAng = -90 ; + //// recupero i vettori con le direzioni parallele alle basi del tool + //vtDirTopStartEx.Rotate( vtLs.front(), dAng) ; + //vtDirTipStartEx.Rotate( vtLs.front(), dAng) ; + //vtDirTopEndEx.Rotate( vtLe.back(), dAng) ; + //vtDirTipEndEx.Rotate( vtLe.back(), dAng) ; + //vvPntSq.emplace_back( PNTVECTOR( { vPntTopStartEx.front(), vPntTopStartEx.back(), vPntTopStartEx.front() + vtDirTopStartEx, vPntTopStartEx.back() + vtDirTopStartEx})) ; // top start + //vvPntSq.emplace_back( PNTVECTOR( { vPntTipStartEx.front(), vPntTipStartEx.back(), vPntTipStartEx.front() + vtDirTipStartEx, vPntTipStartEx.back() + vtDirTipStartEx})) ; // tip start + //vvPntSq.emplace_back( PNTVECTOR( { vPntTopEndEx.front(), vPntTopEndEx.back(), vPntTopEndEx.front() + vtDirTopEndEx, vPntTopEndEx.back() + vtDirTopEndEx})) ; // top end + //vvPntSq.emplace_back( PNTVECTOR( { vPntTipEndEx.front(), vPntTipEndEx.back(), vPntTipEndEx.front() + vtDirTipEndEx, vPntTipEndEx.back() + vtDirTipEndEx})) ; // tip end + //ISURFBEZPOVECTOR vBezCaps ; + //BOXVECTOR vBezCapBox( 4) ; + //for ( int z = 0 ; z < 3 ; ++z) { + // //inizializzo la superficie + // vBezCaps.emplace_back( CreateSurfBezier()) ; + // vBezCaps.back()->Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ; + // vBezCaps.back()->SetControlPoint( 0, vvPntSq[z][0]) ; + // vBezCaps.back()->SetControlPoint( 1, vvPntSq[z][1]) ; + // vBezCaps.back()->SetControlPoint( 2, vvPntSq[z][2]) ; + // vBezCaps.back()->SetControlPoint( 3, vvPntSq[z][3]) ; + // // creo la box della superficie + // vBezCapBox[z].Add( vvPntSq[z]) ; + //} + // scorro tutti gli spilloni interessati for ( int i = nStartI ; i <= nEndI ; ++ i) { for ( int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -1547,28 +1645,152 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt } } - // interseco con i cilindri di inizio e fine moto + // interseco con la prima metà del tool in posizione iniziale e con la seconda metà del tool in posizione finale // 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) ; + frStartCyl.Set( ptP1T, vtLs[0]) ; Point3d pt1, pt2 ; Vector3d vt1, vt2 ; if ( IntersLineCylinder( r, Z_AX, frStartCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)) { - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + bool bUpdate1 = false ; + bool bUpdate2 = false ; + if ( dSide > 0) { + double dPerp = abs( vtDirTip * vtLs[0]) ; + double dDirTip = vtDirTip.Len() ; + double dParall = sqrt( pow( dDirTip,2) - pow( dPerp,2)) ; + double dDistOverlap = dMinRad / dParall * dDirTip ; + bUpdate1 = Dist( ptP1T, pt1) < dDistOverlap && vt1 * vtDirTip > 0 ; + bUpdate2 = Dist( ptP1T, pt2) < dDistOverlap && vt2 * vtDirTip > 0 ; + } + else { + double dPerp = abs( vtDirTop * vtLs[0]) ; + double dDirTop = vtDirTop.Len() ; + double dParall = sqrt( pow( dDirTop,2) - pow( dPerp,2)) ; + double dDistOverlap = dMinRad / dParall * dDirTop ; + bUpdate1 = Dist(ptS[0], pt1) < dDistOverlap && vt1 * vtDirTop > 0 ; + bUpdate2 = Dist(ptS[0], pt2) < dDistOverlap && vt2 * vtDirTop > 0 ; + } + // se ho un'intersezione su una base devo verificare se la devo considerare o no + if ( ! bUpdate1 && (( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL || ( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL)) { + // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari + //base inferiore + double dSectorAng = 0 ; + if ( ( pt1 - frStartCyl.Orig()) * vtDirTipEndEx > 0) { + vvtTipStartAux.front().GetAngle(pt1 - frStartCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate1 = (pt1 - frStartCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + // base superiore + else if(( pt1 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) { + vvtTopStartAux.front().GetAngle(pt1 - frStartCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate1 = (pt1 - frStartCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + } + // se ho un'intersezione su una base devo verificare se la devo considerare o no + if ( ! bUpdate2 && (( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL || ( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL)) { + // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari + //base inferiore + double dSectorAng = 0 ; + if ( ( pt2 - frStartCyl.Orig()) * vtDirTipEndEx > 0) { + vvtTipStartAux.front().GetAngle(pt2 - frStartCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate2 = (pt2 - frStartCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + // base superiore + else if(( pt2 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) { + vvtTopStartAux.front().GetAngle(pt2 - frStartCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate2 = (pt2 - frStartCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + } + if ( bUpdate1) + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + if ( bUpdate2) + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; } } if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { Frame3d frEndCyl ; - frEndCyl.Set( ptP2T, vtLe) ; + frEndCyl.Set( ptP2T, vtLe.back()) ; Point3d pt1, pt2 ; Vector3d vt1, vt2 ; if ( IntersLineCylinder( r, Z_AX, frEndCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)){ - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + bool bUpdate1 = false ; + bool bUpdate2 = false ; + if ( dSide > 0) { + double dPerp = abs( vtDirTop * vtLs[0]) ; + double dDirTop = vtDirTop.Len() ; + double dParall = sqrt( pow( dDirTop,2) - pow( dPerp,2)) ; + double dDistOverlap = dMinRad / dParall * dDirTop ; + bUpdate1 = Dist( ptE.back(), pt1) < dDistOverlap && vt1 * vtDirTop < 0 ; + bUpdate2 = Dist( ptE.back(), pt2) < dDistOverlap && vt2 * vtDirTop < 0 ; + } + else { + double dPerp = abs( vtDirTip * vtLs[0]) ; + double dDirTip = vtDirTip.Len() ; + double dParall = sqrt( pow( dDirTip,2) - pow( dPerp,2)) ; + double dDistOverlap = dMinRad / dParall * dDirTip ; + bUpdate1 = Dist( ptP2T, pt1) < dDistOverlap && vt1 * vtDirTip < 0 ; + bUpdate2 = Dist( ptP2T, pt2) < dDistOverlap && vt2 * vtDirTip < 0 ; + } + // se ho un'intersezione su una base devo verificare se la devo considerare o no + if ( ! bUpdate1 && (( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL || ( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL)) { + // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari + //base inferiore + double dSectorAng = 0 ; + if ( ( pt1 - frEndCyl.Orig()) * vtDirTipEndEx > 0) { + vvtTipStartAux.front().GetAngle(pt1 - frEndCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate1 = (pt1 - frEndCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + // base superiore + else if(( pt1 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) { + vvtTopStartAux.front().GetAngle(pt1 - frEndCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate1 = (pt1 - frEndCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + } + // se ho un'intersezione su una base devo verificare se la devo considerare o no + if ( ! bUpdate2 && (( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL || ( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL)) { + // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari + //base inferiore + double dSectorAng = 0 ; + if ( ( pt2 - frEndCyl.Orig()) * vtDirTipEndEx > 0) { + vvtTipStartAux.front().GetAngle(pt2 - frEndCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate2 = (pt2 - frEndCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + // base superiore + else if(( pt2 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) { + vvtTopStartAux.front().GetAngle(pt2 - frEndCyl.Orig(), dSectorAng) ; + // determino in quale settore del semicerchio approssimato mi trovo + int nSector = dSectorAng / ( 180. / nSub) + 1 ; + // verifico se l'intersezione linea-base è interna o esterna + bUpdate2 = (pt2 - frEndCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ; + } + } + if ( bUpdate1) + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + if ( bUpdate2) + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; } } } @@ -1576,7 +1798,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt else { if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) { Frame3d frStartCon ; - frStartCon.Set( ptVS, vtLs) ; + frStartCon.Set( ptVS, vtLs[0]) ; Point3d pt1, pt2 ; Vector3d vt1, vt2 ; if ( IntersLineConus( r, Z_AX, frStartCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2)) { @@ -1586,7 +1808,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt } if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { Frame3d frEndCon ; - frEndCon.Set( ptVE, vtLe) ; + frEndCon.Set( ptVE, vtLe.back()) ; Point3d pt1, pt2 ; Vector3d vt1, vt2 ; if ( IntersLineConus( r, Z_AX, frEndCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2)) { @@ -1595,6 +1817,9 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt } } } + // interseco con le basi trimmate dei cilindri ( che tengono conto dell'approssimazione fatta con bilineari del volume spazzato da top e tip) + + if ( dMax > 0 && dMin < dMax) SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, nToolNum) ; } @@ -1644,7 +1869,8 @@ VolZmap::Cyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co double dHeight = CurrTool.GetHeigth() - dHeightCorr ; double dRadius = CurrTool.GetRadius() ; - return CompCyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHeight, dRadius, nToolNum, nPhase) ; + //return CompCyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHeight, dRadius, nToolNum, nPhase) ; + return false ; } //---------------------------------------------------------------------------- @@ -1657,7 +1883,9 @@ VolZmap::CylBall_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE 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) ; + //CompCyl_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dRadius, dHeight, nToolNum, nPhase) ; + return false ; + // 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()) ; @@ -1697,7 +1925,8 @@ VolZmap::CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& p } // tolgo il valume spazzato dal tool durante il movimento - bOk = bOk && Comp_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHei, dMaxRad, dMinRad, nToolNum) ; + //bOk = bOk && Comp_5AxisMilling( nGrid, ptS, ptE, vtLs, vtLe, dHei, dMaxRad, dMinRad, nToolNum) ; + return false ; return bOk ; } @@ -1856,6 +2085,7 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co vtLs_j[z] = vtLs[z][j] ; vtLe_j[z] = vtLe[z][j] ; } + int nPhase = 0 ; SelectGeneralMotion( j, ptLs_j, ptLe_j, vtLs_j,vtLe_j, nPhase) ; }