From faa2004c298ad6a2d3e35c61fbf893cdf7beb779 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Mon, 22 Apr 2024 13:21:37 +0200 Subject: [PATCH] EgtGeomKernel : - integrate modifiche vMill additivo dal ramo TempForVmill. --- Tool.cpp | 83 +++ Tool.h | 4 +- VolZmap.cpp | 19 + VolZmap.h | 11 + VolZmapCreation.cpp | 96 +++- VolZmapVolume.cpp | 1243 +++++++++++++++++++++++++++++++++---------- 6 files changed, 1171 insertions(+), 285 deletions(-) diff --git a/Tool.cpp b/Tool.cpp index 46b5756..0c4fd11 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -580,3 +580,86 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, return true ; } + +//---------------------------------------------------------------------------- +bool +Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) +{ + // Impostazioni generali + m_sName = sToolName ; + m_nCurrentNum = nToolNum ; + m_nType = UNDEF ; + m_Outline.Clear() ; + m_ArcLineApprox.Clear() ; + + // verifica sulle minime dimensioni globali + if ( dH < EPS_SMALL || dR < EPS_SMALL || dRC < - EPS_SMALL) + return false ; + + m_dHeight = dH ; + m_dRadius = dR ; + m_dRCorner = dRC ; + m_dTipHeight = 0 ; + m_dTipRadius = 0 ; + m_dRefRadius = 0 ; + m_dCutterHeight = dH ; + + bool bToolDefined = true ; + + double dSquareCornerRadProj = m_dRCorner * m_dRCorner - 0.25 * m_dHeight * m_dHeight ; + // Utensile sfiancato + if ( dSquareCornerRadProj > 0) { + double dCenX = m_dRadius - m_dRCorner ; + double dCylRad = dCenX + sqrt( dSquareCornerRadProj) ; + // Utensile mal definito + if ( dCylRad < EPS_SMALL) + return false ; + // Profilo + m_Outline.AddPoint( Point3d( 0, 0, 0)) ; + m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + CurveArc cvArc ; + cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ; + m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; + m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; + bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ; + } + // Utensile cilindrico con eventuale raggio corner + else { + // Utensile mal definito + if ( m_dRadius - m_dRCorner < 0) + return false ; + // Utensile sferico + else if ( m_dRadius - m_dRCorner < EPS_SMALL) + ; + // Raggio corner nullo: cilindro + else if ( m_dRCorner < EPS_SMALL) { + ; + } + else { + // Profilo + m_Outline.AddPoint( Point3d( 0, 0, 0)) ; + m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + CurveArc cvArc ; + cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, - m_dRCorner, 0)) ; + m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; + m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, - m_dHeight, 0)) ; + m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; + m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; + bToolDefined = SetGenTool( sToolName, &m_Outline, nToolNum) ; + } + } + + m_nType = ADDITIVE ; + return bToolDefined ; +} \ No newline at end of file diff --git a/Tool.h b/Tool.h index dcee784..5180e4b 100644 --- a/Tool.h +++ b/Tool.h @@ -33,6 +33,7 @@ class Tool bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) ; bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) ; bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nToolNum) ; + bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) ; bool SetToolNum( int nToolNum) { m_nCurrentNum = nToolNum ; return true ; } int GetType() const @@ -70,7 +71,8 @@ class Tool BULLNOSEMILL = 4, // Naso di toro CONEMILL = 5, // Con parte terminale conica MORTISER = 6, // Mortasatrice - CHISEL = 7} ; // Scalpello + CHISEL = 7, // Scalpello + ADDITIVE = 8} ; // Additivo private : bool ModifyForCutterHeight( void) ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 7142e7e..bb0dd5e 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -2172,6 +2172,25 @@ VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dT return m_vTool[m_nCurrTool].SetChiselTool( sToolName, dH, dW, dTh, nFlag) ; } +//---------------------------------------------------------------------------- +bool +VolZmap::SetAdditiveTool( const std::string& sToolName, + double dH, double dR, double dRC, int nFlag, bool bFirst) +{ + if ( bFirst) { + m_vTool.resize( 1) ; + m_vTool[0].Clear( true) ; + } + else + m_vTool.emplace_back( true) ; + m_nCurrTool = int( m_vTool.size()) - 1 ; + if ( m_nCurrTool < 0) + return false ; + m_vTool[m_nCurrTool].SetTolerances( m_dToolLinTol, m_dToolAngTolDeg) ; + return m_vTool[m_nCurrTool].SetAdditiveTool( sToolName, dH, dR, dRC, nFlag) ; +} + + //---------------------------------------------------------------------------- int VolZmap::GetToolCount( void) const diff --git a/VolZmap.h b/VolZmap.h index 17e8656..b1c6619 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -78,6 +78,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool CopyFrom( const IGeoObj* pGObjSrc) override ; bool Clear( void) override ; bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ; + bool CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) override ; bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ; bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) override ; int GetBlockCount( void) const override ; @@ -109,6 +110,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW double dH, double dW, double dTh, double dRc, int nFlag, bool bFirst) override ; bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nFlag, bool bFirst) override ; + bool SetAdditiveTool( const std::string& sToolName, + double dH, double dR, double dRC, int nFlag, bool bFirst) override ; int GetToolCount( void) const override ; bool SetCurrTool( int nCurrTool) override ; bool ResetTools( void) override ; @@ -319,6 +322,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp // Generica traslazione sfera bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ; + // Additivi + bool AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ; + bool AddingCylinder( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dRad) ; + bool AddingTruncatedCone( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dMaxRad, double dMinRad, double dHei, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) ; + bool AddingGeneral( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) ; // BBox per utensili e solidi semplici con movimenti di traslazione inline bool TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, int& nStI, int& nStJ, int& nEnI, int& nEnJ) ; diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index a0b4a5b..4158804 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 @@ -29,11 +29,11 @@ using namespace std ; bool VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) { - // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo + // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) return false ; - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Aggiorno la dimensione della mappa 1 o 3 @@ -133,6 +133,80 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) +{ + // Controlli sull'ammissibilit� delle dimensioni lineari del grezzo e del passo + if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) + return false ; + + // Il passo di discretizzazione non pu� essere inferiore a 100 * EPS_SMALL + m_dStep = max( dStep, 100 * EPS_SMALL) ; + + // Aggiorno la dimensione della mappa 1 o 3 + m_nMapNum = ( bTriDex ? 3 : 1) ; + + // Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z + // di uno si ottengono da una permutazione ciclica di quelle del precedente sistema. + // es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1) + + // Definisco il sistema di riferimento intrinseco + m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; + + // Definisco i vettori dei limiti su indici + m_nNx[0] = max( int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5), 1) ; + m_nNy[0] = max( int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5), 1) ; + + // Numero di componenti connesse + m_nConnectedCompoCount = 1 ; + + // Se tridexel + if ( bTriDex) { + m_nNx[1] = m_nNy[0] ; + m_nNy[1] = max( int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5), 1) ; + m_nNx[2] = m_nNy[1] ; + m_nNy[2] = m_nNx[0] ; + } + + // altrimenti mono dexel + else { + m_nNx[1] = 0 ; + m_nNy[1] = 0 ; + m_nNx[2] = 0 ; + m_nNy[2] = 0 ; + } + + // Definisco il numero di blocchi lungo x,y e z + if ( ! CalcBlockNum()) + return false ; + + // Creazione delle mappe + // Calcolo del numero di celle per ogni mappa + for ( int i = 0 ; i < m_nMapNum ; ++ i) + m_nDim[i] = m_nNx[i] * m_nNy[i] ; + + // Creazione delle celle per ogni mappa + for ( int i = 0 ; i < m_nMapNum ; ++ i) + m_Values[i].resize( m_nDim[i]) ; + + // Definizione delle limitazioni iniziali in Z per ogni mappa + m_dMinZ[0] = 0 ; + m_dMaxZ[0] = dLengthZ ; + m_dMinZ[1] = 0 ; + m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; + m_dMinZ[2] = 0 ; + m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; + + // Tipologia + m_nShape = GENERIC ; + + // Aggiornamento dello stato + m_nStatus = OK ; + + return true ; +} + //---------------------------------------------------------------------------- bool VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) @@ -140,7 +214,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Aggiorno la dimensione della mappa 1 o 3 m_nMapNum = ( bTriDex ? 3 : 1) ; - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Determino il bounding box della flat region @@ -223,11 +297,11 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double CRVCVECTOR IntersectionResults ; Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ; - // Analizzo le parti in cui la retta è stata divisa + // Analizzo le parti in cui la retta è stata divisa int nPart = int( IntersectionResults.size()) ; for ( int k = 0 ; k < nPart ; ++ k) { - // Se la retta è interna alla regione o coincidente con parte della sua frontiera + // Se la retta è interna alla regione o coincidente con parte della sua frontiera int nType = IntersectionResults[k].nClass ; if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { @@ -334,7 +408,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double int nPart = int( IntersectionResults.size()) ; for ( int k = 0 ; k < nPart ; ++ k) { - // Se la retta è interna alla regione o coincidente con parte della sua frontiera + // Se la retta è interna alla regione o coincidente con parte della sua frontiera int nType = IntersectionResults[k].nClass ; if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { @@ -471,7 +545,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co int nIntType = IntersectionResults[k].nILTT ; - // Se c'è intersezione + // Se c'è intersezione if ( nIntType != ILTT_NO) { double dCos = IntersectionResults[k].dCosDN ; @@ -527,7 +601,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co bool VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) { - // Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare + // Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare double dVol ; if ( ! Surf.IsClosed() || ! Surf.GetVolume( dVol) || dVol < 0) return false ; @@ -543,14 +617,14 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex Point3d ptMapOrig, ptMapEnd ; SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; - // Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione, + // Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione, // quindi espandiamo il bounding box per ovviare al problema. SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ; // Sistema di riferimento intrinseco dello Zmap m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ; - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dStep, 100 * EPS_SMALL) ; // Determino le dimensioni lineari del BBox diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index ebeeaec..b5726c0 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2015-2020 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 05.10.20 Versione : 2.2j1 @@ -108,10 +108,10 @@ VolZmap::SubtractIntervals( int nGrid, int nI, int nJ, -- i ; } } - // se è tutto minore dell'intervallo corrente, ho finito + // se è tutto minore dell'intervallo corrente, ho finito else if ( dMax <= vDexel[i].dMin + EPS_ZERO) break ; - // altrimenti è tutto maggiore dell'intervallo corrente, passo al successivo + // altrimenti è tutto maggiore dell'intervallo corrente, passo al successivo else // dMin >= vDexel[i].dMax - EPS_ZERO ; } @@ -252,229 +252,351 @@ bool VolZmap::AddIntervals( int nGrid, int nI, int nJ, double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum) { -// // Controllo che dMin e dMax non siano quasi coincidenti -// if ( abs( dMax - dMin) < EPS_SMALL) -// return true ; -// -// // Controllo che il numero di griglia sia entro i limiti -// if ( nGrid < 0 || nGrid > 2) -// return false ; -// -// // Controllo che dMin < dMax -// if ( dMin > dMax) -// swap( dMin, dMax) ; -// -// // Controllo che indici nI, nJ siano entro i limiti -// if ( nI < 0 && nI >= m_nNx[nGrid] && -// nJ < 0 && nJ >= m_nNy[nGrid]) -// return false ; -// -// // Riporto le coordinate cicliche nell'ordine di partenza -// Vector3d vtNmi = vtNMin ; -// Vector3d vtNma = vtNMax ; -// if ( nGrid == 1) { -// swap( vtNmi.x, vtNmi.z) ; -// swap( vtNmi.y, vtNmi.z) ; -// swap( vtNma.x, vtNma.z) ; -// swap( vtNma.y, vtNma.z) ; -// } -// else if ( nGrid == 2) { -// swap( vtNmi.y, vtNmi.z) ; -// swap( vtNmi.x, vtNmi.z) ; -// swap( vtNma.y, vtNma.z) ; -// swap( vtNma.x, vtNma.z) ; -// } -// -// // Calcolo nPos -// unsigned int nPos = nJ * m_nNx[nGrid] + nI ; -// -// -// // Se spillone vuoto -// if ( m_Values[nGrid][nPos].size() == 0) { -// -// m_Values[nGrid][nPos].resize( 1) ; -// -// m_Values[nGrid][nPos][0].dMin = dMin ; -// m_Values[nGrid][nPos][0].dMax = dMax ; -// -// m_Values[nGrid][nPos][0].vtMinN = vtNmi ; -// m_Values[nGrid][nPos][0].vtMaxN = vtNma ; -// -// if ( dMax > m_dMaxZ[nGrid]) -// m_dMinZ[nGrid] = dMax ; -// -// if ( dMin < m_dMinZ[nGrid]) -// m_dMinZ[nGrid] = dMin ; -// -// m_OGrMgr.Reset() ; -// -// return true ; -// } -// -// // Ciclo sugli intervalli dello spillone -// bool bModified = false ; -// unsigned int i = 0 ; -// while ( i < m_Values[nGrid][nPos].size()) { -// -// // Eventuale aggiustamento di intervalli sovrapposti -// if ( i < m_Values[nGrid][nPos].size() - 1) { -// if ( m_Values[nGrid][nPos][i].dMax > m_Values[nGrid][nPos][i + 1].dMin - EPS_SMALL) { -// -// // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva -// if ( m_Values[nGrid][nPos][i].dMin < m_Values[nGrid][nPos][i + 1].dMin + EPS_SMALL) { -// -// m_Values[nGrid][nPos][i].dMax = m_Values[nGrid][nPos][i + 1].dMax ; -// m_Values[nGrid][nPos][i].vtMaxN = m_Values[nGrid][nPos][i + 1].vtMaxN ; -// } -// // altrimenti -// else { -// -// m_Values[nGrid][nPos][i].dMin = m_Values[nGrid][nPos][i].dMin ; -// m_Values[nGrid][nPos][i].vtMinN = m_Values[nGrid][nPos][i].vtMinN ; -// -// m_Values[nGrid][nPos][i].dMax = m_Values[nGrid][nPos][i].dMax ; -// m_Values[nGrid][nPos][i].vtMaxN = m_Values[nGrid][nPos][i].vtMaxN ; -// } -// -// for ( unsigned int j = i + 1 ; j < m_Values[nGrid][nPos].size() - 1 ; ++ j) { -// -// m_Values[nGrid][nPos][j].dMin = m_Values[nGrid][nPos][j + 1].dMin ; -// m_Values[nGrid][nPos][j].vtMinN = m_Values[nGrid][nPos][j + 1].vtMinN ; -// -// m_Values[nGrid][nPos][j].dMax = m_Values[nGrid][nPos][j + 1].dMax ; -// m_Values[nGrid][nPos][j].vtMaxN = m_Values[nGrid][nPos][j + 1].vtMaxN ; -// } -// -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() - 1) ; -// -// i = i - 1 ; -// } -// } -// -// -// // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente -// if ( m_Values[nGrid][nPos][i].dZVal > dMax + EPS_SMALL) { -// -// bModified = true ; -// -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() + 2) ; -// -// for ( size_t j = m_Values[nGrid][nPos].size() - 1 ; j >= i + 2 ; -- j) { -// -// m_Values[nGrid][nPos][j].dZVal = m_Values[nGrid][nPos][j - 2].dZVal ; -// m_Values[nGrid][nPos][j].vtN = m_Values[nGrid][nPos][j - 2].vtN ; -// } -// -// -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// -// m_Values[nGrid][nPos][i].vtN = vtNMin ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNMax ; -// -// i = i + 2 ; -// } -// -// // Casi d'intersezione: -// else if ( m_Values[nGrid][nPos][i + 1].dZVal > dMax - EPS_SMALL) { -// -// // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente -// if ( m_Values[nGrid][nPos][i].dZVal > dMin - EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i].vtN = vtNmi ; -// } -// } -// -// else { -// // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi -// if ( m_Values[nGrid][nPos][i].dZVal > dMin + EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// m_Values[nGrid][nPos][i].vtN = vtNMin ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNma ; -// } -// // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente -// else if ( m_Values[nGrid][nPos][i + 1].dZVal > dMin - EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNma ; -// } -// else { -// // Aggiungo intervallo a destra dell'ultimo intervallo -// if ( i == m_Values[nGrid][nPos].size() - 2) { -// -// bModified = true ; -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() + 2) ; -// -// m_Values[nGrid][nPos][i + 2].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 3].dZVal = dMax ; -// m_Values[nGrid][nPos][i + 2].vtN = vtNmi ; -// m_Values[nGrid][nPos][i + 3].vtN = vtNma ; -// -// i = i + 2 ; -// } -// } -// } -// -// i = i + 2 ; -// } -// -// // se eseguita modifica, imposto ricalcolo della grafica -// if ( bModified) { -// -// // Determino quali blocchi sono stati modificati -// int nLayerBlock = m_nFracLin[0] * m_nFracLin[1] ; -// -// if ( nGrid == 0) { -// -// int nXBlock = min( nI / m_nDexNumPBlock, m_nFracLin[0] - 1) ; -// int nYBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[1] - 1) ; -// int nMinZBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxZBlock = min( int( m_nFracLin[2] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) -// -// m_BlockToUpdate[k * nLayerBlock + nYBlock * m_nFracLin[0] + nXBlock] = true ; -// } -// else if ( nGrid == 1) { -// -// int nYBlock = min( nI / m_nDexNumPBlock, m_nFracLin[1] - 1) ; -// int nZBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[2] - 1) ; -// int nMinXBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxXBlock = min( int( m_nFracLin[0] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) -// -// m_BlockToUpdate[nZBlock * nLayerBlock + nYBlock * m_nFracLin[0] + k] = true ; -// } -// else if ( nGrid == 2) { -// -// int nXBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[0] - 1) ; -// int nZBlock = min( nI / m_nDexNumPBlock, m_nFracLin[2] - 1) ; -// int nMinYBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxYBlock = min( int( m_nFracLin[1] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) -// -// m_BlockToUpdate[nZBlock * nLayerBlock + k * m_nFracLin[0] + nXBlock] = true ; -// } -// -// m_OGrMgr.Reset() ; -// -// // Aggiorno massima e minima Z -// // sullo Zmap -// if ( dMax > m_dMaxZ[nGrid]) -// m_dMinZ[nGrid] = dMax ; -// -// if ( dMin < m_dMinZ[nGrid]) -// m_dMinZ[nGrid] = dMin ; -// } -// + // Controllo che il numero di griglia sia entro i limiti + if ( nGrid < 0 || nGrid > 2) + return false ; + + // Controllo che indici nI, nJ siano entro i limiti + if ( nI < 0 && nI >= m_nNx[nGrid] && + nJ < 0 && nJ >= m_nNy[nGrid]) + return false ; + + // Controllo che dMin < dMax + Vector3d vtNmi = vtNMin ; + Vector3d vtNma = vtNMax ; + if ( dMin > dMax) { + swap( dMin, dMax) ; + swap( vtNmi, vtNma) ; + } + + // Restringo minimo e massimo entro i limiti della mappa + if ( dMin < m_dMinZ[nGrid]) { + dMin = m_dMinZ[nGrid] ; + vtNmi = - Z_AX ; + } + else if ( dMin > m_dMaxZ[nGrid]) { + dMin = m_dMaxZ[nGrid] ; + vtNmi = - Z_AX ; + } + if ( dMax < m_dMinZ[nGrid]) { + dMax = m_dMinZ[nGrid] ; + vtNma = Z_AX ; + } + else if ( dMax > m_dMaxZ[nGrid]) { + dMax = m_dMaxZ[nGrid] ; + vtNma = Z_AX ; + } + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Riporto le coordinate cicliche nell'ordine di partenza + if ( nGrid == 1) { + swap( vtNmi.x, vtNmi.z) ; + swap( vtNmi.y, vtNmi.z) ; + swap( vtNma.x, vtNma.z) ; + swap( vtNma.y, vtNma.z) ; + } + else if ( nGrid == 2) { + swap( vtNmi.y, vtNmi.z) ; + swap( vtNmi.x, vtNmi.z) ; + swap( vtNma.y, vtNma.z) ; + swap( vtNma.x, vtNma.z) ; + } + + // Calcolo nPos + unsigned int nPos = nJ * m_nNx[nGrid] + nI ; + vector& vDexel = m_Values[nGrid][nPos] ; + + bool bModified = false ; + + // Non esistono segmenti + if ( int( vDexel.size()) == 0) { + + vDexel.emplace_back() ; + vDexel.back().dMin = dMin ; + vDexel.back().vtMinN = vtNmi ; + vDexel.back().nToolMin = nToolNum ; + vDexel.back().dMax = dMax ; + vDexel.back().vtMaxN = vtNma ; + vDexel.back().nToolMax = nToolNum ; + + m_OGrMgr.Reset() ; + + bModified = true ; + } + // Esiste almeno un segmento + else { + // Cerco l'ultimo intervallo a sinistra e l'ultimo intervallo a destra + // di quello da aggiungere, che non interferiscono con quest'ultimo. + auto itLastLeft = vDexel.end() ; + auto itFirstRight = vDexel.end() ; + for ( auto it = vDexel.begin() ; it != vDexel.end() ; ++ it) { + if ( dMin > it->dMax + EPS_SMALL) + itLastLeft = it ; + if ( dMax < it->dMin - EPS_SMALL && itFirstRight == vDexel.end()) + itFirstRight = it ; + } + // Esistono intervalli a sinistra. + if ( itLastLeft != vDexel.end()) { + // Intervallo successivo all'ultimo a sinistra + auto itNextToLastLeft = itLastLeft ; + ++ itNextToLastLeft ; + // Il successivo non esiste. + if ( itNextToLastLeft == vDexel.end()) { + // Aggiungo il nuovo semgento + vDexel.emplace_back() ; + vDexel.back().dMin = dMin ; + vDexel.back().dMax = dMax ; + vDexel.back().vtMinN = vtNmi ; + vDexel.back().vtMaxN = vtNma; + vDexel.back().nToolMin = nToolNum ; + vDexel.back().nToolMax = nToolNum ; + //m_Values[nGrid][nPos].back().nCompo = ; + bModified = true ; + } + // Il successivo esiste. + else { + // Il successivo è il primo a destra. + if ( itNextToLastLeft == itFirstRight) { + // Inserisco nuovo segmento- + Data NewSegment ; + NewSegment.dMin = dMin ; + NewSegment.dMax = dMax ; + NewSegment.vtMinN = vtNmi ; + NewSegment.vtMaxN = vtNma ; + NewSegment.nToolMin = nToolNum ; + NewSegment.nToolMax = nToolNum ; + //NewSegment.nCompo = ; + vDexel.insert( itFirstRight, NewSegment) ; + bModified = true ; + } + else { + // Il successivo non esce a sinistra da quello da aggiungere. + if ( itNextToLastLeft->dMin > dMin + EPS_SMALL) { + itNextToLastLeft->dMin = dMin ; + itNextToLastLeft->vtMinN = vtNmi ; + itNextToLastLeft->nToolMin = nToolNum ; + } + // Cerco l'ultimo segmento che interferisce con quello da aggiungere. + auto itPrevToFirstRight = vDexel.end() ; + for ( auto it = itNextToLastLeft ; it != itFirstRight ; ++ it) { + itPrevToFirstRight = it ; + } + // L'ultimo che interferisce non esce a destra da quello da aggiungere. + if ( itPrevToFirstRight->dMax < dMax - EPS_SMALL) { + itNextToLastLeft->dMax = dMax ; + itNextToLastLeft->vtMaxN = vtNma ; + itNextToLastLeft->nToolMax = nToolNum ; + bModified = true ; + } + else { + itNextToLastLeft->dMax = itPrevToFirstRight->dMax ; + itNextToLastLeft->vtMaxN = itPrevToFirstRight->vtMaxN ; + itNextToLastLeft->nToolMax = nToolNum ; + bModified = true ; + } + auto itFirstToCancel = itNextToLastLeft ; + ++ itFirstToCancel ; + vDexel.erase( itFirstToCancel, itFirstRight) ; + } + } + } + // Non esistono neanche a destra. + else if ( itFirstRight == m_Values[nGrid][nPos].end()) { + // Il primo intervallo non sporge a sinistra + if ( vDexel.begin()->dMin > dMin + EPS_SMALL) { + vDexel.begin()->dMin = dMin ; + vDexel.begin()->vtMinN = vtNmi ; + vDexel.begin()->nToolMin = nToolNum ; + bModified = true ; + } + // L'ultimo intervallo sporge a destra. + if ( m_Values[nGrid][nPos].back().dMax > dMax + EPS_SMALL) { + // Ci sono più segmenti, inglobo tutti nel primo. + if ( vDexel.back().dMax > vDexel.begin()->dMax + EPS_SMALL) { + vDexel.begin()->dMax = vDexel.back().dMax ; + vDexel.begin()->vtMaxN = vDexel.back().vtMaxN ; + vDexel.begin()->nToolMax = nToolNum ; + bModified = true ; + } + } + // L'ultimo intervallo non sporge a destra. + else { + vDexel.begin()->dMax = dMax ; + vDexel.begin()->vtMaxN = vtNma ; + vDexel.begin()->nToolMax = nToolNum ; + bModified = true ; + } + vDexel.erase( vDexel.begin() + 1, vDexel.end()) ; + } + // A destra esistono. + else { + // Tutti i segmenti sono a destra di qullo da aggiungere. + if ( itFirstRight == vDexel.begin()) { + // Inserisco nuovo segmento- + Data NewSegment ; + NewSegment.dMin = dMin ; + NewSegment.dMax = dMax ; + NewSegment.vtMinN = vtNmi ; + NewSegment.vtMaxN = vtNma ; + NewSegment.nToolMin = nToolNum ; + NewSegment.nToolMax = nToolNum ; + vDexel.insert( vDexel.begin(), NewSegment) ; + bModified = true ; + } + else { + // Se il primo segmento non esce a sinistra da quello da aggiungere, cambio l'inizio. + if ( vDexel.begin()->dMin > dMin + EPS_SMALL) { + vDexel.begin()->dMin = dMin ; + vDexel.begin()->vtMinN = vtNmi ; + vDexel.begin()->nToolMin = nToolNum ; + bModified = true ; + } + // Cerco l'ultimo segmento che interferisce con quello da aggiungere. + auto itPrevToFirstRight = vDexel.begin() ; + for ( auto it = m_Values[nGrid][nPos].begin() ; it != itFirstRight ; ++ it) { + itPrevToFirstRight = it ; + } + // L'ultimo che interferisce non esce a destra da quello da aggiungere. + if ( itPrevToFirstRight->dMax < dMax - EPS_SMALL) { + vDexel.begin()->dMax = dMax ; + vDexel.begin()->vtMaxN = vtNma ; + vDexel.begin()->nToolMax = nToolNum ; + bModified = true ; + } + else { + vDexel.begin()->dMax = itPrevToFirstRight->dMax ; + vDexel.begin()->vtMaxN = itPrevToFirstRight->vtMaxN ; + vDexel.begin()->nToolMax = nToolNum ; + bModified = true ; + } + auto itFirstToCancel = vDexel.begin() ; + ++ itFirstToCancel ; + vDexel.erase( itFirstToCancel, itFirstRight) ; + } + } + } + + // Se nessuna modifica, esco + if ( ! bModified) + return true ; + + // Imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + // Imposto forma generica + m_nShape = GENERIC ; + // Imposto ricalcolo numero di componenti connesse + m_nConnectedCompoCount = - 1 ; + + // Passo da indici di dexel a indici di voxel + nI /= m_nDexVoxRatio ; + nJ /= m_nDexVoxRatio ; + + // Determino quali blocchi sono stati modificati + if ( nGrid == 0) { + // Voxel lungo X + int nXStop = 1 ; + int nXBlock[2] ; + nXBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[0] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nXBlock[0] > 0) { + nXBlock[1] = nXBlock[0] - 1 ; + ++ nXStop ; + } + // Voxel lungo Y + int nYStop = 1 ; + int nYBlock[2] ; + nYBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[1] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nYBlock[0] > 0) { + nYBlock[1] = nYBlock[0] - 1 ; + ++ nYStop ; + } + // Voxel lungo Z + int nVoxNumZ = int( m_nNy[1] / m_nDexVoxRatio + ( m_nNy[1] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinK = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumZ - 2) ; + int nMaxK = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumZ - 2) ; + int nMinZBlock = ( m_nMapNum == 1 ? 0 : Clamp( nMinK / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[2] - 1))) ; + int nMaxZBlock = min( int( m_nFracLin[2] - 1), nMaxK / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nXStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nYStop ; ++ tJ) { + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + int nBlockNum = k * m_nFracLin[0] * m_nFracLin[1] + nYBlock[tJ] * m_nFracLin[0] + nXBlock[tI] ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + + else if ( nGrid == 1) { + // Voxel lungo Y + int nYStop = 1 ; + int nYBlock[2] ; + nYBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[1] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nYBlock[0] > 0) { + nYBlock[1] = nYBlock[0] - 1 ; + ++ nYStop ; + } + // Voxel lungo Z + int nZStop = 1 ; + int nZBlock[2] ; + nZBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[2] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nZBlock[0] > 0) { + nZBlock[1] = nZBlock[0] - 1 ; + ++ nZStop ; + } + // Voxel lungo X + int nVoxNumX = int( m_nNx[0] / m_nDexVoxRatio + ( m_nNx[0] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinI = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumX - 2) ; + int nMaxI = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumX - 2) ; + int nMinXBlock = Clamp( nMinI / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[0] - 1)) ; + int nMaxXBlock = min( int( m_nFracLin[0] - 1), nMaxI / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nYStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nZStop ; ++ tJ) { + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + int nBlockNum = nZBlock[tJ] * m_nFracLin[0] * m_nFracLin[1] + nYBlock[tI] * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + + else if ( nGrid == 2) { + // Voxel lungo X + int nXStop = 1 ; + int nXBlock[2] ; + nXBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[0] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nXBlock[0] > 0) { + nXBlock[1] = nXBlock[0] - 1 ; + ++ nXStop ; + } + // Voxel lungo Z + int nZStop = 1 ; + int nZBlock[2] ; + nZBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[2] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nZBlock[0] > 0) { + nZBlock[1] = nZBlock[0] - 1 ; + ++ nZStop ; + } + // Voxel lungo Y + int nVoxNumY = int( m_nNy[0] / m_nDexVoxRatio + ( m_nNy[0] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinJ = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumY - 2) ; + int nMaxJ = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumY - 2) ; + int nMinYBlock = Clamp( nMinJ / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[1] - 1)) ; + int nMaxYBlock = min( int( m_nFracLin[1] - 1), nMaxJ / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nZStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nXStop ; ++ tJ) { + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + int nBlockNum = nZBlock[tI] * m_nFracLin[0] * m_nFracLin[1] + k * m_nFracLin[0] + nXBlock[tJ] ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + return true ; } @@ -501,7 +623,7 @@ VolZmap::MillingStep( int nCurrTool, m_nCurrTool = nCurrTool ; Tool& CurrTool = m_vTool[m_nCurrTool] ; - // Se non è definito l'utensile, non posso fare alcunchè + // Se non è definito l'utensile, non posso fare alcunchè if ( CurrTool.GetType() == Tool::UNDEF) return false ; // Controllo definizione vettori direzione @@ -698,6 +820,8 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons return Mrt_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; case Tool::CHISEL : return Chs_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; + case Tool::ADDITIVE : + return AddingMotion( nGrid, ptLs, ptLe, vtL) ; } } @@ -752,13 +876,15 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons case Tool::BALLMILL : return CylBall_XYPerp( nGrid, ptLs, ptLe, vtL) ; case Tool::CONEMILL : - // Usiamo la generica per via dell'intsabilità di Conus_XYPerp + // Usiamo la generica per via dell'intsabilità di Conus_XYPerp //return Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; return Conus_Milling( nGrid, ptLs, ptLe, vtL) ; case Tool::MORTISER : return Mrt_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; case Tool::CHISEL : return Chs_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; + case Tool::ADDITIVE : + return AddingMotion( nGrid, ptLs, ptLe, vtL) ; } } // Fresatura con vettore movimento generico rispetto all'utensile @@ -925,7 +1051,7 @@ VolZmap::CylBall_ZPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Definizione di un sistema di riferimento ad hoc Point3d ptSxy( ptS.x, ptS.y, 0) ; Vector3d vtV1 = vtMove ; - vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 + vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 0, 1) ; @@ -1067,7 +1193,7 @@ VolZmap::CylBall_ZMilling( int nGrid, const Point3d & ptS, const Point3d & ptE, // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; - // Se la lunghezza è troppo piccola lo allungo + // Se la lunghezza è troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else @@ -1645,7 +1771,7 @@ VolZmap::Mrt_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const CompPar_ZDrilling( nGrid, dLenX, dLenY, dLenZ, ptS, ptEOnP, vtToolDir, vtAux, CurrTool.GetToolNum()) ; - // Se la punta è di tipo bull-nose + // Se la punta è di tipo bull-nose if ( abs( CurrTool.GetMrtChsWidth() - 2 * CurrTool.GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta @@ -1669,7 +1795,7 @@ VolZmap::Mrt_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, CurrTool.GetCornRadius(), false, false, CurrTool.GetToolNum()) ; } - // se la punta è di tipo sfera + // se la punta è di tipo sfera else { // Cilindro Point3d ptCylS = ptS - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; @@ -1734,7 +1860,7 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi const VCT3DVECTOR& vArcNorm = CurrTool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + // 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) ; @@ -1763,19 +1889,19 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c // Ne determino l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; if ( dHeight > EPS_SMALL) { - // Se X costante, è un cilindro + // Se X costante, è un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; if ( dRadius > 10 * EPS_SMALL) CompCyl_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, CurrTool.GetToolNum()) ; } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // 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, CurrTool.GetToolNum()) ; } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // 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 ; @@ -1831,7 +1957,7 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi const VCT3DVECTOR& vArcNorm = CurrTool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + // 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) ; @@ -1860,19 +1986,19 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Ne determino l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; if ( dHeight > EPS_SMALL) { - // Se X costante, è un cilindro + // 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, CurrTool.GetToolNum()) ; } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // 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, CurrTool.GetToolNum()) ; } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // 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 ; @@ -1982,9 +2108,9 @@ VolZmap::CylBall_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, CurrTool.GetToolNum()) ; } - // Se l'utensile è sferico sottraggo anche la punta + // Se l'utensile è sferico sottraggo anche la punta if ( CurrTool.GetType() == Tool::BALLMILL) - if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO + if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO double dH = sqrt( dSqRad - dSqLen) ; double dMin = dZ - dH ; @@ -2025,7 +2151,7 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons // Studio simmetrie del problema Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ; - // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile + // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile Vector3d vtErr = 0.5 * ( ( ptF - ptI) * vtToolDir) * vtToolDir ; ptI += vtErr ; ptF -= vtErr ; @@ -2203,7 +2329,7 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons } } - // Se l'utensile è ball-end sottraggo la punta + // Se l'utensile è ball-end sottraggo la punta if ( CurrTool.GetType() == Tool::BALLMILL) { if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || @@ -2452,7 +2578,7 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Studio delle simmetrie del moto Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; - // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile + // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile Vector3d vtErr = 0.5 * ( ( ptF - ptI) * vtToolDir) * vtToolDir ; ptI += vtErr ; ptF -= vtErr ; @@ -2779,7 +2905,7 @@ VolZmap::CylBall_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co double dStemHeigth = CurrTool.GetHeigth() - CurrTool.GetTipHeigth() ; // Sottraggo cilindro CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, CurrTool.GetRadius(), false, false, CurrTool.GetToolNum()) ; - // Se è sfera la sottraggo + // Se è sfera la sottraggo if ( CurrTool.GetType() == Tool::BALLMILL) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; @@ -2801,7 +2927,7 @@ VolZmap::CylBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con double dStemHeigth = CurrTool.GetHeigth() - CurrTool.GetTipHeigth() ; // Sottraggo cilindro CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, CurrTool.GetRadius(), false, false, CurrTool.GetToolNum()) ; - // Se è sfera la sottraggo + // Se è sfera la sottraggo if ( CurrTool.GetType() == Tool::BALLMILL) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; @@ -2896,7 +3022,7 @@ VolZmap::Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const double dLenZ = CurrTool.GetHeigth() - CurrTool.GetCornRadius() ; CompPar_Drilling( nGrid, dLenX, dLenY, dLenZ, ptS, ptEOnP, vtToolDir, vtAux, CurrTool.GetToolNum()) ; - // Se la punta è di tipo bull-nose + // Se la punta è di tipo bull-nose if ( abs( CurrTool.GetMrtChsWidth() - 2 * CurrTool.GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta @@ -2920,7 +3046,7 @@ VolZmap::Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, CurrTool.GetCornRadius(), false, false, CurrTool.GetToolNum()) ; } - // se la punta è di tipo sfera + // se la punta è di tipo sfera else { // Cilindro Point3d ptCylS = ptS - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; @@ -2951,7 +3077,7 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V Point3d ptBasePE = ptE - 0.5 * dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; CompPar_Milling( nGrid, dLenX, dLenZ, dLenY, ptBasePS, ptBasePE, vtAux, vtToolDir, CurrTool.GetToolNum()) ; - // Se la punta è di tipo bull-nose + // Se la punta è di tipo bull-nose if ( abs( CurrTool.GetMrtChsWidth() - 2 * CurrTool.GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta @@ -2978,7 +3104,7 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, CurrTool.GetCornRadius(), false, false, CurrTool.GetToolNum()) ; } - // se la punta è di tipo sfera + // se la punta è di tipo sfera else { // Cilindro Point3d ptCylS = ptBasePS - 0.5 * dLenZ * vtToolDir ; @@ -2999,7 +3125,7 @@ VolZmap::Chs_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const return false ; Tool& CurrTool = m_vTool[m_nCurrTool] ; - // Proiezione della traiettoria sulla varietà del movimento + // Proiezione della traiettoria sulla varietà del movimento Point3d ptProjE = ptS + ( ptE - ptS) * vtToolDir * vtToolDir ; CompPar_Drilling( nGrid, CurrTool.GetMrtChsWidth(), CurrTool.GetMrtChsThickness(), CurrTool.GetHeigth(), @@ -3043,7 +3169,7 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi const VCT3DVECTOR& vArcNorm = CurrTool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + // 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) ; @@ -3092,19 +3218,19 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x) bTapB = true ; } - // Se X costante, è un cilindro + // 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, CurrTool.GetToolNum()) ; } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // 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, CurrTool.GetToolNum()) ; } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // 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 ; @@ -3168,7 +3294,7 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi const VCT3DVECTOR& vArcNorm = CurrTool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + // 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) ; @@ -3217,20 +3343,20 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x) bTapB = false ; } - // Se X costante, è un cilindro + // 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, CurrTool.GetToolNum()) ; } - // se altrimenti X decrescente, è un cono con vettore equiverso a quello dell'utensile + // se altrimenti X decrescente, è un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn, CurrTool.GetToolNum()) ; } - // altrimenti X crescente, è un cono con vettore opposto a quello dell'utensile + // altrimenti X crescente, è un cono con vettore opposto a quello dell'utensile else { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; @@ -3343,9 +3469,9 @@ VolZmap::CompConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dAngC = dHei / ( dMaxRad - dMinRad) ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; - double dSafeSqMaxRad = dSqMaxRad - 2 * dMaxRad * EPS_SMALL ; // Questa variabile è sperimentale: serve per evitare il taglio di un dexel dalla parte cilindrica del volume spazzato dalla traslazione del cono. - double dDeltaR = dMaxRad - dMinRad ; // Per tornare alla versione precedente basta sostituire dSafeSqMaxRad con dSqMaxRad. Per risolvere il problema in modo forse più sicuro, ma - // computazionalmente più pesante è sottrarre prima il cilindro con dSafeSqMaxRad e dopo il cono con dSqMaxRad. + double dSafeSqMaxRad = dSqMaxRad - 2 * dMaxRad * EPS_SMALL ; // Questa variabile è sperimentale: serve per evitare il taglio di un dexel dalla parte cilindrica del volume spazzato dalla traslazione del cono. + double dDeltaR = dMaxRad - dMinRad ; // Per tornare alla versione precedente basta sostituire dSafeSqMaxRad con dSqMaxRad. Per risolvere il problema in modo forse più sicuro, ma + // computazionalmente più pesante è sottrarre prima il cilindro con dSafeSqMaxRad e dopo il cono con dSqMaxRad. // Studio delle simmetrie if ( vtToolDir.z > 0) { dZMin = ( ptS.z < ptE.z ? ptS.z - dHei : ptE.z - dHei) ; @@ -3378,7 +3504,7 @@ VolZmap::CompConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, dZMin, dZMax, Z_AX, -Z_AX, nToolNum) ; } - else if ( dSqDist < dSafeSqMaxRad) { // dSafeSqMaxRad è sperimentale + else if ( dSqDist < dSafeSqMaxRad) { // dSafeSqMaxRad è sperimentale double dr = sqrt( dSqDist) ; @@ -3528,7 +3654,7 @@ VolZmap::CompCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; - // Se la lunghezza è troppo piccola lo allungo + // Se la lunghezza è troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else @@ -3937,7 +4063,7 @@ VolZmap::CompConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } //---------------------------------------------------------------------------- -bool // E' in realtà MillingPerp +bool // E' in realtà MillingPerp VolZmap::CompPar_ZMilling( int nGrid, double dLenX, double dLenY, double dLenZ, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) @@ -4074,7 +4200,7 @@ VolZmap::CompConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, Frame3d ConusFrame ; ConusFrame.Set( ptVertex, vtToolDir) ; Frame3d CylFrame = ConusFrame ; CylFrame.Translate( vtToolDir * dConeMaxH) ; - // L'altezza del cilindro è il movimento + // L'altezza del cilindro è il movimento double dH = ( ptE - ptS).Len() ; for ( int i = nStartI ; i <= nEndI ; ++ i) { @@ -4216,7 +4342,7 @@ VolZmap::CompCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, nToolNum) ; } - // Cilindro finale:L'unica differenza rispetto a prima è l'origine + // Cilindro finale:L'unica differenza rispetto a prima è l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. CylFrame.ChangeOrig( ptITip + vtMove) ; @@ -4239,7 +4365,7 @@ VolZmap::CompCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, nToolNum) ; } - // Cilindro ellittico di base: L'unica differenza rispetto a prima è l'origine + // Cilindro ellittico di base: L'unica differenza rispetto a prima è l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. CylFrame.ChangeOrig( ptITip + dHei * vtV1) ; @@ -4349,7 +4475,7 @@ VolZmap::CompConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptFacet135( 0, 0, dLenZ) ; Point3d ptFacet246( dLenX + dDeltaX, dLenY + dDeltaY, - dLenZ - dDeltaZ) ; - // Necessità ricalcolo normali (perchè variabili per approx curve) + // Necessità ricalcolo normali (perchè variabili per approx curve) bool bRecalNorm = ( ! vtArcNormMaxR.IsSmall() && ! vtArcNormMinR.IsSmall()) ; if ( dRatio * dTan <= 1) { @@ -4748,7 +4874,7 @@ VolZmap::CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ, // ---------- SFERA ---------------------------------------------------------- -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- pizza bool VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, double dRad, int nToolNum) { @@ -4810,6 +4936,577 @@ VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, return true ; } +// ------------------------- Utensili additivi --------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) +{ + // Dimensioni lineari dell'utensile + double dHei = m_vTool[m_nCurrTool].GetHeigth() ; + double dRad = m_vTool[m_nCurrTool].GetRadius() ; + double dCornerRad = m_vTool[m_nCurrTool].GetCornRadius() ; + + // Utensile sfiancato + if ( dCornerRad * dCornerRad - 0.25 * dHei * dHei > 0) { + AddingGeneral( nGrid, ptS, ptE, vtAx) ; + } + // Utensile sferico + else if ( dRad - dCornerRad < EPS_SMALL) { + AddingSphere( nGrid, ptS - dRad * vtAx, ptE - dRad * vtAx, dRad) ; + } + // Utensile cilindro + else if ( dCornerRad < EPS_SMALL) { + AddingCylinder( nGrid, ptS, ptE, vtAx, dHei, dRad) ; + } + // Utensile naso di toro + else { + AddingGeneral( nGrid, ptS, ptE, vtAx) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingGeneral( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx) +{ + // Descrizione geometrica del moto + Point3d ptI = ptS ; + Point3d ptF = ptE ; + Vector3d vtMove = ptE - ptS ; + // Vettore delle normali agli archi + const VCT3DVECTOR& vArcNorm = m_vTool[m_nCurrTool].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_vTool[m_nCurrTool].GetApproxOutline() ; + int i = - 1 ; + 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) { + // Se X costante, è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + double dRadius = ptStart.x ; + if (dRadius > 10 * EPS_SMALL) + AddingCylinder( nGrid, ptI, ptF, vtAx, 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 ; + AddingTruncatedCone( nGrid, ptI, ptF, vtAx, dMaxRad, dMinRad, dHeight, 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 - vtAx * dHeight ; + Point3d ptFn = ptIn + vtMove ; + vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ; + AddingTruncatedCone( nGrid, ptIn, ptFn, - vtAx, dMaxRad, dMinRad, dHeight, vtNormEn, vtNormSt) ; + + } + // Passo alla curva successiva + pCurve = ToolProfile.GetCurve( ++ i) ; + } + else { + // Passo alla curva successiva + pCurve = ToolProfile.GetCurve( ++ i) ; + } + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtAx * dHeight ; + ptF = ptI + vtMove ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingCylinder( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dRad) +{ + // Controllo utensile + if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size())) + return false ; + Tool& CurrTool = m_vTool[m_nCurrTool] ; + + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + Vector3d vtV1 = ptE - ptS ; + double dLen1 = vtV1.Len() ; + vtV1 /= dLen1 ; + + if ( nGrid == 0) { + + Vector3d vtV2 = Z_AX ^ vtV1 ; + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Vector3d vtStC( ( i + 0.5) * m_dStep - ptS.x, ( j + 0.5) * m_dStep - ptS.y, 0) ; + Vector3d vtEnC = vtStC - dLen1 * vtV1 ; + + double dX1 = vtStC * vtV1 ; + double dX2 = vtStC * vtV2 ; + + if ( ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dRad + EPS_SMALL) || + vtStC.SqLen() < dRad * dRad + 2 * dRad * EPS_SMALL || + vtEnC.SqLen() < dRad * dRad + 2 * dRad * EPS_SMALL) { + AddIntervals( nGrid, i, j, ptS.z - dHei, ptS.z, - Z_AX, Z_AX, CurrTool.GetToolNum()) ; + } + } + } + } + else { + double dMyTol = 0 ; + Frame3d CylFrame, PolyFrame ; + CylFrame.Set( ptS - dHei * vtAx, vtAx) ; + PolyFrame.Set( ptS - ( dHei + dMyTol) * vtAx, vtV1, vtAx ^ vtV1, vtAx) ; + 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) ; + + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dHei, dRad, true, true, + ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, - vtN1, - vtN2, CurrTool.GetToolNum()) ; + } + + if ( IntersLineCylinder( ptC - dLen1 * vtV1, Z_AX, CylFrame, dHei, dRad, true, true, + ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z + dLen1 * vtV1.z, ptInt2.z + dLen1 * vtV1.z, - vtN1, - vtN2, CurrTool.GetToolNum()) ; + } + + if ( IntersLineMyPolyhedron( ptC, Z_AX, PolyFrame, dLen1, 2 * ( dRad + dMyTol), dHei + 2 * dMyTol, 0, + ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, - vtN1, - vtN2, CurrTool.GetToolNum()) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingTruncatedCone( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dMaxRad, double dMinRad, double dHei, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + // Controllo utensile + if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size())) + return false ; + Tool& CurrTool = m_vTool[m_nCurrTool] ; + + // Verifico interferenza + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Geometria del cono + double dDeltaR = dMaxRad - dMinRad ; + + // Studio simmetrie + Point3d ptI = ( vtAx * ( ptE - ptS) > 0 ? ptS : ptE) ; + Point3d ptF = ( vtAx * ( ptE - ptS) > 0 ? ptE : ptS) ; + + double dL = ( dMaxRad * dHei) / dDeltaR ; + double dl = dL - dHei ; + + Point3d ptV = ptI - vtAx * dL ; + + // Vettori caratteristici del movimento + // Elimino eventuali componenti del moto lungo l'asse. + Vector3d vtMove = ptF - ptI ; + Vector3d vtMvLong = ( vtMove * vtAx) * vtAx ; + Vector3d vtMvOrt = vtMove - vtMvLong ; + + // Terna destrorsa e unitaria + Vector3d vtV1 = vtAx ; + Vector3d vtV2 = vtMvOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Sistema di riferimento intrinseco del movimento + Frame3d ConusFrame ; ConusFrame.Set( ptV, vtV2, vtV3, vtV1) ; + + // Dimensioni lineari movimento + double dLongLen = 0 ; + double dOrtLen = vtMvOrt.Len() ; + + // Apertura del cono + double dTan = dDeltaR / dHei ; + double dRatio = dLongLen / dOrtLen ; + + // Per costruire piani laterali poliedro interno + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + // Dimensioni lineari descriventi il poliedro interno + double dLenX = dLongLen ; + double dLenY = dOrtLen ; + double dLenZ = dSin * dMinRad ; + double dDeltaX = dHei ; + double dDeltaY = dCos * dDeltaR ; + double dDeltaZ = dSin * dDeltaR ; + + // Sistema di riferimento poliedro + Point3d ptO = ptV + vtV1 * dl + vtV2 * ( dCos * dMinRad) ; + Frame3d PolyFrame ; + PolyFrame.Set( ptO, vtV1, vtV2, vtV3) ; + + // Versori piani nel riferimento poliedro ( riferiti al sistema di riferimento) : + // Sx, Dx + Vector3d vtNs( - dTan, dCos, dSin) ; + vtNs.Normalize() ; + Vector3d vtNd( - dTan, dCos, - dSin) ; + vtNd.Normalize() ; + // Iniziale e finale + Vector3d vtIF( - dDeltaY, dDeltaX, 0) ; + vtIF.Normalize() ; + // Up e Down + Vector3d vtUD( - dLenY, dLenX, 0) ; + vtUD.Normalize() ; + + // Punti dei piani (sempre espressi nel sistema PolyFrame) + Point3d ptFacet135( 0, 0, dLenZ) ; + Point3d ptFacet246( dLenX + dDeltaX, dLenY + dDeltaY, - dLenZ - dDeltaZ) ; + + Vector3d vtUmv = vtMove ; vtUmv.Normalize() ; + + 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) ; + + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Cono iniziale + ConusFrame.ChangeOrig( ptV) ; + if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, true, true, ptInt1, vtN1, ptInt2, vtN2)) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + if ( ! ( vtArcNormMaxR.IsSmall() || vtArcNormMinR.IsSmall())) { + if ( ! AreSameOrOppositeVectorEpsilon( vtN1, vtAx, 0.1 * EPS_SMALL)) { + Vector3d vtL1 = ptInt1 - ptV ; + vtL1 -= ( vtL1 * vtAx) * vtAx ; + double dL1 = vtL1.Len() ; + vtL1 /= dL1 ; + Vector3d vtOriginalN1 = ( ( dDeltaR - dL1 + dMinRad) / dDeltaR) * vtArcNormMinR + ((dL1 - dMinRad) / dDeltaR) * vtArcNormMaxR; + vtOriginalN1.Normalize() ; + vtN1 = vtOriginalN1.z * vtAx + vtOriginalN1.x * vtL1 ; + vtN1.Normalize() ; + } + if ( ! AreSameOrOppositeVectorEpsilon( vtN2, vtAx, 0.1 * EPS_SMALL)) { + Vector3d vtL2 = ptInt2 - ptV ; + vtL2 -= ( vtL2 * vtAx) * vtAx ; + double dL2 = vtL2.Len() ; + vtL2 /= dL2 ; + Vector3d vtOriginalN2 = ( ( dDeltaR - dL2 + dMinRad) / dDeltaR) * vtArcNormMinR + ( ( dL2 - dMinRad) / dDeltaR) * vtArcNormMaxR ; + vtOriginalN2.Normalize() ; + vtN2 = vtOriginalN2.z * vtAx + vtOriginalN2.x * vtL2 ; + vtN2.Normalize() ; + } + } + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, CurrTool.GetToolNum()) ; + } + + // Cono finale + ConusFrame.ChangeOrig( ptV + vtMove) ; + if ( IntersLineConus( ptC, Z_AX, ConusFrame, dTan, dl, dL, true, true, ptInt1, vtN1, ptInt2, vtN2)) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + if ( ! ( vtArcNormMaxR.IsSmall() || vtArcNormMinR.IsSmall())) { + if ( ! AreSameOrOppositeVectorEpsilon( vtN1, vtAx, 0.1 * EPS_SMALL)) { + Vector3d vtL1 = ptInt1 - ptV - vtMove ; + vtL1 -= ( vtL1 * vtAx) * vtAx ; + double dL1 = vtL1.Len() ; + vtL1 /= dL1 ; + Vector3d vtOriginalN1 = ( ( dDeltaR - dL1 + dMinRad) / dDeltaR) * vtArcNormMinR + ( ( dL1 - dMinRad) / dDeltaR) * vtArcNormMaxR ; + vtOriginalN1.Normalize() ; + vtN1 = vtOriginalN1.z * vtAx + vtOriginalN1.x * vtL1 ; + vtN1.Normalize() ; + } + if ( ! AreSameOrOppositeVectorEpsilon(vtN2, vtAx, 0.1 * EPS_SMALL)) { + Vector3d vtL2 = ptInt2 - ptV - vtMove ; + vtL2 -= (vtL2 * vtAx) * vtAx; + double dL2 = vtL2.Len() ; + vtL2 /= dL2 ; + Vector3d vtOriginalN2 = ( ( dDeltaR - dL2 + dMinRad) / dDeltaR) * vtArcNormMinR + ( ( dL2 - dMinRad) / dDeltaR) * vtArcNormMaxR ; + vtOriginalN2.Normalize() ; + vtN2 = vtOriginalN2.z * vtAx + vtOriginalN2.x * vtL2 ; + vtN2.Normalize() ; + } + } + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, CurrTool.GetToolNum()) ; + } + + // Solido interno + Point3d ptPoly = ptC ; + Vector3d vtPoly = Z_AX ; + + ptPoly.ToLoc( PolyFrame) ; + vtPoly.ToLoc( PolyFrame) ; + + Point3d ptPoly1 = ptPoly + ( ( ( ptFacet135 - ptPoly) * vtNs) / ( vtPoly * vtNs)) * vtPoly ; + Point3d ptPoly2 = ptPoly + ( ( ( ptFacet246 - ptPoly) * vtNd) / ( vtPoly * vtNd)) * vtPoly ; + Point3d ptPoly3 = ptPoly + ( ( ( ptFacet135 - ptPoly) * vtIF) / ( vtPoly * vtIF)) * vtPoly ; + Point3d ptPoly4 = ptPoly + ( ( ( ptFacet246 - ptPoly) * vtIF) / ( vtPoly * vtIF)) * vtPoly ; + Point3d ptPoly5 = ptPoly + ( ( ( ptFacet135 - ptPoly) * vtUD) / ( vtPoly * vtUD)) * vtPoly ; + Point3d ptPoly6 = ptPoly + ( ( ( ptFacet246 - ptPoly) * vtUD) / ( vtPoly * vtUD)) * vtPoly ; + + int nIntNum = 0 ; + + // Intersezione con la prima faccia + if ( abs( vtPoly * vtNs) > COS_ORTO_ANG_ZERO) { + if ( dLenY * ( ptPoly1.x + EPS_SMALL) > dLenX * ptPoly1.y && + dLenY * ( ptPoly1.x - dDeltaX - EPS_SMALL) < dLenX * ( ptPoly1.y - dDeltaY) && + dDeltaX * ( ptPoly1.y + EPS_SMALL) > dDeltaY * ptPoly1.x && + dDeltaX * ( ptPoly1.y - dLenY - EPS_SMALL) < dDeltaY * ( ptPoly1.x - dLenX)) { + ptInt1 = ptPoly1 ; + vtN1 = - vtNs ; + if ( ! ( vtArcNormMaxR.IsSmall() || vtArcNormMinR.IsSmall())) { + Vector3d vtRadial( 0, dMinRad * dCos, dMinRad * dSin) ; + vtRadial.Normalize() ; + Vector3d vtOrigMaxR = - vtArcNormMaxR.x * vtRadial - vtArcNormMaxR.z * X_AX ; + Vector3d vtOrigMinR = - vtArcNormMinR.x * vtRadial - vtArcNormMinR.z * X_AX ; + vtOrigMaxR.Normalize() ; + vtOrigMinR.Normalize() ; + vtN1 = - ( ( dDeltaZ - ptInt1.z + dLenZ) / dDeltaZ) * vtOrigMinR - ( ( ptInt1.z - dLenZ) / dDeltaZ) * vtOrigMaxR ; + vtN1.Normalize() ; + } + ++ nIntNum ; + } + } + // Intersezione con la seconda faccia + if ( abs( vtPoly * vtNd) > COS_ORTO_ANG_ZERO) { + if ( dLenY * ( ptPoly2.x + EPS_SMALL) > dLenX * ptPoly2.y && + dLenY * ( ptPoly2.x - dDeltaX - EPS_SMALL) < dLenX * ( ptPoly2.y - dDeltaY) && + dDeltaX * ( ptPoly2.y + EPS_SMALL) > dDeltaY * ptPoly2.x && + dDeltaX * ( ptPoly2.y - dLenY - EPS_SMALL) < dDeltaY * ( ptPoly2.x - dLenX)) { + + if ( nIntNum == 0) { + ptInt1 = ptPoly2 ; + vtN1 = - vtNd ; + if ( ! ( vtArcNormMaxR.IsSmall() || vtArcNormMinR.IsSmall())) { + Vector3d vtRadial( 0, dMinRad * dCos, - dMinRad * dSin) ; + vtRadial.Normalize() ; + Vector3d vtOrigMaxR = - vtArcNormMaxR.x * vtRadial - vtArcNormMaxR.z * X_AX ; + Vector3d vtOrigMinR = - vtArcNormMinR.x * vtRadial - vtArcNormMinR.z * X_AX ; + vtOrigMaxR.Normalize() ; + vtOrigMinR.Normalize() ; + vtN1 = - ( ( dDeltaZ - abs( ptInt1.z) + dLenZ) / dDeltaZ) * vtOrigMinR - ( ( abs( ptInt1.z) - dLenZ) / dDeltaZ) * vtOrigMaxR ; + vtN1.Normalize() ; + } + ++ nIntNum ; + } + else if ( ( ptInt1 - ptPoly2).SqLen() > SQ_EPS_SMALL) { + ptInt2 = ptPoly2 ; + vtN2 = - vtNd ; + if ( ! ( vtArcNormMaxR.IsSmall() || vtArcNormMinR.IsSmall())) { + Vector3d vtRadial( 0, dMinRad * dCos, -dMinRad * dSin) ; + vtRadial.Normalize() ; + Vector3d vtOrigMaxR = -vtArcNormMaxR.x * vtRadial - vtArcNormMaxR.z * X_AX ; + Vector3d vtOrigMinR = -vtArcNormMinR.x * vtRadial - vtArcNormMinR.z * X_AX ; + vtOrigMaxR.Normalize() ; + vtOrigMinR.Normalize() ; + vtN2 = - ( ( dDeltaZ - abs( ptInt2.z) + dLenZ) / dDeltaZ) * vtOrigMinR - ( ( abs( ptInt2.z) - dLenZ) / dDeltaZ) * vtOrigMaxR ; + vtN2.Normalize() ; + } + ++ nIntNum ; + } + } + } + // Intersezione con la terza faccia + if ( abs( vtPoly * vtIF) > COS_ORTO_ANG_ZERO) { + if ( nIntNum < 2 && + ptPoly3.x > - EPS_SMALL && ptPoly3.x < dDeltaX + EPS_SMALL && + dDeltaX * abs( ptPoly3.z) < dDeltaX * dLenZ + dDeltaZ * ptPoly3.x + dDeltaX * EPS_SMALL) { + + if ( nIntNum == 0) { + ptInt1 = ptPoly3 ; + vtN1 = - vtIF ; + ++ nIntNum ; + } + else if ( ( ptInt1 - ptPoly3).SqLen() > SQ_EPS_SMALL) { + ptInt2 = ptPoly3 ; + vtN2 = - vtIF ; + ++ nIntNum ; + } + } + } + + // Intersezione con la quarta faccia + if ( abs( vtPoly * vtIF) > COS_ORTO_ANG_ZERO) { + if ( nIntNum < 2 && + ptPoly4.x > dLenX - EPS_SMALL && ptPoly4.x < dLenX + dDeltaX + EPS_SMALL && + dDeltaX * abs( ptPoly4.z) < dDeltaX * dLenZ + dDeltaZ * ( ptPoly4.x - dLenX) + dDeltaX * EPS_SMALL) { + + if ( nIntNum == 0) { + ptInt1 = ptPoly4 ; + vtN1 = vtIF ; + ++ nIntNum ; + } + else if ( ( ptInt1 - ptPoly4).SqLen() > SQ_EPS_SMALL) { + ptInt2 = ptPoly4 ; + vtN2 = vtIF ; + ++ nIntNum ; + } + } + } + + // Intersezione con la quinta faccia + if ( abs( vtPoly * vtUD) > COS_ORTO_ANG_ZERO) { + if ( nIntNum < 2 && + ptPoly5.y >= 0 && ptPoly5.y <= dLenY && + abs( ptPoly5.z) <= dLenZ) { + + if ( nIntNum == 0) { + ptInt1 = ptPoly5 ; + vtN1 = vtUD ; + ++ nIntNum ; + } + else if ( ( ptInt1 - ptPoly5).SqLen() > SQ_EPS_SMALL) { + ptInt2 = ptPoly5 ; + vtN2 = vtUD ; + ++ nIntNum ; + } + } + } + + // Intersezione con la sesta faccia + if ( abs( vtPoly * vtUD) > COS_ORTO_ANG_ZERO) { + if ( nIntNum < 2 && + ptPoly6.y >= dDeltaY && ptPoly6.y <= dLenY + dDeltaY && + abs( ptPoly6.z) <= dLenZ + dDeltaZ) { + + if ( nIntNum == 0) { + ptInt1 = ptPoly6; + vtN1 = - vtUD ; + ++ nIntNum ; + } + else if ( ( ptInt1 - ptPoly6).SqLen() > SQ_EPS_SMALL) { + ptInt2 = ptPoly6; + vtN2 = - vtUD ; + ++ nIntNum ; + } + } + } + // Se il poliedro � attraversato, aggiungo + if ( nIntNum == 2) { + + // Riporto le intersezioni nel sistema griglia + ptInt1.ToGlob( PolyFrame) ; + vtN1.ToGlob( PolyFrame) ; + ptInt2.ToGlob( PolyFrame) ; + vtN2.ToGlob( PolyFrame) ; + + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, CurrTool.GetToolNum()) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingSphere( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad) +{ + // Controllo utensile + if ( m_nCurrTool < 0 || m_nCurrTool >= int( m_vTool.size())) + return false ; + Tool& CurrTool = m_vTool[m_nCurrTool] ; + + // Verifico interferisca + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, V_NULL, dRad, 0, 0, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + // Vettore movimento + Vector3d vtV = ptE - ptS ; + double dLengthPath = vtV.Len() ; + if ( dLengthPath > EPS_ZERO) + vtV /= dLengthPath ; + // Riferimento per cilindro inviluppo della sfera lungo il movimento + Frame3d CylFrame ; + CylFrame.Set( ptS, vtV) ; + + double dSqRad = dRad * dRad ; + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + Point3d ptC( dX, dY, 0) ; + + // Sfera in posizione start + double dStSqDXY = SqDistXY( ptC, ptS) ; + if ( dStSqDXY < dSqRad) { + double dMin = ptS.z - sqrt( dSqRad - dStSqDXY) ; + Vector3d vtNmin = Point3d( dX, dY, dMin) - ptS ; + vtNmin.Normalize() ; + double dMax = ptS.z + sqrt( dSqRad - dStSqDXY) ; + Vector3d vtNmax = Point3d( dX, dY, dMax) - ptS ; + vtNmax.Normalize() ; + AddIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax, CurrTool.GetToolNum()) ; + } + + // Sfera in posizione end + double dEnSqDXY = SqDistXY( ptC, ptE) ; + if ( dEnSqDXY < dSqRad) { + double dMin = ptE.z - sqrt( dSqRad - dEnSqDXY) ; + Vector3d vtNmin = Point3d( dX, dY, dMin) - ptE ; + vtNmin.Normalize() ; + double dMax = ptE.z + sqrt( dSqRad - dEnSqDXY) ; + Vector3d vtNmax = Point3d( dX, dY, dMax) - ptE ; + vtNmax.Normalize() ; + AddIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax, CurrTool.GetToolNum()) ; + } + + // Cilindro inviluppo della sfera + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dLengthPath, dRad, false, false, ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, - vtN1, - vtN2, CurrTool.GetToolNum()) ; + } + } + } + + return true ; +} + + // ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -4878,7 +5575,7 @@ VolZmap::TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, con { // I punti e i vettori devono essere nel sistema di riferimento opportuno - // Controllo sull'ammissibilità del numero di griglia + // Controllo sull'ammissibilità del numero di griglia if ( nGrid < 0 || nGrid > 2) return false ; @@ -4917,7 +5614,7 @@ VolZmap::TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const double dSemiDiag = sqrt( dLenX * dLenX + dLenY * dLenY) / 2 ; - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento double dMinX = min( min( ptS.x, ptSTip.x), min( ptE.x, ptETip.x)) - dSemiDiag ; double dMinY = min( min( ptS.y, ptSTip.y), min( ptE.y, ptETip.y)) - dSemiDiag ; double dMinZ = min( min( ptS.z, ptSTip.z), min( ptE.z, ptETip.z)) - dSemiDiag ;