diff --git a/BBox3d.cpp b/BBox3d.cpp index 49eca78..5593e0f 100644 --- a/BBox3d.cpp +++ b/BBox3d.cpp @@ -77,6 +77,14 @@ BBox3d::IsSmallXY( void) const m_ptMax.y - m_ptMin.y < EPS_SMALL) ; } +//---------------------------------------------------------------------------- +bool +BBox3d::IsSmallZ( void) const +{ + return ( ! IsValid() || + m_ptMax.z - m_ptMin.z < EPS_SMALL) ; +} + //---------------------------------------------------------------------------- bool BBox3d::IsEpsilon( double dToler) const @@ -96,6 +104,14 @@ BBox3d::IsEpsilonXY( double dToler) const m_ptMax.y - m_ptMin.y < dToler) ; } +//---------------------------------------------------------------------------- +bool +BBox3d::IsEpsilonZ( double dToler) const +{ + return ( ! IsValid() || + m_ptMax.z - m_ptMin.z < dToler) ; +} + //---------------------------------------------------------------------------- void BBox3d::Add( const Point3d& ptP) diff --git a/CurveArc.cpp b/CurveArc.cpp index 200f6e9..445418a 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -242,9 +242,8 @@ CurveArc::Set2PNB( const Point3d& ptIni, const Point3d& ptFin, const Vector3d& v return false ; // deltaN eventuale ( è componente parallela a VtN) m_dDeltaN = vtDiff * m_VtN ; - if ( fabs( m_dDeltaN) > EPS_SMALL) - vtDiff -= m_dDeltaN * m_VtN ; - else + vtDiff -= m_dDeltaN * m_VtN ; + if ( fabs( m_dDeltaN) < EPS_SMALL) m_dDeltaN = 0 ; // verifico sia un arco (uso la lunghezza della saetta) double dDist = vtDiff.Len() ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 50cf2f0..d7ccefa 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -587,12 +587,15 @@ CurveComposite::Dump( string& sOut, bool bMM, const char* szNewLine) const // dati generali di una curva if ( ! CurveDump( *this, sOut, bMM, szNewLine)) return false ; + // prealloco la stringa + const int MAX_CRV = 1000 ; + sOut.reserve( 100 + min( int (m_CrvSmplS.size()), MAX_CRV) * 60) ; // parametri : numero di curve sOut += "CrvNbr=" + ToString( int( m_CrvSmplS.size())) + szNewLine ; - // ciclo sulle curve componenti + // ciclo sulle curve componenti int i = 0 ; const ICurve* pCrvSmpl = GetFirstCurve() ; - while ( pCrvSmpl != nullptr) { + while ( pCrvSmpl != nullptr && i < MAX_CRV) { // assegno ed emetto nome e tipo della curva semplice sOut += "#" + ToString( ++i) + " " + pCrvSmpl->GetTitle() + szNewLine ; // salvataggio della curva semplice @@ -601,6 +604,8 @@ CurveComposite::Dump( string& sOut, bool bMM, const char* szNewLine) const // passo alla successiva pCrvSmpl = GetNextCurve() ; } + if ( pCrvSmpl != nullptr) + sOut += string( ". . .") + szNewLine ; return true ; } diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 798946f..52d304f 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -699,7 +699,7 @@ VolZmap::AvoidCylinder( const Frame3d& frCyl, double dL, double dR) const // La funzione restituisce true in caso di intersezione, false altrimenti. bool VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, - const Frame3d& CylFrame, double dH, double dR, bool bTapO, bool bTapL, + const Frame3d& CylFrame, double dH, double dR, bool bTapB, bool bTapT, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) { Point3d ptP = ptLineSt ; @@ -740,7 +740,7 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, ptInt1.ToGlob( CylFrame) ; ptInt2.ToGlob( CylFrame) ; vtN1.ToGlob( CylFrame) ; - vtN2.ToGlob( CylFrame) ; + vtN2.ToGlob( CylFrame) ; return true ; } // Nessuna intersezione @@ -757,54 +757,43 @@ VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, // appartiene alla superficie if ( nRoot == 2) { - // Tolleranze per tagliare o meno i dexel a filo sulle - // circonferenze di base e di top. - double dEpsO = ( bTapO ? - EPS_SMALL : EPS_SMALL) ; - double dEpsL = ( bTapL ? EPS_SMALL : - EPS_SMALL) ; - // Punti d'intersezione trovati + // Ordino i parametri di intersezione + double dUmin = vdRoots[0] ; + double dUmax = vdRoots[1] ; + if ( dUmin > dUmax) + swap( dUmin, dUmax) ; + // Calcolo i punti d'intersezione (ordinati secondo Z crescente) ptInt1 = ptP + vdRoots[0] * vtV ; ptInt2 = ptP + vdRoots[1] * vtV ; - if ( ptInt1.z > ptInt2.z) swap( ptInt1, ptInt2) ; - - // Setto le normali - vtN1.Set( ( ORIG - ptInt1).x, ( ORIG - ptInt1).y, 0) ; - vtN2.Set( ( ORIG - ptInt2).x, ( ORIG - ptInt2).y, 0) ; - vtN1.Normalize() ; - vtN2.Normalize() ; - // Studio le soluzioni - if ( ptInt1.z < dH + dEpsL) { - if ( ptInt1.z > dEpsO) { - if ( ptInt2.z > dH + dEpsL) { - ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ; - vtN2.Set( 0, 0, -1) ; - } - } - else { - if ( ptInt2.z > dH + dEpsL) { - ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; - ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ; - vtN1.Set( 0, 0, 1) ; - vtN2.Set( 0, 0, -1) ; - } - else if ( ptInt2.z > dEpsO) { - ptInt1 = ptP - ( ptP.z / vtV.z) * vtV ; - vtN1.Set( 0, 0, 1) ; - } - else - return false ; - } - } - else + // Quote limitazione, dipendenti dalla tappatura estremità + double dZbot = ( bTapB ? -EPS_SMALL : EPS_SMALL) ; + double dZtop = ( bTapT ? dH + EPS_SMALL : dH - EPS_SMALL) ; + // Se intersezioni entrambe fuori dal cilindro limitato, non vanno considerate + if ( ptInt2.z < dZbot || ptInt1.z > dZtop) return false ; - + // Calcolo le normali + vtN1.Set( ( ORIG - ptInt1).x, ( ORIG - ptInt1).y, 0) ; + vtN1.Normalize() ; + vtN2.Set( ( ORIG - ptInt2).x, ( ORIG - ptInt2).y, 0) ; + vtN2.Normalize() ; + // Limitazioni per intersezione con piano basso + if ( ptInt1.z < dZbot - EPS_ZERO) { + ptInt1 = ptP + Clamp( ( dZbot - ptP.z / vtV.z), dUmin, dUmax) * vtV ; + vtN1.Set( 0, 0, 1) ; + } + // Limitazioni per intersezione con piano alto + if ( ptInt2.z > dZtop + EPS_ZERO) { + ptInt2 = ptP + Clamp( ( ( dZtop - ptP.z) / vtV.z), dUmin, dUmax) * vtV ; + vtN2.Set( 0, 0, -1) ; + } // Riporto le coordinate nel sistema di riferimento griglia ptInt1.ToGlob( CylFrame) ; ptInt2.ToGlob( CylFrame) ; vtN1.ToGlob( CylFrame) ; - vtN2.ToGlob( CylFrame) ; - } + vtN2.ToGlob( CylFrame) ; + } return true ; } diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index b84c0f2..a80d0ad 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -4760,38 +4760,21 @@ VolZmap::CompPar_Milling( unsigned int nGrid, double dLenX, double dLenY, double bool VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad) { + // Verifico interferisca unsigned int nStartI, nStartJ, nEndI, nEndJ ; bool bInterf = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; - if ( ! bInterf) + if ( ! bInterf) return true ; - + // Vettore modivemnto Vector3d vtV = ptLe - ptLs ; - double dLengthPath = vtV.Len() ; - vtV.Normalize() ; - - Vector3d vtW ; - - // Costruisco sistema di riferimento - if ( vtV.x * vtV.x > 0.09) - vtW.Set( - ( vtV.y + vtV.z) / vtV.x, 1, 1) ; - - else if ( vtV.y * vtV.y > 0.09) - vtW.Set( 1, - ( vtV.x + vtV.z) / vtV.y, 1) ; - - else - vtW.Set( 1, 1, - ( vtV.x + vtV.y) / vtV.z) ; - - //Point3d ptOnX = ptLs + vtW ; - - Frame3d CylFrame ; CylFrame.Set( ptLs, vtV, vtW) ; + // Riferimento per cilindro inviluppo della sfera lungo il movimento + Frame3d CylFrame ; + CylFrame.Set( ptLs, vtV) ; double dSqRad = dRad * dRad ; - double dMin, dMax ; - Vector3d vtNmin, vtNmax ; - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -4803,62 +4786,49 @@ VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point double dStSqDXY = SqDistXY( ptC, ptLs) ; double dEnSqDXY = SqDistXY( ptC, ptLe) ; - // Prima sfera + // Sfera in posizione start if ( dStSqDXY < dSqRad) { - dMin = ptLs.z - sqrt( dSqRad - dStSqDXY) ; - dMax = ptLs.z + sqrt( dSqRad - dStSqDXY) ; - - Point3d ptIntMin( dX, dY, dMin) ; - Point3d ptIntMax( dX, dY, dMax) ; - - vtNmin = ptLs - ptIntMin ; - vtNmax = ptLs - ptIntMax ; + double dMin = ptLs.z - sqrt( dSqRad - dStSqDXY) ; + double dMax = ptLs.z + sqrt( dSqRad - dStSqDXY) ; + Vector3d vtNmin = ptLs - Point3d( dX, dY, dMin) ; vtNmin.Normalize() ; + Vector3d vtNmax = ptLs - Point3d( dX, dY, dMax) ; vtNmax.Normalize() ; SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } - // Seconda sfera + // Sfera in posizione end if ( dEnSqDXY < dSqRad) { - dMin = ptLe.z - sqrt( dSqRad - dEnSqDXY) ; - dMax = ptLe.z + sqrt( dSqRad - dEnSqDXY) ; - - Point3d ptIntMin( dX, dY, dMin) ; - Point3d ptIntMax( dX, dY, dMax) ; - - vtNmin = ptLe - ptIntMin ; - vtNmax = ptLe - ptIntMax ; + double dMin = ptLe.z - sqrt( dSqRad - dEnSqDXY) ; + double dMax = ptLe.z + sqrt( dSqRad - dEnSqDXY) ; + Vector3d vtNmin = ptLe - Point3d( dX, dY, dMin) ; vtNmin.Normalize() ; + Vector3d vtNmax = ptLe - Point3d( dX, dY, dMax) ; vtNmax.Normalize() ; SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } + // Cilindro inviluppo della sfera Point3d ptInt1, ptInt2 ; Vector3d vtN1, vtN2 ; - - // Cilindro if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dLengthPath, dRad, false, false, ptInt1, ptInt2, vtN1, vtN2)) { - if ( ptInt1.z < ptInt2.z) { - dMin = ptInt1.z ; - dMax = ptInt2.z ; - vtNmin = vtN1 ; - vtNmax = vtN2 ; + double dMin = ptInt1.z ; + double dMax = ptInt2.z ; + Vector3d vtNmin = vtN1 ; + Vector3d vtNmax = vtN2 ; + if ( ptInt1.z > ptInt2.z) { + swap( dMin, dMax) ; + swap( vtNmin, vtNmax) ; } - else { - dMin = ptInt2.z ; - dMax = ptInt1.z ; - vtNmin = vtN2 ; - vtNmax = vtN1 ; - } - SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } } } + return true ; }