diff --git a/VolZmap.h b/VolZmap.h index 5bd6aab..109491c 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -389,6 +389,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Frame3d& frTruncPyramFrame, double dSegMin, double dSegMax, double dHeight, Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ; + // aggiornamento intersezioni + bool UpdateMaxMin( Point3d ptBez, Vector3d vtN, double& dMin, double& dMax, Point3d& ptMin, Point3d& ptMax, Vector3d& vtMin, Vector3d& vtMax, + int& nSurfIdMax, int& nSurfIdMin, const int nSurfId) const ; // Voxel: esistenza e passaggio da N a ijk per i voxel bool IsValidVoxel( int nN) const ; bool IsValidVoxel( int nI, int nJ, int nK) const ; @@ -457,6 +460,13 @@ class VolZmap : public IVolZmap, public IGeoObjRW COUNT_START_END = 3 } ; + enum CuttingSurface { + NONE = -1, + TOOL = 0 , + TOP_BOT_BZ = 1 , + LATERAL = 2 + } ; + private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; enum Shape { GENERIC = 0, BOX = 1, EXTRUSION = 2} ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 7f0d77d..48dad54 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -1118,17 +1118,28 @@ GetAlongAcrossRotation( const Vector3d& vtDir1, const Vector3d& vtDir2, const Ve return true ; } +//---------------------------------------------------------------------------- bool -UpdateMaxMin(Point3d ptBez, Vector3d vtN, double& dMin, double& dMax, Point3d& ptMin, Point3d& ptMax, Vector3d& vtMin, Vector3d& vtMax) { +VolZmap::UpdateMaxMin( Point3d ptBez, Vector3d vtN, double& dMin, double& dMax, Point3d& ptMin, Point3d& ptMax, Vector3d& vtMin, Vector3d& vtMax, + int& nSurfIdMax, int& nSurfIdMin, const int nSurfId) const +{ if ( ptBez.z > dMax) { - dMax = ptBez.z ; - ptMax = ptBez ; - vtMax = -vtN ; // inverto il segno della normale, perché devo passare la normale della supercie tagliata, non di quella di taglio + bool bCorrectUpdate = ! (ptBez.z - dMax < 2 && ( (nSurfIdMax == CuttingSurface::TOOL && nSurfId == CuttingSurface::TOP_BOT_BZ) || (nSurfIdMax == CuttingSurface::TOP_BOT_BZ && nSurfId == CuttingSurface::TOOL))) ; + if ( bCorrectUpdate) { + dMax = ptBez.z ; + ptMax = ptBez ; + vtMax = -vtN ; // inverto il segno della normale, perché devo passare la normale della supercie tagliata, non di quella di taglio + nSurfIdMax = nSurfId ; + } } if ( ptBez.z < dMin) { - dMin = ptBez.z ; - ptMin = ptBez ; - vtMin = -vtN ; // inverto il segno della normale, perché devo passare la normale della supercie tagliata, non di quella di taglio + bool bCorrectUpdate = ! (dMin - ptBez.z < 2 && ( (nSurfIdMin == CuttingSurface::TOOL && nSurfId == CuttingSurface::TOP_BOT_BZ) || (nSurfIdMin == CuttingSurface::TOP_BOT_BZ && nSurfId == CuttingSurface::TOOL))) ; + if ( bCorrectUpdate) { + dMin = ptBez.z ; + ptMin = ptBez ; + vtMin = -vtN ; // inverto il segno della normale, perché devo passare la normale della supercie tagliata, non di quella di taglio + nSurfIdMin = nSurfId ; + } } return true ; } @@ -1290,6 +1301,11 @@ VolZmap::GenTool_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE return true ; } +//debug +static vector vGeo ; +static int nCount = 0 ; +//debug + //---------------------------------------------------------------------------- bool VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, @@ -1417,11 +1433,11 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c vvPtCtrl.emplace_back( PNTVECTOR({ ptTop1s, ptTop2s, ptTop1e, ptTop2e})) ; } else { - // superfici superiori + // superfici inferiori for ( int i = 0 ; i < nSub ; ++i) { vvPtCtrl.emplace_back( PNTVECTOR({ vPntTipStart[i], vPntTipStart[i+1], vPntTipEnd[i], vPntTipEnd[i+1]})) ; } - // superficie inferiori + // superficie superiori for ( int i = 0 ; i < nSub ; ++i) { vvPtCtrl.emplace_back( PNTVECTOR({ vPntTopStart[i], vPntTopStart[i+1], vPntTopEnd[i], vPntTopEnd[i+1]})) ; } @@ -1437,10 +1453,6 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c int nTotSurf = 2 + nSub * 2 ; BOXVECTOR vSurfBox( nTotSurf) ; - ////debug - //vector vGeo ; - ////debug - for( int s = 0 ; s < nTotSurf ; ++s) { vSurfBez.emplace_back( CreateSurfBezier()) ; vSurfBez.back()->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ; @@ -1461,13 +1473,16 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c A2.push_back( a.y * q.z - a.z * q.y) ; B2.push_back( b.y * q.z - b.z * q.y) ; C2.push_back( c.y * q.z - c.z * q.y) ; - //vGeo.push_back( vSurfBez[s]) ; + if ( nGrid == 0) + vGeo.push_back( vSurfBez[s]->Clone()) ; } - ////debug - //SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ; - //return true ; + //if ( nGrid == 0) { + // if ( nCount == 20) + // SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ; + // ++nCount ; + //} ////debug BBox3d bbStartCyl = GetCylMoveBBox( ptS, ptS, vtLs, dMaxRad, dHeight) ; @@ -1500,59 +1515,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptMin, ptMax ; double dMin = INFINITO, dMax = -10 ; Vector3d vtMin, vtMax ; - - // interseco con i cilindri di inizio e fine moto - // se sto trattando un cilindro - if ( dMaxRad - dMinRad < EPS_SMALL) { - // prima di calcolare l'intersezione verifico che ci sia interferenza con i box - if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) { - Frame3d frStartCyl ; - frStartCyl.Set( ptP1T, vtLs) ; - Point3d pt1, pt2 ; - Vector3d vt1, vt2 ; - IntersLineCylinder( r, Z_AX, frStartCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2) ; - if ( ! AreSameVectorExact( vt1, V_NULL)) - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - if ( ! AreSameVectorExact( vt2, V_NULL)) - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - } - if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { - Frame3d frEndCyl ; - frEndCyl.Set( ptP2T, vtLe) ; - Point3d pt1, pt2 ; - Vector3d vt1, vt2 ; - IntersLineCylinder( r, Z_AX, frEndCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2) ; - if ( ! AreSameVectorExact( vt1, V_NULL)) - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - if ( ! AreSameVectorExact( vt2, V_NULL)) - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - } - } - // se sto trattando un cono - else { - if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) { - Frame3d frStartCon ; - frStartCon.Set( ptVS, vtLs) ; - Point3d pt1, pt2 ; - Vector3d vt1, vt2 ; - IntersLineConus( r, Z_AX, frStartCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2) ; - if ( ! AreSameVectorExact( vt1, V_NULL)) - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - if ( ! AreSameVectorExact( vt2, V_NULL)) - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - } - if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { - Frame3d frEndCon ; - frEndCon.Set( ptVE, vtLe) ; - Point3d pt1, pt2 ; - Vector3d vt1, vt2 ; - IntersLineConus( r, Z_AX, frEndCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2) ; - if ( ! AreSameVectorExact( vt1, V_NULL)) - UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - if ( ! AreSameVectorExact( vt2, V_NULL)) - UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; - } - } + int nSurfIdMin = CuttingSurface::NONE, nSurfIdMax = CuttingSurface::NONE ; // interseco con le bilineari for( int s = 0 ; s < nTotSurf ; ++s) { @@ -1574,7 +1537,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptBez1 ; Vector3d vtN1 ; vSurfBez[s]->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez1, vtN1) ; - UpdateMaxMin( ptBez1, vtN1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + UpdateMaxMin( ptBez1, vtN1, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOP_BOT_BZ) ; } } if ( nRoots > 1 && vdRoots[1] > 0 - EPS_ZERO && vdRoots[1] < 1 + EPS_ZERO) { @@ -1584,12 +1547,61 @@ VolZmap::Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptBez2 ; Vector3d vtN2 ; vSurfBez[s]->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptBez2, vtN2) ; - UpdateMaxMin( ptBez2, vtN2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ; + UpdateMaxMin( ptBez2, vtN2, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOP_BOT_BZ) ; } } } } } + + // interseco con i cilindri di inizio e fine moto + // se sto trattando un cilindro + if ( dMaxRad - dMinRad < EPS_SMALL) { + // prima di calcolare l'intersezione verifico che ci sia interferenza con i box + if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) { + Frame3d frStartCyl ; + frStartCyl.Set( ptP1T, vtLs) ; + Point3d pt1, pt2 ; + Vector3d vt1, vt2 ; + if ( IntersLineCylinder( r, Z_AX, frStartCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)) { + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + } + } + if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { + Frame3d frEndCyl ; + frEndCyl.Set( ptP2T, vtLe) ; + Point3d pt1, pt2 ; + Vector3d vt1, vt2 ; + if ( IntersLineCylinder( r, Z_AX, frEndCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)){ + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + } + } + } + // se sto trattando un cono + else { + if( bbStartCyl.SqDistFromPointXY( r) < EPS_ZERO) { + Frame3d frStartCon ; + frStartCon.Set( ptVS, vtLs) ; + Point3d pt1, pt2 ; + Vector3d vt1, vt2 ; + if ( IntersLineConus( r, Z_AX, frStartCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2)) { + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + } + } + if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) { + Frame3d frEndCon ; + frEndCon.Set( ptVE, vtLe) ; + Point3d pt1, pt2 ; + Vector3d vt1, vt2 ; + if ( IntersLineConus( r, Z_AX, frEndCon, dTan, dMinH, dMaxH, false, false, pt1, vt1, pt2, vt2)) { + UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax, nSurfIdMax, nSurfIdMin, CuttingSurface::TOOL) ; + } + } + } if ( dMax > 0 && dMin < dMax) SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, nToolNum) ; } @@ -1781,8 +1793,8 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co Point3d ptSti = ptPs ; Vector3d vtDSi = vtDs ; double dCorr = 0.05 * 1. / nStepCnt ; // creo una sovrapposizone tra uno step e il successivo + dCorr = 0. ; // tolgo la sovrapposizione for ( int i = 0 ; i <= nStepCnt && bOk ; ++ i) { - ////////// debug - vecchia modalità // double dPosCoeff, dDirCoeff ; @@ -1831,32 +1843,36 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co InitializePointsAndVectors( ptSti, ptEni, vtDSi, vtDEi, ptLs, ptLe, vtLs, vtLe) ; ///// decommentare solo per debug - for( int i = 0 ; i < N_MAPS; ++i) - SelectGeneralMotion( i, ptLs[i], ptLe[i], vtLs[i],vtLe[i], nPhase) ; + for( int j = 0 ; j < N_MAPS; ++j) + SelectGeneralMotion( j, ptLs[j], ptLe[j], vtLs[j],vtLe[j], nPhase) ; //// Ciclo sulle mappe //vector< future> vRes ; //vRes.resize( m_nMapNum) ; - //for ( int i = 0 ; i < m_nMapNum ; ++ i) { - // vRes[i] = async( launch::async, &VolZmap::SelectGeneralMotion, this, i, cref( ptLs[i]), cref( ptLe[i]), cref( vtLs[i]), cref( vtLe[i]), nPhase) ; + //for ( int j = 0 ; j < m_nMapNum ; ++ j) { + // vRes[j] = async( launch::async, &VolZmap::SelectGeneralMotion, this, j, cref( ptLs[j]), cref( ptLe[j]), cref( vtLs[j]), cref( vtLe[j]), nPhase) ; //} //bool bOk = true ; //int nTerminated = 0 ; //while ( nTerminated < m_nMapNum) { - // for ( int i = 0 ; i < m_nMapNum ; ++ i) { - // if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { - // bOk = vRes[i].get() && bOk ; + // for ( int j = 0 ; j < m_nMapNum ; ++ j) { + // if ( vRes[j].valid() && vRes[j].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { + // bOk = vRes[j].get() && bOk ; // ++ nTerminated ; // } // } //} ////debug - //if ( i == 0) + //if ( i == 1) // return true ; ////debug } + + //debug + SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ; + //debug return bOk ; }