diff --git a/Tool.cpp b/Tool.cpp index 07f4cce..4d77586 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -26,8 +26,8 @@ using namespace std ; //---------------------------------------------------------------------------- Tool::Tool( void) - : m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG), m_nType( UNDEF), m_nCurrentNum( 0), m_dHeigth( 0), - m_dTipHeigth( 0), m_dRadius( 0), m_dRCorner( 0), m_dTipRadius( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0) + : m_dLinTol( 2 * LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG), m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), + m_dTipHeight( 0), m_dRadius( 0), m_dRCorner( 0), m_dTipRadius( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0) { } @@ -62,25 +62,25 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, // utensile cilindrico if ( dCornR < EPS_SMALL) { m_nType = CYLMILL ; - m_dHeigth = dH ; + m_dHeight = dH ; m_dRadius = dR ; - m_dTipHeigth = 0 ; + m_dTipHeight = 0 ; m_dTipRadius = m_dRadius ; m_dRCorner = 0 ; } // utensile naso di toro else if ( dCornR < dR - EPS_SMALL) { - m_dHeigth = dH ; + m_dHeight = dH ; m_dRadius = dR ; - m_dTipHeigth = dCornR ; + m_dTipHeight = dCornR ; m_dTipRadius = dR - dCornR ; m_dRCorner = dCornR ; // come profilo Point3d pt0( 0, 0, 0) ; Point3d pt1( m_dRadius, 0, 0) ; - Point3d pt2( m_dRadius, - m_dHeigth + m_dTipHeigth, 0) ; - Point3d pt3( m_dTipRadius, - m_dHeigth, 0) ; - Point3d pt4( 0, - m_dHeigth, 0) ; + Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; + Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; + Point3d pt4( 0, - m_dHeight, 0) ; m_Outline.Clear() ; CurveLine Line ; Line.Set( pt0, pt1) ; @@ -93,9 +93,9 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, // utensile sferico else if ( dCornR < dR + EPS_SMALL) { m_nType = BALLMILL ; - m_dHeigth = dH ; + m_dHeight = dH ; m_dRadius = dR ; - m_dTipHeigth = m_dRadius ; + m_dTipHeight = m_dRadius ; m_dTipRadius = 0 ; m_dRCorner = m_dRadius ; } @@ -125,9 +125,9 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, return SetStdTool( sToolName, dH, dR, dCornR, nToolNum) ; // Caso avanzato - m_dHeigth = dH ; + m_dHeight = dH ; m_dRadius = dR ; - m_dTipHeigth = dTipH ; + m_dTipHeight = dTipH ; m_dTipRadius = max( dTipR, 0.) ; // Se raggio corner nullo, allora utensile conico @@ -144,7 +144,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // Definisco il profilo Point3d pt0( 0, 0, 0) ; Point3d pt1( m_dRadius, 0, 0) ; - Point3d pt2( m_dRadius, - m_dHeigth + m_dTipHeigth, 0) ; + Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; if ( m_dTipRadius < m_dRadius) { @@ -296,11 +296,14 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, m_nType = GEN ; - // Dimensioni dell'utensile + // Il profilo dell'utensile deve stare nel 4° quadrante del piano XY BBox3d Bounding ; - m_Outline.GetLocalBBox( Bounding) ; - double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; - double m_dRadius = Bounding.GetMax().x - Bounding.GetMin().x ; + m_Outline.GetLocalBBox( Bounding) ; + if ( Bounding.GetMin().x < - 10 * EPS_SMALL || Bounding.GetMax().y > 10 * EPS_SMALL) + return false ; + // Assegno le dimensioni dell'utensile + m_dHeight = - Bounding.GetMin().y ; + m_dRadius = Bounding.GetMax().x ; return true ; } @@ -319,7 +322,7 @@ Tool::SetMortiserTool( const std::string& sToolName, double dH, double dW, doubl dTh < EPS_SMALL || dRc < 0 || dW - 2 * dRc < 0) return false ; - m_dHeigth = dH ; + m_dHeight = dH ; m_dRCorner = dRc ; m_dMrtChsWidth = dW ; m_dMrtChsThickness = dTh ; @@ -344,7 +347,7 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, if ( dH < EPS_SMALL || dW < EPS_SMALL || dTh < 0) return false ; - m_dHeigth = dH ; + m_dHeight = dH ; m_dMrtChsWidth = dW ; m_dMrtChsThickness = dTh ; diff --git a/Tool.h b/Tool.h index 49896e5..725155c 100644 --- a/Tool.h +++ b/Tool.h @@ -35,9 +35,9 @@ class Tool int GetCurrentToolNum() const { return m_nCurrentNum ; } double GetHeigth() const - { return m_dHeigth ; } + { return m_dHeight ; } double GetTipHeigth() const - { return m_dTipHeigth ; } + { return m_dTipHeight ; } double GetRadius() const { return m_dRadius ; } double GetTipRadius() const @@ -76,8 +76,8 @@ class Tool int m_nCurrentNum ; CurveComposite m_Outline ; CurveComposite m_ArcLineApprox ; - double m_dHeigth ; - double m_dTipHeigth ; + double m_dHeight ; + double m_dTipHeight ; double m_dRadius ; double m_dRCorner ; double m_dTipRadius ; diff --git a/VolZmap.h b/VolZmap.h index 9828eae..f9d46b0 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -37,7 +37,7 @@ struct TriaStruct { // Vettore di TriaStruct con sharp fature interni a un blocco typedef std::vector TriHolder ; -// Vettori di TriHolder con sharp feature di frontiera: +// Vettore di TriHolder con sharp feature di frontiera: // il primo indice individua il blocco, il secondo il voxel typedef std::vector TriaMatrix ; @@ -137,6 +137,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW struct HeigthAndColor { int nTool ; double dHeigth ; + HeigthAndColor( void) : nTool( 0), dHeigth( 0) {} + HeigthAndColor( int nT, double dH) : nTool( nT), dHeigth( dH) {} } ; typedef std::unordered_map VoxelContainer ; // Struttura voxel @@ -157,7 +159,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool ProcessCell( int nGrid, int nCellI, int nCellJ, const Plane3d& plPlane, std::vector& vLine) const ; bool ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold) const ; bool ExtMarchingCubes( std::vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh) const ; - bool FlipEdgesII( TriHolder& TriHold, bool bGraph) const ; + bool FlipEdgesII( TriHolder& TriHold) const ; bool FlipEdgesBB( TriaMatrix& InterTria) const ; bool IsThereMat( int nI, int nJ, int nK) const ; bool InOut( const Plane3d& plPlane, int nGrid, int nI, int nJ) const ; diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 57cec72..9c1aa52 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2016 +// EgalTech 2015-2018 //---------------------------------------------------------------------------- -// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// File : VolZmap.cpp Data : 27.01.18 Versione : 1.8a3 // Contenuto : Implementazione della classe Volume Zmap (tre griglie) // // @@ -38,7 +38,7 @@ static int NeighbourTable[8][4] = { {1, 3, -1, -1}, {2, 1, 3, -1}, {2, 2, 3, -1}, - {3, 1, 2, 3} + {3, 1, 2, 3} } ; // ------------------------- FUNZIONE TEST SULLE NORMALI -------------------------------------------------------------------------- @@ -49,21 +49,21 @@ enum CanonicDir { X_PLUS = 1, X_MINUS = -1, Y_PLUS = 2, Y_MINUS = -2, Z_PLUS = 3 int TestOnNormal( const VectorField CompoVert[], int nCompoElem) { - // Cerco la massima deviazione tra le normali nei punti della parte connessa + // Cerco la massima deviazione tra le normali nei punti della parte connessa int nI, nJ ; double dMinCosTheta = 2 ; for ( int i = 0 ; i < nCompoElem ; ++ i) { for ( int j = i + 1 ; j < nCompoElem ; ++ j) { double dCurrCos = CompoVert[i].vtNorm * CompoVert[j].vtNorm ; if ( dCurrCos < dMinCosTheta) { - dMinCosTheta = dCurrCos ; + dMinCosTheta = dCurrCos ; nI = i ; nJ = j ; } } } - // Se la massima deviazione non supera il limite non è feature + // Se la massima deviazione non supera il limite non è feature const double SHARP_COS = 0.9 ; if ( dMinCosTheta >= SHARP_COS) return NO_FEATURE ; @@ -83,7 +83,7 @@ TestOnNormal( const VectorField CompoVert[], int nCompoElem) const double CORNER_COS = 0.7 ; if ( dMaxAbsCos > CORNER_COS) return CORNER ; - else + else return EDGE ; } @@ -143,18 +143,18 @@ DotTest( const VectorField CompoVert[], int nCompoElem, Vector3d& vtAvg, double for ( int j = i + 1 ; j < nCompoElem ; ++ j) { double dCurrCos = CompoVert[i].vtNorm * CompoVert[j].vtNorm ; if ( dCurrCos < dMinCosTheta) { - dMinCosTheta = dCurrCos ; + dMinCosTheta = dCurrCos ; } } } - // se normali sparpagliate oltre limite - if ( dMinCosTheta < dThreshold) + // se normali sparpagliate oltre limite + if ( dMinCosTheta < dThreshold) return false ; // determino media delle normali vtAvg = V_NULL ; - for ( int i = 0 ; i < nCompoElem ; ++ i) + for ( int i = 0 ; i < nCompoElem ; ++ i) vtAvg += CompoVert[i].vtNorm ; vtAvg /= nCompoElem ; @@ -164,7 +164,7 @@ DotTest( const VectorField CompoVert[], int nCompoElem, Vector3d& vtAvg, double //---------------------------------------------------------------------------- bool VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], - int nIndArrey[][4], int nVertComp[], int nCompCount, bool& bGridControl) const + int nIndArrey[][4], int nVertComp[], int nCompCount, bool& bGridControl) const { // Ordino i 4 indici in senso crescente for ( int nSrtInd1 = 0 ; nSrtInd1 < nVertComp[nCompCount - 1] - 1 ; ++ nSrtInd1) { @@ -179,22 +179,22 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], ( nIndArrey[nCompCount - 1][0] == 4 && nIndArrey[nCompCount - 1][1] == 6 && nIndArrey[nCompCount - 1][2] == 9 && nIndArrey[nCompCount - 1][3] == 10) || ( nIndArrey[nCompCount - 1][0] == 4 && nIndArrey[nCompCount - 1][1] == 6 && - nIndArrey[nCompCount - 1][2] == 8 && nIndArrey[nCompCount - 1][3] == 11) || + nIndArrey[nCompCount - 1][2] == 8 && nIndArrey[nCompCount - 1][3] == 11) || ( nIndArrey[nCompCount - 1][0] == 0 && nIndArrey[nCompCount - 1][1] == 2 && nIndArrey[nCompCount - 1][2] == 8 && nIndArrey[nCompCount - 1][3] == 11) || ( nIndArrey[nCompCount - 1][0] == 1 && nIndArrey[nCompCount - 1][1] == 3 && nIndArrey[nCompCount - 1][2] == 8 && nIndArrey[nCompCount - 1][3] == 9 ) || ( nIndArrey[nCompCount - 1][0] == 1 && nIndArrey[nCompCount - 1][1] == 3 && - nIndArrey[nCompCount - 1][2] == 10 && nIndArrey[nCompCount - 1][3] == 11) || + nIndArrey[nCompCount - 1][2] == 10 && nIndArrey[nCompCount - 1][3] == 11) || ( nIndArrey[nCompCount - 1][0] == 5 && nIndArrey[nCompCount - 1][1] == 7 && - nIndArrey[nCompCount - 1][2] == 10 && nIndArrey[nCompCount - 1][3] == 11) || + nIndArrey[nCompCount - 1][2] == 10 && nIndArrey[nCompCount - 1][3] == 11) || ( nIndArrey[nCompCount - 1][0] == 5 && nIndArrey[nCompCount - 1][1] == 7 && nIndArrey[nCompCount - 1][2] == 8 && nIndArrey[nCompCount - 1][3] == 9 )) { - if ( AreSameVectorApprox( VecField[nIndArrey[nCompCount - 1][0]].vtNorm, VecField[nIndArrey[nCompCount - 1][1]].vtNorm) && - abs( VecField[nIndArrey[nCompCount - 1][0]].vtNorm * VecField[nIndArrey[nCompCount - 1][2]].vtNorm) < EPS_SMALL && + if ( AreSameVectorApprox( VecField[nIndArrey[nCompCount - 1][0]].vtNorm, VecField[nIndArrey[nCompCount - 1][1]].vtNorm) && + abs( VecField[nIndArrey[nCompCount - 1][0]].vtNorm * VecField[nIndArrey[nCompCount - 1][2]].vtNorm) < EPS_SMALL && abs( VecField[nIndArrey[nCompCount - 1][0]].vtNorm * VecField[nIndArrey[nCompCount - 1][3]].vtNorm) < EPS_SMALL) { - + Point3d ptBarycenter = ( CompoVert[nCompCount - 1][0].ptInt + CompoVert[nCompCount - 1][1].ptInt + CompoVert[nCompCount - 1][2].ptInt + CompoVert[nCompCount - 1][3].ptInt) / 4 ; @@ -235,9 +235,9 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], } ++ nBarInd ; } - } + } } - + else if ( vtVecField.z * vtVecField.z > 1 - EPS_SMALL * EPS_SMALL) { if ( abs( CompoVert[nCompCount - 1][0].ptInt.z - ptBarycenter.z) < EPS_SMALL && abs( CompoVert[nCompCount - 1][1].ptInt.z - ptBarycenter.z) < EPS_SMALL && @@ -326,16 +326,15 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], } } - else if ( ( nIndArrey[nCompCount - 1][0] == 0 && nIndArrey[nCompCount - 1][1] == 1 && + else if ( ( nIndArrey[nCompCount - 1][0] == 0 && nIndArrey[nCompCount - 1][1] == 1 && nIndArrey[nCompCount - 1][2] == 4 && nIndArrey[nCompCount - 1][3] == 5) || - ( nIndArrey[nCompCount - 1][0] == 1 && nIndArrey[nCompCount - 1][1] == 2 && + ( nIndArrey[nCompCount - 1][0] == 1 && nIndArrey[nCompCount - 1][1] == 2 && nIndArrey[nCompCount - 1][2] == 5 && nIndArrey[nCompCount - 1][3] == 6) || - ( nIndArrey[nCompCount - 1][0] == 2 && nIndArrey[nCompCount - 1][1] == 3 && - nIndArrey[nCompCount - 1][2] == 6 && nIndArrey[nCompCount - 1][3] == 7) || + ( nIndArrey[nCompCount - 1][0] == 2 && nIndArrey[nCompCount - 1][1] == 3 && + nIndArrey[nCompCount - 1][2] == 6 && nIndArrey[nCompCount - 1][3] == 7) || ( nIndArrey[nCompCount - 1][0] == 0 && nIndArrey[nCompCount - 1][1] == 3 && nIndArrey[nCompCount - 1][2] == 4 && nIndArrey[nCompCount - 1][3] == 7)) { - if ( AreSameVectorApprox( VecField[nIndArrey[nCompCount - 1][0]].vtNorm, VecField[nIndArrey[nCompCount - 1][2]].vtNorm) && abs( VecField[nIndArrey[nCompCount - 1][0]].vtNorm * VecField[nIndArrey[nCompCount - 1][1]].vtNorm) < EPS_SMALL && abs( VecField[nIndArrey[nCompCount - 1][0]].vtNorm * VecField[nIndArrey[nCompCount - 1][3]].vtNorm) < EPS_SMALL) { @@ -380,7 +379,7 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], } ++ nBarInd ; } - } + } } else if ( vtVecField.z * vtVecField.z > 1 - EPS_SMALL * EPS_SMALL) { @@ -400,7 +399,7 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], ++ nBarInd ; } } - } + } } else if ( AreSameVectorApprox( VecField[nIndArrey[nCompCount - 1][1]].vtNorm, VecField[nIndArrey[nCompCount - 1][3]].vtNorm) && @@ -447,7 +446,7 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], } ++ nBarInd ; } - } + } } else if ( vtVecField.z * vtVecField.z > 1 - EPS_SMALL * EPS_SMALL) { @@ -470,10 +469,10 @@ VolZmap::GridControl( VectorField VecField[], VectorField CompoVert[][12], } } } - + return true ; } - + // ------------------------- VISUALIZZAZIONE -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool @@ -481,36 +480,28 @@ VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) con { // Se richiesti spilloni ( 0 <= nDir < 3) if ( nDir < 3) { - // Controllo l'ammissibilità della griglia if ( nDir < 0 || nDir > 2) return false ; - // Verifiche sugli indici if ( nPos1 < 0 || nPos1 >= int( m_nNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nNy[nDir])) return false ; - int nPos = nPos1 + nPos2 * m_nNx[nDir] ; - if ( nPos < 0 || nPos >= int( m_Values[nDir].size())) return false ; - // Definisco un sistema di riferimento opportuno Frame3d frMapFrame ; if ( nDir == 0) frMapFrame = m_MapFrame ; - else if ( nDir == 1) - frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ; - else if ( nDir == 2) + else if ( nDir == 1) + frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ; + else if ( nDir == 2) frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersZ(), m_MapFrame.VersX(), m_MapFrame.VersY()) ; - // Calcolo coordinate punto double dX = m_dStep * ( 0.5 + nPos1) ; double dY = m_dStep * ( 0.5 + nPos2) ; - // Determino il punto di partenza sulla griglia Point3d ptP = frMapFrame.Orig() + dX * frMapFrame.VersX() + dY * frMapFrame.VersY() ; - // Creo le polilinee for ( int j = 0 ; j < int( m_Values[nDir][nPos].size()) ; j += 1) { // aggiungo polilinea a lista @@ -521,41 +512,33 @@ VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) con } return true ; } + // altrimenti richieste normali ( 3 <= nDir < 6) else { - // riporto a indice griglia nDir -= 3 ; - // Controllo l'ammissibilità della griglia if ( nDir < 0 || nDir > 2) return false ; - // Verifiche sugli indici if ( nPos1 < 0 || nPos1 >= int( m_nNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nNy[nDir])) return false ; - int nPos = nPos1 + nPos2 * m_nNx[nDir] ; - if ( nPos < 0 || nPos >= int( m_Values[nDir].size())) return false ; - // Definisco un sistema di riferimento opportuno Frame3d frMapFrame ; if ( nDir == 0) frMapFrame = m_MapFrame ; - else if ( nDir == 1) - frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ; - else if ( nDir == 2) + else if ( nDir == 1) + frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ; + else if ( nDir == 2) frMapFrame.Set( m_MapFrame.Orig(), m_MapFrame.VersZ(), m_MapFrame.VersX(), m_MapFrame.VersY()) ; - // Calcolo coordinate punto double dX = m_dStep * ( 0.5 + nPos1) ; double dY = m_dStep * ( 0.5 + nPos2) ; - // Determino il punto di partenza sulla griglia Point3d ptP = frMapFrame.Orig() + dX * frMapFrame.VersX() + dY * frMapFrame.VersY() ; - // Creo le polilinee for ( int j = 0 ; j < int( m_Values[nDir][nPos].size()) ; j += 1) { // aggiungo polilinea a lista @@ -595,12 +578,12 @@ VolZmap::GetAllTriangles( TRIA3DEXLIST& lstTria) const } return true ; -} +} //---------------------------------------------------------------------------- bool VolZmap::GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DEXLISTVECTOR& vLstTria) const -{ +{ // Se nessun blocco modificato, è richiesta esterna e li considero tutti modificati bool bSomeModif = false ; for ( size_t i = 0 ; i < m_nNumBlock ; ++ i) { @@ -612,14 +595,14 @@ VolZmap::GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DEXLIST if ( ! bSomeModif) bAllBlocks = true ; - // Caso di singola mappa + // Caso di singola mappa if ( m_nMapNum == 1) { const int MAX_DIM_CHUNK = 128 ; nModifiedBlocks.resize( m_nNumBlock) ; vLstTria.reserve( m_nNumBlock) ; - + // Ciclo sui blocchi for ( size_t t = 0 ; t < m_nNumBlock ; ++ t) { @@ -681,14 +664,10 @@ VolZmap::GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DEXLIST vLstTria.emplace_back() ; nModifiedBlocks[t] = int( vLstTria.size()) - 1 ; m_InterBlockTria[t].clear() ; - #if 1 - ExtMarchingCubes( int( t), vLstTria.back(), VecTriHold[t]) ; - // Flipping fra voxel interni - FlipEdgesII( VecTriHold[t], true) ; - bCalcInterBlock = true ; - #else - MarchingCubes( int( t), vLstTria.back()) ; - #endif + ExtMarchingCubes( int( t), vLstTria.back(), VecTriHold[t]) ; + // Flipping fra voxel interni + FlipEdgesII( VecTriHold[t]) ; + bCalcInterBlock = true ; m_BlockToUpdate[t] = false ; } else @@ -704,34 +683,53 @@ VolZmap::GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DEXLIST InterBlockTria = m_InterBlockTria ; FlipEdgesBB( InterBlockTria) ; } - + // Inserisco in lista i triangoli di feature derivanti dai blocchi for ( size_t t = 0 ; t < m_nNumBlock ; ++ t) { if ( nModifiedBlocks[t] >= 0) { // ciclo sui voxel del blocco - for ( size_t t1 = 0 ; t1 < VecTriHold[t].size() ; ++ t1) { + for ( size_t t1 = 0 ; t1 < VecTriHold[t].size() ; ++ t1) { // ciclo sulle componenti connesse del voxel for ( size_t t2 = 0 ; t2 < VecTriHold[t][t1].vCompoTria.size() ; ++ t2) { // ciclo sui triangoli delle componenti connesse for ( size_t t3 = 0 ; t3 < VecTriHold[t][t1].vCompoTria[t2].size() ; ++ t3) { + // Controllo normali + Vector3d vtN = VecTriHold[t][t1].vCompoTria[t2][t3].GetN() ; + bool bNormN = vtN.IsNormalized() ; + for ( int nV = 0 ; nV < 3 ; ++ nV) { + Vector3d vtNV = VecTriHold[t][t1].vCompoTria[t2][t3].GetVertexNorm( nV) ; + bool bNormV = vtNV.IsNormalized() ; + if ( bNormN && bNormV && vtN * vtNV < 0.87) + VecTriHold[t][t1].vCompoTria[t2][t3].SetVertexNorm( nV, vtN) ; + } // aggiungo triangolo alla lista vLstTria[nModifiedBlocks[t]].emplace_back( VecTriHold[t][t1].vCompoTria[t2][t3]) ; } } } } - } + } // Inserisco in lista i triangoli di frontiera tra feature di blocchi diversi if ( bCalcInterBlock) { vLstTria.resize( vLstTria.size() + 1) ; size_t nPos = size_t( vLstTria.size() - 1) ; - for ( size_t t = 0 ; t < m_InterBlockTria.size() ; ++ t) { - for ( size_t t1 = 0 ; t1 < m_InterBlockTria[t].size() ; ++ t1) { - for ( size_t t2 = 0 ; t2 < m_InterBlockTria[t][t1].vCompoTria.size() ; ++ t2) { - for ( size_t t3 = 0 ; t3 < m_InterBlockTria[t][t1].vCompoTria[t2].size() ; ++ t3) { - if ( m_InterBlockTria[t][t1].vCompoTria[t2][t3].GetArea() > SQ_EPS_SMALL) { + for ( size_t t = 0 ; t < InterBlockTria.size() ; ++ t) { + for ( size_t t1 = 0 ; t1 < InterBlockTria[t].size() ; ++ t1) { + for ( size_t t2 = 0 ; t2 < InterBlockTria[t][t1].vCompoTria.size() ; ++ t2) { + for ( size_t t3 = 0 ; t3 < InterBlockTria[t][t1].vCompoTria[t2].size() ; ++ t3) { + if ( InterBlockTria[t][t1].vCompoTria[t2][t3].GetArea() > SQ_EPS_SMALL) { + // Controllo normali + Vector3d vtN = InterBlockTria[t][t1].vCompoTria[t2][t3].GetN() ; + bool bNormN = vtN.IsNormalized() ; + for ( int nV = 0 ; nV < 3 ; ++ nV) { + Vector3d vtNV = InterBlockTria[t][t1].vCompoTria[t2][t3].GetVertexNorm( nV) ; + bool bNormV = vtNV.IsNormalized() ; + if ( bNormN && bNormV && vtN * vtNV < 0.87) + InterBlockTria[t][t1].vCompoTria[t2][t3].SetVertexNorm( nV, vtN) ; + } + // aggiungo triangolo alla lista vLstTria[nPos].emplace_back( InterBlockTria[t][t1].vCompoTria[t2][t3]) ; } } @@ -745,7 +743,7 @@ VolZmap::GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DEXLIST else nModifiedBlocks.back() = - 1 ; } - + return true ; } @@ -769,14 +767,14 @@ VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx[0] ; if ( nPos > int( m_nDim[0]) || int( m_Values[0][nPos].size()) != 1) - bIsSimple = false ; + bIsSimple = false ; else if ( i == 0 && j == 0) { dBotZ = m_Values[0][nPos][0].dMin ; dTopZ = m_Values[0][nPos][0].dMax ; } else if ( abs( m_Values[0][nPos][0].dMin - dBotZ) > EPS_SMALL || abs( m_Values[0][nPos][0].dMax - dTopZ) > EPS_SMALL) - bIsSimple = false ; + bIsSimple = false ; } } @@ -792,7 +790,7 @@ VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; - } + } } } // altrimenti @@ -801,7 +799,7 @@ VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk for ( int i = 0 ; i < nDim1 ; ++ i) { for ( int j = 0 ; j < nDim2 ; ++ j) { CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; - } + } } } return true ; @@ -955,9 +953,9 @@ bool VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, TriHolder& triHold, bool bEnh) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Se il voxel non esiste, vi è un errore. if ( nVoxI + 1 < 0 || nVoxI + 2 > nVoxNumX || @@ -1023,34 +1021,34 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // Arrey numero di vertici della base del fan per componente // connessa: nVertComp[i] contiene il numero di vertici - // della base del fan della (i+1)-esima componente connessa. + // della base del fan della (i+1)-esima componente connessa. int nVertComp[6] ; // Matrice di indici dei punti: serve per la gestione del caso - int nIndArrey[6][4] ; + int nIndArrey[6][4] ; int nExtTabOff = nComponents ; int nStdTabOff = 0 ; - // Carico le matrici CompoVert e CompoTriVert + // Carico le matrici CompoVert e CompoTriVert for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) { // Numero vertici per componenti nVertComp[nCompCount - 1] = TriangleTableEn[nIndex][1][nCompCount] ; - // Riempio il nCompCount-esimo vettore di vertici della base del fan - for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) + // Riempio il nCompCount-esimo vettore di vertici della base del fan + for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) CompoVert[nCompCount - 1][nVertCount] = VecField[TriangleTableEn[nIndex][1][nVertCount + nExtTabOff + 1]] ; // Serve per la gestione del caso ... if ( nVertComp[nCompCount - 1] == 4) { - for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) + for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) nIndArrey[nCompCount - 1][nVertCount] = TriangleTableEn[nIndex][1][nVertCount + nExtTabOff + 1] ; } - // Riempio il nCompCount-esimo vettore di vertici dei triangoli in assenza di + // Riempio il nCompCount-esimo vettore di vertici dei triangoli in assenza di // sharp feature: in una mesh di triangoli con n vertici vi sono n - 2 triangoli. - for ( int nVertCount = 0 ; nVertCount < 3 * ( nVertComp[nCompCount - 1] - 2) ; nVertCount += 3) { + for ( int nVertCount = 0 ; nVertCount < 3 * ( nVertComp[nCompCount - 1] - 2) ; nVertCount += 3) { CompoTriVert[nCompCount - 1][nVertCount] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+2]] ; CompoTriVert[nCompCount - 1][nVertCount+1] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+1]] ; CompoTriVert[nCompCount - 1][nVertCount+2] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount]] ; @@ -1070,13 +1068,13 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr bool bSecondConfig6 = false ; if ( bReg) { - if ( nAllConfig[nIndex] == 3) { + if ( nAllConfig[nIndex] == 3) { - Vector3d vtCmpAvg0, vtCmpAvg1 ; + Vector3d vtCmpAvg0, vtCmpAvg1 ; - // Verifico se i versori delle componenti sono tutti + // Verifico se i versori delle componenti sono tutti // più o meno concordi (per esserlo non devono esserci - // due vettori di una medesima componente con prodotto + // due vettori di una medesima componente con prodotto // scalare inferiore a 0.7). bool bTest0 = DotTest( CompoVert[0], 3, vtCmpAvg0, 0.7) ; bool bTest1 = DotTest( CompoVert[1], 3, vtCmpAvg1, 0.7) ; @@ -1170,7 +1168,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr for ( int nC = 1 ; nC <= nComponents ; ++ nC) { // Numero vertici per componenti - nVertComp[nC - 1] = 7 ; + nVertComp[nC - 1] = 7 ; // Matrici dei vertici dei triangoli in assenza di sharp feature for ( int nTriVert = 0 ; nTriVert < 3 * ( nVertComp[nC - 1] - 2) ; nTriVert += 3) { @@ -1251,7 +1249,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // Controllo per il caso piano su una griglia // con versori normali a due a due paralleli. bool bGridControl = true ; - if ( nFeatureType != NO_FEATURE) { + if ( nFeatureType != NO_FEATURE) { if ( nVertComp[nCompCount - 1] == 4) GridControl( VecField, CompoVert, nIndArrey, nVertComp, nCompCount, bGridControl) ; } @@ -1316,7 +1314,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr int nFtVxI, nFtVxJ, nFtVxK ; if ( GetPointVoxel( ptSol, nFtVxI, nFtVxJ, nFtVxK)) { - + if ( abs( nFtVxI - nVoxI) > 2 || abs( nFtVxJ - nVoxJ) > 2 || abs( nFtVxK - nVoxK) > 2) @@ -1326,7 +1324,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr double dDistFeature = vtFeature.Len() ; const double MAX_DIST = sqrt( 3) * N_DEXVOXRATIO * m_dStep ; bOutside = ( dDistFeature > MAX_DIST) ; - } + } TRIA3DVECTOR triContainer ; @@ -1345,14 +1343,14 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr bool bDangerInversion = false ; // Caso ventaglio con tre vertici di base - if ( nVertComp[nCompCount - 1] == 3) { + if ( nVertComp[nCompCount - 1] == 3) { // Controllo se esiste almeno un triangolo con normale avente prodotto scalare // negativo con la normale di almeno uno dei vertici di base del ventaglio. bool bInversione = false ; for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { - int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; + int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; double dDI = triContainer[ni].GetN() * CompoVert[nCompCount - 1][ni].vtNorm ; double dDJ = triContainer[ni].GetN() * CompoVert[nCompCount - 1][nj].vtNorm ; @@ -1425,7 +1423,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // Il triangolo è pronto Triangle3d CurrentTriangle ; CurrentTriangle.Set( ptSol, CompoVert[nCompCount - 1][nj].ptInt, CompoVert[nCompCount - 1][ni].ptInt) ; - CurrentTriangle.Validate( true) ; + CurrentTriangle.Validate( true) ; // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } @@ -1435,13 +1433,10 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // si passa alla routine standard se il voxel // in cui cade è pieno. else { - int nAdjVoxI, nAdjVoxJ, nAdjVoxK ; if ( GetPointVoxel( ptSolZMapFrame, nAdjVoxI, nAdjVoxJ, nAdjVoxK)) { - // Classificazione del voxel adiacente int nAdjIndex = CalcIndex( nAdjVoxI, nAdjVoxJ, nAdjVoxK) ; - // Se il voxel è pieno if ( EdgeTable[nAdjIndex] != 0) bDangerInversion = true ; @@ -1468,14 +1463,12 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr if ( dDI < - EPS_SMALL || dDJ < - EPS_SMALL) bInversione = true ; } + // Se tale triangolo esiste continuo i test if ( bInversione) { - // Se la feature non cade nel suo voxel if ( ! IsPointInsideVoxelApprox( nVoxI, nVoxJ, nVoxK, ptSol)) { - Vector3d vtNullSpace( dMatrixV( 0, 2), dMatrixV( 1, 2), dMatrixV( 2, 2)) ; - double dParInt1, dParInt2 ; Point3d ptVoxMin( ( nVoxI * N_DEXVOXRATIO + 0.5) * m_dStep, ( nVoxJ * N_DEXVOXRATIO + 0.5) * m_dStep, ( nVoxK * N_DEXVOXRATIO + 0.5) * m_dStep) ; @@ -1484,16 +1477,11 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // Se è possibile riportarla dentro e il voxel in cui cade è pieno, la riporto nel suo voxel // lungo la sua linea if ( IntersLineBox( ptSol, vtNullSpace, ptVoxMin, ptVoxMax, dParInt1, dParInt2)) { - triContainer.resize( 0) ; - - double dPar = abs( dParInt1) < abs( dParInt2) ? dParInt1 + ( dParInt2 - dParInt1) / 100 : + double dPar = abs( dParInt1) < abs( dParInt2) ? dParInt1 + ( dParInt2 - dParInt1) / 100 : dParInt2 + ( dParInt1 - dParInt2) / 100 ; - Point3d ptNewSol = ptSol + dPar * vtNullSpace ; - ptSol = ptNewSol ; - // Costruisco triangoli di prova for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; @@ -1519,7 +1507,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr } } } - } + } } // Valuto normali: questo è ancora un controllo @@ -1590,7 +1578,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr // Aggiungo una componente per il vettore dei triangoli della componente connessa. triHold[nCurrent].vCompoTria.resize( nNewFeatureNum) ; - for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) { + for ( int ni = 0 ; ni < int( vInnerTriaTemp.size()) ; ++ ni) { triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( vInnerTriaTemp[ni]) ; } } @@ -1605,7 +1593,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr CurrentTriangle.Set( CompoTriVert[nCompCount - 1][TriIndex].ptInt, CompoTriVert[nCompCount - 1][TriIndex+1].ptInt, CompoTriVert[nCompCount - 1][TriIndex+2].ptInt) ; - bool bV = CurrentTriangle.Validate( true) ; + bool bV = CurrentTriangle.Validate( true) ; // Aggiungo alla lista lstTria.emplace_back( CurrentTriangle) ; } @@ -1621,7 +1609,7 @@ VolZmap::ProcessCube( int nVoxI, int nVoxJ, int nVoxK, TRIA3DEXLIST& lstTria, Tr CurrentTriangle.Set( CompoTriVert[nCompCount - 1][TriIndex].ptInt, CompoTriVert[nCompCount - 1][TriIndex+1].ptInt, CompoTriVert[nCompCount - 1][TriIndex+2].ptInt) ; - bool bV = CurrentTriangle.Validate( true) ; + bool bV = CurrentTriangle.Validate( true) ; // Aggiungo alla lista lstTria.emplace_back( CurrentTriangle) ; } @@ -1671,14 +1659,14 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Indici i,j,k dei vertici int IndexCorner[8][3] = { - { i, j, k}, - { i + 1, j, k}, - { i + 1, j + 1, k}, - { i, j + 1, k}, - { i, j, k + 1}, - { i + 1, j, k + 1}, - { i + 1, j + 1, k + 1}, - { i, j + 1, k + 1} + { i, j, k}, + { i + 1, j, k}, + { i + 1, j + 1, k}, + { i, j + 1, k}, + { i, j, k + 1}, + { i + 1, j, k + 1}, + { i + 1, j + 1, k + 1}, + { i, j + 1, k + 1} } ; static int intersections[12][2] = { @@ -1689,7 +1677,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Array di strutture punto di intersezione e normale alla superficie in esso. VectorField VecField[12] ; - // Flag di regolarità dei campi scalare e vettoriale + // Flag di regolarità dei campi scalare e vettoriale bool bReg = true ; // Ciclo sui segmenti @@ -1719,12 +1707,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold VectorField CompoTriVert[6][17] ; // Arrey numero di vertici della base del fan per componente - // connessa: nVertComp[i] contiene il numero di vertici - // della base del fan della (i+1)-esima componente connessa. + // connessa: nVertComp[i] contiene il numero di vertici + // della base del fan della (i+1)-esima componente connessa. int nVertComp[6] ; // Matrice di indici dei punti: serve per la gestione del caso - int nIndArrey[6][4] ; + int nIndArrey[6][4] ; int nExtTabOff = nComponents ; int nStdTabOff = 0 ; @@ -1735,152 +1723,108 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Numero vertici per componenti nVertComp[nCompCount - 1] = TriangleTableEn[nIndex][1][nCompCount] ; - // Riempio il nCompCount-esimo vettore di vertici della base del fan - for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) + // Riempio il nCompCount-esimo vettore di vertici della base del fan + for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) CompoVert[nCompCount - 1][nVertCount] = VecField[TriangleTableEn[nIndex][1][nVertCount + nExtTabOff + 1]] ; // Serve per la gestione del caso ... if ( nVertComp[nCompCount - 1] == 4) { - for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) + for ( int nVertCount = 0 ; nVertCount < nVertComp[nCompCount - 1] ; ++ nVertCount) nIndArrey[nCompCount - 1][nVertCount] = TriangleTableEn[nIndex][1][nVertCount + nExtTabOff + 1] ; } - // Riempio il nCompCount-esimo vettore di vertici dei triangoli in assenza di + // Riempio il nCompCount-esimo vettore di vertici dei triangoli in assenza di // sharp feature: in una mesh di triangoli con n vertici vi sono n - 2 triangoli. - for ( int nVertCount = 0 ; nVertCount < 3 * ( nVertComp[nCompCount - 1] - 2) ; nVertCount += 3) { + for ( int nVertCount = 0 ; nVertCount < 3 * ( nVertComp[nCompCount - 1] - 2) ; nVertCount += 3) { CompoTriVert[nCompCount - 1][nVertCount] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+2]] ; CompoTriVert[nCompCount - 1][nVertCount+1] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount+1]] ; CompoTriVert[nCompCount - 1][nVertCount+2] = VecField[TriangleTableEn[nIndex][0][nStdTabOff + nVertCount]] ; } - // Aggiorno gli offsets per raggiungere i - // vertici della componente successiva. + // Aggiorno gli offsets per raggiungere i vertici della componente successiva. nExtTabOff += nVertComp[nCompCount - 1] ; nStdTabOff += 3 * ( nVertComp[nCompCount - 1] - 2) ; } // Controllo se il voxel ha una sola faccia che giace in un piano canonico e quindi ha gestione speciale - // Faccia XY normale Z+ + // Faccia XY normale Z+ if ( nIndex == 15) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], Z_PLUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContXYSup.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContXYSup.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } - // Faccia YZ normale X+ + // Faccia YZ normale X+ else if ( nIndex == 153) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], X_PLUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContYZSup.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContYZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } // Faccia ZX normale Y+ else if ( nIndex == 51) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], Y_PLUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContXZSup.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContXZSup.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } // Faccia YX normale Z- else if ( nIndex == 240) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], Z_MINUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContXYInf.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContXYInf.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } // Faccia ZY normale X- else if ( nIndex == 102) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], X_MINUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContYZInf.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContYZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } // Faccia XZ normale Y- else if ( nIndex == 204) { - int nTool ; - double dPos ; + int nTool ; double dPos ; if ( CanonicPlaneTest( CompoVert[0], Y_MINUS, dPos, nTool)) { - int nN ; - GetVoxNFromIJK( i, j, k, nN) ; - HeigthAndColor FlatVox ; - FlatVox.nTool = nTool ; - FlatVox.dHeigth = dPos ; - VoxContXZInf.emplace( nN, FlatVox) ; + int nN ; GetVoxNFromIJK( i, j, k, nN) ; + VoxContXZInf.emplace( nN, HeigthAndColor( nTool, dPos)) ; continue ; } } - // Test sulla topologia: dal momento che il nostro test - // si fonda sugli angoli compresi fra le normali, esso ha - // senso solo se il campo è regolare. + // Test sulla topologia: richiede campo regolare perchè si fonda su angoli tra normali if ( bReg) { - if ( nAllConfig[nIndex] == 3) { + // Configurazione 3 + if ( nAllConfig[nIndex] == 3) { + + // Verifico concordanza tra i versori di una stessa componente + // (ogni coppia di vettori di una medesima componente deve avere prodotto scalare non inferiore a 0.7) Vector3d vtCmpAvg0, vtCmpAvg1 ; - - // Verifico se i versori delle componenti sono tutti - // più o meno concordi (per esserlo non devono esserci - // due vettori di una medesima componente con prodotto - // scalare inferiore a 0.7). bool bTest0 = DotTest( CompoVert[0], 3, vtCmpAvg0, 0.7) ; bool bTest1 = DotTest( CompoVert[1], 3, vtCmpAvg1, 0.7) ; - // Se i versori di entrambe le componenti sono concordi - // ha senso parlare di vettori medi, altrimenti non ha - // senso. Se non ha senso parlare di vettori medi non - // ha senso parlare di prodotti scalari fra loro, - // quindi pongo il loro prodotto a un valore assurdo -2 - // (il prodotto scalare fra versori ha modulo non superiore - // a uno). + // Se i versori di entrambe le componenti sono concordi ha senso parlare di vettori medi. + // Altrimenti assegno al loro prodotto scalare un valore assurdo come -2 double dScProd = - 2 ; - if ( bTest0 && bTest1) dScProd = vtCmpAvg0 * vtCmpAvg1 ; - double dThreshold = 0.7 ; - - if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > dThreshold)) { + if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > 0.7)) { int nt = 0 ; - while ( nIndexVsIndex3[nt][0] != nIndex) ++ nt ; - int nRotCase = nIndexVsIndex3[nt][1] ; nComponents = Cases3Plus[nRotCase][1][0] ; @@ -1891,75 +1835,57 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Modifico le matrici for ( int nC = 1 ; nC <= nComponents ; ++ nC) { - // Numero vertici per componenti nVertComp[nC - 1] = Cases3Plus[nRotCase][1][nC] ; - // Matrice dei vertici della base del fan for ( int nFanVert = 0 ; nFanVert < nVertComp[nC - 1] ; ++ nFanVert) - - CompoVert[nC - 1][nFanVert] = VecField[Cases3Plus[nRotCase][1][nFanVert + nExtTabOff + 1]] ; - + CompoVert[nC - 1][nFanVert] = VecField[Cases3Plus[nRotCase][1][nFanVert + nExtTabOff + 1]] ; // Matrici dei vertici dei triangoli in assenza di sharp feature for ( int nTriVert = 0 ; nTriVert < 3 * ( nVertComp[nC - 1] - 2) ; nTriVert += 3) { - CompoTriVert[nC - 1][nTriVert] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+2]] ; CompoTriVert[nC - 1][nTriVert+1] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert+1]] ; CompoTriVert[nC - 1][nTriVert+2] = VecField[Cases3Plus[nRotCase][0][nStdTabOff + nTriVert]] ; } - - // Aggiorno gli offsets per raggiungere i - // vertici della componente successiva. + // Aggiorno gli offsets per raggiungere i vertici della componente successiva. nExtTabOff += nVertComp[nC - 1] ; nStdTabOff += 3 * ( nVertComp[nC - 1] - 2) ; } - - } } + // Configurazione 6 else if ( nAllConfig[nIndex] == 6) { // Procedura analoga a quella della configurazione 3 Vector3d vtCmpAvg0, vtCmpAvg1 ; - bool bTest0 = DotTest( CompoVert[0], 4, vtCmpAvg0, 0.7) ; bool bTest1 = DotTest( CompoVert[1], 3, vtCmpAvg1, 0.7) ; double dScProd = - 2 ; - - if ( bTest0 && bTest1) + if ( bTest0 && bTest1) dScProd = vtCmpAvg0 * vtCmpAvg1 ; - double dThreshold = 0.7 ; - - if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > dThreshold)) { + if ( ! ( bTest0 && bTest1) || ( bTest0 && bTest1 && dScProd > 0.7)) { int nt = 0 ; - while ( nIndexVsIndex6[nt][0] != nIndex) ++ nt ; - int nRotCase = nIndexVsIndex6[nt][1] ; // Costruzione dei triangoli for ( int TriIndex = 0 ; TriIndex < 15 ; TriIndex += 3) { - - // Costruzione triangolo + // Indici vertici int i0 = Cases6Plus[nRotCase][TriIndex + 2] ; int i1 = Cases6Plus[nRotCase][TriIndex + 1] ; int i2 = Cases6Plus[nRotCase][TriIndex] ; - + // Costruzione triangolo Triangle3dEx CurrentTriangle ; - - // Il triangolo è pronto CurrentTriangle.Set( VecField[i0].ptInt, VecField[i1].ptInt, VecField[i2].ptInt) ; + CurrentTriangle.Validate( true) ; CurrentTriangle.SetVertexNorm( 0, VecField[i0].vtNorm) ; CurrentTriangle.SetVertexNorm( 1, VecField[i1].vtNorm) ; CurrentTriangle.SetVertexNorm( 2, VecField[i2].vtNorm) ; - bool bV = CurrentTriangle.Validate( true) ; CurrentTriangle.ToGlob( m_MapFrame) ; - // Aggiungo alla lista lstTria.emplace_back( CurrentTriangle) ; } @@ -1967,13 +1893,14 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold } } + // Configurazione 10 else if ( nAllConfig[nIndex] == 10) { - // Verifico se i versori delle componenti sono tutti - // più o meno concordi (soglia su prodotto scalare 0, forse 0.7?) + // Verifico concordanza tra i versori di una stessa componente + // (ogni coppia di vettori di una medesima componente deve avere prodotto scalare non inferiore a 0.0) Vector3d vtCmpAvg0, vtCmpAvg1 ; - bool bTest0 = DotTest( CompoVert[0], 4, vtCmpAvg0) ; - bool bTest1 = DotTest( CompoVert[1], 4, vtCmpAvg1) ; + bool bTest0 = DotTest( CompoVert[0], 4, vtCmpAvg0, 0.0) ; + bool bTest1 = DotTest( CompoVert[1], 4, vtCmpAvg1, 0.0) ; if ( ! bTest0 || ! bTest1) { int nt = 0 ; @@ -2015,19 +1942,16 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Ciclo sulle componenti for ( int nCompCount = 1 ; nCompCount <= nComponents ; ++ nCompCount) { - + int nFeatureType = NO_FEATURE ; // Se i componenti sono regolari valuto le normali per stabilire se eseguire ExtMC o MC if ( bReg) nFeatureType = TestOnNormal( CompoVert[nCompCount - 1], nVertComp[nCompCount - 1]) ; - - // Controllo per il caso piano su una griglia - // con versori normali a due a due paralleli. + + // Controllo per il caso piano su una griglia con versori normali a due a due paralleli bool bGridControl = true ; - if ( nFeatureType != NO_FEATURE) { - if ( nVertComp[nCompCount - 1] == 4) - GridControl( VecField, CompoVert, nIndArrey, nVertComp, nCompCount, bGridControl) ; - } + if ( nFeatureType != NO_FEATURE && nVertComp[nCompCount - 1] == 4) + GridControl( VecField, CompoVert, nIndArrey, nVertComp, nCompCount, bGridControl) ; // Flag ExtMC bool bExtMC = ( nFeatureType != NO_FEATURE && bGridControl) ; @@ -2038,7 +1962,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Passo al sistema di riferimento del baricentro Point3d ptGravityCenter( 0, 0, 0) ; for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) - ptGravityCenter = ptGravityCenter + CompoVert[nCompCount - 1][ni].ptInt ; + ptGravityCenter += CompoVert[nCompCount - 1][ni].ptInt ; ptGravityCenter = ptGravityCenter / nVertComp[nCompCount - 1] ; Vector3d vtTrasf[12] ; @@ -2053,12 +1977,29 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold dSystemMatrix dMatrixN( nVertComp[nCompCount - 1], 3) ; dSystemVector dKnownVector( nVertComp[nCompCount - 1], 1) ; + // medio le normali adiacenti molto vicine (delta angolare inferiore a 22.5 deg) + Vector3d vtNorm[12] ; + for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) + vtNorm[ni] = CompoVert[nCompCount - 1][ni].vtNorm ; + for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { + int nj = ( ni + 1) % nVertComp[nCompCount - 1] ; + if ( vtNorm[ni] * vtNorm[nj] > 0.92) { + Vector3d vtNI = ( 0.66 * vtNorm[ni] + 0.33 * vtNorm[nj]) ; + Vector3d vtNJ = ( 0.33 * vtNorm[ni] + 0.66 * vtNorm[nj]) ; + vtNorm[ni] = vtNI ; + vtNorm[ni].Normalize() ; + vtNorm[nj] = vtNJ ; + vtNorm[nj].Normalize() ; + ++ ni ; + } + } + // Caso generale for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { - dMatrixN( ni, 0) = CompoVert[nCompCount - 1][ni].vtNorm.x ; - dMatrixN( ni, 1) = CompoVert[nCompCount - 1][ni].vtNorm.y ; - dMatrixN( ni, 2) = CompoVert[nCompCount - 1][ni].vtNorm.z ; - dKnownVector( ni) = CompoVert[nCompCount - 1][ni].vtNorm * vtTrasf[ni] ; + dMatrixN( ni, 0) = vtNorm[ni].x ; + dMatrixN( ni, 1) = vtNorm[ni].y ; + dMatrixN( ni, 2) = vtNorm[ni].z ; + dKnownVector( ni) = vtNorm[ni] * vtTrasf[ni] ; } // calcolo SVD @@ -2089,18 +2030,17 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold int nFtVxI, nFtVxJ, nFtVxK ; if ( GetPointVoxel( ptSol, nFtVxI, nFtVxJ, nFtVxK)) { - - if ( abs( nFtVxI - i) > 2 || + if ( abs( nFtVxI - i) > 2 || abs( nFtVxJ - j) > 2 || abs( nFtVxK - k) > 2) bOutside = true ; } else { double dDistFeature = vtFeature.Len() ; - const double MAX_DIST = sqrt( 3) * N_DEXVOXRATIO * m_dStep ; + const double MAX_DIST = sqrt( 3) * N_DEXVOXRATIO * m_dStep ; bOutside = ( dDistFeature > MAX_DIST) ; - } - + } + TRIA3DEXVECTOR triContainer ; // Costruisco triangoli di prova @@ -2137,13 +2077,13 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Caso ventaglio con tre vertici di base if ( nVertComp[nCompCount - 1] == 3) { - + // Controllo se esiste almeno un triangolo con normale avente prodotto scalare - // negativo con la normale di almeno uno dei vertici di base del ventaglio. + // negativo con la normale di almeno uno dei vertici di base del ventaglio. bool bInversione = false ; for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { - int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; + int nj = ( ni + 1 < nVertComp[nCompCount - 1]) ? ni + 1 : 0 ; double dDI = triContainer[ni].GetN() * CompoVert[nCompCount - 1][ni].vtNorm ; double dDJ = triContainer[ni].GetN() * CompoVert[nCompCount - 1][nj].vtNorm ; @@ -2183,7 +2123,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // Se tale normale esiste if ( bInversione2) { - + // Se la soluzione non cade nel voxel di appartenenza vedo se può // essere riportata dentro muovendosi lungo la linea di feature. if ( ! IsPointInsideVoxelApprox( i, j, k, ptSol)) { @@ -2202,7 +2142,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold double dPar = abs( dParInt1) < abs( dParInt2) ? dParInt1 + ( dParInt2 - dParInt1) / 100 : dParInt2 + ( dParInt1 - dParInt2) / 100 ; - + ptSol += dPar * vtNullSpace ; // Costruisco triangoli di prova @@ -2222,10 +2162,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold else CurrentTriangle.SetGrade( 0) ; CurrentTriangle.Validate( true) ; - CurrentTriangle.SetVertexNorm( 0, V_NULL) ; - CurrentTriangle.SetVertexNorm( 1, V_NULL) ; - CurrentTriangle.SetVertexNorm( 2, V_NULL) ; - // Aggiungo triangolo al vettore temporaneo + // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } } @@ -2250,13 +2187,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold } } } - } + } // Ventaglio con base a quattro vertici else if ( nVertComp[nCompCount - 1] == 4) { - // Controllo se esiste almeno un triangolo con normale avente prodotto scalare - // negativo con la normale di almeno uno dei vertici di base del ventaglio. + // negativo con la normale di almeno uno dei vertici di base del ventaglio. bool bInversione = false ; for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { @@ -2270,12 +2206,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold } // Se tale triangolo esiste continuo i test if ( bInversione) { - + // Se la feature non cade nel suo voxel if ( ! IsPointInsideVoxelApprox( i, j, k, ptSol)) { Vector3d vtNullSpace( dMatrixV( 0, 2), dMatrixV( 1, 2), dMatrixV( 2, 2)) ; - + double dParInt1, dParInt2 ; Point3d ptVoxMin( ( i * N_DEXVOXRATIO + 0.5) * m_dStep, ( j * N_DEXVOXRATIO + 0.5) * m_dStep, ( k * N_DEXVOXRATIO + 0.5) * m_dStep) ; @@ -2289,7 +2225,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold double dPar = abs( dParInt1) < abs( dParInt2) ? dParInt1 + ( dParInt2 - dParInt1) / 100 : dParInt2 + ( dParInt1 - dParInt2) / 100 ; - + ptSol += dPar * vtNullSpace ; // Costruisco triangoli di prova for ( int ni = 0 ; ni < nVertComp[nCompCount - 1] ; ++ ni) { @@ -2305,12 +2241,9 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold else if ( CurrentTriangle.GetAttrib( 1) > 0 || CurrentTriangle.GetAttrib( 2) > 0) CurrentTriangle.SetGrade( 1) ; - else + else CurrentTriangle.SetGrade( 0) ; CurrentTriangle.Validate( true) ; - CurrentTriangle.SetVertexNorm( 0, V_NULL) ; - CurrentTriangle.SetVertexNorm( 1, V_NULL) ; - CurrentTriangle.SetVertexNorm( 2, V_NULL) ; // Aggiungo triangolo al vettore temporaneo triContainer.emplace_back( CurrentTriangle) ; } @@ -2415,7 +2348,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold triHold[nCurrent].vCompoTria[nOldFeatureNum].emplace_back( vInnerTriaTemp[ni]) ; } } - + // Triangoli di frontiera if ( vBorderTriaTemp.size() > 0) { @@ -2455,7 +2388,7 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold // ExtMC non confermato, si passa a MC else { - std::vector vTria ; + vector vTria ; // Costruzione dei triangoli for ( int TriIndex = 0; TriIndex < ( nVertComp[nCompCount - 1] - 2) * 3 ; TriIndex += 3) { // Il triangolo è pronto @@ -2476,17 +2409,17 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.SetGrade( nTool0) ; else if ( nTool1 == nTool2) CurrentTriangle.SetGrade( nTool1) ; - // Setto le normali del campo vettoriali ai relativi vertici se non siamo in - // caso di triangoli ribaltati, altrimenti chiamiamo solo Validate( true) - if ( ! CurrentTriangle.GetVertexNorm( 0).IsSmall() && - ! CurrentTriangle.GetVertexNorm( 1).IsSmall() && - ! CurrentTriangle.GetVertexNorm( 2).IsSmall()) { - CurrentTriangle.SetVertexNorm( 0, CompoTriVert[nCompCount - 1][TriIndex].vtNorm) ; - CurrentTriangle.SetVertexNorm( 1, CompoTriVert[nCompCount - 1][TriIndex+1].vtNorm) ; - CurrentTriangle.SetVertexNorm( 2, CompoTriVert[nCompCount - 1][TriIndex+2].vtNorm) ; + // Valido il triangolo e setto le normali del campo vettoriale ai corrispondenti vertici + if ( CurrentTriangle.Validate( true)) { + for ( int nV = 0 ; nV < 3 ; ++ nV) { + const Vector3d& vtVertNorm = CompoTriVert[nCompCount - 1][TriIndex+nV].vtNorm ; + // si può inserire controllo su normalizzazione di vtVertNorm + if ( CurrentTriangle.GetN() * vtVertNorm > 0.87) + CurrentTriangle.SetVertexNorm( nV, vtVertNorm) ; + else + CurrentTriangle.SetVertexNorm( nV, CurrentTriangle.GetN()) ; + } } - // Valido il triangolo - bool bV = CurrentTriangle.Validate( true) ; // Riporto le coordinate nel sistema in cui è immerso lo Zmap CurrentTriangle.ToGlob( m_MapFrame) ; // Aggiungo alla lista @@ -2505,12 +2438,12 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold } } for ( int nT = 0 ; nT < int( vTria.size()) ; ++ nT) - lstTria.emplace_back( vTria[nT]) ; + lstTria.emplace_back( vTria[nT]) ; } } // Standard MC - else { + else { // Costruzione dei triangoli for ( int TriIndex = 0; TriIndex < ( nVertComp[nCompCount - 1] - 2) * 3 ; TriIndex += 3) { // Il triangolo è pronto @@ -2518,20 +2451,27 @@ VolZmap::ExtMarchingCubes( int nBlock, TRIA3DEXLIST& lstTria, TriHolder& triHold CurrentTriangle.Set( CompoTriVert[nCompCount - 1][TriIndex].ptInt, CompoTriVert[nCompCount - 1][TriIndex+1].ptInt, CompoTriVert[nCompCount - 1][TriIndex+2].ptInt) ; - // Setto il numero di utensile - int nTool0 = CompoTriVert[nCompCount - 1][TriIndex].nToolFlag ; - int nTool1 = CompoTriVert[nCompCount - 1][TriIndex+1].nToolFlag ; - int nTool2 = CompoTriVert[nCompCount - 1][TriIndex+2].nToolFlag ; + // Setto il numero di utensile (conta solo positivo, nullo o negativo) + int nTool0 = Clamp( CompoTriVert[nCompCount - 1][TriIndex].nToolFlag, -1, 1) ; + int nTool1 = Clamp( CompoTriVert[nCompCount - 1][TriIndex+1].nToolFlag, -1, 1) ; + int nTool2 = Clamp( CompoTriVert[nCompCount - 1][TriIndex+2].nToolFlag, -1, 1) ; if ( nTool0 == nTool1 || nTool0 == nTool2) - CurrentTriangle.SetGrade( nTool0) ; + CurrentTriangle.SetGrade( nTool0) ; else if ( nTool1 == nTool2) CurrentTriangle.SetGrade( nTool1) ; - // Setto le normali del campo vettoriali ai relativi vertici - CurrentTriangle.SetVertexNorm( 0, CompoTriVert[nCompCount - 1][TriIndex].vtNorm) ; - CurrentTriangle.SetVertexNorm( 1, CompoTriVert[nCompCount - 1][TriIndex+1].vtNorm) ; - CurrentTriangle.SetVertexNorm( 2, CompoTriVert[nCompCount - 1][TriIndex+2].vtNorm) ; - // Valido il triangolo - bool bV = CurrentTriangle.Validate( true) ; + // Valido il triangolo e setto le normali del campo vettoriale ai corrispondenti vertici + if ( CurrentTriangle.Validate( true)) { + for ( int nV = 0 ; nV < 3 ; ++ nV) { + const Vector3d& vtVertNorm = CompoTriVert[nCompCount - 1][TriIndex+nV].vtNorm ; + if ( CurrentTriangle.GetN() * vtVertNorm > 0.87) + CurrentTriangle.SetVertexNorm( nV, vtVertNorm) ; + else + CurrentTriangle.SetVertexNorm( nV, CurrentTriangle.GetN()) ; + } + } + else + int qqq = 0 ; + // si può inserire controllo sui colori per i casi 2 e 8 come per ext non confermato // Riporto le coordinate nel sistema in cui è immerso lo Zmap CurrentTriangle.ToGlob( m_MapFrame) ; // Aggiungo alla lista @@ -2565,7 +2505,7 @@ VolZmap::ExtMarchingCubes( vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh TriHolder triHold ; int nOriginalSize = int( vVox.size()) ; for ( int nV = 0 ; nV < int( vVox.size()) ; ++ nV) { - // I voxel intersecati dalla retta hanno indice nel vettore + // I voxel intersecati dalla retta hanno indice nel vettore // nV < OriginalSize; quelli adiacenti avranno indice // nV >= OriginalSize if ( nV < nOriginalSize) { @@ -2588,7 +2528,6 @@ VolZmap::ExtMarchingCubes( vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh // lo ignoro, altrimenti lo metto in coda nel TriHolder. int nOldV = 0 ; for ( ; nOldV < nOriginalSize ; ++ nOldV) { - if ( vVox[nOldV].nI == vVox[nV].nI + i || vVox[nOldV].nJ == vVox[nV].nJ + j || vVox[nOldV].nK == vVox[nV].nK + k) @@ -2596,11 +2535,11 @@ VolZmap::ExtMarchingCubes( vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh } if ( nOldV == nOriginalSize) { Voxel NewVox ; - NewVox.nI = vVox[nV].nI + i ; - NewVox.nJ = vVox[nV].nJ + j ; - NewVox.nK = vVox[nV].nK + k ; + NewVox.nI = vVox[nV].nI + i ; + NewVox.nJ = vVox[nV].nJ + j ; + NewVox.nK = vVox[nV].nK + k ; vVox.emplace_back( NewVox) ; - } + } } } } @@ -2609,11 +2548,11 @@ VolZmap::ExtMarchingCubes( vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh } // Se il voxel non è attraversato dalla retta, ma fa parte di // quelli adiacenti lo processiamo normalmente - else + else ProcessCube( vVox[nV].nI, vVox[nV].nJ, vVox[nV].nK, lstTria, triHold, bEnh) ; } // Eseguo il flipping - FlipEdgesII( triHold, false) ; + FlipEdgesII( triHold) ; // Aggiungo alla lista di triangoli, tutti quelli che formano una sharp-feature. for ( int nVox = 0 ; nVox < int( triHold.size()) ; ++ nVox) { for ( int nCompo = 0 ; nCompo < int( triHold[nVox].vCompoTria.size()) ; ++ nCompo) { @@ -2627,57 +2566,34 @@ VolZmap::ExtMarchingCubes( vector& vVox, TRIA3DEXLIST& lstTria, bool bEnh } //---------------------------------------------------------------------------- -// Esegue il flipping dei triangoli contenuti nel TriHolder. -// Se si usa la funzione per la visualizzazione dei triangoli, -// bGraph deve valere true, se si intende calcolare la profondità -// del materiale bGraph deve valere false. +// Esegue il flipping dei triangoli contenuti nel TriHolder, +// bGraph indica se chiamata per grafica o per calcolo di profondità. bool -VolZmap::FlipEdgesII( TriHolder& TriHold, bool bGraph) const +VolZmap::FlipEdgesII( TriHolder& TriHold) const { // Numero di voxel in cui si presentano sharp feature int nVoxelNum = int( TriHold.size()) ; - // Ciclo su tali voxel + // Ciclo sui voxel con sharp feature for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) { - for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) { - - // Flag voxel adiacenti o meno - bool bAdj ; - // Se la funzione è chiamata per la grafica i voxel sono ordinati nel TriHolder, - // non serve confrontare i triangoli con quelli dei voxel precedenti. - if ( bGraph) { - bAdj = ( TriHold[n2].i >= TriHold[n1].i && TriHold[n2].i <= TriHold[n1].i + 1) || - ( TriHold[n2].j >= TriHold[n1].j && TriHold[n2].j <= TriHold[n1].j + 1) || - ( TriHold[n2].k >= TriHold[n1].k && TriHold[n2].k <= TriHold[n1].k + 1) ; - } - // Se la funzione è chiamata per il calcolo della profondità del materiale i voxel non - // sono ordinati nel TriHolder, quindi può capitare di dover confrontare i triangoli con - // quelli dei voxel precedenti. - else { - bAdj = abs( TriHold[n2].i - TriHold[n1].i) == 1 || - abs( TriHold[n2].j - TriHold[n1].j) == 1 || - abs( TriHold[n2].k - TriHold[n1].k) == 1 ; - } // Se i voxel sono adiacenti proseguo - if ( ( TriHold[n2].i >= TriHold[n1].i && TriHold[n2].i <= TriHold[n1].i + 1) || - ( TriHold[n2].j >= TriHold[n1].j && TriHold[n2].j <= TriHold[n1].j + 1) || - ( TriHold[n2].k >= TriHold[n1].k && TriHold[n2].k <= TriHold[n1].k + 1)) { + if ( abs( TriHold[n2].i - TriHold[n1].i) <= 1 || + abs( TriHold[n2].j - TriHold[n1].j) <= 1 || + abs( TriHold[n2].k - TriHold[n1].k) <= 1 ) { // Numero delle componenti connesse nei due voxel int nNumCompo1 = int( TriHold[n1].ptCompoVert.size()) ; int nNumCompo2 = int( TriHold[n2].ptCompoVert.size()) ; - int nCompo1 = 0 ; - // Ciclo sulle componenti - for ( ; nCompo1 < nNumCompo1 ; ++ nCompo1) { + int nCompo1 = 0 ; + for ( ; nCompo1 < nNumCompo1 ; ++ nCompo1) { int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ; - for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) { - + // Numero di triangoli per le componenti connesse int nTriNum1 = int( TriHold[n1].vCompoTria[nCompo1].size()) ; int nTriNum2 = int( TriHold[n2].vCompoTria[nCompo2].size()) ; @@ -2704,16 +2620,13 @@ VolZmap::FlipEdgesII( TriHolder& TriHold, bool bGraph) const if ( ! ( AreSamePointEpsilon( ptP1, ptVert1, EPS_ZERO) || AreSamePointEpsilon( ptP2, ptVert2, EPS_ZERO))) { - SharedIndex.emplace_back( nVert1) ; SharedIndex.emplace_back( nVert2) ; } } - if ( SharedIndex.size() > 2) break ; } - if ( SharedIndex.size() > 2) break ; } @@ -2762,12 +2675,11 @@ VolZmap::FlipEdgesII( TriHolder& TriHold, bool bGraph) const // Vertice condiviso fra nTri1 e quello del suo fan int nCol1 = TriHold[n1].vCompoTria[nCompo1][nTri1].GetAttrib( SharedIndex[2]) ; int nCol2 = TriHold[n2].vCompoTria[nCompo2][nTri2].GetAttrib( SharedIndex[1]) ; - // Modifico i punti e gli indici TriHold[n1].vCompoTria[nCompo1][nTri1].SetP( SharedIndex[0], - TriHold[n2].ptCompoVert[nCompo2]) ; + TriHold[n2].ptCompoVert[nCompo2]) ; TriHold[n2].vCompoTria[nCompo2][nTri2].SetP( SharedIndex[3], - TriHold[n1].ptCompoVert[nCompo1]) ; + TriHold[n1].ptCompoVert[nCompo1]) ; TriHold[n1].vCompoTria[nCompo1][nTri1].SetGrade( nCol1) ; TriHold[n2].vCompoTria[nCompo2][nTri2].SetGrade( nCol2) ; // Valido i triangoli @@ -2792,14 +2704,12 @@ VolZmap::FlipEdgesII( TriHolder& TriHold, bool bGraph) const TriHold[n1].vCompoTria[nCompo1][nTri1].SetVertexNorm( nFeatureIndex1, vtNorm1) ; TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( SharedIndex[3], vtNorm2) ; TriHold[n2].vCompoTria[nCompo2][nTri2].SetVertexNorm( nFeatureIndex2, vtNorm2) ; - bModified = true ; break ; } } } } - if ( bModified) break ; } @@ -2807,25 +2717,7 @@ VolZmap::FlipEdgesII( TriHolder& TriHold, bool bGraph) const } } } - // La gestione dei triangoli ribaltati annulla le normali ai vertici - // di tutti i triangoli del fan. A quelli che poi partecipano a un flipping - // le normali vengono aggiustate in tale sede, ai rimanenti devono ancora essere - // aggiustate. Tale operazione è svolta qui. - int nNumComp = int( TriHold[n1].ptCompoVert.size()) ; - for ( int nComp = 0 ; nComp < nNumComp ; ++ nComp) { - int nTriNum = int( TriHold[n1].vCompoTria[nComp].size()) ; - for ( int nTri = 0 ; nTri < nTriNum ; ++ nTri) { - Vector3d vtV0 = TriHold[n1].vCompoTria[nComp][nTri].GetVertexNorm( 0) ; - Vector3d vtV1 = TriHold[n1].vCompoTria[nComp][nTri].GetVertexNorm( 1) ; - Vector3d vtV2 = TriHold[n1].vCompoTria[nComp][nTri].GetVertexNorm( 2) ; - if ( vtV0.SqLen() < EPS_SMALL * EPS_SMALL || - vtV1.SqLen() < EPS_SMALL * EPS_SMALL || - vtV2.SqLen() < EPS_SMALL * EPS_SMALL) - TriHold[n1].vCompoTria[nComp][nTri].Validate( true) ; - } - } } - return true ; } @@ -2848,8 +2740,8 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const GetBlockIJKFromN( int( tLB), nLBijk) ; // Se i blocchi non sono adiacenti salto l'iterazione - if ( ! ( abs( nFBijk[0] - nLBijk[0]) <= 1 && - abs( nFBijk[1] - nLBijk[1]) <= 1 && + if ( ! ( abs( nFBijk[0] - nLBijk[0]) <= 1 && + abs( nFBijk[1] - nLBijk[1]) <= 1 && abs( nFBijk[2] - nLBijk[2]) <= 1)) continue ; @@ -2860,22 +2752,17 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const // Ciclo sui voxel dei due blocchi for ( size_t tVFB = 0 ; tVFB < nVoxelNumFB ; ++ tVFB) { for ( size_t tVLB = 0 ; tVLB < nVoxelNumLB ; ++ tVLB) { - // Se i voxel non sono adiacenti salto l'iterazione - if ( ! ( abs( InterTria[tFB][tVFB].i - InterTria[tLB][tVLB].i) <= 1 && - abs( InterTria[tFB][tVFB].j - InterTria[tLB][tVLB].j) <= 1 && + if ( ! ( abs( InterTria[tFB][tVFB].i - InterTria[tLB][tVLB].i) <= 1 && + abs( InterTria[tFB][tVFB].j - InterTria[tLB][tVLB].j) <= 1 && abs( InterTria[tFB][tVFB].k - InterTria[tLB][tVLB].k) <= 1)) - continue ; - // Numero di componenti connesse dei voxel size_t nCompoVFBNum = InterTria[tFB][tVFB].ptCompoVert.size() ; size_t nCompoVLBNum = InterTria[tLB][tVLB].ptCompoVert.size() ; - // Ciclo sulle componenti connesse for ( size_t tCmpF = 0 ; tCmpF < nCompoVFBNum ; ++ tCmpF) { for ( size_t tCmpL = 0 ; tCmpL < nCompoVLBNum ; ++ tCmpL) { - // Numero di triangoli delle componenti connesse size_t nTriFBNum = InterTria[tFB][tVFB].vCompoTria[tCmpF].size() ; size_t nTriLBNum = InterTria[tLB][tVLB].vCompoTria[tCmpL].size() ; @@ -2988,7 +2875,6 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const InterTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( nFeatureIndexF, vtNormF) ; InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( SharedIndex[3], vtNormL) ; InterTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( nFeatureIndexL, vtNormL) ; - bModified = true ; break ; } @@ -3003,26 +2889,6 @@ VolZmap::FlipEdgesBB( TriaMatrix& InterTria) const } } } - // La gestione dei triangoli ribaltati annulla le normali ai vertici - // di tutti i triangoli del fan. A quelli che poi partecipano a un flipping - // le normali vengono aggiustate in tale sede, ai rimanenti devono ancora essere - // aggiustate. Tale operazione è svolta qui. - int nVoxelNum = int( InterTria[tFB].size()) ; - for ( int nVox = 0 ; nVox < nVoxelNum ; ++ nVox) { - int nCompNum = int( InterTria[tFB][nVox].ptCompoVert.size()) ; - for ( int nComp = 0 ; nComp < nCompNum ; ++ nComp) { - int nTriNum = int( InterTria[tFB][nVox].vCompoTria[nComp].size()) ; - for ( int nTri = 0 ; nTri < nTriNum ; ++ nTri) { - Vector3d vtV0 = InterTria[tFB][nVox].vCompoTria[nComp][nTri].GetVertexNorm( 0) ; - Vector3d vtV1 = InterTria[tFB][nVox].vCompoTria[nComp][nTri].GetVertexNorm( 1) ; - Vector3d vtV2 = InterTria[tFB][nVox].vCompoTria[nComp][nTri].GetVertexNorm( 2) ; - if ( vtV0.SqLen() < EPS_SMALL * EPS_SMALL || - vtV1.SqLen() < EPS_SMALL * EPS_SMALL || - vtV2.SqLen() < EPS_SMALL * EPS_SMALL) - InterTria[tFB][nVox].vCompoTria[nComp][nTri].Validate( true) ; - } - } - } } return true ; } @@ -3068,7 +2934,7 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const // verifica spillone su vertice size_t nIndex = 0 ; unsigned int nPos = nGrJ * m_nNx[nGrid] + nGrI ; - size_t nDexSize = m_Values[nGrid][nPos].size() ; + size_t nDexSize = m_Values[nGrid][nPos].size() ; while ( nIndex < nDexSize) { if ( dZ > m_Values[nGrid][nPos][nIndex].dMin - 2 * EPS_SMALL && dZ < m_Values[nGrid][nPos][nIndex].dMax + 2 * EPS_SMALL) { @@ -3076,7 +2942,7 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const break ; } nIndex += 1 ; - } + } } return ( nCount == 3) ; } @@ -3303,9 +3169,9 @@ bool VolZmap::GetVoxIJKFromN( int nN, int& nI, int& nJ, int& nK) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Controllo sulla validità del voxel if ( nN < 0 || nN >= nVoxNumX * nVoxNumY * nVoxNumZ) @@ -3327,16 +3193,16 @@ bool VolZmap::GetVoxNFromIJK( int nI, int nJ, int nK, int& nN) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Controllo la validità del voxel if ( nI <= - 2 || nI >= nVoxNumX - 1 || nJ <= - 2 || nJ >= nVoxNumY - 1 || nK <= - 2 || nK >= nVoxNumZ - 1 ) return false ; - + // Calcolo il numero di Voxel nN = nVoxNumX * nVoxNumY * ( nK + 1) + nVoxNumX * ( nJ + 1) + nI + 1 ; @@ -3388,24 +3254,24 @@ VolZmap::GetBlockLimitsIJK( const int nIJK[], int nLimits[]) const return false ; // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Calcolo limiti per l'indice i - nLimits[0] = ( nIJK[0] == 0 ? - 1 : nIJK[0] * int( m_nVoxNumPerBlock)) ; + nLimits[0] = ( nIJK[0] == 0 ? - 1 : nIJK[0] * int( m_nVoxNumPerBlock)) ; nLimits[1] = ( nIJK[0] + 1 == int( m_nFracLin[0]) ? nVoxNumX - 1 : ( nIJK[0] + 1) * int( m_nVoxNumPerBlock)) ; // Calcolo limiti per l'indice j - nLimits[2] = ( nIJK[1] == 0 ? - 1 : nIJK[1] * int( m_nVoxNumPerBlock)) ; + nLimits[2] = ( nIJK[1] == 0 ? - 1 : nIJK[1] * int( m_nVoxNumPerBlock)) ; nLimits[3] = ( nIJK[1] + 1 == int( m_nFracLin[1]) ? nVoxNumY - 1 : ( nIJK[1] + 1) * int( m_nVoxNumPerBlock)) ; // Calcolo limiti per l'indice k - nLimits[4] = ( nIJK[2] == 0 ? - 1 : nIJK[2] * int( m_nVoxNumPerBlock)) ; + nLimits[4] = ( nIJK[2] == 0 ? - 1 : nIJK[2] * int( m_nVoxNumPerBlock)) ; nLimits[5] = ( nIJK[2] + 1 == int( m_nFracLin[2]) ? - nVoxNumZ - 1 : ( nIJK[2] + 1) * int( m_nVoxNumPerBlock)) ; + nVoxNumZ - 1 : ( nIJK[2] + 1) * int( m_nVoxNumPerBlock)) ; return true ; } @@ -3415,9 +3281,9 @@ bool VolZmap::IsPointInsideVoxelApprox( int nI, int nJ, int nK, const Point3d& ptP, double dPrec) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Controllo sulla validità del voxel if ( nI <= - 2 || nI >= nVoxNumX - 1 || nJ <= - 2 || nJ >= nVoxNumY - 1 || @@ -3433,7 +3299,7 @@ VolZmap::IsPointInsideVoxelApprox( int nI, int nJ, int nK, const Point3d& ptP, d ptP.y < ( ( nJ + 1) * N_DEXVOXRATIO + 0.5) * m_dStep + dPrec ; bool bK = ptP.z > ( nK * N_DEXVOXRATIO + 0.5) * m_dStep - dPrec && ptP.z < ( ( nK + 1) * N_DEXVOXRATIO + 0.5) * m_dStep + dPrec ; - + return ( bI && bJ && bK) ; } @@ -3442,15 +3308,15 @@ bool VolZmap::GetPointVoxel( const Point3d& ptP, int& nVoxI, int& nVoxJ, int& nVoxK) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Calcolo gli indici del voxel nVoxI = int( floor( ( ptP.x - 0.5 * m_dStep) / ( m_dStep * N_DEXVOXRATIO))) ; nVoxJ = int( floor( ( ptP.y - 0.5 * m_dStep) / ( m_dStep * N_DEXVOXRATIO))) ; nVoxK = int( floor( ( ptP.z - 0.5 * m_dStep) / ( m_dStep * N_DEXVOXRATIO))) ; // Controllo la validità del voxel - return ( nVoxI >= - 1 && nVoxI < nVoxNumX - 1) && + return ( nVoxI >= - 1 && nVoxI < nVoxNumX - 1) && ( nVoxJ >= - 1 && nVoxJ < nVoxNumY - 1) && ( nVoxK >= - 1 && nVoxK < nVoxNumZ - 1) ; } @@ -3460,9 +3326,9 @@ bool VolZmap::GetVoxelBlockIJK( const int nVoxIJK[], int nBlockIJK[]) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Controllo sull'ammissibilità del voxel if ( nVoxIJK[0] <= - 2 || nVoxIJK[0] >= nVoxNumX - 1 || nVoxIJK[1] <= - 2 || nVoxIJK[1] >= nVoxNumY - 1 || @@ -3505,12 +3371,12 @@ bool VolZmap::IsAVoxelOnBoundary( const int nLimits[], const int nIJK[], bool bType) const { // Calcolo il numero di voxel lungo X,Y e Z - int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; - int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumX = int( m_nNx[0] / N_DEXVOXRATIO + ( m_nNx[0] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumY = int( m_nNy[0] / N_DEXVOXRATIO + ( m_nNy[0] / N_DEXVOXRATIO == 0 ? 1 : 2)) ; + int nVoxNumZ = int( m_nNy[1] / N_DEXVOXRATIO + ( m_nNy[1] % N_DEXVOXRATIO == 0 ? 1 : 2)) ; // Test sulla validità dei limiti - if ( nLimits[0] < - 1 || nLimits[0] > nVoxNumX - 1 || + if ( nLimits[0] < - 1 || nLimits[0] > nVoxNumX - 1 || nLimits[1] < - 1 || nLimits[1] > nVoxNumX - 1 || nLimits[2] < - 1 || nLimits[2] > nVoxNumY - 1 || nLimits[3] < - 1 || nLimits[3] > nVoxNumY - 1 || @@ -3622,7 +3488,7 @@ VolZmap::ProcessVoxContXY( VoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& { VoxelContainer::iterator it = VoxContXY.begin() ; while ( it != VoxContXY.end()) { - + int nN = ( *it).first ; int nI, nJ, nK ; GetVoxIJKFromN( nN, nI, nJ, nK) ; @@ -3634,7 +3500,7 @@ VolZmap::ProcessVoxContXY( VoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& int nMaxJ = nJ ; int nToolNum = ( *it).second.nTool ; double dCordZ = ( *it).second.dHeigth ; - + // Flag sul ritrovamento di un rettangolo più grande. bool bOkI = true ; bool bOkJ = true ; @@ -3668,7 +3534,7 @@ VolZmap::ProcessVoxContXY( VoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& bOkI = bSupJ || bInfJ ; } // altrimenti se precedente espansione J ok - else if ( bOkJ) { + else if ( bOkJ) { // Analizzo linea destra bool bSupI = true ; for ( int j = nMinJ ; bSupI && j <= nMaxJ ; ++ j) { @@ -3694,7 +3560,7 @@ VolZmap::ProcessVoxContXY( VoxelContainer& VoxContXY, bool bPlus, TRIA3DEXLIST& -- nMinI ; } bOkJ = bSupI || bInfI ; - } + } } Point3d ptT0( ( nMinI * N_DEXVOXRATIO + 0.5) * m_dStep, @@ -3744,7 +3610,7 @@ VolZmap::ProcessVoxContYZ( VoxelContainer& VoxContYZ, bool bPlus, TRIA3DEXLIST& { VoxelContainer::iterator it = VoxContYZ.begin() ; while ( it != VoxContYZ.end()) { - + int nN = ( *it).first ; int nI, nJ, nK ; GetVoxIJKFromN( nN, nI, nJ, nK) ; @@ -3761,7 +3627,7 @@ VolZmap::ProcessVoxContYZ( VoxelContainer& VoxContYZ, bool bPlus, TRIA3DEXLIST& bool bOkJ = true ; bool bOkK = true ; while ( bOkJ || bOkK) { - // Se precedente espansione ok e lato J più lungo o non ok K + // Se precedente espansione ok e lato J più lungo o non ok K if ( bOkJ && ( nMaxJ - nMinJ >= nMaxK - nMinK || ! bOkK)) { // Analizzo linea superiore bool bSupK = true ; @@ -3816,7 +3682,7 @@ VolZmap::ProcessVoxContYZ( VoxelContainer& VoxContYZ, bool bPlus, TRIA3DEXLIST& -- nMinJ ; } bOkK = bSupJ || bInfJ ; - } + } } Point3d ptT0( dCordX, ( nMinJ * N_DEXVOXRATIO + 0.5) * m_dStep, @@ -3852,7 +3718,7 @@ VolZmap::ProcessVoxContYZ( VoxelContainer& VoxContYZ, bool bPlus, TRIA3DEXLIST& // Elimino il voxel da cui sono partito a ingrandire. VoxContYZ.erase( nN) ; - + // Passo al primo voxel rimasto it = VoxContYZ.begin() ; } @@ -3866,7 +3732,7 @@ VolZmap::ProcessVoxContXZ( VoxelContainer& VoxContXZ, bool bPlus, TRIA3DEXLIST& { VoxelContainer::iterator it = VoxContXZ.begin() ; while ( it != VoxContXZ.end()) { - + int nN = ( *it).first ; int nI, nJ, nK ; GetVoxIJKFromN( nN, nI, nJ, nK) ; @@ -3915,7 +3781,7 @@ VolZmap::ProcessVoxContXZ( VoxelContainer& VoxContXZ, bool bPlus, TRIA3DEXLIST& else if ( bOkK) { // Analizzo linea destra bool bSupI = true ; - for ( int k = nMinK ; bSupI && k <= nMaxK ; ++ k) { + for ( int k = nMinK ; bSupI && k <= nMaxK ; ++ k) { if ( ! Find( VoxContXZ, nMaxI + 1, nJ, k, dCordY, nToolNum)) bSupI = false ; } @@ -3938,7 +3804,7 @@ VolZmap::ProcessVoxContXZ( VoxelContainer& VoxContXZ, bool bPlus, TRIA3DEXLIST& -- nMinI ; } bOkK = bSupI || bInfI ; - } + } } Point3d ptT0( ( nMinI * N_DEXVOXRATIO + 0.5) * m_dStep, dCordY, diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index c8189f5..4bcc4cb 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -15,6 +15,7 @@ #include "stdafx.h" #include "CurveLine.h" +#include "CurveArc.h" #include "VolZmap.h" #include "GeoConst.h" #include "IntersLineSurfTm.h" @@ -669,6 +670,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& break ; } } + // Fresatura con vettore movimento perpendicolare all'utensile else if ( abs( vtMove.z) < EPS_SMALL) { switch ( m_Tool.GetType()) { @@ -690,6 +692,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& break ; } } + // Fresatura con vettore movimento generico rispetto all'utensile else { switch ( m_Tool.GetType()) { @@ -705,6 +708,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& } } } + // Versore utensile nel piano else if ( abs( vtLs[i].z) < EPS_SMALL) { @@ -825,6 +829,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& } } } + else ; // Altri casi al momento non gestiti // return false ; @@ -1764,105 +1769,84 @@ VolZmap::Chs_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& pt //---------------------------------------------------------------------------- bool -VolZmap::GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +VolZmap::GenTool_ZDrilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - // Posizioni iniziale e finale dell'utensile + // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; Point3d ptF = ptE ; - // vettore movimento + // Vettore movimento Vector3d vtMove = ptE - ptS ; - // Settaggio profilo - const CurveComposite* pToolProfile = m_Tool.GetOutline() ; - // Ciclo sulle curve + const CurveComposite* pToolProfile = m_Tool.GetOutline() ; const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { - + double dHeight ; - int nCurveType = pCurve -> GetType() ; - // Caso segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro + // Se segmento + if ( pCurve->GetType() == CRV_LINE) { + // Recupero gli estremi + const ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptStart = pLine->GetStart() ; + Point3d ptEnd = pLine->GetEnd() ; + // 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 ; CompCyl_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } - - // Il componente è 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) ; } - - // Il componente è un cono con vettore opposto a quello dell'utesile + // 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 ; - CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } + CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } } - - else - dHeight = 0 ; } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; - - + // se altrimenti 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) ; - } + } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; - // Aggiorno il puntatore + // Passo alla curva successiva del profilo pCurve = pToolProfile->GetNextCurve() ; } + return true ; } //---------------------------------------------------------------------------- bool -VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { // Posizioni iniziale e finale dell'utensile Point3d ptI = ptS ; @@ -1871,43 +1855,34 @@ VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 // vettore movimento Vector3d vtMove = ptE - ptS ; - // Settaggio profilo + // Ciclo sulle curve del profilo utensile const CurveComposite* pToolProfile = m_Tool.GetOutline() ; - - // Ciclo sulle curve const ICurve* pCurve = pToolProfile->GetFirstCurve() ; while ( pCurve != nullptr) { double dHeight ; - int nCurveType = pCurve -> GetType() ; - - // Caso segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro + // Se segmento + if ( pCurve->GetType() == CRV_LINE) { + // Recupero gli estremi + const ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptStart = pLine->GetStart() ; + Point3d ptEnd = pLine->GetEnd() ; + // 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 ; CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } - - // Il componente è 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) ; } - - // Il componente è 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 ; @@ -1916,34 +1891,21 @@ VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; } } - - else - dHeight = 0 ; } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - + // se altrimenti 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, ptOSt, ptOEn, dRadius) ; - + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; } @@ -1952,9 +1914,10 @@ VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; - // Aggiorno il puntatore + // Passo alla curva successiva del profilo pCurve = pToolProfile->GetNextCurve() ; } + return true ; } @@ -3029,95 +2992,61 @@ VolZmap::Chs_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE //---------------------------------------------------------------------------- bool -VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +VolZmap::GenTool_Drilling( unsigned 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 ; - // Settaggio profilo + // Ciclo sulle curve del profilo const CurveComposite* pToolProfile = m_Tool.GetOutline() ; - - // Ciclo sulle curve + const ICurve* pPrevCurve = nullptr ; const ICurve* pCurve = pToolProfile->GetFirstCurve() ; - const ICurve* pFirstConst = pCurve ; - while ( pCurve != nullptr) { double dHeight ; - int nCurveType = pCurve -> GetType() ; - - // Caso di segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - bool bTapB, bTapT ; - - pCurve = pToolProfile -> GetPrevCurve() ; - - // Dettagli curva precedente - int nPrevType = pCurve -> GetType() ; - Point3d ptPrevFirst, ptPrevLast ; - pCurve -> GetStartPoint( ptPrevFirst) ; - pCurve -> GetEndPoint( ptPrevLast) ; - - double dAbsDYPr = abs( ptPrevFirst.y - ptPrevLast.y) ; - double dDeltaXPr = ptPrevFirst.x - ptPrevLast.x ; - - // Setto le variabili per il tappo superiore - if ( pCurve == pFirstConst || - nPrevType == CRV_ARC || - ( dDeltaXPr < 0 && dAbsDYPr)) - bTapB = false ; - else - bTapB = true ; - - // Dettagli curva successiva - - pCurve = pToolProfile -> GetNextCurve() ; - pCurve = pToolProfile -> GetNextCurve() ; - - int nNextType = pCurve -> GetType() ; - Point3d ptNextFirst ; - Point3d ptNextLast ; - pCurve -> GetStartPoint( ptNextFirst) ; - pCurve -> GetEndPoint( ptNextLast) ; - - double dAbsDYNx = abs( ptNextFirst.y - ptNextLast.y) ; - double dDeltaXNx = ptNextFirst.x - ptNextLast.x ; - double dAbsXEnd = abs( ptNextLast.x) ; - - if ( pCurve == nullptr || - nNextType == CRV_ARC || - ( dAbsDYNx < EPS_SMALL && ( dDeltaXNx > 0 || dAbsXEnd < EPS_SMALL))) - bTapT = false ; - else - bTapT = true ; - - // Il componente è un cilindro + // Se segmento + if ( pCurve->GetType() == CRV_LINE) { + // Recupero gli estremi + const ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptStart = pLine->GetStart() ; + Point3d ptEnd = pLine->GetEnd() ; + // 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 = pToolProfile->GetNextCurve() ; + 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 ; CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; } - - // Il componente è 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) ; } - - // Il componente è 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 ; @@ -3125,49 +3054,40 @@ VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 Point3d ptFn = ptIn + vtMove ; CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB) ; } + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pNextCurve ; } - else { - dHeight = 0 ; - pCurve = pToolProfile -> GetNextCurve() ; + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pToolProfile->GetNextCurve() ; } } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - + // 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 ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - + Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; + Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; - + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; - - pCurve = pToolProfile -> GetNextCurve() ; + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pToolProfile->GetNextCurve() ; } // Determino le posizioni iniziale e finale del componente successivo ptI = ptI - vtToolDir * dHeight ; ptF = ptI + vtMove ; - - // Aggiorno il puntatore - // pCurve = pToolProfile->GetNextCurve() ; } return true ; @@ -3175,137 +3095,97 @@ VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3 //---------------------------------------------------------------------------- bool -VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +VolZmap::GenTool_Milling( unsigned 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 ; - - // Settaggio profilo + + // Ciclo sulle curve del profilo const CurveComposite* pToolProfile = m_Tool.GetOutline() ; - - // Ciclo sulle curve + const ICurve* pPrevCurve = nullptr ; const ICurve* pCurve = pToolProfile->GetFirstCurve() ; - const ICurve* pFirstConst = pCurve ; - while ( pCurve != nullptr) { double dHeight ; - int nCurveType = pCurve -> GetType() ; - - // Caso di segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - bool bTapB, bTapT ; - - pCurve = pToolProfile -> GetPrevCurve() ; - - // Dettagli curva precedente - int nPrevType = pCurve -> GetType() ; - Point3d ptPrevFirst, ptPrevLast ; - pCurve -> GetStartPoint( ptPrevFirst) ; - pCurve -> GetEndPoint( ptPrevLast) ; - - double dAbsDYPr = abs( ptPrevFirst.y - ptPrevLast.y) ; - double dDeltaXPr = ptPrevFirst.x - ptPrevLast.x ; - - // Setto le variabili per il tappo superiore - if ( pCurve == pFirstConst || - nPrevType == CRV_ARC || - ( dDeltaXPr < 0 && dAbsDYPr)) - bTapB = false ; - else - bTapB = true ; - - // Dettagli curva successiva - pCurve = pToolProfile -> GetNextCurve() ; - pCurve = pToolProfile -> GetNextCurve() ; - - int nNextType = pCurve -> GetType() ; - Point3d ptNextFirst ; - Point3d ptNextLast ; - pCurve -> GetStartPoint( ptNextFirst) ; - pCurve -> GetEndPoint( ptNextLast) ; - - double dAbsDYNx = abs( ptNextFirst.y - ptNextLast.y) ; - double dDeltaXNx = ptNextFirst.x - ptNextLast.x ; - double dAbsXEnd = abs( ptNextLast.x) ; - - if ( pCurve == nullptr || - nNextType == CRV_ARC || - ( dAbsDYNx < EPS_SMALL && ( dDeltaXNx > 0 || dAbsXEnd < EPS_SMALL))) - - bTapT = false ; - else - bTapT = true ; - - // Il componente è un cilindro + // Se segmento + if ( pCurve->GetType() == CRV_LINE) { + // Recupero gli estremi + const ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptStart = pLine->GetStart() ; + Point3d ptEnd = pLine->GetEnd() ; + // 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 = pToolProfile->GetNextCurve() ; + 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 ; CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; } - - // Il componente è 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_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT) ; } - - // Il componente è 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 ; Point3d ptIn = ptI - vtToolDir * dHeight ; Point3d ptFn = ptIn + vtMove ; CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB) ; - } + } + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pNextCurve ; } - else { - dHeight = 0 ; - pCurve = pToolProfile -> GetNextCurve() ; + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pToolProfile->GetNextCurve() ; } } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - + // 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 ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - + Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; + Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; - + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; // aggiorno l'altezza dHeight = abs( ptStart.y - ptEnd.y) ; - - pCurve = pToolProfile -> GetNextCurve() ; + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = pToolProfile->GetNextCurve() ; } // Determino le posizioni iniziale e finale del componente successivo @@ -3325,18 +3205,15 @@ VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point { // Verifica sull'interferenza con lo Zmap unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, - dRad, dRad, dHei) ; - - if ( ! bTest) + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + if ( ! bInterf) return true ; // Proiezione dei punti sul piano Point3d ptSxy( ptS.x, ptS.y, 0) ; // Parametri geometrici dell'utensile - double dSqRad = dRad * dRad ; - double dSafeSqRad = dSqRad - 2 * dRad * EPS_SMALL ; + double dSafeSqRad = dRad * dRad - 2 * dRad * EPS_SMALL ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dHei ; @@ -3350,15 +3227,17 @@ VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptSxy ; double dSqLen = vtC.SqLen() ; // Se il punto si trova dentro il cerchio taglio if ( dSqLen < dSafeSqRad) - SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, - Z_AX) ; + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, -Z_AX) ; } } return true ; @@ -3370,9 +3249,8 @@ VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Poi { // Verifica sull'interferenza con lo Zmap unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( ! Control) + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + if ( ! bInterf) return true ; Point3d ptO( ptS.x, ptS.y, 0) ; @@ -3512,9 +3390,8 @@ VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3 { // Verifica sull'interferenza con lo Zmap unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( ! bTest) + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + if ( ! bInterf) return true ; // Parametri geometrici @@ -3642,9 +3519,8 @@ bool VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( ! Control) + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + if ( ! bInterf) return true ; Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; @@ -4023,9 +3899,9 @@ VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d& ptS, const Point3d double dHei, double dRad, bool bTapB, bool bTapT) { unsigned int nStartI, nEndI, nStartJ, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - if ( ! Control) + if ( ! bInterf) return true ; // Studio delle simmetrie @@ -4092,9 +3968,9 @@ VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Poin double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - if ( ! Control) + if ( ! bInterf) return true ; // Apertura del cono @@ -4251,9 +4127,9 @@ VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d& ptS, const Point3d& { // Verifica sull'interferenza utensile Zmap unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - if ( ! Control) + if ( ! bInterf) return true ; // Studio delle simmetrie @@ -4404,9 +4280,9 @@ VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point double dHei, double dMaxRad, double dMinRad, bool bTapB, bool bTapT) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, + bool bInterf = BBoxComponent( nGrid, ptS, ptE, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - if ( ! Control) + if ( ! bInterf) return true ; // Geometria del cono @@ -4941,8 +4817,8 @@ bool VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad) { unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool Control = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; - if ( ! Control) + bool bInterf = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; + if ( ! bInterf) return true ; Vector3d vtV = ptLe - ptLs ;