From f302e52206c629115487ef1b3fe8d2a68b3e2db9 Mon Sep 17 00:00:00 2001 From: LorenzoM Date: Tue, 3 Aug 2021 16:16:42 +0200 Subject: [PATCH] Modifiche ad asportazioni volumi avanzate --- SurfTriMeshBooleans.cpp | 333 -------- Tool.cpp | 12 +- Tool.h | 2 + VolZmap.h | 13 +- VolZmapVolume.cpp | 1684 ++++++++++++++++++++++++++++++--------- 5 files changed, 1331 insertions(+), 713 deletions(-) diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 6db28fb..ce1bc35 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -3055,247 +3055,6 @@ TrimLineWithExtPolygon( const CurveLine& cvLine, const POLYLINEVECTOR& vContourV return true ; } -//---------------------------------------------------------------------------- -static bool -ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) -{ - // Rinomino la lista di punti della PolyLine. - PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso pi� vicino al punto. - double dMinSqDist = DBL_MAX ; - auto itMinDist = LoopList.end() ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - itMinDist = itSt ; - } - } - // Se il punto non sta sul loop, errore - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Se il punto non sta su un vertice del segmento, lo aggiungo. Altrimenti non devo fare nulla. - auto itNewPointSt = LoopList.begin() ; - auto itNext = itMinDist ; - ++ itNext ; - bool bOnStart = AreSamePointApprox( ptNewStart, itMinDist->first) ; - bool bOnEnd = AreSamePointApprox( ptNewStart, itNext->first) ; - itNewPointSt = LoopList.emplace( itNext, ptNewStart, 0) ; - // Sposto i punti precedenti in coda. - bool bStartRemoved = false ; - auto it = LoopList.begin() ; - while ( it != itNewPointSt) { - if ( bStartRemoved) { - LoopList.emplace_back( it->first, it->second) ; - } - bStartRemoved = true ; - it = LoopList.erase( it) ; - } - // Se il punto inserito non coincide con l'inizio del segmento chiudo il loop. - if ( ! bOnStart) { - LoopList.emplace_back( ptNewStart, 0) ; - // Se coincide con la fine tolgo il punto di fine che diviene inutile. - if ( bOnEnd) { - //LoopList.erase( itNext) ; - auto itNewStart = LoopList.begin() ; - ++ itNewStart ; - LoopList.erase( itNewStart) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -// nSegNum 0-based -static bool -PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) -{ - // Rinomino la lista di punti della PolyLine. - /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso pi� vicino al punto. - nSegNum = - 1 ; - double dMinSqDist = DBL_MAX ; - int nS = 0 ; - auto itMinDistSt = LoopList.end() ; - auto itMinDistEn = itMinDistSt ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn, ++ nS) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - nSegNum = nS ; - dMinSqDist = dSqDist ; - itMinDistSt = itSt ; - itMinDistEn = itEn ; - } - } - // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Calcolo il parametro lungo il segmento. - Vector3d vtSeg = itMinDistEn->first - itMinDistSt->first ; - double dSegLen = vtSeg.Len() ; - if ( dSegLen < EPS_SMALL) - return false ; - vtSeg /= dSegLen ; - dParOnSeg = Clamp( ( ptPoint - itMinDistSt->first) * vtSeg, 0., dSegLen) ; - return true ; -} - -//---------------------------------------------------------------------------- -static bool -IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) -{ - // Se la PolyLine non � chiusa, il punto non pu� essere interno. - if ( ! plPoly.IsClosed()) - return false ; - // Lista dei punti - /*const*/ PNTULIST& List = plPoly.GetUPointList() ; - // Ciclo sui segmenti della PolyLine per cercarne il tratto pi� vicino al punto. - double dMinSqDist = DBL_MAX ; - Point3d ptMinDist ; - auto itMinDistSt = List.end() ; - auto itSt = List.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != List.end() && itEn != List.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptP, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - dDistCalc.GetMinDistPoint( ptMinDist) ; - itMinDistSt = itSt ; - } - } - // Termine del segmento di minima distanza. - auto itMinDistEn = itMinDistSt ; - ++ itMinDistEn ; - // Punto di minima distanza nell'estremo iniziale del segento - if ( AreSamePointApprox( ptMinDist, itMinDistSt->first)) { - auto itPrevSt = List.begin() ; - if ( itMinDistSt == List.begin()) { - auto itAuxNext = itPrevSt ; - ++ ( ++ itAuxNext) ; - for ( ; itAuxNext != List.end() ; ++ itPrevSt, ++ itAuxNext) - ; - } - else { - auto itAuxNext = itPrevSt ; - ++ itAuxNext ; - for (; itAuxNext != itMinDistSt; ++itPrevSt, ++itAuxNext) - ; - } - Vector3d vtPrevTan = itMinDistSt->first - itPrevSt->first ; - vtPrevTan.Normalize() ; - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtPrevOut = vtPrevTan ^ vtPolyNorm ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - // Caso concavo - if ( vtTan * vtPrevOut > 0) { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtPrevOut < 0 || vtTest * vtOut < 0) - return true ; - } - // Caso convesso - else { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtPrevOut < 0 && vtTest * vtOut < 0) - return true ; - } - } - // Punto di minima distanza nell'estremo finale del segento - else if ( AreSamePointApprox( ptMinDist, itMinDistEn->first)) { - auto itNextEn = itMinDistEn ; - ++ itNextEn ; - if ( itNextEn == List.end()) { - itNextEn = List.begin() ; - ++ itNextEn ; - } - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Vector3d vtNextTan = itNextEn->first - itMinDistEn->first ; - vtNextTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - Vector3d vtNextOut = vtNextTan ^ vtPolyNorm ; - // Caso concavo - if ( vtNextTan * vtOut > 0) { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtOut < 0 || vtTest * vtNextOut < 0) - return true ; - } - // Caso convesso - else { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtOut < 0 && vtTest * vtNextOut < 0) - return true ; - } - } - // Punto di minima distanza interno al segmeno - else { - Vector3d vtP = ptP - itMinDistSt->first ; - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - vtP -= ( vtP * vtTan) * vtTan ; - if ( vtP * vtOut < - EPS_SMALL) - return true ; - } - return false ; -} - -//---------------------------------------------------------------------------- -bool -DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dPointPolyLineDist) -{ - if ( plPoly.GetPointNbr() == 0) - return false ; - dPointPolyLineDist = DBL_MAX ; - Point3d ptSt, ptEn ; - bool bContinue = plPoly.GetFirstPoint( ptSt) && plPoly.GetNextPoint( ptEn) ; - while ( bContinue) { - double dPoinLineDist ; - DistPointLine PointLineDistCalc( ptP, ptSt, ptEn) ; - PointLineDistCalc.GetDist( dPoinLineDist) ; - if ( dPoinLineDist < dPointPolyLineDist) - dPointPolyLineDist = dPoinLineDist ; - ptSt = ptEn ; - bContinue = plPoly.GetNextPoint( ptEn) ; - } - return true ; -} - //---------------------------------------------------------------------------- // Una faccia di una trimesh ha una sola componente connessa. // Si assume che i loop siano corretti e rispettino tale propriet�. @@ -3339,98 +3098,6 @@ DistPointFacet( const Point3d& ptP, /*const*/ POLYLINEVECTOR& vPolyVec, double& return true ; } -//---------------------------------------------------------------------------- -static bool -SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) -{ - // Rinomino la lista di punti della PolyLine. - /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso pi� vicino al punto. - double dMinSqDist = DBL_MAX ; - auto itMinDistSt = LoopList.end() ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - itMinDistSt = itSt ; - } - } - // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Se il punto di stop sta su un vertice non devo aggiungerlo e il - // punto di stop sar� uno degli estremi del segmento su cui giace. - auto itStop = itMinDistSt ; - auto itNext = itMinDistSt ; - ++ itNext ; - if ( AreSamePointApprox( ptPoint, itStop->first)) - ; - else if ( AreSamePointApprox( ptPoint, itNext->first)) - itStop = itNext ; - else { - itStop = LoopList.emplace( itNext, ptPoint, 0.) ; - } - // Creo i due loop - PNTULIST& LoopList1 = Loop1.GetUPointList() ; - PNTULIST& LoopList2 = Loop2.GetUPointList() ; - for ( auto it = LoopList.begin() ; it != itStop ; ++ it) { - LoopList1.emplace_back( it->first, it->second) ; - } - LoopList1.emplace_back( itStop->first, itStop->second) ; - for ( auto it = itStop ; it != LoopList.end() ; ++ it) { - LoopList2.emplace_back( it->first, it->second) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -static bool -AddPolyLineToPolyLine( PolyLine& Poly, PolyLine& PolyToAdd) -{ - // Se la PolyLine a cui devo aggiungere l'altra � chiusa, non posso aggiungere nulla. - if ( Poly.IsClosed()) - return false ; - // Se la PolyLina che devo aggiungere � vuota, ho finito. - PNTULIST& PolyToAddList = PolyToAdd.GetUPointList() ; - if ( int( PolyToAddList.size()) == 0) - return true ; - // Se Poly non � vuota e la sua fine non coincide con l'inizio di PolyToAdd, non � possibile aggiungere nulla. - Point3d ptLast ; - Poly.GetLastPoint( ptLast) ; - auto it = PolyToAddList.begin() ; - if ( Poly.GetPointNbr() != 0 && ! AreSamePointEpsilon( it->first, ptLast, 10 * EPS_SMALL)) - return false ; - /*if ( Poly.GetPointNbr() == 0) - Poly.AddUPoint( 0., it->first) ; - ++ it ;*/ - // Aggiungo i punti. - for ( ; it != PolyToAddList.end() ; ++ it) { - Poly.AddUPoint( 0., it->first) ; - } - return true ; -} - -////---------------------------------------------------------------------------- -//struct PositionOnPolyLine { -// int nIndexInVec ; -// int nSegNum ; -// double dParOnSeg ; -// PositionOnPolyLine( int nIndex, int nSeg, double dPar) { -// nIndexInVec = nIndex ; -// nSegNum = nSeg ; -// dParOnSeg = dPar ; -// } -//} ; - //---------------------------------------------------------------------------- bool SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet) diff --git a/Tool.cpp b/Tool.cpp index 98d4fbd..613a4c3 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -446,6 +446,11 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, const ICurve* pCurve = m_Outline.GetFirstCurve() ; while ( pCurve != nullptr) { + int nCutTempProp = pCurve->GetTempProp( 1) ; + if ( nCutTempProp == 0) { + m_bAllPartCut = false ; + } + // Se la curva è un arco ed è richiesto la verifica per l'approssimazione, // verifico se approssimarlo if ( m_bApproxWithLines && pCurve->GetType() == CRV_ARC) { @@ -493,6 +498,7 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, m_vArcNormals.emplace_back( vtExtN) ; int nCvCount = m_ArcLineApprox.GetCurveCount() ; m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, int( m_vArcNormals.size()) - 1) ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; } } // altrimenti lo aggiungo semplicemente @@ -500,11 +506,15 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, m_ArcLineApprox.AddCurve( *pCurve, true) ; int nCvCount = m_ArcLineApprox.GetCurveCount() ; m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, - 1) ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; } } // altrimenti è segmento e lo aggiungo semplicemente - else + else { m_ArcLineApprox.AddCurve( *pCurve, true) ; + int nCvCount = m_ArcLineApprox.GetCurveCount() ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; + } pCurve = m_Outline.GetNextCurve() ; } diff --git a/Tool.h b/Tool.h index d96a5c5..501bc1b 100644 --- a/Tool.h +++ b/Tool.h @@ -61,6 +61,8 @@ class Tool { return ( m_ArcLineApprox.GetCurveCount() == 0 ? m_Outline : m_ArcLineApprox) ; } const VCT3DVECTOR& GetArcNormalVec( void) const { return m_vArcNormals ; } + bool GetCuttingFlag() const + { return m_bAllPartCut ; } public : enum ToolType { UNDEF = 0, // Utensile indefinito diff --git a/VolZmap.h b/VolZmap.h index 60736da..00d29a8 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -306,12 +306,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW // Asportazioni superfici elementari vuote bool SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; /*bool SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad, bool bTapB, bool bTapT) ; bool SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad, bool bTapB, bool bTapT) ;*/ bool SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, - double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) ; + double dHei, double dRad, bool bOuterCutter) ; bool SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) ; bool SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, @@ -321,6 +324,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; bool SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfSpherePart_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dInfH, double dSupH, bool bOuterCutter) ; // Intersezioni @@ -355,6 +363,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW // Intersezioni 2 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*public:*/ + int IntersLineCircCrown( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dMaxRad, double dMinRad, + Point3d& ptInt, Vector3d& vtN) const ; int IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir, const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2, bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 6dd268f..6fba426 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1718,6 +1718,7 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -1734,19 +1735,33 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c vtNormEn.ToLoc( frNormFrame) ; } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; + // Cilindro o cono if ( dHeight > EPS_SMALL) { // Se X costante, è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) + if ( dRadius > 10 * EPS_SMALL && m_Tool.GetCuttingFlag()) CompCyl_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } // Se X crescente, è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp(1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormEn, vtNormSt) ; + } + } } // Se X decrescente, è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { @@ -1756,7 +1771,26 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormEn, vtNormSt) ; + else { + vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ; + SurfConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormSt, vtNormEn) ; + } + } + } + } + // Corona circolare + else if ( m_Tool.GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_ZDrilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_ZDrilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; } } } @@ -1775,11 +1809,11 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; // Passo alla curva successiva del profilo @@ -1810,6 +1844,7 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -1826,19 +1861,41 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co vtNormEn.ToLoc( frNormFrame) ; } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { // Se X costante, è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) - CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + if ( dRadius > 10 * EPS_SMALL) { + if ( m_Tool.GetCuttingFlag()) + CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfCyl_ZMilling( nGrid, ptS, ptE, vtToolDir, dHeight, dRadius, true) ; + else { + SurfCyl_ZMilling( nGrid, ptS, ptE, - vtToolDir, dHeight, dRadius, false) ; + } + } + } } // Se X crescente, è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormEn, vtNormSt) ; + } + } } // Se X decrescente, è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { @@ -1848,9 +1905,27 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormSt, vtNormEn) ; + } + } } } + else if ( m_Tool.GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_ZMilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_ZMilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } + } } // se altrimenti arco @@ -1867,11 +1942,11 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; // Passo alla curva successiva del profilo @@ -2917,6 +2992,124 @@ VolZmap::Chs_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V // ---------- Utensile generico ---------------------------------------------- //---------------------------------------------------------------------------- +//bool +//VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) +//{ +// // Descrizione geometrica del moto +// Point3d ptI = ptS ; +// Point3d ptF = ptE ; +// Vector3d vtMove = ptE - ptS ; +// // Vettore delle normali agli archi +// const VCT3DVECTOR& vArcNorm = m_Tool.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 = m_Tool.GetApproxOutline() ; +// int i = - 1 ; +// const ICurve* pPrevCurve = nullptr ; +// const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; +// while ( pCurve != nullptr) { +// +// 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 = false ; +// 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 = true ; +// } +// // Verifiche curva successiva per eventuale tappo sotto +// bool bTapB = false ; +// 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 = true ; +// } +// // Se X costante, è un cilindro +// if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { +// double dRadius = ptStart.x ; +// if ( dRadius > 10 * EPS_SMALL) +// CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; +// } +// // Se X crescente, è un cono con vettore equiverso a quello dell'utensile +// else if ( ptStart.x > ptEnd.x) { +// double dMaxRad = ptStart.x ; +// double dMinRad = ptEnd.x ; +// CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; +// } +// // Se X decrescente, è un cono con vettore opposto a quello dell'utensile +// else if ( ptStart.x < ptEnd.x) { +// double dMaxRad = ptEnd.x ; +// double dMinRad = ptStart.x ; +// Point3d ptIn = ptI - vtToolDir * dHeight ; +// Point3d ptFn = ptIn + vtMove ; +// vtNormEn.z *= -1 ; +// vtNormSt.z *= -1 ; +// CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; +// } +// // 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 - vtToolDir * ( ptStart.y - ptCen.y) ; +// Point3d ptCenE = ptCenS + vtMove ; +// // Eseguo l'asportazione del materiale +// CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; +// // 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 +// ptI = ptI - vtToolDir * dHeight ; +// ptF = ptI + vtMove ; +// } +// +// return true ; +//} bool VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { @@ -2938,6 +3131,7 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -2954,7 +3148,8 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co vtNormEn.ToLoc(frNormFrame); } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { // Verifiche curva precedente per eventuale tappo sopra bool bTapT = false ; @@ -2978,14 +3173,26 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Se X costante, è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) + if ( dRadius > 10 * EPS_SMALL && m_Tool.GetCuttingFlag()) CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; } // Se X crescente, è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapB, bTapT, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapT, bTapB, vtNormEn, vtNormSt) ; + } + } } // Se X decrescente, è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { @@ -2995,16 +3202,27 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapT, bTapB, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapB, bTapT, vtNormSt, vtNormEn) ; + } + } + } - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = pNextCurve ; } - else { - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + else if ( m_Tool.GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_Drilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_Drilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } } } @@ -3022,15 +3240,16 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; + + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = ToolProfile.GetCurve( ++ i) ; } return true ; @@ -3058,7 +3277,7 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con while ( pCurve != nullptr) { double dHeight = 0 ; - + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { // Recupero gli estremi @@ -3074,7 +3293,8 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con vtNormEn.ToLoc(frNormFrame); } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { // verifiche curva precedente per eventuale tappo sopra bool bTapT = true ; @@ -3098,14 +3318,34 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con // Se X costante, è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) - CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + if ( dRadius > 10 * EPS_SMALL) { + if ( m_Tool.GetCuttingFlag()) + CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, true, bTapB, bTapT) ; + else + SurfCyl_Milling( nGrid, ptI, ptF, - vtToolDir, dHeight, dRadius, false, bTapB, bTapT) ; + } + } } // Se X crescente, è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapB, bTapT, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapT, bTapB, vtNormEn, vtNormSt) ; + } + } } // Se X decrescente, è un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { @@ -3115,16 +3355,26 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + if ( m_Tool.GetCuttingFlag()) + CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptI.y > ptF.y) + SurfConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapT, bTapB, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapB, bTapT, vtNormSt, vtNormEn) ; + } + } } - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = pNextCurve ; } - else { - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + else if ( m_Tool.GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_Milling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_Milling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } } } @@ -3142,15 +3392,16 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con // Eseguo l'asportazione del materiale CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; + + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = ToolProfile.GetCurve( ++ i) ; } return true ; @@ -4650,6 +4901,37 @@ VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, // Superfici ausiliarie +//---------------------------------------------------------------------------- +// Calcola l'intersezione di una retta, descritta da punto iniziale ptLineP e versore della direzione +// vtLineDir, e la superficie definita da una corona circolare nello spazio, descritta dal centro delle +// circonferenze di frontiera, dal versore del loro asse di simmetria rotazionale e dai loro raggi. +// Il versore normale alla superficie coincide con quello dell'asse di simmetria e quello vtN +// dell'intersezione è opposto ad'esso. +int +VolZmap::IntersLineCircCrown( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dMaxRad, double dMinRad, + Point3d& ptInt, Vector3d& vtN) const +{ + // Definisco il versore normale al piano e il piano stesso. + Plane3d plMyPlane ; + Vector3d vtPlaneN = vtAx ; + if ( ! vtPlaneN.Normalize() || ! plMyPlane.Set( ptCen, vtPlaneN)) + return 0 ; + + // Intersezione retta piano + int nIntType = IntersLinePlane( ptLineP, vtLineDir, 1000, plMyPlane, ptInt, false) ; + if ( nIntType == ILPT_YES /* || nIntType == ILPT_START || nIntType == ILPT_END*/) { + // Se il punto d'intersezione sta nella corona + double dSqIntCenDist = ( ptInt - ptCen) * ( ptInt - ptCen) ; + if ( dSqIntCenDist > dMinRad * dMinRad && dSqIntCenDist > dMaxRad * dMaxRad) { + vtN = - vtAx ; + return 1 ; + } + } + + return 0 ; +} + //---------------------------------------------------------------------------- // Calcola l'intersezione di una retta, descritta da punto iniziale ptLineP e versore della // direzione vtLineDir, e la superficie definita da un parallelogramma nello spazio, descritto da un punto @@ -4690,6 +4972,7 @@ VolZmap::IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLine // Oppure crei poliline e chiami la funzione per testare se // un punto è interno o meno a una polyline chiusa e piana. } + return 0 ; } @@ -5057,7 +5340,7 @@ VolZmap::SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& { // Verifica sull'interferenza utensile Zmap int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMaxRad, 1, nStartI, nStartJ, nEndI, nEndJ)) return true ; // Se il movimento è in direzione opposta a quella ove la corona può tagliare, non devo fare nulla. @@ -5082,10 +5365,10 @@ VolZmap::SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& Vector3d vtMinN, vtMaxN ; if ( ptE.z < ptS.z) { vtMinN.z = 1 ; - vtMaxN; + vtMaxN.z = 1 ; } else { - vtMinN; + vtMinN.z = - 1 ; vtMaxN.z = - 1 ; } } @@ -5095,6 +5378,238 @@ VolZmap::SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Se il movimento è in direzione opposta a quella ove la corona può tagliare, non devo fare nulla. + double dMotProjOnAx = vtAx * ( ptE - ptS) ; + if ( dMotProjOnAx < EPS_ZERO) + return true ; + + // Vettore di piani fittizio + vector vEmptyPlaneVec ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro esterno + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, dMotProjOnAx, false, vEmptyPlaneVec, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro interno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMinRad, dMotProjOnAx, true, vEmptyPlaneVec, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptS, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptE, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + return SurfCircCrown_Milling( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad) ; + // Verifica sull'interferenza utensile Zmap + //int nStartI, nStartJ, nEndI, nEndJ ; + //if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + // return true ; + // + //Vector3d vtDisp = ptE - ptS ; + // + //// Se il movimento è in direzione opposta a quella ove la corona può tagliare, non devo fare nulla. + //if ( vtAx.z * vtDisp.z < EPS_ZERO) + // return true ; + // + //// Sistema di riferimento piano del moto + //Point3d ptSXY( ptS.x, ptS.y, 0) ; + //Vector3d vtV1( vtDisp.x, vtDisp.y, 0) ; + //double dDispLenXY = vtV1.Len() ; + //vtV1 /= dDispLenXY ; + //Vector3d vtV2 = Z_Ax ^ vtV1 ; + // + //// Ciclo sui dexel. + //for ( int i = nStartI ; i <= nEndI ; ++ i) { + // for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + // Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + // Vector3d vtR = ptC - ptSXY ; + // double dR1 = vtR * vtV1 ; + // double dR2 = vtR * vtV2 ; + // double dCircMin1 = sqrt( max( d)) ; + // double dSqLenR = vtR * vtR ; + // if ( dSqLenR > dSqSafeMinRad && dSqLenR < dSqSafeMaxRad) { + // double dMinZ = min( ptS.z, ptE.z) ; + // double dMaxZ = max( ptS.z, ptE.z) ; + // Vector3d vtMinN, vtMaxN ; + // if ( ptE.z < ptS.z) { + // vtMinN.z = 1 ; + // vtMaxN.z = 1 ; + // } + // else { + // vtMinN.z = - 1 ; + // vtMaxN.z = - 1 ; + // } + // } + // } + //} + // + //return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMaxRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Se il movimento è in direzione opposta a quella ove la corona può tagliare, non devo fare nulla. + Vector3d vtDisp = ( ptE - ptS) ; + double dMotProjOnAx = vtAx * vtDisp ; + if ( dMotProjOnAx < EPS_ZERO) + return true ; + + // Vettore di piani fittizio + vector vEmptyPlaneVec ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro ellittico esterno + int nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, false, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico interno + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMinRad, vtDisp, true, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptS, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptE, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + + return true ; +} + // Cilindro //---------------------------------------------------------------------------- //bool @@ -5114,25 +5629,25 @@ VolZmap::SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& //---------------------------------------------------------------------------- bool -VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, - double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) +VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dRad, bool bOuterCutter) { // Verifica sull'interferenza utensile Zmap int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) return true ; // Vettore spostamento Vector3d vtDisp = ptE - ptS ; // Dimensioni del moto nella direzione utensile e ortogonale e quote iniziali e finali - double dDispZ = vtDisp * vtToolDir ; + double dDispZ = vtDisp * vtAx ; double dDispXY = sqrt( max( vtDisp.SqLen() - dDispZ * dDispZ, 0.)) ; double dStartTopZ = ptS.z ; - double dStartBotZ = ( ptS - dHei * vtToolDir).z ; + double dStartBotZ = ( ptS - dHei * vtAx).z ; // Sistema di riferimento del moto - Vector3d vtV3 = vtToolDir ; + Vector3d vtV3 = vtAx ; Vector3d vtV1 = vtDisp - dDispZ * vtV3 ; vtV1.Normalize() ; Vector3d vtV2 = vtV3 ^ vtV1 ; Point3d ptSxy( ptS.x, ptS.y, 0) ; @@ -5152,24 +5667,12 @@ VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Vector3d vtRad = dCirc1 * vtV1 + dProj2 * vtV2 ; Vector3d vtTan( - vtRad.y, vtRad.x, 0) ; Vector3d vtCross = vtTan ^ vtDisp ; - Vector3d vtSup = ( vtCross * vtToolDir > 0 ? - vtCross : vtCross) ; - vtSup.Normalize() ; - Vector3d vtInf = - vtSup ; - // Quote inferiore e superiore rispetto al sistema griglia e versori normali associati - double dMin, dMax ; - Vector3d vtMax, vtMin ; - if ( vtToolDir.z > 0) { - dMin = dInfZ ; - dMax = dSupZ ; - vtMax = vtSup ; - vtMin = vtInf ; - } - else { - dMin = dSupZ ; - dMax = dInfZ ; - vtMax = vtInf ; - vtMin = vtSup ; - } + vtCross.Normalize() ; + // Quote minima e massima rispetto al sistema griglia e versori normali associati + double dMin = vtAx.z > 0 ? dInfZ : dSupZ ; + double dMax = vtAx.z > 0 ? dSupZ : dInfZ ; + Vector3d vtMin = bOuterCutter ? - vtCross : vtCross ; + Vector3d vtMax = bOuterCutter ? vtCross : - vtCross ; // Taglio dei dexel SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; } @@ -5182,21 +5685,26 @@ VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co //---------------------------------------------------------------------------- bool VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, - const Vector3d& vtToolDir, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) + const Vector3d& vtAx, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) { // Verifica sull'interferenza utensile Zmap int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) return true ; // Vettore spostamento Vector3d vtDisp = ptE - ptS ; // Versore della componente del moto ortogonale all'asse dell'utensile - double dDispZ = vtDisp * vtToolDir ; - Vector3d vtOrtDisp = vtDisp - dDispZ * vtToolDir ; + double dDispZ = vtDisp * vtAx ; + Vector3d vtOrtDisp = vtDisp - dDispZ * vtAx ; vtOrtDisp.Normalize() ; - + // Versore direzione del moto + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + // Versore laterale + Vector3d vtLat = vtAx ^ vtOrtDisp ; + // Definisco i piani utilizzati per tagliare le superfici elementari. // Piano per cilindro in posizione iniziale vector vCutCylPlaneVecSt ; @@ -5206,46 +5714,30 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, vector vCutCylPlaneVecEn ; vCutCylPlaneVecEn.emplace_back() ; vCutCylPlaneVecEn.back().Set( ptE, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; - // Piani per cilindro ellittico superiore + // Piano per cilindro ellittico superiore vector vCutEllipCylPlaneVecUp ; if ( dDispZ > 0) { - Vector3d vtDispDir = vtDisp ; - vtDispDir.Normalize() ; - Vector3d vtRadial = vtToolDir ^ vtDisp ; - vtRadial.Normalize() ; vCutEllipCylPlaneVecUp.emplace_back() ; - vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtRadial) ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtLat) ; } else { - Vector3d vtDispDir = vtDisp ; - vtDispDir.Normalize() ; - Vector3d vtRadial = vtToolDir ^ vtDisp ; - vtRadial.Normalize() ; vCutEllipCylPlaneVecUp.emplace_back() ; - vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtRadial ^ vtDispDir) ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? - 1 : 1) * vtDispDir ^ vtLat) ; } // Piani per cilindro ellittico inferiore vector vCutEllipCylPlaneVecDw ; if ( dDispZ > 0) { - Vector3d vtDispDir = vtDisp ; - vtDispDir.Normalize() ; - Vector3d vtRadial = vtToolDir ^ vtDisp ; - vtRadial.Normalize() ; vCutEllipCylPlaneVecDw.emplace_back() ; - vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtToolDir, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtRadial) ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtLat) ; } else { - Vector3d vtDispDir = vtDisp ; - vtDispDir.Normalize() ; - Vector3d vtRadial = vtToolDir ^ vtDisp ; - vtRadial.Normalize() ; vCutEllipCylPlaneVecDw.emplace_back() ; - vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtToolDir, ( bOuterCutter ? 1 : - 1) * vtRadial ^ vtDispDir) ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx, ( bOuterCutter ? - 1 : 1) * vtDispDir ^ vtLat) ; } // Deduzione dei punti per la definizione dei piani laterali - Point3d ptPlanePlus = ptS - dHei * vtToolDir + dRad * ( vtToolDir ^ vtOrtDisp) ; - Point3d ptPlaneMinus = ptS - dHei * vtToolDir - dRad * ( vtToolDir ^ vtOrtDisp) ; + Point3d ptPlanePlus = ptS - dHei * vtAx + dRad * vtLat ; + Point3d ptPlaneMinus = ptS - dHei * vtAx - dRad * vtLat ; for ( int i = nStartI ; i <= nEndI ; ++ i) { for ( int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -5257,7 +5749,7 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, Vector3d vtN1, vtN2 ; // Intersezione con cilindro in posizione iniziale - int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dRad, - dHei, false, vCutCylPlaneVecSt, + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dRad, - dHei, ! bOuterCutter, vCutCylPlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5271,7 +5763,7 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con cilindro in posizione finale - nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dRad, - dHei, false, vCutCylPlaneVecEn, + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, vtAx, dRad, - dHei, ! bOuterCutter, vCutCylPlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5285,7 +5777,7 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con cilindro ellittico superiore - nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dRad, vtDisp, true, vCutEllipCylPlaneVecUp, + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dRad, vtDisp, bOuterCutter == dDispZ > 0, vCutEllipCylPlaneVecUp, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5299,7 +5791,7 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con cilindro ellittico inferiore - nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dRad, vtDisp, false, vCutEllipCylPlaneVecDw, + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dRad, vtDisp, bOuterCutter != dDispZ > 0, vCutEllipCylPlaneVecDw, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5312,8 +5804,8 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, } } - // Piano + (con normale + vtToolDir ^ vtOrtDisp) - nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtToolDir, vtDisp, + // Piano + (con normale + vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtAx, vtDisp, true, ptInt1, vtN1) ; if ( nIntNum == 1) { vParAndNormIntersVec.emplace_back() ; @@ -5321,8 +5813,8 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, vParAndNormIntersVec.back().second = vtN1 ; } - // Piano - (con normale - vtToolDir ^ vtOrtDisp) - nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtToolDir, vtDisp, + // Piano - (con normale - vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtAx, vtDisp, false, ptInt1, vtN1) ; if ( nIntNum == 1) { vParAndNormIntersVec.emplace_back() ; @@ -5351,20 +5843,20 @@ VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, // Cono //---------------------------------------------------------------------------- bool -VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, +VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) { // Verifica sull'interferenza con lo Zmap int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) return true ; // Raggi di sicurezza per evitare di tagliare i dexel a filo del bordo dela regione interessata dal taglio. double dSqSafeMinRad = dMinRad * dMinRad + 2 * dMinRad * EPS_SMALL ; double dSqSafeMaxRad = dMaxRad * dMaxRad - 2 * dMaxRad * EPS_SMALL ; - if ( ( vtToolDir.z * ( ptE.z - ptS.z) > 0 && bOuterCutter) || - ( vtToolDir.z * ( ptE.z - ptS.z) < 0 && ! bOuterCutter)) + // Se il movimento è nella direzione ove il cono non taglia, ho finito. + if ( vtAx.z * ( ptE.z - ptS.z) > 0 == bOuterCutter) return true ; // Ciclo sui punti @@ -5378,7 +5870,7 @@ VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, if ( dR < dSqSafeMinRad || dR > dSqSafeMaxRad) continue ; - if ( vtToolDir.z > 0) { + if ( vtAx.z > 0) { double dr = sqrt( dR) ; // Quote Z double dMinZ = min( ptS.z, ptE.z) - dHei + ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; @@ -5387,23 +5879,29 @@ VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, Vector3d vtMinN, vtMaxN ; if ( bOuterCutter) { double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; - Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtToolDir ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; Point3d ptIntMinP( dX, dY, dMinZ) ; Vector3d vtIntMinV = ptIntMinP - ptVertE ; - double dCompLong = vtIntMinV * vtToolDir ; - Vector3d vtIntMinLongV = dCompLong * vtToolDir ; + double dCompLong = vtIntMinV * vtAx ; + Vector3d vtIntMinLongV = dCompLong * vtAx ; Vector3d vtIntMinOrtV = vtIntMinV - vtIntMinLongV ; - vtMinN = - vtIntMinOrtV + dCompLong * vtToolDir ; + double dCompOrt = vtIntMinOrtV.Len() ; + vtIntMinOrtV /= dCompOrt ; + vtMinN = - dCompLong * vtIntMinOrtV + dCompOrt * vtAx ; + vtMaxN = vtMinN ; } else { double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; - Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtToolDir ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; Point3d ptIntMaxP( dX, dY, dMaxZ) ; Vector3d vtIntMaxV = ptIntMaxP - ptVertE ; - double dCompLong = vtIntMaxV * vtToolDir ; - Vector3d vtIntMaxLongV = dCompLong * vtToolDir ; + double dCompLong = vtIntMaxV * vtAx ; + Vector3d vtIntMaxLongV = dCompLong * vtAx ; Vector3d vtIntMaxOrtV = vtIntMaxV - vtIntMaxLongV ; - vtMaxN = vtIntMaxOrtV - dCompLong * vtToolDir ; + double dCompOrt = vtIntMaxOrtV.Len() ; + vtIntMaxOrtV /= dCompOrt ; + vtMaxN = - dCompLong * vtIntMaxOrtV + dCompOrt * vtAx ; + vtMinN = vtMaxN ; } } else { @@ -5415,23 +5913,29 @@ VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, Vector3d vtMinN, vtMaxN; if ( bOuterCutter) { double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; - Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtToolDir ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; Point3d ptIntMaxP( dX, dY, dMaxZ) ; Vector3d vtIntMaxV = ptIntMaxP - ptVertE ; - double dCompLong = vtIntMaxV * vtToolDir ; - Vector3d vtIntMaxLongV = dCompLong * vtToolDir ; + double dCompLong = vtIntMaxV * vtAx ; + Vector3d vtIntMaxLongV = dCompLong * vtAx ; Vector3d vtIntMaxOrtV = vtIntMaxV - vtIntMaxLongV ; - vtMaxN = - vtIntMaxOrtV + dCompLong * vtToolDir ; + double dCompOrt = vtIntMaxOrtV.Len() ; + vtIntMaxOrtV /= dCompOrt ; + vtMaxN = - dCompLong * vtIntMaxOrtV + dCompOrt * vtAx ; + vtMinN = vtMaxN ; } else { double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; - Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtToolDir ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; Point3d ptIntMinP( dX, dY, dMinZ) ; Vector3d vtIntMinV = ptIntMinP - ptVertE ; - double dCompLong = vtIntMinV * vtToolDir ; - Vector3d vtIntMinLongV = dCompLong * vtToolDir ; + double dCompLong = vtIntMinV * vtAx ; + Vector3d vtIntMinLongV = dCompLong * vtAx ; Vector3d vtIntMinOrtV = vtIntMinV - vtIntMinLongV ; - vtMinN = vtIntMinOrtV - dCompLong * vtToolDir ; + double dCompOrt = vtIntMinOrtV.Len() ; + vtIntMinOrtV /= dCompOrt ; + vtMinN = - dCompLong * vtIntMinOrtV + dCompOrt * vtAx ; + vtMaxN = vtMinN ; } } } @@ -5442,32 +5946,33 @@ VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, //---------------------------------------------------------------------------- bool -VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, +VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) { int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) return true ; - // Vettore spostamento + // Vettore spostamento e sua componente lungo l'asse del cono Vector3d vtDisp = ptE - ptS ; + double dDispLong = vtAx * vtDisp ; - bool bToolVecAndDispAreOpposite = vtToolDir * vtDisp < 0 ; - if ( ( ! bToolVecAndDispAreOpposite && bOuterCutter) || - ( bToolVecAndDispAreOpposite && ! bOuterCutter)) + // Se lo spostamento è in direzione opposta a quella ove il cono taglia, ho finito. + bool bToolVecAndDispAreOpposite = dDispLong < 0 ; + if ( bToolVecAndDispAreOpposite != bOuterCutter) return true ; // Vertici cono iniziale e finale double dDeltaHei = ( dMinRad * dHei) / ( dMaxRad - dMinRad) ; - Point3d ptVs = ptS - ( dHei + dDeltaHei) * vtToolDir ; - Point3d ptVe = ptE - ( dHei + dDeltaHei) * vtToolDir ; + Point3d ptVs = ptS - ( dHei + dDeltaHei) * vtAx ; + Point3d ptVe = ptE - ( dHei + dDeltaHei) * vtAx ; // Piani per tagliare le superfici elementari. vector vCutConePlaneVecSt ; vCutConePlaneVecSt.emplace_back() ; - vCutConePlaneVecSt.back().Set( ptS - dHei * vtToolDir, - vtToolDir) ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtAx, - vtAx) ; vector vCutConePlaneVecEn ; vCutConePlaneVecEn.emplace_back() ; - vCutConePlaneVecEn.back().Set( ptE - dHei * vtToolDir, - vtToolDir) ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtAx, - vtAx) ; vector vEmptyPlaneVec ; // Ciclo sui punti @@ -5481,8 +5986,8 @@ VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, Vector3d vtN1, vtN2 ; // Intersezione con il cono in posizione iniziale - int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMaxRad, dHei, true, - vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVs, vtAx, dMaxRad, dHei + dDeltaHei, ! bToolVecAndDispAreOpposite, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; vParAndNormIntersVec.back().first = ptInt1.z ; @@ -5495,7 +6000,7 @@ VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con il cono in posizione finale - nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE - dHei * vtToolDir, vtToolDir, dMaxRad, dHei, true, + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVe, vtAx, dMaxRad, dHei + dDeltaHei, ! bToolVecAndDispAreOpposite, vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5509,7 +6014,7 @@ VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con il cilindro esterno - nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, ( bToolVecAndDispAreOpposite ? - 1 : 1) * dHei, true, + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, dDispLong, false, vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5523,7 +6028,7 @@ VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } // Intersezione con il cilindro interno - nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS/* - dHei * vtToolDir*/, vtToolDir, dMinRad, ( bToolVecAndDispAreOpposite ? - 1 : 1) * dHei, true, + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMinRad, dDispLong, true, vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; if ( nIntNum >= 1) { vParAndNormIntersVec.emplace_back() ; @@ -5555,26 +6060,28 @@ VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } //---------------------------------------------------------------------------- -/*bool -VolZmap::SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, +bool +VolZmap::SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) { - int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) - return true ; + return SurfConus_Milling( nGrid, ptS, ptE, vtAx, dHei, dMaxRad, dMinRad, bOuterCutter, true, true, vtArcNormMaxR, vtArcNormMinR) ; - // Descrizione del moto - Point3d ptSXY( ptS.x, ptS.y, 0) ; - Vector3d vtDisp = ptE - ptS ; - double dDispLong = vtDisp * vtToolDir ; - Vector3d vtDispXY( vtDisp.x, vtDisp.y, 0) ; // = vtDisp - dDispLong * vtToolDir; - double dDispOrt = vtDispXY.Len(); - vtDispXY /= dDispOrt ; - double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; - double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; - double dCosTheta = ( dTanAlpha * vtDisp * vtToolDir) / ( vtDisp * vtDispXY) ; - bool bElevation = dDispLong > 0 ; - bool bLimPassed = dCosTheta > 1 ; + //int nStartI, nStartJ, nEndI, nEndJ ; + //if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + // return true ; + // + //// Descrizione del moto + //Point3d ptSXY( ptS.x, ptS.y, 0) ; + //Vector3d vtDisp = ptE - ptS ; + //double dDispLong = vtDisp * vtToolDir ; + //Vector3d vtDispXY( vtDisp.x, vtDisp.y, 0) ; // = vtDisp - dDispLong * vtToolDir; + //double dDispOrt = vtDispXY.Len(); + //vtDispXY /= dDispOrt ; + //double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; + //double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; + //double dCosTheta = ( dTanAlpha * vtDisp * vtToolDir) / ( vtDisp * vtDispXY) ; + //bool bElevation = dDispLong > 0 ; + //bool bLimPassed = dCosTheta > 1 ; //// Ciclo sui punti //for ( int i = nStartI ; i <= nEndI ; ++ i) { @@ -5619,39 +6126,45 @@ VolZmap::SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, //} return true ; -}*/ +} //---------------------------------------------------------------------------- -/*bool -VolZmap::SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, - double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT, +bool +VolZmap::SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) { // Verifico interferenza int nStartI, nStartJ, nEndI, nEndJ ; - if ( ! TestCompoBBox( nGrid, ptS, ptE, vtToolDir, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) return true ; // Vettore spostamento Vector3d vtDisp = ptE - ptS ; // Spostamento nella direzione utensile e in quella ortogonale - double dDispProjOnToolDir = vtDisp * vtToolDir ; - Vector3d vtDispLong = dDispProjOnToolDir * vtToolDir ; + double dDispProjOnAxDir = vtDisp * vtAx ; + Vector3d vtDispLong = dDispProjOnAxDir * vtAx ; Vector3d vtDispOrt = vtDisp - vtDispLong ; // Terna di riferimento del movimento - Vector3d vtV1 = vtDispOrt ; vtV2.Normalize() ; - Vector3d vtV2 = vtToolDir ^ vtV1 ; - Vector3d vtV3 = vtToolDir ; + Vector3d vtV1 = vtDispOrt ; vtV1.Normalize() ; + Vector3d vtV2 = vtAx ^ vtV1 ; + Vector3d vtV3 = vtAx ; // Parametri geometrici descriventi il cono e il moto double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; - double dCosTheta = ( dTanAlpha * vtDisp * vtToolDir) / ( vtDisp * vtDispXY) ; + double dCosTheta = ( dTanAlpha * vtDisp * vtV3) / ( vtDisp * vtV1) ; double dSinTheta = sqrt( max( 1 - dCosTheta * dCosTheta, 0.)) ; - bool bLimPassed = dCosTheta > 1 ; + bool bLimPassed = abs( dCosTheta) > 1 ; + + // Se il movimento non è compatibile con il verso delle normali, ho finito. + if ( bLimPassed && ( bOuterCutter == dDispProjOnAxDir > 0)) + return true ; + // Vertici del cono nelle posizioni iniziale e finale - Point3d ptVertSt = ptS - dHei * vtToolDir ; - Point3d ptVertEn = ptE - dHei * vtToolDir ; + Point3d ptVertSt = ptS - ( dHei + dDeltaHei) * vtAx ; + Point3d ptVertEn = ptE - ( dHei + dDeltaHei) * vtAx ; + // Vettori radiali per definire i piani Vector3d vtRadPlus = dCosTheta * vtV1 + dSinTheta * vtV2 ; Vector3d vtRadMinus = dCosTheta * vtV1 - dSinTheta * vtV2 ; @@ -5660,215 +6173,630 @@ VolZmap::SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, c // Piani per cono in posizione iniziale vector vCutConePlaneVecSt ; vCutConePlaneVecSt.emplace_back() ; - vCutConePlaneVecSt.back().Set( ptS - dHei * vtToolDir, - vtToolDir) ; - Vector3d vtConePlaneNormSt = ( ptS + vtRadPlus - ptVertSt) ^ ( ptS + vtRadMinus - ptVertSt) ; vtConePlaneNormSt.Normalize() ; - vCutConePlaneVecSt.emplace_back() ; - vCutConePlaneVecSt.back().Set( ptVertSt, vtConePlaneNormSt) ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtAx, - vtAx) ; // Piani per cono in posizione finale vector vCutConePlaneVecEn ; vCutConePlaneVecEn.emplace_back() ; - vCutConePlaneVecEn.back().Set( ptE - dHei * vtToolDir, - vtToolDir) ; - vCutConePlaneVecEn.emplace_back() ; - Vector3d vtConePlaneNormEn = ( ptE + vtRadPlus - ptVertEn) ^ ( ptE + vtRadMinus - ptVertEn) ; vtConePlaneNormEn.Normalize() ; - vCutConePlaneVecEn.back().Set( ptVertEn, vtConePlaneNormEn) ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtAx, - vtAx) ; // Piani per cilindro ellittico superiore - vector vCutEllipCylPlaneVecUpSt ; - vCutEllipCylPlaneVecUpSt.emplace_back() ; - vCutEllipCylPlaneVecUpSt.back(); - vCutEllipCylPlaneVecUpSt.emplace_back() ; - vCutEllipCylPlaneVecUpSt.back(); - vCutEllipCylPlaneVecUpSt.emplace_back() ; - vCutEllipCylPlaneVecUpSt.back(); + vector vCutEllipCylPlaneVecUp ; // Piani per cilindro ellittico inferiore - vector vCutEllipCylPlaneVecUpEn ; - vCutEllipCylPlaneVecUpEn.emplace_back() ; - vCutEllipCylPlaneVecUpEn.back(); - vCutEllipCylPlaneVecUpEn.emplace_back() ; - vCutEllipCylPlaneVecUpEn.back(); - vCutEllipCylPlaneVecUpEn.emplace_back() ; - vCutEllipCylPlaneVecUpEn.back(); - // Vettore di piani vuoto - vector vEmptyPlaneVec ; + vector vCutEllipCylPlaneVecDw ; + + // Caso di limete oltrepassato + if ( bLimPassed) { - //// Ciclo sui punti - //for ( int i = nStartI ; i <= nEndI ; ++ i) { - // for ( int j = nStartJ ; j <= nEndJ ; ++ j) { - // - // Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - // - // if ( bLimPassed) { - // - // vector> vParAndNormIntersVec ; - // Point3d ptInt1, ptInt2 ; - // Vector3d vtN1, vtN2 ; - // - // // Intersezione con il cono in posizione iniziale - // int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, dHei, true, - // vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con il cono in posizione finale - // nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dMaxRad, dHei, true, - // vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con cilindro ellittico esterno - // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, vtDisp,true, , - // ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con cilindro ellittico interno - // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMinRad, vtDisp, true, vCutEllipCylPlaneVecUpSt, - // ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. - // sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) - // { return Int1.first < Int2.first ; }) ; - // - // // Sottraggo gli intervalli - // double dMyEps = EPS_ZERO ; - // for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { - // if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { - // SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, - // vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; - // } - // } - // } - // else { - // - // vector> vParAndNormIntersVec ; - // Point3d ptInt1, ptInt2 ; - // Vector3d vtN1, vtN2 ; - // - // // Intersezione con il cono in posizione iniziale - // int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, dHei, true, - // vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2); - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con il cono in posizione finale - // nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptE, vtToolDir, dMaxRad, dHei, true, - // vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con cilindro ellittico superiore - // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtToolDir, dMaxRad, vtDisp, , vCutEllipCylPlaneVecUpSt, - // ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Intersezione con cilindro ellittico inferiore - // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtToolDir, vtToolDir, dMinRad, vtDisp, , vCutEllipCylPlaneVecUpSt, - // ptInt1, vtN1, ptInt2, vtN2) ; - // if ( nIntNum >= 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // if ( nIntNum == 2) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt2.z ; - // vParAndNormIntersVec.back().second = vtN2 ; - // } - // } - // - // // Piano + (con normale + vtToolDir ^ vtOrtDisp) - // nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtToolDir, vtDisp, - // true, ptInt1, vtN1) ; - // if ( nIntNum == 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // } - // - // // Piano - (con normale - vtToolDir ^ vtOrtDisp) - // nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtToolDir, vtDisp, - // false, ptInt1, vtN1) ; - // if ( nIntNum == 1) { - // vParAndNormIntersVec.emplace_back() ; - // vParAndNormIntersVec.back().first = ptInt1.z ; - // vParAndNormIntersVec.back().second = vtN1 ; - // } - // - // // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. - // sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) - // { return Int1.first < Int2.first ; }) ; - // - // // Sottraggo gli intervalli - // double dMyEps = EPS_ZERO ; - // for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { - // if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { - // SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, - // vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; - // } - // } - // } - // } - //} + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertSt, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertEn, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico esterno + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, false, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2); + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico interno + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dMinRad, vtDisp, true, vCutEllipCylPlaneVecDw, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), []( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI + 1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI + 1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI + 1].second) ; + } + } + } + } + } + else { + + // Vettore normale ai piani per il nuovo taglio dei coni. + Vector3d vtConePlaneNorm = ( ptS + dMaxRad * vtRadPlus - ptVertSt) ^ ( ptS + dMaxRad * vtRadMinus - ptVertSt) ; vtConePlaneNorm.Normalize() ; + if ( bOuterCutter) + vtConePlaneNorm *= - 1 ; + // Aggiorno vettore di piani per tagliare il cono in posizione iniziale. + vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptVertSt, vtConePlaneNorm) ; + // Aggiorno vettore di piani per tagliare il cono in posizione finale. + vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptVertEn, vtConePlaneNorm) ; + + // Aggiorno il vettore dei piani per tagliare il cilindro ellittico superiore. + Vector3d vtEllipCylPlaneNormUp = vtDisp ^ vtV2 ; vtEllipCylPlaneNormUp.Normalize() ; + if ( bOuterCutter == dDispProjOnAxDir > 0) + vtEllipCylPlaneNormUp *= - 1 ; + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS + dMaxRad * dCosTheta * vtV1, vtEllipCylPlaneNormUp) ; + // Aggiorno il vettore dei piani per tagliare il cilindro ellittico inferiore. + Vector3d vtEllipCylPlaneNormDw = - vtEllipCylPlaneNormUp ; + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx + dMinRad * dCosTheta * vtV1, vtEllipCylPlaneNormDw) ; + + // Punti e normali dei piani laterali + Point3d ptPlanePlusP = ptS - dHei * vtAx + dMinRad * vtRadPlus ; + Point3d ptPlaneMinusP = ptS - dHei * vtAx + dMinRad * vtRadMinus ; + Vector3d vtPlanePlusN = ptS + dMaxRad * vtRadPlus - ptPlanePlusP ; + Vector3d vtPlaneMinusN = ptS + dMaxRad * vtRadPlus - ptPlaneMinusP ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertSt, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertEn, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, bOuterCutter, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dMinRad, vtDisp, ! bOuterCutter, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Piano + (con normale + vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlusP, vtPlanePlusN, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinusP, vtPlaneMinusN, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + } return true ; -}*/ +} + +// Parte di sfera +//---------------------------------------------------------------------------- +bool +VolZmap::SurfSpherePart_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dInfH, double dSupH, bool bOuterCutter) +{ + // Verifico interferisca + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptS, V_NULL, dRad, 0, 0, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + Vector3d vtDispVers = vtDisp ; + double dDispLen = vtDispVers.Len() ; + vtDispVers /= dDispLen ; + + // Prodotto scalare fra versore del movimento e asse della calotta sferica + double dAxDispDot = vtDispVers * vtAx ; + + // Raggi dei cilindri ellittici + double dInfRad = sqrt( max( dRad * dRad - dInfH * dInfH, 0.)) ; + double dSupRad = sqrt( max( dRad * dRad - dSupH * dSupH, 0.)) ; + + // Coseni limite + double dCosInf = dInfRad / dRad ; + double dCosSup = dSupRad / dRad ; + + // Vettore dei piani di taglio della sfera in posizione iniziale + vector vSphereCutPlanesVecSt ; + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS - dSupH * vtAx, vtAx) ; + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS - dInfH * vtAx, - vtAx) ; + // Vettore dei piani di taglio della sfera in posizione finale + vector vSphereCutPlanesVecEn ; + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE - dSupH * vtAx, vtAx) ; + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE - dInfH * vtAx, - vtAx) ; + + if ( abs( dAxDispDot) >= dCosSup) { + + if ( bOuterCutter == dAxDispDot > 0) + return true ; + + // Vettori dei piani di taglio del cilindro ellittico superiore e inferiore + vector vEllipCylCutPlanesVecSup ; + vector vEllipCylCutPlanesVecInf ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, ! bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, false, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, true, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + } + else if ( abs( dAxDispDot) >= dCosInf) { + + // Aggiorno il vettore dei piani di taglio della sfera in posizione iniziale. + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS, bOuterCutter ? - vtDispVers : vtDispVers) ; + // Aggiorno il vettore dei piani di taglio della sfera in posizione finale. + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE, bOuterCutter ? - vtDispVers : vtDispVers) ; + + // Versore della componente del moto perpendicolare all'asse + Vector3d vtOrtDispVers = vtDisp - dAxDispDot * vtAx ; + double dOrtDispLen = vtOrtDispVers.Len() ; + vtOrtDispVers /= dOrtDispLen ; + + // Vettore dei piani di taglio del cilindro ellittico superiore + Vector3d vtPlaneN = - dAxDispDot * vtOrtDispVers + dOrtDispLen * vtAx ; + if ( bOuterCutter != dAxDispDot > 0) + vtPlaneN *= - 1 ; + double dC = vtDispVers * vtAx ; + double dS = sqrt( max( 1 - dC * dC, 0.)) ; + Point3d ptPlaneP = ptS - dSupH * vtAx + ( dC * dSupH / dS) * vtOrtDispVers ; + vector vEllipCylCutPlanesVecSup ; + vEllipCylCutPlanesVecSup.emplace_back() ; + vEllipCylCutPlanesVecSup.back().Set( ptPlaneP, vtPlaneN) ; + + // Vettore dei piani di taglio del cilindro ellittico inferiore + vector vEllipCylCutPlanesVecInf ; + + // Vettore dei piani di taglio del cilindro + vector vCylCutPlanesVec ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneP, bOuterCutter == dAxDispDot > 0 ? vtPlaneN : - vtPlaneN) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, ! bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, bOuterCutter == dAxDispDot > 0, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore, se necessario + if ( bOuterCutter != dAxDispDot > 0) { + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, true, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + } + + // Intersezione con cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, - vtDispVers, dRad, dDispLen, false, + vCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + } + else { + + // Aggiorno il vettore dei piani di taglio della sfera in posizione iniziale. + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS, bOuterCutter ? - vtDispVers : vtDispVers) ; + // Aggiorno il vettore dei piani di taglio della sfera in posizione finale. + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE, bOuterCutter ? - vtDispVers : vtDispVers) ; + + // Versore della componente del moto perpendicolare all'asse + Vector3d vtOrtDispVers = vtDisp - dAxDispDot * vtAx ; + double dOrtDispLen = vtOrtDispVers.Len() ; + vtOrtDispVers /= dOrtDispLen ; + + // Determinazione dei piani di taglio dei cilindri ellittici + Vector3d vtPlaneN = - dAxDispDot * vtOrtDispVers + dOrtDispLen * vtAx ; + if ( bOuterCutter != dAxDispDot > 0) + vtPlaneN *= - 1 ; + double dC = vtDispVers * vtAx ; + double dS = sqrt( max( 1 - dC * dC, 0.)) ; + Point3d ptPlaneSupP = ptS - dSupH * vtAx + ( dC * dSupH / dS) * vtOrtDispVers ; + Point3d ptPlaneInfP = ptS - dInfH * vtAx + ( dC * dInfH / dS) * vtOrtDispVers ; + // Vettore dei piani di taglio del cilindro ellittico superiore + vector vEllipCylCutPlanesVecSup ; + vEllipCylCutPlanesVecSup.emplace_back() ; + vEllipCylCutPlanesVecSup.back().Set( ptPlaneSupP, vtPlaneN) ; + // Vettore dei piani di taglio del cilindro ellittico inferiore + vector vEllipCylCutPlanesVecInf ; + vEllipCylCutPlanesVecInf.emplace_back() ; + vEllipCylCutPlanesVecInf.back().Set( ptPlaneInfP, vtPlaneN) ; + + // Vettore dei piani di taglio del cilindro + vector vCylCutPlanesVec ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneSupP, bOuterCutter == dAxDispDot > 0 ? vtPlaneN : - vtPlaneN) ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneInfP, bOuterCutter == dAxDispDot > 0 ? - vtPlaneN : vtPlaneN) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + vector> vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, ! bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, bOuterCutter == dAxDispDot > 0, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, bOuterCutter != dAxDispDot > 0, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, - vtDispVers, dRad, dDispLen, false, + vCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Riordino le intersezioni in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vParAndNormIntersVec.begin(), vParAndNormIntersVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + // Sottraggo gli intervalli + double dMyEps = EPS_ZERO ; + for ( int nI = 0 ; nI < int( vParAndNormIntersVec.size()) - 1 ; ++ nI) { + if ( vParAndNormIntersVec[nI].second.z < - dMyEps && vParAndNormIntersVec[nI+1].second.z > dMyEps) { + SubtractIntervals( nGrid, i, j, vParAndNormIntersVec[nI].first, vParAndNormIntersVec[nI+1].first, + vParAndNormIntersVec[nI].second, vParAndNormIntersVec[nI+1].second) ; + } + } + } + } + } + + return true ; +} // ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------