diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index d4b25d6..92bc664 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1823,14 +1823,15 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt 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) + else if ( vInters.size() == 2){ + vStartEnds.push_back( INTINT(0,1)) ; 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 + PNTVEC3DVECTOR vIntersTool ; BOOLVECTOR vbUpdate( 2) ; PNTVECTOR vPntInters( 2) ; VCT3DVECTOR vVtIntersNorm( 2) ; @@ -1858,306 +1859,426 @@ 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) { - fill(vbUpdate.begin(), vbUpdate.end(), true) ; // tengo tutte le intersezioni col cilindro + // ciclo sulle due intersezioni + fill( vbUpdate.begin(), vbUpdate.end(), false) ; + INTVECTOR vnPos(2) ; // salvo le posizioni dei punti + 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 ; - //// 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 ( 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) { + 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 ( 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 < 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 ; + } + } + } + // se sto per buttare via l'intersezione, la sposto invece all'interno dell'intervallo di intersezione fatto dal volume definito dalle bilineari + // se non ho neanche questa intersezione allora posso buttare via tutto + if ( ! vbUpdate[p] && vInters.size() != 0) { + int c = 0 ; + int nClosePair = -1 ; + bool bStartOrEndPair = false ; // true = start ; false = end + double dMinDist = INFINITO ; + for ( auto& pair : vStartEnds) { + double dDist = Dist( vPntInters[p], vInters[pair.first].first) ; + if ( dDist < dMinDist ) { + dMinDist = dDist ; + bStartOrEndPair = true ; + nClosePair = c ; + } + dDist = Dist( vPntInters[p], vInters[pair.second].first) ; + if ( dDist < dMinDist) { + dMinDist = dDist ; + bStartOrEndPair = false ; + nClosePair = c ; + } + ++c ; + } + if( bStartOrEndPair) + vPntInters[p] = vInters[vStartEnds[nClosePair].first].first ; + else + vPntInters[p] = vInters[vStartEnds[nClosePair].second].first ; + } + } + // 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] ; - // 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 < 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 ; + } + } + } + // se sto per buttare via l'intersezione, la sposto invece all'interno dell'intervallo di intersezione fatto dal volume definito dalle bilineari + // se non ho neanche questa intersezione allora posso buttare via tutto + if ( ! vbUpdate[p] && vInters.size() != 0) { + int c = 0 ; + int nClosePair = -1 ; + bool bStartOrEndPair = false ; // true = start ; false = end + double dMinDist = INFINITO ; + for ( auto& pair : vStartEnds) { + double dDist = Dist( vPntInters[p], vInters[pair.first].first) ; + if ( dDist < dMinDist ) { + dMinDist = dDist ; + bStartOrEndPair = true ; + nClosePair = c ; + } + dDist = Dist( vPntInters[p], vInters[pair.second].first) ; + if ( dDist < dMinDist) { + dMinDist = dDist ; + bStartOrEndPair = false ; + nClosePair = c ; + } + ++c ; + } + if( bStartOrEndPair) + vPntInters[p] = vInters[vStartEnds[nClosePair].first].first ; + else + vPntInters[p] = vInters[vStartEnds[nClosePair].second].first ; + } + } + 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 ; + } + // superficie laterale + 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[p]) { + //calcolo in che settore sono + double dTopSectorAng = 0 ; + double dBottomSectorAng = 0 ; + // settore top + if ( t == 0) + vvtTopStartAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dTopSectorAng) ; + else if( t == 1) + vvtTopEndAux.front().GetAngle( vPntInters[p] - ( frTool.Orig() + frTool.VersZ() * dHeight ), dTopSectorAng) ; + // settore bottom + if ( t == 0) + vvtTipStartAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dBottomSectorAng) ; + else if( t == 1) + vvtTipEndAux.front().GetAngle( vPntInters[p] - frTool.Orig(), dBottomSectorAng) ; - // 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 ; - // } - // } + int nTopSector = int( dTopSectorAng / ( 180. / nSub) + 1) ; + int nBottomSector = int( dBottomSectorAng / ( 180. / nSub) + 1) ; + bool bUnderTop = false ; + bool bOverBottom = false ; + if( n5AxisType != VolZmap::Move5Axis::ALONG_CONCAVE) { + // controllo la posizione del punto rispetto alla superificie bilineare di quel settore + int nSurf = 0 ; + if( n5AxisType != VolZmap::Move5Axis::NO_BASE_INTERS) { + if ( (dSide < 0 && t == 0) || (dSide > 0 && t == 1)) + nSurf = 2 + nSub + nTopSector ; + else + bUnderTop = true ; + } + else if ( n5AxisType != VolZmap::Move5Axis::ALONG_CONVEX) { + // dovrebbe avere dSide > 0 + if ( t == 0) { + if ( dSide > 0) + nSurf = 2 + nSub + nTopSector ; + else + nSurf = 2 + nTopSector ; + } + else if ( t == 1) { + if ( dSide > 0) + nSurf = 2 + nTopSector ; + else + nSurf = 2 + nSub + nTopSector ; + } + } + else if ( n5AxisType != VolZmap::Move5Axis::ACROSS) { + if ( t == 0) { + if ( dSide > 0) + nSurf = 2 + nSub + nTopSector ; + else + nSurf = 2 + 3*nSub + nTopSector ; + } + else if ( t == 1) { + if ( dSide > 0) + nSurf = 2 + 3*nSub + nTopSector ; + else + nSurf = 2 + nSub + nTopSector ; + } + } - // //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( ! bUnderTop) { + Point3d ptCTop ; + Vector3d vtNTop ; + vSurfBez[nSurf]->GetPointNrmD1D2( 0.5, 0.5, ISurfBezier::Side::FROM_MINUS,ISurfBezier::Side::FROM_MINUS, ptCTop, vtNTop) ; + Vector3d vtIntTop = vPntInters[p] - ptCTop ; + bUnderTop = vtIntTop * vtNTop < 0 ; + } + } + if ( n5AxisType != VolZmap::Move5Axis::ALONG_CONVEX) { + int nSurf = 0 ; + if( n5AxisType != VolZmap::Move5Axis::NO_BASE_INTERS) { + if ( ( dSide > 0 && t == 0) || ( dSide < 0 && t == 1)) + nSurf = 2 + nBottomSector ; + else + bOverBottom = true ; + } + else if ( n5AxisType != VolZmap::Move5Axis::ALONG_CONCAVE) { + // dovrebbe avere dSide < 0 + if( t == 0) { + if ( dSide < 0) + nSurf = 2 + nBottomSector ; + else + nSurf = 2 + nSub + nBottomSector ; + } + else if ( t == 1 ) { + if ( dSide < 0) + nSurf = 2 + nSub + nBottomSector ; + else + nSurf = 2 + nBottomSector ; + } + } + else if ( n5AxisType != VolZmap::Move5Axis::ACROSS) { + if( t == 0) { + if ( dSide < 0) + nSurf = 2 + nBottomSector ; + else + nSurf = 2 + 2 * nSub + nBottomSector ; + } + else if ( t == 1 ) { + if ( dSide < 0) + nSurf = 2 + 2 * nSub + nBottomSector ; + else + nSurf = 2 + nBottomSector ; + } + } - // 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 ; - // } - // } + if( ! bOverBottom) { + Point3d ptCBottom ; + Vector3d vtNBottom ; + vSurfBez[nSurf]->GetPointNrmD1D2( 0.5, 0.5, ISurfBezier::Side::FROM_MINUS,ISurfBezier::Side::FROM_MINUS, ptCBottom, vtNBottom) ; + Vector3d vtIntBottom = vPntInters[p] - ptCBottom ; + bOverBottom = vtIntBottom * vtNBottom < 0 ; + } + } + bool bNo_inters = n5AxisType == VolZmap::Move5Axis::NO_BASE_INTERS && (( dSide < 0 && ( t == 0 && bUnderTop) || ( t == 1 && bOverBottom)) || + ( dSide > 0 && ( t == 0 && bOverBottom) || ( t == 1 && bUnderTop))) ; + bool bAlong_Convex = n5AxisType == VolZmap::Move5Axis::ALONG_CONVEX && bUnderTop ; + bool bAlong_Concave = n5AxisType == VolZmap::Move5Axis::ALONG_CONCAVE && bOverBottom ; + bool bAcross = n5AxisType == VolZmap::Move5Axis::ACROSS && bUnderTop && bOverBottom ; + + if ( bNo_inters || bAlong_Convex || bAlong_Concave || bAcross) + vbUpdate[p] = true ; + } + } + } - // //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) ; + UpdateMaxMin( vPntInters[0], vVtIntersNorm[0], vIntersTool) ; //debug vSurfInters.push_back( t == 0 ? -1 : -2) ; } if ( vbUpdate[1]) { - UpdateMaxMin( vPntInters[1], vVtIntersNorm[1], vInters) ; + UpdateMaxMin( vPntInters[1], vVtIntersNorm[1], vIntersTool) ; //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 ( vIntersTool.size() == 2) { + sort( vIntersTool.begin(), vIntersTool.end(), []( PNTVEC3D& a, PNTVEC3D& b){ return a.first.z < b.first.z ;}) ; + SubtractIntervals( nGrid, i, j, vIntersTool.front().first.z, vIntersTool.back().first.z, vIntersTool.front().second, vIntersTool.back().second, nToolNum) ; + vIntersTool.clear() ; } } } - - //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) ; - //} } }