diff --git a/CurveArc.cpp b/CurveArc.cpp index 08445d8..3ed03ac 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -1487,7 +1487,7 @@ CurveArc::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dC return false ; // verifico non sia nulla - if ( fabs( dCoeffX) < EPS_ZERO) + if ( fabs( dCoeffX) < EPS_ZERO || m_dRad * fabs( dCoeffX) <= EPS_SMALL) return false ; // imposto ricalcolo della grafica diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 78ba233..fb19b7e 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -1929,12 +1929,30 @@ CurveBezier::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double if ( fabs( dCoeffX) < EPS_ZERO && fabs( dCoeffY) < EPS_ZERO && fabs( dCoeffZ) < EPS_ZERO) return false ; + // verifico che la scalatura dei punti non li porti tutti a coincidere + PNTVECTOR vPnt ; + vPnt.reserve( m_nDeg + 1) ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) { + Point3d ptTmp = m_aPtCtrl[i] ; + ptTmp.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + vPnt.push_back( ptTmp) ; + } + bool bOk = false ; + for ( int i = 1 ; i <= m_nDeg ; ++ i) { + if ( ! AreSamePointApprox( vPnt[0], vPnt[i])) { + bOk = true ; + break ; + } + } + if ( ! bOk) + return false ; + // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // scalo i punti di controllo for ( int i = 0 ; i <= m_nDeg ; ++ i) - m_aPtCtrl[i].Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + m_aPtCtrl[i] = vPnt[i] ; // scalo vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; double dLen = m_VtExtr.Len() ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index c5f3d79..efa35e9 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -1833,6 +1833,20 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou if ( fabs( dCoeffX) < EPS_ZERO && fabs( dCoeffY) < EPS_ZERO && fabs( dCoeffZ) < EPS_ZERO) return false ; + // calcolo bbox allineato con riferimento di scalatura e senza tener conto dello spessore + // lo scalo per verificare se tutto si riduce a un punto + BBox3d b3Ref ; + double dOriThick = 0 ; + swap( dOriThick, m_dThick) ; + if ( ! GetBBox( frRef, b3Ref)) + return false ; + swap( dOriThick, m_dThick) ; + Vector3d vtDelta = b3Ref.GetMax() - b3Ref.GetMin() ; + if ( fabs( vtDelta.x * dCoeffX) < EPS_SMALL && + fabs( vtDelta.y * dCoeffY) < EPS_SMALL && + fabs( vtDelta.z * dCoeffZ) < EPS_SMALL) + return false ; + // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -1843,11 +1857,18 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou } // scalo le singole curve - PCSD_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( PCSD_ITER Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ) { // eseguo la scalatura - if ( ! (*Iter)->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ)) - return false ; + bool bOk = (*Iter)->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + // se tutto bene, passo alla prossima + if ( bOk) + ++Iter ; + // altrimenti, l'entità si è annullata => devo toglierla dalla lista e cancellarla + else { + // si è annullata l'entità, la elimino e la tolgo dalla lista + delete (*Iter) ; + Iter = m_CrvSmplS.erase( Iter) ; + } } // scalo i punti estremi @@ -2166,8 +2187,7 @@ bool CurveComposite::ArcsToBezierCurves( void) { // verifico le singole curve - PCSD_ITER Iter ; - for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { + for ( PCSD_ITER Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) { // se arco, devo trasformare in una o più curve di Bezier if ( (*Iter)->GetType() == CRV_ARC) { // eseguo trasformazione @@ -2187,8 +2207,7 @@ CurveComposite::ArcsToBezierCurves( void) return false ; // inserisco le curve prima dell'arco int nParts = 0 ; - PCSD_ITER Iter2 ; - for ( Iter2 = pCC->m_CrvSmplS.begin() ; Iter2 != pCC->m_CrvSmplS.end() ; ++ Iter2) { + for ( PCSD_ITER Iter2 = pCC->m_CrvSmplS.begin() ; Iter2 != pCC->m_CrvSmplS.end() ; ++ Iter2) { Iter = m_CrvSmplS.insert( Iter, (*Iter2)) ; ++ Iter ; ++ nParts ; diff --git a/CurveLine.cpp b/CurveLine.cpp index 6ebff3d..260f2b2 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -810,12 +810,20 @@ CurveLine::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double d if ( fabs( dCoeffX) < EPS_ZERO && fabs( dCoeffY) < EPS_ZERO && fabs( dCoeffZ) < EPS_ZERO) return false ; + // verifico che la scalatura dei punti non li porti a coincidere + Point3d ptNewStart = m_PtStart ; + ptNewStart.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + Point3d ptNewEnd = m_PtEnd ; + ptNewEnd.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + if ( AreSamePointApprox( ptNewStart, ptNewEnd)) + return false ; + // imposto ricalcolo della grafica m_OGrMgr.Reset() ; - // scalo i punti estremi - m_PtStart.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; - m_PtEnd.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + // uso i punti estremi + m_PtStart = ptNewStart ; + m_PtEnd = ptNewEnd ; // scalo vettore estrusione, lo normalizzo e aggiusto spessore m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; double dLen = m_VtExtr.Len() ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 0c4f88c..65bf2ea 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 4fca3b3..a96e420 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -2140,10 +2140,17 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double if ( fabs( dCoeffX) < EPS_ZERO && fabs( dCoeffY) < EPS_ZERO && fabs( dCoeffZ) < EPS_ZERO) return false ; - // determino se contiene anche un mirror (numero dispari di coefficienti negativi) - bool bMirror = ( dCoeffX < 0) ; - bMirror = ( bMirror ? ( dCoeffY > 0) : ( dCoeffY < 0)) ; - bMirror = ( bMirror ? ( dCoeffZ > 0) : ( dCoeffZ < 0)) ; + // calcolo bbox allineato con riferimento di scalatura e senza tener conto dello spessore + // lo scalo per verificare se tutto si riduce a un punto o una linea (solo se diretta come assi ref) + BBox3d b3Ref ; + if ( ! GetBBox( frRef, b3Ref)) + return false ; + Vector3d vtDelta = b3Ref.GetMax() - b3Ref.GetMin() ; + bool bZeroX = ( fabs( vtDelta.x * dCoeffX) < EPS_SMALL) ; + bool bZeroY = ( fabs( vtDelta.y * dCoeffY) < EPS_SMALL) ; + bool bZeroZ = ( fabs( vtDelta.z * dCoeffZ) < EPS_SMALL) ; + if ( ( bZeroX && bZeroY) || ( bZeroX && bZeroZ) || ( bZeroY && bZeroZ)) + return false ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -2154,19 +2161,25 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double m_vVert[i].ptP.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; } + // determino se contiene anche un mirror (numero dispari di coefficienti negativi) + bool bMirror = ( dCoeffX < 0) ; + bMirror = ( bMirror ? ( dCoeffY > 0) : ( dCoeffY < 0)) ; + bMirror = ( bMirror ? ( dCoeffZ > 0) : ( dCoeffZ < 0)) ; + // aggiorno le facce + bool bOk = true ; for ( int i = 0 ; i < GetTriangleSize() ; ++ i) { if ( m_vTria[i].nIdVert[0] != SVT_DEL) { // se c'è mirror, devo invertire la faccia if ( bMirror && ! InvertTriangle( i)) - return false ; + bOk = false ; // aggiorno la normale if ( ! CalcTriangleNormal( i)) - return false ; + bOk = false ; } } - return true ; + return bOk ; } //----------------------------------------------------------------------------