EgtGeomKernel :
- versione corretta del VM a 5 assi per lama e 3 assi.
This commit is contained in:
+214
-135
@@ -1120,18 +1120,10 @@ GetAlongAcrossRotation( const Vector3d& vtDir1, const Vector3d& vtDir2, const Ve
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::UpdateMaxMin( Point3d ptBez, Vector3d vtN, double& dMin, double& dMax, Point3d& ptMin, Point3d& ptMax, Vector3d& vtMin, Vector3d& vtMax) const
|
||||
VolZmap::UpdateMaxMin( Point3d ptBez, Vector3d vtN, PNTVECTVECTOR& vInters) 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
|
||||
}
|
||||
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
|
||||
}
|
||||
if ( ! AreSameVectorExact( vtN, V_NULL))
|
||||
vInters.emplace_back( PNTVECT( ptBez, vtN)) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1297,7 +1289,7 @@ VolZmap::GenTool_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR&
|
||||
|
||||
//debug
|
||||
static vector<IGeoObj*> vGeo ;
|
||||
static int nCount = 0 ;
|
||||
//static int nCount = 0 ;
|
||||
//debug
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1321,12 +1313,12 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
bool bRat = false ;
|
||||
|
||||
int nSub = 4 ; // numero di bilineari con cui approssimare il (quasi) semi-cilindro ellissoide che descrive il volume della punta e della cima del tool
|
||||
ISURFBEZPOVECTOR vSurfBez ;
|
||||
PNTVECTOR d ;
|
||||
Vector3d q = Z_AX ;
|
||||
DBLVECTOR A1, B1, C1, A2, B2, C2 ;
|
||||
int nTotSurf = 2 + nSub * 2 ;
|
||||
BOXVECTOR vSurfBox( nTotSurf) ;
|
||||
ISURFBEZPOVECTOR vSurfBez( nTotSurf * nStepCnt) ;
|
||||
BOXVECTOR vSurfBox( nTotSurf * nStepCnt) ;
|
||||
double dSide = 0 ;
|
||||
// punti per le bilineari, sulle posizioni del tool alle estremità del movimento
|
||||
PNTVECTOR vPntTipStartEx ;
|
||||
@@ -1392,7 +1384,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
Vector3d vtTopBaseEnd = vtDirTop - ( (vtDirTop * vtLe[s]) * vtLe[s]) ;
|
||||
vtTopBaseEnd.Normalize() ;
|
||||
vtTopBaseEnd *= dMaxRad ;
|
||||
if ( s == nStepCnt)
|
||||
if ( s == nStepCnt - 1)
|
||||
vtDirTopEndEx = vtTopBaseEnd ;
|
||||
Point3d ptRefEnd = ptE[s] - vtTopBaseEnd ;
|
||||
Vector3d vtTopBaseStart = vtDirTop - ( ( vtDirTop * vtLs[s]) * vtLs[s]) ;
|
||||
@@ -1411,7 +1403,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
Vector3d vtTipBaseEnd = - (vtLe[s] ^ vtDirTip) ;
|
||||
vtTipBaseEnd.Normalize() ;
|
||||
vtTipBaseEnd *= dMinRad ;
|
||||
if ( s == nStepCnt)
|
||||
if ( s == nStepCnt - 1)
|
||||
vtDirTipEndEx = vtTipBaseEnd ;
|
||||
// aggiungo il primo punto per ognuno dei gruppi
|
||||
vtTopBaseStart.Rotate( vtLs[s], 90) ;
|
||||
@@ -1482,13 +1474,14 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
|
||||
// inizializzo le superfici bilineari e i parametri per le intersezioni
|
||||
for( int z = 0 ; z < nTotSurf ; ++z) {
|
||||
vSurfBez.emplace_back( CreateSurfBezier()) ;
|
||||
vSurfBez.back()->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
||||
vSurfBez.back()->SetControlPoint( 0, vvPtCtrl[z][0]) ;
|
||||
vSurfBez.back()->SetControlPoint( 1, vvPtCtrl[z][1]) ;
|
||||
vSurfBez.back()->SetControlPoint( 2, vvPtCtrl[z][2]) ;
|
||||
vSurfBez.back()->SetControlPoint( 3, vvPtCtrl[z][3]) ;
|
||||
vSurfBox[z].Add( vvPtCtrl[z]) ;
|
||||
int nSurfInd = s * nTotSurf + z ;
|
||||
vSurfBez[nSurfInd].Set( CreateSurfBezier()) ;
|
||||
vSurfBez[nSurfInd]->Init(nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
||||
vSurfBez[nSurfInd]->SetControlPoint( 0, vvPtCtrl[z][0]) ;
|
||||
vSurfBez[nSurfInd]->SetControlPoint( 1, vvPtCtrl[z][1]) ;
|
||||
vSurfBez[nSurfInd]->SetControlPoint( 2, vvPtCtrl[z][2]) ;
|
||||
vSurfBez[nSurfInd]->SetControlPoint( 3, vvPtCtrl[z][3]) ;
|
||||
vSurfBox[nSurfInd].Add(vvPtCtrl[z]) ;
|
||||
|
||||
Vector3d a = vvPtCtrl[z][3] - vvPtCtrl[z][1] + ( vvPtCtrl[z][0] - vvPtCtrl[z][2]) ;
|
||||
Vector3d b = vvPtCtrl[z][1] - vvPtCtrl[z][0] ;
|
||||
@@ -1502,17 +1495,15 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
B2.push_back( b.y * q.z - b.z * q.y) ;
|
||||
C2.push_back( c.y * q.z - c.z * q.y) ;
|
||||
if ( nGrid == 0)
|
||||
vGeo.push_back( vSurfBez[z]->Clone()) ;
|
||||
vGeo.push_back( vSurfBez[nSurfInd]->Clone()) ;
|
||||
}
|
||||
}
|
||||
|
||||
////debug
|
||||
//if ( nGrid == 0) {
|
||||
// if ( nCount == 20)
|
||||
// SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ;
|
||||
// ++nCount ;
|
||||
//}
|
||||
////debug
|
||||
//debug
|
||||
if ( nGrid == 0) {
|
||||
SaveGeoObj( vGeo, "D:/Temp/VirtualMilling/5axisAdvanced/finalApprox.nge", 2) ;
|
||||
}
|
||||
//debug
|
||||
|
||||
BBox3d bbStartCyl = GetCylMoveBBox( ptS[0], ptS[0], vtLs[0], dMaxRad, dHeight) ;
|
||||
BBox3d bbEndCyl = GetCylMoveBBox( ptE.back(), ptE.back(), vtLe.back(), dMaxRad, dHeight) ;
|
||||
@@ -1561,14 +1552,23 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
// frTopStart.Set( ptS[0], ) ;
|
||||
// frTopEnd.Set( ptE.back(), ) ;
|
||||
//}
|
||||
for ( int i = 1 ; i <= nSub ; ++i) {
|
||||
vvtTipStartAux[i] = Media( vPntTipStartEx[i-1],vPntTipStartEx[i]) - ptP1T;
|
||||
vvtTipEndAux[i] = Media( vPntTipEndEx[i-1],vPntTipEndEx[i]) - ptP2T ;
|
||||
vvtTopStartAux[i] = Media( vPntTopStartEx[i-1],vPntTopStartEx[i]) - ptS[0] ;
|
||||
vvtTopEndAux[i] = Media( vPntTopEndEx[i-1],vPntTopEndEx[i]) - ptE.back() ;
|
||||
}
|
||||
double dMinRadApprox = 0 ;
|
||||
double dMaxRadApprox = 0 ;
|
||||
|
||||
double dRadApprox = vvtTipStartAux.back().Len() ;
|
||||
for ( int i = 1 ; i <= nSub ; ++i) {
|
||||
vvtTipStartAux[i] = Media( vPntTipStartEx[i-1],vPntTipStartEx[i]) - ptP1T ;
|
||||
if ( i == nSub)
|
||||
dMinRadApprox = vvtTipStartAux[i].Len() ;
|
||||
vvtTipStartAux[i].Normalize() ;
|
||||
vvtTipEndAux[i] = Media( vPntTipEndEx[i-1],vPntTipEndEx[i]) - ptP2T ;
|
||||
vvtTipEndAux[i].Normalize() ;
|
||||
vvtTopStartAux[i] = Media( vPntTopStartEx[i-1],vPntTopStartEx[i]) - ptS[0] ;
|
||||
if ( i == nSub)
|
||||
dMaxRadApprox = vvtTopStartAux[i].Len() ;
|
||||
vvtTopStartAux[i].Normalize() ;
|
||||
vvtTopEndAux[i] = Media( vPntTopEndEx[i-1],vPntTopEndEx[i]) - ptE.back() ;
|
||||
vvtTopEndAux[i].Normalize() ;
|
||||
}
|
||||
|
||||
//// creo le quattro superficie quadrate per fare i cap della giunzione tra cilindri e bilineari
|
||||
//PNTMATRIX vvPntSq( 4) ;
|
||||
@@ -1599,17 +1599,15 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
//}
|
||||
|
||||
// scorro tutti gli spilloni interessati
|
||||
int nAllStepsSurfs = nTotSurf * nStepCnt ;
|
||||
for ( int i = nStartI ; i <= nEndI ; ++ i) {
|
||||
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
|
||||
double dX = ( i + 0.5) * m_dStep ;
|
||||
double dY = ( j + 0.5) * m_dStep ;
|
||||
Point3d r( dX, dY, 0) ;
|
||||
Point3d ptMin, ptMax ;
|
||||
double dMin = INFINITO, dMax = -10 ;
|
||||
Vector3d vtMin, vtMax ;
|
||||
|
||||
PNTVECTVECTOR vInters ;
|
||||
// interseco con le bilineari
|
||||
for( int s = 0 ; s < nTotSurf ; ++s) {
|
||||
for( int s = 0 ; s < nAllStepsSurfs ; ++s) {
|
||||
// verifico che lo spillone faccia interferenza con il box della superficie
|
||||
if ( vSurfBox[s].SqDistFromPointXY( r) < EPS_ZERO) {
|
||||
double D1 = ( d[s].x - r.x) * q.z - ( d[s].z - r.z) * q.x ;
|
||||
@@ -1628,7 +1626,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
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, vInters) ;
|
||||
}
|
||||
}
|
||||
if ( nRoots > 1 && vdRoots[1] > 0 - EPS_ZERO && vdRoots[1] < 1 + EPS_ZERO) {
|
||||
@@ -1638,7 +1636,7 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
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, vInters) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1657,68 +1655,88 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
if ( IntersLineCylinder( r, Z_AX, frStartCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)) {
|
||||
bool bUpdate1 = false ;
|
||||
bool bUpdate2 = false ;
|
||||
if ( dSide > 0) {
|
||||
double dPerp = abs( vtDirTip * vtLs[0]) ;
|
||||
double dDirTip = vtDirTip.Len() ;
|
||||
double dParall = sqrt( pow( dDirTip,2) - pow( dPerp,2)) ;
|
||||
double dDistOverlap = dMinRad / dParall * dDirTip ;
|
||||
bUpdate1 = Dist( ptP1T, pt1) < dDistOverlap && vt1 * vtDirTip > 0 ;
|
||||
bUpdate2 = Dist( ptP1T, pt2) < dDistOverlap && vt2 * vtDirTip > 0 ;
|
||||
}
|
||||
else {
|
||||
double dPerp = abs( vtDirTop * vtLs[0]) ;
|
||||
double dDirTop = vtDirTop.Len() ;
|
||||
double dParall = sqrt( pow( dDirTop,2) - pow( dPerp,2)) ;
|
||||
double dDistOverlap = dMinRad / dParall * dDirTop ;
|
||||
bUpdate1 = Dist(ptS[0], pt1) < dDistOverlap && vt1 * vtDirTop > 0 ;
|
||||
bUpdate2 = Dist(ptS[0], pt2) < dDistOverlap && vt2 * vtDirTop > 0 ;
|
||||
}
|
||||
bool bOnTopBase1 = ( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL ;
|
||||
bool bOnBottomBase1 = ( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL ;
|
||||
bool bOnTopBase2 = ( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL ;
|
||||
bool bOnBottomBase2 = ( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL ;
|
||||
// se ho un'intersezione su una base devo verificare se la devo considerare o no
|
||||
if ( ! bUpdate1 && (( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL || ( pt1 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL)) {
|
||||
if ( bOnBottomBase1 || bOnTopBase1) {
|
||||
// verifico se sono nella metà della base il cui contorno è in contatto con le bilineari
|
||||
//base inferiore
|
||||
double dSectorAng = 0 ;
|
||||
if ( ( pt1 - frStartCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
if ( bOnBottomBase1 && ( pt1 - frStartCyl.Orig()) * vtDirTipStartEx > 0) {
|
||||
vvtTipStartAux.front().GetAngle(pt1 - frStartCyl.Orig(), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub) + 1) ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate1 = (pt1 - frStartCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = (pt1 - frStartCyl.Orig()) * vvtTipStartAux[nSector] ;
|
||||
if ( dSide > 0)
|
||||
bUpdate1 = dDist < dMinRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate1 = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ;
|
||||
}
|
||||
// base superiore
|
||||
else if(( pt1 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle(pt1 - frStartCyl.Orig(), dSectorAng) ;
|
||||
else if( bOnTopBase1 && ( pt1 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight))* vtDirTopStartEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle( pt1 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate1 = (pt1 - frStartCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = ( pt1 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight)) * vvtTopStartAux[nSector] ;
|
||||
if( dSide < 0)
|
||||
bUpdate1 = dDist < dMaxRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate1 = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ;
|
||||
}
|
||||
else
|
||||
bUpdate1 = true ;
|
||||
}
|
||||
else {
|
||||
double dHInters1 = (pt1 - ptP1T) * vtLs.front() ;
|
||||
Vector3d vtDir1 = Media( vtDirTip, vtDirTop, dHInters1 / dHeight) ;
|
||||
bUpdate1 = vt1 * vtDir1 > 0 ;
|
||||
}
|
||||
// se ho un'intersezione su una base devo verificare se la devo considerare o no
|
||||
if ( ! bUpdate2 && (( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() < EPS_SMALL || ( pt2 - frStartCyl.Orig()) * frStartCyl.VersZ() > dHeight - EPS_SMALL)) {
|
||||
if ( bOnBottomBase2 || bOnTopBase2) {
|
||||
// verifico se sono nella metà della base il cui contorno è in contatto con le bilineari
|
||||
//base inferiore
|
||||
double dSectorAng = 0 ;
|
||||
if ( ( pt2 - frStartCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
vvtTipStartAux.front().GetAngle(pt2 - frStartCyl.Orig(), dSectorAng) ;
|
||||
if ( bOnBottomBase2 && ( pt2 - frStartCyl.Orig()) * vtDirTipStartEx > 0) {
|
||||
vvtTipStartAux.front().GetAngle( pt2 - frStartCyl.Orig(), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate2 = (pt2 - frStartCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = ( pt2 - frStartCyl.Orig()) * vvtTipStartAux[nSector] ;
|
||||
if ( dSide > 0)
|
||||
bUpdate2 = dDist < dMinRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate2 = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ;
|
||||
|
||||
}
|
||||
// base superiore
|
||||
else if(( pt2 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle(pt2 - frStartCyl.Orig(), dSectorAng) ;
|
||||
else if( bOnTopBase2 && ( pt2 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight))* vtDirTopStartEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle( pt2 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate2 = (pt2 - frStartCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = ( pt2 - ( frStartCyl.Orig() + frStartCyl.VersZ() * dHeight)) * vvtTopStartAux[nSector] ;
|
||||
if ( dSide < 0)
|
||||
bUpdate2 = dDist < dMaxRadApprox - EPS_SMALL ;
|
||||
else {
|
||||
bUpdate2 = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ;
|
||||
}
|
||||
}
|
||||
else
|
||||
bUpdate2 = true ;
|
||||
}
|
||||
else {
|
||||
double dHInters2 = ( pt2 - ptP1T) * vtLs.front() ;
|
||||
Vector3d vtDir2 = Media( vtDirTip, vtDirTop, dHInters2 / dHeight) ;
|
||||
bUpdate2 = vt2 * vtDir2 > 0 ;
|
||||
}
|
||||
if ( bUpdate1)
|
||||
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt1, vt1, vInters) ;
|
||||
if ( bUpdate2)
|
||||
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt2, vt2, vInters) ;
|
||||
}
|
||||
}
|
||||
if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) {
|
||||
@@ -1729,68 +1747,86 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
if ( IntersLineCylinder( r, Z_AX, frEndCyl, dHeight, dMaxRad, false, false, pt1, vt1, pt2, vt2)){
|
||||
bool bUpdate1 = false ;
|
||||
bool bUpdate2 = false ;
|
||||
if ( dSide > 0) {
|
||||
double dPerp = abs( vtDirTop * vtLs[0]) ;
|
||||
double dDirTop = vtDirTop.Len() ;
|
||||
double dParall = sqrt( pow( dDirTop,2) - pow( dPerp,2)) ;
|
||||
double dDistOverlap = dMinRad / dParall * dDirTop ;
|
||||
bUpdate1 = Dist( ptE.back(), pt1) < dDistOverlap && vt1 * vtDirTop < 0 ;
|
||||
bUpdate2 = Dist( ptE.back(), pt2) < dDistOverlap && vt2 * vtDirTop < 0 ;
|
||||
}
|
||||
else {
|
||||
double dPerp = abs( vtDirTip * vtLs[0]) ;
|
||||
double dDirTip = vtDirTip.Len() ;
|
||||
double dParall = sqrt( pow( dDirTip,2) - pow( dPerp,2)) ;
|
||||
double dDistOverlap = dMinRad / dParall * dDirTip ;
|
||||
bUpdate1 = Dist( ptP2T, pt1) < dDistOverlap && vt1 * vtDirTip < 0 ;
|
||||
bUpdate2 = Dist( ptP2T, pt2) < dDistOverlap && vt2 * vtDirTip < 0 ;
|
||||
}
|
||||
bool bOnTopBase1 = ( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL ;
|
||||
bool bOnBottomBase1 = ( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL ;
|
||||
bool bOnTopBase2 = ( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL ;
|
||||
bool bOnBottomBase2 = ( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL ;
|
||||
// se ho un'intersezione su una base devo verificare se la devo considerare o no
|
||||
if ( ! bUpdate1 && (( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL || ( pt1 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL)) {
|
||||
if ( bOnBottomBase1 || bOnTopBase1) {
|
||||
// verifico se sono nella metà della base il cui contorno è in contatto con le bilineari
|
||||
//base inferiore
|
||||
double dSectorAng = 0 ;
|
||||
if ( ( pt1 - frEndCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
if ( bOnBottomBase1 && ( pt1 - frEndCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
vvtTipStartAux.front().GetAngle(pt1 - frEndCyl.Orig(), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate1 = (pt1 - frEndCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = (pt1 - frEndCyl.Orig()) * vvtTipStartAux[nSector] ;
|
||||
if ( dSide < 0)
|
||||
bUpdate1 = dDist < dMinRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate1 = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ;
|
||||
}
|
||||
// base superiore
|
||||
else if(( pt1 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle(pt1 - frEndCyl.Orig(), dSectorAng) ;
|
||||
else if( bOnTopBase1 && ( pt1 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight))* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle( pt1 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate1 = (pt1 - frEndCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = ( pt1 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight)) * vvtTopStartAux[nSector] ;
|
||||
if ( dSide > 0)
|
||||
bUpdate1 = dDist < dMaxRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate1 = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ;
|
||||
}
|
||||
else
|
||||
bUpdate1 = true ;
|
||||
}
|
||||
else {
|
||||
double dHInters1 = (pt1 - ptP2T) * vtLe.back() ;
|
||||
Vector3d vtDir1 = Media( vtDirTip, vtDirTop, dHInters1 / dHeight) ;
|
||||
bUpdate1 = vt1 * vtDir1 < 0 ;
|
||||
}
|
||||
// se ho un'intersezione su una base devo verificare se la devo considerare o no
|
||||
if ( ! bUpdate2 && (( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() < EPS_SMALL || ( pt2 - frEndCyl.Orig()) * frEndCyl.VersZ() > dHeight - EPS_SMALL)) {
|
||||
if ( bOnBottomBase2 || bOnTopBase2) {
|
||||
// verifico se sono nella metà della base il cui contorno è in contatto con le bilineari
|
||||
//base inferiore
|
||||
double dSectorAng = 0 ;
|
||||
if ( ( pt2 - frEndCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
if ( bOnBottomBase2 && ( pt2 - frEndCyl.Orig()) * vtDirTipEndEx > 0) {
|
||||
vvtTipStartAux.front().GetAngle(pt2 - frEndCyl.Orig(), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate2 = (pt2 - frEndCyl.Orig()) * vvtTipStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = (pt2 - frEndCyl.Orig()) * vvtTipStartAux[nSector] ;
|
||||
if ( dSide < 0)
|
||||
bUpdate2 = dDist < dMinRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate2 = dDist > dMinRadApprox - EPS_SMALL && dDist < dMinRad ;
|
||||
}
|
||||
// base superiore
|
||||
else if(( pt2 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight ) )* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle(pt2 - frEndCyl.Orig(), dSectorAng) ;
|
||||
else if( bOnTopBase2 && ( pt2 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight))* vtDirTopEndEx > 0) {
|
||||
vvtTopStartAux.front().GetAngle( pt2 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight), dSectorAng) ;
|
||||
// determino in quale settore del semicerchio approssimato mi trovo
|
||||
int nSector = dSectorAng / ( 180. / nSub) + 1 ;
|
||||
int nSector = int( dSectorAng / ( 180. / nSub)) + 1 ;
|
||||
// verifico se l'intersezione linea-base è interna o esterna
|
||||
bUpdate2 = (pt2 - frEndCyl.Orig()) * vvtTopStartAux[nSector] < dRadApprox - EPS_SMALL ;
|
||||
double dDist = ( pt2 - ( frEndCyl.Orig() + frEndCyl.VersZ() * dHeight)) * vvtTopStartAux[nSector] ;
|
||||
if ( dSide > 0)
|
||||
bUpdate2 = dDist < dMaxRadApprox - EPS_SMALL ;
|
||||
else
|
||||
bUpdate2 = dDist > dMaxRadApprox - EPS_SMALL && dDist < dMaxRad ;
|
||||
}
|
||||
else
|
||||
bUpdate2 = true ;
|
||||
}
|
||||
else {
|
||||
double dHInters2 = (pt2 - ptP2T) * vtLe.back() ;
|
||||
Vector3d vtDir2 = Media( vtDirTip, vtDirTop, dHInters2 / dHeight) ;
|
||||
bUpdate2 = vt2 * vtDir2 < 0 ;
|
||||
}
|
||||
if ( bUpdate1)
|
||||
UpdateMaxMin( pt1, -vt1, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt1, vt1, vInters) ;
|
||||
if ( bUpdate2)
|
||||
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt2, vt2, vInters) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1802,8 +1838,8 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
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) ;
|
||||
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt1, vt1, vInters) ;
|
||||
UpdateMaxMin( pt2, vt2, vInters) ;
|
||||
}
|
||||
}
|
||||
if ( bbEndCyl.SqDistFromPointXY( r) < EPS_ZERO) {
|
||||
@@ -1812,16 +1848,61 @@ VolZmap::Comp_5AxisMilling( int nGrid, const PNTVECTOR& ptS, const PNTVECTOR& pt
|
||||
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) ;
|
||||
UpdateMaxMin( pt2, -vt2, dMin, dMax, ptMin, ptMax, vtMin, vtMax) ;
|
||||
UpdateMaxMin( pt1, vt1, vInters) ;
|
||||
UpdateMaxMin( pt2, vt2, vInters) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// interseco con le basi trimmate dei cilindri ( che tengono conto dell'approssimazione fatta con bilineari del volume spazzato da top e tip)
|
||||
|
||||
|
||||
if ( dMax > 0 && dMin < dMax)
|
||||
SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax, nToolNum) ;
|
||||
if ( vInters.size() != 0 ) {
|
||||
// se ho un numero dispari di intersezioni devo migliorare la gestione
|
||||
|
||||
// riordino le intersezioni rispetto alla loro z
|
||||
sort( vInters.begin(), vInters.end(), []( PNTVECT& a, PNTVECT& b){ return a.first.z < b.first.z ;}) ;
|
||||
if ( vInters.size() > 2) {
|
||||
INTVECTOR vErase ;
|
||||
bool bStartNewInterval = true ;
|
||||
// elimino eventuali doppioni di punti
|
||||
for ( int w = 0 ; w < int( vInters.size()) ; ++w) {
|
||||
// se è l'ultimo punto esco
|
||||
if ( w == int( vInters.size() - 1))
|
||||
break ;
|
||||
// se sono due punti vicino tolgo il secondo se sto cercando l'inizio di un intervallo
|
||||
// mentre se sto cercando la fine tolgo il primo
|
||||
if ( vInters[w + 1].first.z - vInters[w].first.z < 1) {
|
||||
if ( bStartNewInterval) {
|
||||
// se sto cercando l'inizio, ma sono gli ultimi due punti e sono vicini allora tolgo entrambi ed esco
|
||||
if ( w == int( vInters.size() - 2)) {
|
||||
// serve che siano in quest'ordine
|
||||
vErase.push_back( w) ;
|
||||
vErase.push_back( w + 1) ;
|
||||
break ;
|
||||
}
|
||||
else
|
||||
vErase.push_back( w + 1) ;
|
||||
++w ;
|
||||
}
|
||||
else {
|
||||
vErase.push_back( w) ;
|
||||
++w ;
|
||||
}
|
||||
}
|
||||
bStartNewInterval = ! bStartNewInterval ;
|
||||
}
|
||||
|
||||
// elimino i doppioni
|
||||
for ( int w = vErase.size() - 1 ; w >= 0 ; --w)
|
||||
vInters.erase( vInters.begin() + vErase[w]) ;
|
||||
}
|
||||
if ( vInters.size() % 2 == 0) {
|
||||
for( int z = 0 ; z < int( vInters.size()) ; z += 2)
|
||||
SubtractIntervals( nGrid, i, j, vInters[z].first.z, vInters[z+1].first.z, vInters[z].second, vInters[z+1].second, nToolNum) ;
|
||||
}
|
||||
else if ( vInters.size() == 3)
|
||||
SubtractIntervals( nGrid, i, j, vInters.front().first.z, vInters.back().first.z, vInters.front().second, vInters.back().second, nToolNum) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2054,14 +2135,14 @@ 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. ;
|
||||
BIPNTVECTOR vPntStep( nStepCnt) ;
|
||||
vector<pair<Vector3d, Vector3d>> vDirStep( nStepCnt) ;
|
||||
//dCorr = 0. ; // annullo la sovrapposizione // debug
|
||||
//BIPNTVECTOR vPntStep( nStepCnt) ;
|
||||
//vector<pair<Vector3d, Vector3d>> vDirStep( nStepCnt) ;
|
||||
|
||||
vector<Point3d[N_MAPS]> ptLs( nStepCnt) ;
|
||||
vector<Point3d[N_MAPS]> ptLe( nStepCnt) ;
|
||||
vector<Vector3d[N_MAPS]> vtLs( nStepCnt) ;
|
||||
vector<Vector3d[N_MAPS]> vtLe( nStepCnt) ;
|
||||
vector<Point3d[N_MAPS]> ptLs( nStepCnt + 1) ;
|
||||
vector<Point3d[N_MAPS]> ptLe( nStepCnt + 1) ;
|
||||
vector<Vector3d[N_MAPS]> vtLs( nStepCnt + 1) ;
|
||||
vector<Vector3d[N_MAPS]> vtLe( nStepCnt + 1) ;
|
||||
|
||||
for ( int i = 0 ; i <= nStepCnt && bOk ; ++ i) {
|
||||
//// replico il tutto ma tenendo degli step più ampi e usando i veri vettori di start e end del tratto
|
||||
@@ -2083,18 +2164,16 @@ VolZmap::MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, co
|
||||
if ( i == nStepCnt)
|
||||
nPhase = VolZmap::MillingPhase::COUNT_END_VOL ;
|
||||
|
||||
Point3d ptLs[N_MAPS] ;
|
||||
|
||||
InitializePointsAndVectors( ptSti, ptEni, vtDSi, vtDEi, &ptLs[i], ptLe[i], vtLs[i], vtLe[i]) ;
|
||||
InitializePointsAndVectors( ptSti, ptEni, vtDSi, vtDEi, ptLs[i], ptLe[i], vtLs[i], vtLe[i]) ;
|
||||
}
|
||||
|
||||
///// decommentare solo per debug
|
||||
for( int j = 0 ; j < N_MAPS; ++j) {
|
||||
PNTVECTOR ptLs_j( nStepCnt) ;
|
||||
PNTVECTOR ptLe_j( nStepCnt) ;
|
||||
VCT3DVECTOR vtLs_j( nStepCnt) ;
|
||||
VCT3DVECTOR vtLe_j( nStepCnt) ;
|
||||
for ( int z = 0 ; z < nStepCnt ; ++z) {
|
||||
PNTVECTOR ptLs_j( nStepCnt + 1) ;
|
||||
PNTVECTOR ptLe_j( nStepCnt + 1) ;
|
||||
VCT3DVECTOR vtLs_j( nStepCnt + 1) ;
|
||||
VCT3DVECTOR vtLe_j( nStepCnt + 1) ;
|
||||
for ( int z = 0 ; z <= nStepCnt ; ++z) {
|
||||
ptLs_j[z] = ptLs[z][j] ;
|
||||
ptLe_j[z] = ptLe[z][j] ;
|
||||
vtLs_j[z] = vtLs[z][j] ;
|
||||
|
||||
Reference in New Issue
Block a user