From ba75033f0a2d683cb20cc94cb22d4953560711d8 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 14 Jul 2025 17:30:03 +0200 Subject: [PATCH] EgtGeomKernel : - VM 5 assi con volumi chiusi, con bilineari. --- VolZmap.h | 8 +- VolZmapVolume.cpp | 611 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 436 insertions(+), 183 deletions(-) diff --git a/VolZmap.h b/VolZmap.h index be3a3d6..825acb9 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -23,6 +23,10 @@ #include #include #include +#include + +typedef std::pair PNTVEC3D ; +typedef std::vector PNTVEC3DVECTOR ; // vettore di intersezioni punto, vettore, tipo superficie // ------------------------- FORWARD ------------------------------------------------------------- class IntersParLinesSurfTm ; @@ -394,7 +398,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ; // aggiornamento intersezioni - bool UpdateMaxMin( Point3d ptBez, Vector3d vtN, PNTVECTVECTOR& vInters) const ; + bool UpdateMaxMin( Point3d& ptBez, Vector3d& vtN, PNTVEC3DVECTOR& vInters) const ; // Voxel: esistenza e passaggio da N a ijk per i voxel bool IsValidVoxel( int nN) const ; bool IsValidVoxel( int nI, int nJ, int nK) const ; @@ -484,7 +488,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW enum CuttingSurface { NONE = -1, TOOL = 0 , - TOP_BOT_BZ = 1 , + BZ = 1 , LATERAL = 2 } ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 377c90d..d4b25d6 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1131,10 +1131,10 @@ GetAlongAcrossRotation( const Vector3d& vtDir1, const Vector3d& vtDir2, const Ve //---------------------------------------------------------------------------- bool -VolZmap::UpdateMaxMin( Point3d ptBez, Vector3d vtN, PNTVECTVECTOR& vInters) const +VolZmap::UpdateMaxMin( Point3d& ptBez, Vector3d& vtN, PNTVEC3DVECTOR& vInters) const { if ( ! AreSameVectorExact( vtN, V_NULL)) - vInters.emplace_back( PNTVECT( ptBez, vtN)) ; + vInters.emplace_back( PNTVEC3D( ptBez, vtN)) ; return true ; } @@ -1308,10 +1308,13 @@ VolZmap::GenTool_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& return true ; } -//debug -static vector vGeo ; -//static int nCount = 0 ; -//debug +#if true + //debug + #define TEST + static vector vGeo ; + //static int nCount = 0 ; + //debug +#endif //---------------------------------------------------------------------------- bool @@ -1337,11 +1340,11 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt DBLVECTOR A1, B1, C1, A2, B2, C2 ; int nTotSurf = 4; if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) - nTotSurf = 2 + nSub * 2 ; + nTotSurf = 2 * nStepCnt + nSub * 2 * nStepCnt + nSub * 2 ; // sup laterali, sup superiori e inferiori, superfici verticali di inizio e fine else if( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX || n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) - nTotSurf = 2 + nSub * 2 + nStepCnt ; + nTotSurf = 2 * nStepCnt + nSub * 2 * nStepCnt + nStepCnt + nSub * 2 + nSub * 2 ; // verticali esterne e verticali interne else if( n5AxisType == VolZmap::Move5Axis::ACROSS) - nTotSurf = 2 + nSub * 4 ; + nTotSurf = 2 * nStepCnt + nSub * 4 * nStepCnt + nSub * 4 ; ISURFBEZPOVECTOR vSurfBez( nTotSurf * nStepCnt) ; BOXVECTOR vSurfBox( nTotSurf * nStepCnt) ; @@ -1356,10 +1359,12 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt Vector3d vtDirTipStartEx ; Vector3d vtDirTipEndEx ; +#ifdef TEST //debug if( nGrid == 0) vGeo.clear() ; //debug +#endif for ( int s = 0 ; s < nStepCnt ; ++s) { // punti di riferimento sul tool @@ -1432,6 +1437,12 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt vtDirTopStartEx = vtTopBaseStart ; Point3d ptRefStart = ptS[s] + vtTopBaseStart ; dSide = (ptRefEnd - ptRefStart) * vtLs[s] ; + + //debug + string sOut = ToString( dSide) ; + LOG_INFO( GetEGkLogger(), sOut.c_str()) + //debug + // calcolo anche i vettori per le basi inferiori Vector3d vtTipBaseStart = - (vtLs[s] ^ vtDirTip) ; vtTipBaseStart.Normalize() ; @@ -1539,6 +1550,13 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt for ( int i = 0 ; i < nSub ; ++i) { vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart[i], vPntTopStart[i+1], vPntTopEnd[i], vPntTopEnd[i+1]})) ; } + // chiudo il volume con le superici verticali + if( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { + for ( int i = 0 ; i < nSub ; ++i ) { + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i+1], vPntTipStart[i], vPntTopStart[nSub - i - 1], vPntTopStart[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipEnd[i], vPntTipEnd[i+1], vPntTopEnd[nSub - i], vPntTopEnd[nSub - i- 1]})) ; + } + } // aggiungo le superfici bilineari anche nell'altro verso sia per il top che per il tip if( n5AxisType == VolZmap::Move5Axis::ACROSS) { // inferiori @@ -1549,6 +1567,16 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt for ( int i = 0 ; i < nSub ; ++i) { vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart2[i], vPntTopStart2[i+1], vPntTopEnd2[i], vPntTopEnd2[i+1]})) ; } + // chiudo il volume con le superici verticali in avanti + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i+1], vPntTipStart[i], vPntTopStart2[nSub - i - 1], vPntTopStart2[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipEnd2[i], vPntTipEnd2[i+1], vPntTopEnd[nSub - i], vPntTopEnd[nSub - i -1]})) ; + } + // chiudo il volume con le superici verticali indietro + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart2[i+1], vPntTipStart2[i], vPntTopStart[nSub - i - 1], vPntTopStart[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipEnd[i], vPntTipEnd[i+1], vPntTopEnd2[nSub - i], vPntTopEnd2[nSub - i - 1]})) ; + } } } else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX) { @@ -1562,6 +1590,26 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt } // superfici inferiori semplici vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart.front(), vPntTipStart.back(), vPntTipEnd.front(), vPntTipEnd.back()})) ; + + // calcolo i punti di split dei diametri + PNTVECTOR vSplitDiamStart ; + PNTVECTOR vSplitDiamEnd ; + Vector3d vDirDiamStart = (vPntTipStart.back() - vPntTipStart.front()) / nSub ; + Vector3d vDirDiamEnd = (vPntTipEnd.back() - vPntTipEnd.front()) / nSub ; + for ( int i = 0 ; i <= nSub ; ++i) { + vSplitDiamStart.push_back( vPntTipStart.front() + i * vDirDiamStart) ; + vSplitDiamEnd.push_back( vPntTipEnd.front() + i * vDirDiamEnd) ; + } + // aggiungo le superfici verticali esterne + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamStart[i+1], vSplitDiamStart[i], vPntTopStart[nSub - i - 1], vPntTopStart[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamEnd[i], vSplitDiamEnd[i+1], vPntTopEnd2[nSub - i], vPntTopEnd2[nSub - i- 1]})) ; + } + // aggiungo le superfici verticali interne + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamStart[i+1], vSplitDiamStart[i], vPntTopStart2[nSub - i - 1], vPntTopStart2[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamEnd[i], vSplitDiamEnd[i+1], vPntTopEnd[nSub - i], vPntTopEnd[nSub - i- 1]})) ; + } } else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) { // superfici inferiori @@ -1574,6 +1622,26 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt } // superfici superiori semplici vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart.front(), vPntTopStart.back(), vPntTopEnd.front(), vPntTopEnd.back()})) ; + + // calcolo i punti di split dei diametri + PNTVECTOR vSplitDiamStart ; + PNTVECTOR vSplitDiamEnd ; + Vector3d vDirDiamStart = (vPntTopStart.back() - vPntTopStart.front()) / nSub ; + Vector3d vDirDiamEnd = (vPntTopEnd.back() - vPntTopEnd.front()) / nSub ; + for ( int i = 0 ; i <= nSub ; ++i) { + vSplitDiamStart.push_back( vPntTopStart.front() + i * vDirDiamStart) ; + vSplitDiamEnd.push_back( vPntTopEnd.front() + i * vDirDiamEnd) ; + } + // aggiungo le superfici verticali esterne + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamStart[i+1], vSplitDiamStart[i], vPntTipStart[nSub - i - 1], vPntTipStart[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamEnd[i], vSplitDiamEnd[i+1], vPntTipEnd2[nSub - i], vPntTipEnd2[nSub - i- 1]})) ; + } + // aggiungo le superfici verticali interne + for ( int i = 0 ; i < nSub ; ++i) { + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamStart[i+1], vSplitDiamStart[i], vPntTipStart2[nSub - i - 1], vPntTipStart2[nSub - i]})) ; + vvPtCtrl.emplace_back( PNTVECTOR({ vSplitDiamEnd[i], vSplitDiamEnd[i+1], vPntTipEnd[nSub - i], vPntTipEnd[nSub - i- 1]})) ; + } } } @@ -1599,16 +1667,23 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt 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[nSurfInd]->Clone()) ; +#ifdef TEST + if ( nGrid == 0) + vGeo.push_back( vSurfBez[nSurfInd]->Clone()) ; +#endif } } +#ifdef TEST //debug if ( nGrid == 0) { - SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ; + vector vCol( vGeo.size()) ; + fill(vCol.begin(), vCol.end(), Color( 255,128,0)) ; + SaveGeoObj( vGeo, vCol, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ; } //debug +#endif + BBox3d bbStartCyl = GetCylMoveBBox( ptS[0], ptS[0], vtLs[0], dMaxRad, dHeight) ; BBox3d bbEndCyl = GetCylMoveBBox( ptE.back(), ptE.back(), vtLe.back(), dMaxRad, dHeight) ; @@ -1668,7 +1743,11 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; Point3d r( dX, dY, 0) ; - PNTVECTVECTOR vInters ; + PNTVEC3DVECTOR vInters ; + + //debug + INTVECTOR vSurfInters ; + // interseco con le bilineari for( int s = 0 ; s < nAllStepsSurfs ; ++s) { // verifico che lo spillone faccia interferenza con il box della superficie @@ -1689,7 +1768,11 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt Point3d ptBez1 ; Vector3d vtN1 ; vSurfBez[s]->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez1, vtN1) ; - UpdateMaxMin( ptBez1, -vtN1, vInters) ; + vtN1 *= -1 ; + UpdateMaxMin( ptBez1, vtN1, vInters) ; + + //debug + vSurfInters.push_back( s) ; } } if ( nRoots > 1 && vdRoots[1] > 0 - EPS_ZERO && vdRoots[1] < 1 + EPS_ZERO) { @@ -1699,13 +1782,53 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt Point3d ptBez2 ; Vector3d vtN2 ; vSurfBez[s]->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez2, vtN2) ; - UpdateMaxMin( ptBez2, -vtN2, vInters) ; + vtN2 *= -1 ; + UpdateMaxMin( ptBez2, vtN2, vInters) ; + + //debug + vSurfInters.push_back( s) ; } } } } } + INTINTVECTOR vStartEnds ; + if ( vInters.size() > 2) { + sort( vInters.begin(), vInters.end(), []( PNTVEC3D& a, PNTVEC3D& b){ return a.first.z < b.first.z ;}) ; + INTINT pStartEnd ; + bool bDirStart = vInters.front().second * Z_AX > 0 ; + bool bFirstEndFound = false ; + pStartEnd.first = 0 ; + for ( int w = 1 ; w < int( vInters.size()) ; ++w) { + bool bDir = vInters[w].second * Z_AX > 0 ; + // se è l'ultimo punto esco + if ( w == int( vInters.size() - 1) && bDirStart != bDir) { + pStartEnd.second = w ; + vStartEnds.push_back( pStartEnd) ; + break ; + } + // sennò scorro finché non trovo l'uscita più lontana ( prima di un altro ingresso o eventualmente l'ultima inters) + else if( bDirStart != bDir) + bFirstEndFound = true ; + // se trovo di nuovo un'intersezione orientata come la prima dello spillone allora ho un nuovo start e posso chiudere l'intervallo precedente + else if( bFirstEndFound && bDirStart == bDir) { + pStartEnd.second = w - 1 ; + bFirstEndFound = false ; + vStartEnds.push_back( pStartEnd) ; + pStartEnd.first = w ; + pStartEnd.second = -1 ; + } + } + for( auto p : vStartEnds) + SubtractIntervals(nGrid, i, j, vInters[p.first].first.z, vInters[p.second].first.z, vInters[p.first].second, vInters[p.second].second, nToolNum) ; + } + else if ( vInters.size() == 2) + SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ; + else if ( vInters.size() == 1) + return false ; + vInters.clear() ; + // 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 BOOLVECTOR vbUpdate( 2) ; @@ -1735,180 +1858,306 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt bIntersFound = IntersLineConus( r, Z_AX, frTool, dTan, dMinH, dMaxH, false, false, vPntInters[0], vVtIntersNorm[0], vPntInters[1], vVtIntersNorm[1]) ; if ( bIntersFound) { - // ciclo sulle due intersezioni - fill(vbUpdate.begin(), vbUpdate.end(), false) ; - for( int p = 0 ; p < 2 ; ++p) { - bool bOnTopBase = ( vPntInters[p] - frTool.Orig() ) * frTool.VersZ() > dHeight - EPS_SMALL ; - bool bOnBottomBase = ( vPntInters[p] - frTool.Orig() ) * frTool.VersZ() < EPS_SMALL ; - // se ho un'intersezione su una base devo verificare se la devo considerare o no - if ( bOnBottomBase || bOnTopBase) { - // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari - //base inferiore - double dSectorAng = 0 ; - bool bApproxedSideBottom = false ; - bool bApproxedSideTop = false ; - double dBottomBaseSide = 0 ; - if ( t == 0) - dBottomBaseSide = ( vPntInters[p] - frTool.Orig()) * vtDirTipStartEx ; - else if ( t == 1) - dBottomBaseSide = ( vPntInters[p] - frTool.Orig()) * vtDirTipEndEx ; - double dTopBaseSide = 0 ; - if ( t == 0) - dTopBaseSide = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vtDirTopStartEx ; - else if ( t == 1) - dTopBaseSide = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vtDirTopEndEx ; + fill(vbUpdate.begin(), vbUpdate.end(), true) ; // tengo tutte le intersezioni col cilindro - if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { - if ( dSide < 0) { - bApproxedSideBottom = dBottomBaseSide < 0 ; - bApproxedSideTop = dTopBaseSide > 0 ; - } - else { - bApproxedSideBottom = dBottomBaseSide > 0 ; - bApproxedSideTop = dTopBaseSide < 0 ; - } - } - else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) { - if ( t == 0) { - bApproxedSideBottom = dBottomBaseSide < 0 ; - bApproxedSideTop = dTopBaseSide < 0 ; - } - else if ( t == 1) { - bApproxedSideBottom = dBottomBaseSide > 0 ; - bApproxedSideTop = dTopBaseSide > 0 ; - } - } - else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX){ - if ( bOnBottomBase) { - if ( t == 0) - vbUpdate[p] = dBottomBaseSide < 0 ; - else if ( t == 1) - vbUpdate[p] = dBottomBaseSide > 0 ; - } - else if ( bOnTopBase) - bApproxedSideTop = true ; - } - else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) { - if ( bOnBottomBase) - bApproxedSideBottom = true ; - else if ( bOnTopBase) { - if ( t == 0) - vbUpdate[p] = dTopBaseSide < 0 ; - else if( t == 1) - vbUpdate[p] = dTopBaseSide > 0 ; - } - } - if ( bOnBottomBase && bApproxedSideBottom) { - if ( t == 0) - vvtTipStartAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dSectorAng) ; - else if( t == 1) - vvtTipEndAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dSectorAng) ; - // determino in quale settore del semicerchio approssimato mi trovo - int nSector = int( dSectorAng / ( 180. / nSub) + 1) ; - // verifico se l'intersezione linea-base è interna o esterna - if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { - double dDist = 0 ; - if ( t == 0) - dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipStartAux[nSector] ; - else if( t == 1) - dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipEndAux[nSector] ; + //// ciclo sulle due intersezioni + //fill(vbUpdate.begin(), vbUpdate.end(), false) ; + //for( int p = 0 ; p < 2 ; ++p) { + // bool bOnTopBase = ( vPntInters[p] - frTool.Orig() ) * frTool.VersZ() > dHeight - EPS_SMALL ; + // bool bOnBottomBase = ( vPntInters[p] - frTool.Orig() ) * frTool.VersZ() < EPS_SMALL ; + // // se ho un'intersezione su una base devo verificare se la devo considerare o no + // if ( bOnBottomBase || bOnTopBase) { + // // verifico se sono nella metà della base il cui contorno è in contatto con le bilineari + // //base inferiore + // double dSectorAng = 0 ; + // bool bApproxedSideBottom = false ; + // bool bApproxedSideTop = false ; + // double dBottomBaseSide = 0 ; + // if ( t == 0) + // dBottomBaseSide = ( vPntInters[p] - frTool.Orig()) * vtDirTipStartEx ; + // else if ( t == 1) + // dBottomBaseSide = ( vPntInters[p] - frTool.Orig()) * vtDirTipEndEx ; + // double dTopBaseSide = 0 ; + // if ( t == 0) + // dTopBaseSide = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vtDirTopStartEx ; + // else if ( t == 1) + // dTopBaseSide = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vtDirTopEndEx ; - if ( dSide > 0) - vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; - else - vbUpdate[p] = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ; - } - else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) { - double dDist = 0 ; - // per il caso ALONG_CONCAVE dovrei avere dSide < 0, quindi sulla base bottom avere i punti ausiliari nella parte posteriore del cerchio di base - if ( dBottomBaseSide > 0) { - if ( t == 0) { - // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto - dDist = ( vPntInters[p] - frTool.Orig() ) * ( -vvtTipStartAux[( nSub + 1 ) - nSector] ) ; - vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; - } - else if ( t == 1) - vbUpdate[p] = true ; - } - else { - if ( t == 0) - vbUpdate[p] = true ; - else if ( t == 1 ) { - dDist = (vPntInters[p] - frTool.Orig()) * vvtTipEndAux[nSector] ; - vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; - } - } - } - else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) - vbUpdate[p] = true ; - } - // base superiore - else if( bOnTopBase && bApproxedSideTop) { - if ( t == 0) - vvtTopStartAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dSectorAng) ; - else if( t == 1) - vvtTopEndAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dSectorAng) ; - // determino in quale settore del semicerchio approssimato mi trovo - int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ; - // verifico se l'intersezione linea-base è interna o esterna - if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { - double dDist = 0 ; - if ( t == 0) - dDist = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vvtTopStartAux[nSector] ; - else if( t == 1) - dDist = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vvtTopEndAux[nSector] ; + // if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { + // if ( dSide < 0) { + // bApproxedSideBottom = dBottomBaseSide < 0 ; + // bApproxedSideTop = dTopBaseSide > 0 ; + // } + // else { + // bApproxedSideBottom = dBottomBaseSide > 0 ; + // bApproxedSideTop = dTopBaseSide < 0 ; + // } + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) { + // //if ( t == 0) { + // // bApproxedSideBottom = dBottomBaseSide < 0 ; + // // bApproxedSideTop = dTopBaseSide < 0 ; + // //} + // //else if ( t == 1) { + // // bApproxedSideBottom = dBottomBaseSide > 0 ; + // // bApproxedSideTop = dTopBaseSide > 0 ; + // //} - if( dSide < 0) - vbUpdate[p] = dDist < dMaxRadApprox - EPS_SMALL ; - else - vbUpdate[p] = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ; - } - else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX) { - double dDist = 0 ; - // per il caso ALONG_CONVEX dovrei avere dSide > 0, quindi sulla base top avere i punti ausiliari nella parte posteriore del cerchio di base - if ( dTopBaseSide > 0) { - // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto - if ( t == 0) - dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTipStartAux[( nSub + 1 ) - nSector]) ; - else if( t == 1) - dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTipEndAux[( nSub + 1 ) - nSector]) ; - vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; - } - else - vbUpdate[p] = true ; - } - else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) - vbUpdate[p] = true ; - } - else if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS && - (( t == 0 && ((bOnTopBase && dSide < 0) || ( bOnBottomBase && dSide > 0))) || - ( t == 1 && ((bOnTopBase && dSide > 0) || ( bOnBottomBase && dSide < 0))))) - vbUpdate[p] = true ; - } - else { - double dHInters = 0 ; - if ( t == 0) - dHInters = (vPntInters[p] - ptP1T) * vtLs.front() ; - else if( t == 1) - dHInters = (vPntInters[p] - ptP2T) * vtLe.back() ; - Vector3d vtDir = Media( vtDirTip, vtDirTop, dHInters / dHeight) ; - if ( t == 0) - vbUpdate[p] = vVtIntersNorm[p] * vtDir > 0 ; - else if ( t == 1) - vbUpdate[p] = vVtIntersNorm[p] * vtDir < 0 ; - } - } - if ( vbUpdate[0]) + // bApproxedSideBottom = true ; + // bApproxedSideTop = true ; + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX){ + // if ( bOnBottomBase) { + // if ( t == 0) + // vbUpdate[p] = dBottomBaseSide < 0 ; + // else if ( t == 1) + // vbUpdate[p] = dBottomBaseSide > 0 ; + // } + // else if ( bOnTopBase) + // bApproxedSideTop = true ; + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) { + // if ( bOnBottomBase) + // bApproxedSideBottom = true ; + // else if ( bOnTopBase) { + // if ( t == 0) + // vbUpdate[p] = dTopBaseSide < 0 ; + // else if( t == 1) + // vbUpdate[p] = dTopBaseSide > 0 ; + // } + // } + // if ( bOnBottomBase && bApproxedSideBottom) { + // if ( t == 0) + // vvtTipStartAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dSectorAng) ; + // else if( t == 1) + // vvtTipEndAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dSectorAng) ; + // // determino in quale settore del semicerchio approssimato mi trovo + // int nSector = int( dSectorAng / ( 180. / nSub) + 1) ; + // // verifico se l'intersezione linea-base è interna o esterna + // if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { + // double dDist = 0 ; + // if ( t == 0) + // dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipStartAux[nSector] ; + // else if( t == 1) + // dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipEndAux[nSector] ; + + // if ( dSide > 0) + // vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; + // else + // vbUpdate[p] = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ; + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE) { + // double dDist = 0 ; + // // per il caso ALONG_CONCAVE dovrei avere dSide < 0, quindi sulla base bottom avere i punti ausiliari nella parte posteriore del cerchio di base + // if ( dBottomBaseSide > 0) { + // if ( t == 0) { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // dDist = ( vPntInters[p] - frTool.Orig() ) * ( -vvtTipStartAux[( nSub + 1 ) - nSector] ) ; + // vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; + // } + // else if ( t == 1) + // vbUpdate[p] = true ; + // } + // else { + // if ( t == 0) + // vbUpdate[p] = true ; + // else if ( t == 1 ) { + // dDist = (vPntInters[p] - frTool.Orig()) * vvtTipEndAux[nSector] ; + // vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; + // } + // } + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) { + // double dDist = 0 ; + // // con dSide < 0 sulla base bottom/top ho i punti ausiliari nella parte posteriore/anteriore del cerchio di base + // // con dSide > 0 sulla base bottom/top ho i punti ausiliari nella parte anteriore/posteriore del cerchio di base + // + // if ( dBottomBaseSide > 0) { + // if ( t == 0) { + // if ( dSide < 0) { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // dDist = ( vPntInters[p] - frTool.Orig() ) * ( -vvtTipStartAux[( nSub + 1 ) - nSector] ) ; + // } + // else { + // dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipStartAux[nSector] ; + // } + // vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; + // } + // else if ( t == 1) + // vbUpdate[p] = true ; + // } + // else { + // if ( t == 0) + // vbUpdate[p] = true ; + // else if ( t == 1) { + // if ( dSide < 0) { + // dDist = ( vPntInters[p] - frTool.Orig() ) * vvtTipStartAux[nSector] ; + // } + // else { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // dDist = ( vPntInters[p] - frTool.Orig() ) * ( -vvtTipStartAux[( nSub + 1 ) - nSector] ) ; + // } + // vbUpdate[p] = dDist < dMinRadApprox - EPS_SMALL ; + // } + // } + + // //vbUpdate[p] = true ; + // } + // } + // // base superiore + // else if( bOnTopBase && bApproxedSideTop) { + // if ( t == 0) + // vvtTopStartAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dSectorAng) ; + // else if( t == 1) + // vvtTopEndAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dSectorAng) ; + // // determino in quale settore del semicerchio approssimato mi trovo + // int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ; + // // verifico se l'intersezione linea-base è interna o esterna + // if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS) { + // double dDist = 0 ; + // if ( t == 0) + // dDist = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vvtTopStartAux[nSector] ; + // else if( t == 1) + // dDist = ( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight)) * vvtTopEndAux[nSector] ; + + // if( dSide < 0) + // vbUpdate[p] = dDist < dMaxRadApprox - EPS_SMALL ; + // else + // vbUpdate[p] = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ; + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX) { + // double dDist = 0 ; + // // per il caso ALONG_CONVEX dovrei avere dSide > 0, quindi sulla base top avere i punti ausiliari nella parte posteriore del cerchio di base + // if ( dTopBaseSide > 0) { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // if ( t == 0) + // dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTopStartAux[( nSub + 1 ) - nSector]) ; + // else if( t == 1) + // dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTopEndAux[( nSub + 1 ) - nSector]) ; + // vbUpdate[p] = dDist < dMaxRadApprox - EPS_SMALL ; + // } + // else + // vbUpdate[p] = true ; + // } + // else if ( n5AxisType == VolZmap::Move5Axis::ACROSS) { + // double dDist = 0 ; + // // con dSide < 0 sulla base bottom/top ho i punti ausiliari nella parte posteriore/anteriore del cerchio di base + // // con dSide > 0 sulla base bottom/top ho i punti ausiliari nella parte anteriore/posteriore del cerchio di base + // if ( dTopBaseSide > 0) { + // if ( t == 0) { + // if ( dSide < 0) { + // dDist = ( vPntInters[p] - frTool.Orig()) * vvtTopStartAux[nSector] ; + // } + // else { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTopStartAux[( nSub + 1 ) - nSector] ) ; + // } + // vbUpdate[p] = dDist < dMaxRadApprox - EPS_SMALL ; + // } + // else if ( t == 1) + // vbUpdate[p] = true ; + // } + // else { + // if ( t == 0) + // vbUpdate[p] = true ; + // else if ( t == 1) { + // if ( dSide < 0) { + // // in questo caso devo prendere il vettore Aux dell'angolo supplementare e con segno opposto + // dDist = ( vPntInters[p] - frTool.Orig()) * ( -vvtTopStartAux[( nSub + 1 ) - nSector] ) ; + // } + // else { + // dDist = ( vPntInters[p] - frTool.Orig()) * vvtTopStartAux[nSector] ; + // } + // vbUpdate[p] = dDist < dMaxRadApprox - EPS_SMALL ; + // } + // } + + + // //vbUpdate[p] = true ; + // } + // } + // else if ( n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS && + // (( t == 0 && ((bOnTopBase && dSide < 0) || ( bOnBottomBase && dSide > 0))) || + // ( t == 1 && ((bOnTopBase && dSide > 0) || ( bOnBottomBase && dSide < 0))))) + // vbUpdate[p] = true ; + // } + // else { + // double dHInters = 0 ; + // if ( t == 0) + // dHInters = (vPntInters[p] - ptP1T) * vtLs.front() ; + // else if( t == 1) + // dHInters = (vPntInters[p] - ptP2T) * vtLe.back() ; + // Vector3d vtDir = Media( vtDirTip, vtDirTop, dHInters / dHeight) ; + // if ( t == 0) + // vbUpdate[p] = vVtIntersNorm[p] * vtDir > 0 ; // le normali dei punti di intersezione sul cilindro sono rivolte verso l'interno del cilindro + // else if ( t == 1) + // vbUpdate[p] = vVtIntersNorm[p] * vtDir < 0 ; + // } + //} + if ( vbUpdate[0]) { UpdateMaxMin( vPntInters[0], vVtIntersNorm[0], vInters) ; - if ( vbUpdate[1]) + + //debug + vSurfInters.push_back( t == 0 ? -1 : -2) ; + } + if ( vbUpdate[1]) { UpdateMaxMin( vPntInters[1], vVtIntersNorm[1], vInters) ; + + //debug + vSurfInters.push_back( t == 0 ? -1 : -2) ; + } + } + + if ( vInters.size() == 2) { + sort( vInters.begin(), vInters.end(), []( PNTVEC3D& a, PNTVEC3D& b){ return a.first.z < b.first.z ;}) ; + SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ; + vInters.clear() ; } } } - if ( vInters.size() != 0 ) { - sort( vInters.begin(), vInters.end(), []( PNTVECT& a, PNTVECT& b){ return a.first.z < b.first.z ;}) ; - SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ; - } + + //if ( vInters.size() != 0 ) { + // // se ho un numero dispari di intersezioni devo migliorare la gestione + + // // riordino le intersezioni rispetto alla loro z + // sort( vInters.begin(), vInters.end(), []( PNTVEC3D& a, PNTVEC3D& b){ return a.first.z < b.first.z ;}) ; + // INTINTVECTOR vStartEnds ; + // if ( vInters.size() > 2) { + // INTINT pStartEnd ; + // bool bDirStart = vInters.front().second * Z_AX > 0 ; + // bool bFirstEndFound = false ; + // pStartEnd.first = 0 ; + // for ( int w = 1 ; w < int( vInters.size()) ; ++w) { + // bool bDir = vInters[w].second * Z_AX > 0 ; + // // se è l'ultimo punto esco + // if ( w == int( vInters.size() - 1) && bDirStart != bDir) { + // pStartEnd.second = w ; + // vStartEnds.push_back( pStartEnd) ; + // break ; + // } + // // sennò scorro finché non trovo l'uscita più lontana ( prima di un altro ingresso o eventualmente l'ultima inters) + // else if( bDirStart != bDir) + // bFirstEndFound = true ; + // // se trovo di nuovo un'intersezione orientata come la prima dello spillone allora ho un nuovo start e posso chiudere l'intervallo precedente + // else if( bFirstEndFound && bDirStart == bDir) { + // pStartEnd.second = w - 1 ; + // bFirstEndFound = false ; + // vStartEnds.push_back( pStartEnd) ; + // pStartEnd.first = w ; + // pStartEnd.second = -1 ; + // } + // } + // for( auto p : vStartEnds) + // SubtractIntervals(nGrid, i, j, vInters[p.first].first.z, vInters[p.second].first.z, vInters[p.first].second, vInters[p.second].second, nToolNum) ; + // } + // else + // SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ; + //} + + //if ( vInters.size() != 0 ) { + // sort( vInters.begin(), vInters.end(), []( PNTVEC3D& a, PNTVEC3D& b){ return get<0>(a).z < get<0>(b).z ;}) ; + // SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ; + //} } }