EgtMachKernel :

- primo codice di test da migliorare per Trapezi SpiralIn/Out.
This commit is contained in:
Riccardo Elitropi
2023-11-03 18:17:26 +01:00
parent 4ed4445d09
commit 0dfc9a38da
2 changed files with 430 additions and 295 deletions
+425 -291
View File
@@ -4647,6 +4647,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
vector<Vector3d> vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente
INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
BOOLVECTOR vbOptTrap_prec ; // flags per caso ottimizzato svuotratura dello step precedente
int nOffs_act = 0 ;
// ciclo su tutti gli step
@@ -4671,6 +4672,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
vnRegTot_prec.clear() ;
vbMidOutPrec.clear() ;
vvtMidOutPrec.clear() ;
vbOptTrap_prec.clear() ;
}
for ( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo...
@@ -4721,6 +4723,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
bMidOut = vbMidOutPrec[nOffs_act] ;
vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ;
vtMidOut = vvtMidOutPrec[nOffs_act] ;
bOptimizedTrap = vbOptTrap_prec[nOffs_act] ;
}
else {
// se lucidatura con epicicli
@@ -4789,6 +4792,8 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
vnRegTot_prec.push_back( nRegTot) ;
// memorizzo il versore di uscita calcolato
vvtMidOutPrec.push_back( vtMidOut) ;
// memorizzo caso ottimizzato
vbOptTrap_prec.push_back( bOptimizedTrap) ;
}
// controlli per entrate da fuori al grezzo
@@ -5422,66 +5427,43 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
else
return true ;
}
bool bSomeOpen = false ;
int nTmpProp0 = -1 ;
for ( int u = 0 ; u < pCrvBorder->GetCurveCount() && !bSomeOpen; ++ u) {
pCrvBorder->GetCurveTempProp( u, nTmpProp0, 0) ;
bSomeOpen = ( nTmpProp0 == 1) ;
}
// caso trapezoide
Point3d pt ; Vector3d vtB1, vtL1, vtB2 ;
PtrOwner<ICurveComposite> pCrvTrap( CreateCurveComposite()) ;
if ( IsNull( pCrvTrap))
return false ;
Vector3d vtDir ; double dPocketSize ;
pCrvBorder->ToLoc( frPocket) ;
if ( ! GetTrapezoidFromShape( pCrvBorder, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, pCrvTrap,
vtDir, dPocketSize))
pCrvOEWithFlags->ToLoc( frPocket) ;
Frame3d frTrap ;
double dPocketSize ;
int nBase, nSecondBase ;
if ( ! GetTrapezoidFromShape( pCrvOEWithFlags, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec :
m_TParams.m_dDiam + GetOffsR(),
pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase))
return false ;
pCrvTrap->ToGlob( frPocket) ;
if ( pCrvTrap->IsValid()) {
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u) {
const ICurve* pCrv = pCrvTrap->GetCurve( u) ;
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( a, pCrv->GetTempProp( 0) == 0 ? BLUE : RED) ;
pCrvTrap->SetExtrusion( vtExtr) ;
if ( nReg == 0) {
CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, pMCrv, pRCrv, bOptimizedTrap) ;
if ( bOptimizedTrap) {
// ----
pCrvTrap->ToGlob( frPocket) ;
if ( pCrvTrap->IsValid()) {
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u) {
const ICurve* pCrv = pCrvTrap->GetCurve( u) ;
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( a, pCrv->GetTempProp( 0) == 0 ? BLUE : RED) ;
}
}
// ----
pMCrv->ToGlob( frPocket) ;
pRCrv->ToGlob( frPocket) ;
nReg = 1 ;
return true ;
}
}
else
return true ;
}
return false ;
//if ( pCrvOEWithFlags->IsATrapezoid( 100 * EPS_SMALL, pt, vtB1, vtL1, vtB2)) {
// Vector3d vtDir( vtB1), vtOtherDir( vtL1) ;
// // se parallelogramma scelgo come base i lati lunghi
// Vector3d vtL2( - vtB1 + vtL1 + vtB2) ;
// if ( AreSameOrOppositeVectorApprox( vtL1, vtL2)) {
// if ( vtL1.Len() > vtB1.Len())
// swap( vtDir, vtOtherDir) ;
// }
// vtDir.Normalize() ;
// Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ;
// double dPocketSize = vtOrtho.Len() ;
// double dMaxOptSize ;
// FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxOptSize="), dMaxOptSize) ;
// if ( ( ( bSomeOpen && dPocketSize < m_TParams.m_dDiam + EPS_SMALL) ||
// abs( dPocketSize - m_TParams.m_dDiam) < EPS_SMALL) &&
// ( ! FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxOptSize="), dMaxOptSize) ||
// dPocketSize < dMaxOptSize))
// {
/*
if ( nReg == 0) {
CalcTrapezoidSpiral( pCrvOEWithFlags, vtDir, dPocketSize, pMCrv, pRCrv, bOptimizedTrap) ;
if ( bOptimizedTrap) {
nReg = 1 ;
return true ;
}
}
else
return true ;
*/
// }
//}
}
// porto la superficie nel frame della svuotatura
@@ -7568,50 +7550,21 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d
//----------------------------------------------------
bool
Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtDir, double dPocketSize,
ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool& bOptimizedTrap)
Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double dPocketSize, int nBase,
int nSecondBase, ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool& bOptimizedTrap)
{
// parametri
double dDiam = m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam ;
double dOffsR = m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR() ;
double dRad = 0.5 * dDiam + dOffsR ;
const double TOLL = 50 * EPS_SMALL ;
bOptimizedTrap = false ;
Vector3d vtExtr ; pCrvPocket->GetExtrusion( vtExtr) ;
// eventuale approssimazione della curva con polyline per ottenere la stessa curva calcolata in ICurveComposite::IsATrapezoid
if ( pCrvPocket->GetCurveCount() > 4) {
PolyLine PL ;
if ( ! pCrvPocket->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return false ;
pCrvPocket->Clear() ;
pCrvPocket->FromPolyLine( PL) ;
pCrvPocket->SetExtrusion( vtExtr) ;
}
// sistemo senso antiorario visto dalla direzione di estrusione
Plane3d plPlane ; double dArea ;
pCrvPocket->GetArea( plPlane, dArea) ;
if ( plPlane.GetVersN() * vtExtr * dArea < 0)
pCrvPocket->Invert() ;
// passo in un sistema di riferimento locale avente asse X allineato con uno dei due lati paralleli (possibilmente aperto) e centro nel
// punto iniziale del lato
Frame3d frLoc ;
if ( ! CalcTrapezoidSpiralLocalFrame( pCrvPocket, vtDir, frLoc))
return false ;
pCrvPocket->ToLoc( frLoc) ;
// recupero flag aperto/chiuso dei lati (0=chiuso, 1=aperto)
INTVECTOR vnProp( 4, 0) ;
for ( int i = 0 ; i < 4 ; i++)
pCrvPocket->GetCurveTempProp( i, vnProp[i]) ;
// verifico le dimensioni della svuotatura
double dLen0 = 0, dLen2 = 0 ;
pCrvPocket->GetCurve( 0)->GetLength( dLen0) ;
pCrvPocket->GetCurve( 2)->GetLength( dLen2) ;
if ( vnProp[0] == 0 && abs( dPocketSize - m_TParams.m_dDiam) > EPS_SMALL)
return false ;
if ( vnProp[1] == 0 && vnProp[3] == 0) {
if ( dLen0 < m_TParams.m_dDiam - EPS_SMALL || dLen2 < m_TParams.m_dDiam - EPS_SMALL)
return false ;
}
// punto iniziale del lato
pCrvPocket->ToLoc( frTrap) ;
// calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso)
Point3d ptOrig ;
@@ -7625,93 +7578,114 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD
// calcolo percorso di svuotatura
// se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale
if ( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 &&
/*if ( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 &&
dMaxLarg > m_TParams.m_dDiam + 10 * EPS_SMALL && max( dLen0, dLen2) < 2 * m_TParams.m_dDiam + EPS_SMALL) {
if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket)) {
pMCrv->Clear() ;
return false ;
}
}
else {
double dYCoord = dPocketSize - 0.5 * m_TParams.m_dDiam ;
if ( vnProp[0] != 0)
dYCoord -= GetOffsR() ;
if ( vnProp[0] != 0 && vnProp[2] != 0)
dYCoord = 0.5 * dPocketSize ; // se entrambi i lati paralleli sono aperti mi posiziono a metà della svuotatura
else {*/
// trovo la quota Y per centro del Tool
double dYCoord ;
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 0) // se base principale chiusa
dYCoord = 0.5 * dDiam + dOffsR ;
else if ( pCrvPocket->GetCurve( nSecondBase)->GetTempProp( 0) == 0) // se base principale aperta e secondaria chiusa
dYCoord = dPocketSize - 0.5 * dDiam - dOffsR ;
else // se entrambi i lati paralleli sono aperti mi posiziono a metà della svuotatura
dYCoord = 0.5 * dPocketSize ;
double dXCoordStart, dXCoordEnd ;
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, true, dYCoord, dXCoordStart, dPocketSize))
double dXCoordStart, dXCoordEnd ;
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, true, dYCoord, dXCoordStart, dPocketSize))
return false ;
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, false, dYCoord, dXCoordEnd, dPocketSize))
if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, nBase, nSecondBase, false, dYCoord, dXCoordEnd, dPocketSize))
return false ;
if ( dXCoordStart > dXCoordEnd + 500 * EPS_SMALL)
return false ;
Point3d ptStart( dXCoordStart, dYCoord) ;
Point3d ptEnd( dXCoordEnd, dYCoord) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && vnProp[0] != 0) {
Vector3d vtDir1, vtDir3 ;
pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ;
pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ;
// gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile
if ( AreOppositeVectorApprox( vtDir1, vtDir3)) {
PtrOwner<ICurveLine> pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ;
PtrOwner<ICurveLine> pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ;
if ( IsNull( pLine1) || IsNull( pLine3))
return true ;
if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ||
! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()))
return true ;
//if ( AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && vnProp[0] != 0) {
// Vector3d vtDir1, vtDir3 ;
// pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ;
// pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ;
// // gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile
// if ( AreOppositeVectorApprox( vtDir1, vtDir3)) {
// PtrOwner<ICurveLine> pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ;
// PtrOwner<ICurveLine> pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ;
// if ( IsNull( pLine1) || IsNull( pLine3))
// return true ;
// if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ||
// ! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()))
// return true ;
Point3d ptS, ptE ;
if ( vtDir3 * X_AX > EPS_SMALL) {
pLine1->GetStartPoint( ptS) ;
pLine3->GetStartPoint( ptE) ;
}
else {
pLine1->GetEndPoint( ptE) ;
pLine3->GetEndPoint( ptS) ;
}
// Point3d ptS, ptE ;
// if ( vtDir3 * X_AX > EPS_SMALL) {
// pLine1->GetStartPoint( ptS) ;
// pLine3->GetStartPoint( ptE) ;
// }
// else {
// pLine1->GetEndPoint( ptE) ;
// pLine3->GetEndPoint( ptS) ;
// }
pMCrv->AddPoint( ptS) ;
if ( vnProp[2] != 0)
pMCrv->AddLine( ptE) ;
else
pMCrv->AddLine( ptStart) ;
// pMCrv->AddPoint( ptS) ;
// if ( vnProp[2] != 0)
// pMCrv->AddLine( ptE) ;
// else
// pMCrv->AddLine( ptStart) ;
pMCrv->SetCurveTempProp( 0, 1) ;
}
}
else {
// pMCrv->SetCurveTempProp( 0, 1) ;
// }
//}
//else {
if ( ! pMCrv->AddPoint( ptStart))
return true ;
if ( ! pMCrv->AddLine( ptEnd))
return true ;
// aggiustamenti al percorso per rimuovere materiale residuo negli angoli
if ( vnProp[0] != 0) {
if ( vnProp[3] == 0 && ! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, true)) {
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 1 ||
pCrvPocket->GetCurve( nSecondBase)->GetTempProp( 0) == 1) {
if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 0)
pCrvPocket->ChangeStartPoint( nSecondBase) ;
if ( pCrvPocket->GetCurve( 3)->GetTempProp( 0) == 0 &&
! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, true)) {
pMCrv->Clear() ;
return false ;
}
if ( vnProp[1] == 0 && ! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, false)) {
if ( pCrvPocket->GetCurve( 1)->GetTempProp( 0) == 0 &&
! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, false)) {
pMCrv->Clear() ;
return false ;
}
}
}
}
//}
//}
if ( pMCrv->GetCurveCount() == 0)
return true ;
pMCrv->ToGlob( frLoc) ;
pMCrv->ToGlob( frTrap) ;
INTVECTOR vnProp( 4, 0) ;
if ( pCrvPocket->GetCurveCount() == 4) {
for ( int i = 0 ; i < 4 ; i++)
pCrvPocket->GetCurveTempProp( i, vnProp[i]) ;
}
else {
vnProp[1] = pCrvPocket->GetCurve( 1)->GetTempProp() ;
vnProp[3] = pCrvPocket->GetCurve( nSecondBase + 1)->GetTempProp() ;
}
if ( ! m_Params.m_bInvert) {
pMCrv->Invert() ;
// inverto le proprietà in modo che nProp3 sia sempre legata al punto iniziale e nProp1 a quello finale
swap( vnProp[1], vnProp[3]) ;
}
// segno i lati aperti come temp prop della curva
// segno i lati aperti come temp prop della curva
int nOpenEdges = vnProp[0] + vnProp[1] * 2 + vnProp[3] * 8 ;
pMCrv->SetTempProp( nOpenEdges, 0) ;
pMCrv->SetExtrusion( vtExtr) ;
@@ -7722,13 +7696,13 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtD
//----------------------------------------------------
bool
Pocketing::CalcTrapezoidSpiralLocalFrame( ICurveComposite* pCrvPocket, const Vector3d& vtDir, Frame3d& frLoc)
Pocketing::CalcTrapezoidSpiralLocalFrame( ICurveComposite* pCrvTrap, const Vector3d& vtDir, Frame3d& frLoc)
{
// cerco i lati paralleli a vtDir
int nBaseId = -1 ;
for ( int i = 0 ; i < pCrvPocket->GetCurveCount() ; i ++) {
for ( int i = 0 ; i < pCrvTrap->GetCurveCount() ; i ++) {
Vector3d vtEdge ;
pCrvPocket->GetCurve( i)->GetStartDir( vtEdge) ;
pCrvTrap->GetCurve( i)->GetStartDir( vtEdge) ;
if ( AreSameOrOppositeVectorApprox( vtEdge, vtDir)) {
nBaseId = i ;
break ;
@@ -7737,71 +7711,119 @@ Pocketing::CalcTrapezoidSpiralLocalFrame( ICurveComposite* pCrvPocket, const Vec
if ( nBaseId != 0 && nBaseId != 1)
return false ;
// imposto come lato iniziale per la curva uno dei lati paralleli a vtDir (possibilmente aperto)
int nProp0, nProp2 ;
pCrvPocket->GetCurveTempProp( nBaseId, nProp0) ;
pCrvPocket->GetCurveTempProp( nBaseId + 2, nProp2) ;
if ( nProp0 == 0 && nProp2 != 0)
pCrvPocket->ChangeStartPoint( nBaseId + 2) ;
else
pCrvPocket->ChangeStartPoint( nBaseId) ;
Point3d ptOrig ;
pCrvPocket->GetStartPoint( ptOrig) ;
Vector3d vtExtr ;
pCrvPocket->GetExtrusion( vtExtr) ;
Vector3d vtX ;
pCrvPocket->GetStartDir( vtX) ;
return frLoc.Set( ptOrig, vtExtr, vtX) ;
// imposto come lato iniziale per la curva uno dei lati paralleli a vtDir
pCrvTrap->ChangeStartPoint( nBaseId) ;
Point3d ptOrig ; pCrvTrap->GetStartPoint( ptOrig) ;
Vector3d vtX ; pCrvTrap->GetStartDir( vtX) ;
return frLoc.Set( ptOrig, Z_AX, vtX) ;
}
//------------------------------------------------------
bool
Pocketing::CalcTrapezoidSpiralXCoord( const ICurveComposite* pCrvPocket, bool bStart, double dYCoord, double& dXCoord, double dPocketSize)
Pocketing::CalcTrapezoidSpiralXCoord( const ICurveComposite* pCrvPocket, int nBase, int nSecondBase,
bool bStart, double dYCoord, double& dXCoord, double dPocketSize)
{
// se open
int nCrvId = ( bStart ? 3 : 1) ;
int nProp ;
if ( pCrvPocket->GetCurveTempProp( nCrvId, nProp) && nProp != 0) {
// parametri
double dDiam = m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam ;
double dOffsR = m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR() ;
double dRad = 0.5 * dDiam + dOffsR ;
const double TOLL = 50 * EPS_SMALL ;
// recupero la curva di interesse
int nCrvId = ( bStart ? nSecondBase : nBase) + 1 ;
int nProp = - 1 ;
if ( ! pCrvPocket->GetCurveTempProp( nCrvId, nProp))
return false ;
// se open
if ( nProp == 1) {
Point3d pt1, pt2 ;
pCrvPocket->GetCurve( nCrvId)->GetStartPoint( pt1) ;
pCrvPocket->GetCurve( nCrvId)->GetEndPoint( pt2) ;
if ( bStart)
dXCoord = min( pt1.x, pt2.x) ;
else
dXCoord = max( pt1.x, pt2.x) ;
dXCoord = max( pt1.x, pt2.x) ;
}
// se closed
// se closed
else {
double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ;
double dVal ;
Vector3d vtRef ;
pCrvPocket->GetCurve( nCrvId)->GetStartDir( vtRef) ;
double dCosAlpha = vtRef * X_AX ;
if ( dRad * dCosAlpha < dYCoord && dYCoord < dPocketSize + dRad * dCosAlpha) {
double dSinAlpha = ( vtRef ^ X_AX).Len() ;
if ( abs( dSinAlpha) < EPS_SMALL)
// creo la curva destra/sinistra
int nLast = bStart ? pCrvPocket->GetCurveCount() : nSecondBase ;
PtrOwner<ICurveComposite> pCrvSide( ConvertCurveToComposite( pCrvPocket->CopyParamRange( nCrvId, nLast))) ;
if ( IsNull( pCrvSide))
return false ;
// Offsetto la curva
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvSide, - dRad, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( OffsCrv.GetCurveCount() == 0) {
// controllo se avevo una circonferenza
if ( pCrvSide->GetCurveCount() == 1 && pCrvSide->GetFirstCurve()->GetType() == CRV_ARC) {
Point3d ptS ; pCrvSide->GetStartPoint( ptS) ;
dXCoord = ptS.x ;
}
else {
Point3d ptS ; pCrvSide->GetStartPoint( ptS) ;
Point3d ptE ; pCrvSide->GetEndPoint( ptE) ;
dXCoord = bStart ? max( ptS.x, ptE.x) + dRad : min( ptS.x, ptE.x) - dRad ;
}
}
else if ( OffsCrv.GetCurveCount() == 1) {
// controllo se la curva interseca la linea di svuotatura a YCoord
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCrvOffs))
return false ;
dVal = 1.0 / dSinAlpha * ( dRad - dYCoord * dCosAlpha) ;
}
else if ( dYCoord < dRad * dCosAlpha)
dVal = sqrt( dRad * dRad - dYCoord * dYCoord) ;
else {
double dLen ;
pCrvPocket->GetCurve( nCrvId)->GetLength( dLen) ;
dVal = - dLen * dCosAlpha + sqrt( dRad * dRad - dYCoord * dYCoord) ;
}
Point3d ptRef ;
if ( bStart) {
pCrvPocket->GetCurve( nCrvId)->GetEndPoint( ptRef) ;
dXCoord = ptRef.x + dVal ;
}
else {
pCrvPocket->GetCurve( nCrvId)->GetStartPoint( ptRef) ;
dXCoord = ptRef.x - dVal ;
PtrOwner<ICurveLine> pLineMid( CreateCurveLine()) ;
if ( IsNull( pLineMid))
return false ;
pLineMid->Set( Point3d( -3000, dYCoord, 0), Point3d( 3000, dYCoord, 0)) ;
IntersCurveCurve intCC( *pLineMid, *pCrvOffs) ;
IntCrvCrvInfo ccClass ;
if ( intCC.GetIntersCount() != 0) {
// se ho almeno una intersezione
if ( intCC.GetIntCrvCrvInfo( 0, ccClass))
dXCoord = ccClass.IciA[0].ptI.x ;
else
return false ;
}
else {
// se non ho intersezioni...
// prendo il box della curva
BBox3d Box3d ;
pCrvSide->GetLocalBBox( Box3d) ;
// creo la linea limitie verticale
PtrOwner<ICurveLine> pCrvVertLine( CreateCurveLine()) ;
if ( IsNull( pCrvVertLine))
return false ;
if ( bStart)
pCrvVertLine->SetPDL( Box3d.GetMax() + 5 * TOLL * Y_AX, - 90 , 2 * dPocketSize) ;
else
pCrvVertLine->SetPDL( Box3d.GetMin() - 5 * TOLL * Y_AX, 90, 2 * dPocketSize) ;
// intersechiamo
IntersCurveCurve intCC2( *pCrvVertLine, *pCrvSide) ;
if ( intCC2.GetOverlaps()) {
if ( bStart)
dXCoord = Box3d.GetMax().x + dRad ;
else
dXCoord = Box3d.GetMin().x - dRad ;
}
else {
dXCoord = bStart ? -INFINITO : INFINITO ;
for ( int i = 0 ; i < intCC2.GetIntersCount() ; ++ i) {
IntCrvCrvInfo ccClass2 ;
if ( intCC2.GetIntCrvCrvInfo( i, ccClass2)) {
if ( bStart)
dXCoord = max( dXCoord, Box3d.GetMax().x + sqrt( dRad * dRad - pow(( ccClass2.IciA[0].ptI.y - dYCoord), 2))) ;
else
dXCoord = min( dXCoord, Box3d.GetMin().x - sqrt( dRad * dRad - pow(( ccClass2.IciA[0].ptI.y - dYCoord), 2))) ;
}
}
}
}
}
else
return false ;
}
return true ;
}
@@ -8160,7 +8182,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V
return false ;
// se vicino al bordo del grezzo
if ( dDist < m_TParams.m_dDiam / 2 + EPS_SMALL) {
if ( abs( dDist) < m_TParams.m_dDiam / 2 + EPS_SMALL) {
Point3d ptTestO = ptP + vtDirO * ( - dDist + m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) ;
ptTestO += - vtTool * dDepth ;
double dTestElevO ;
@@ -14787,8 +14809,8 @@ Pocketing::GetOptCrvIndex( const vector<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, int
CRVCVECTOR ccClass ;
if ( pSrfChunkFinal->GetCurveClassification( *vCrvOEWithFlags[nStep-1][k], EPS_SMALL, ccClass)) {
bool bIsThis = true ;
for( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++kk) {
if( ccClass[kk].nClass == CRVC_OUT)
for ( int kk = 0 ; kk < ( int)ccClass.size() && bIsThis ; ++kk) {
if ( ccClass[kk].nClass == CRVC_OUT)
bIsThis = false ;
}
if ( bIsThis) {
@@ -14805,12 +14827,51 @@ Pocketing::GetOptCrvIndex( const vector<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, int
//----------------------------------------------------------------------------
bool
Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam, ICurveComposite* pCrvTrap,
Vector3d& vtDir, double& dPocketSize)
Frame3d& frTrap, double& dPocketSize, int& nBase, int& nSecondBase)
{
// controllo parametri
if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid())
return false ;
pCrvTrap->Clear() ; // resterà vuota se il caso non è ottimizzato
nBase = -1 ;
nSecondBase = -1 ;
// se la curva è già un trapezio, non sempre devo adattarla...
Point3d pt ; Vector3d vtDir, vtB2, vtOtherDir ;
if ( pCrvCompo->IsATrapezoid( 100 * EPS_SMALL, pt, vtDir, vtOtherDir, vtB2)) {
pCrvTrap->AddCurve( pCrvCompo->Clone()) ;
// se parallelogramma scelgo come base i lati lunghi
Vector3d vtL2( - vtDir + vtOtherDir + vtB2) ;
if ( AreSameOrOppositeVectorApprox( vtOtherDir, vtL2)) {
if ( vtOtherDir.Len() > vtDir.Len())
swap( vtDir, vtOtherDir) ;
}
vtDir.Normalize() ;
Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ;
dPocketSize = vtOrtho.Len() ;
// eventuale approssimazione della curva con polyline per ottenere la stessa curva calcolata in ICurveComposite::IsATrapezoid
if ( pCrvCompo->GetCurveCount() > 4) {
PolyLine PL ;
if ( ! pCrvCompo->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
return false ;
pCrvTrap->FromPolyLine( PL) ;
}
if ( ! CalcTrapezoidSpiralLocalFrame( pCrvTrap, vtDir, frTrap))
return false ;
// recupero flag aperto/chiuso dei lati
if ( pCrvTrap->GetCurve( 1)->GetTempProp( 0) == 0 && pCrvTrap->GetCurve( 3)->GetTempProp( 0) == 0) {
double dLen0, dLen2 ;
pCrvTrap->GetCurve( 0)->GetLength( dLen0) ;
pCrvTrap->GetCurve( 2)->GetLength( dLen2) ;
if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL)
pCrvTrap->Clear() ;
}
// imposto le basi
nBase = 0 ;
nSecondBase = 2 ;
return true ;
}
// controllo il numero di lati chiusi e salvo i loro indici
int nClosedSide = 0 ;
@@ -14823,36 +14884,28 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
}
}
const double TOLL = 5 * EPS_SMALL ;
// clono la curva Compo
PtrOwner<ICurveComposite> pCrvCompo_c( CloneCurveComposite( pCrvCompo)) ;
if ( IsNull( pCrvCompo_c))
return false ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->Clone()) ;
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvCompo, - 0.5 * dDiam * 1.05 + TOLL, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( OffsCrv.GetCurveCount() > 1) // i chiusi sono troppo vicini => non può essere ottimizzato
return true ;
PtrOwner<ICurveComposite> pCrvCompo_COffs( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
if ( IsNull( pCrvCompo_COffs))
return false ;
int y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo_COffs->Clone()) ;
m_pGeomDB->SetMaterial( y, PURPLE) ;
// tolleranza
const double TOLL = 50 * EPS_SMALL ;
// se tutti lati aperti
if ( nClosedSide == 0) {
// ricavo il box minimo della curva aperta ( passo dalla polyLine)
PolyLine PL ; Point3d ptCen ; double dWidth ;
if ( ! pCrvCompo_COffs->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ||
if ( ! pCrvCompo->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ||
! PL.GetMinAreaRectangleXY( ptCen, vtDir, dWidth, dPocketSize))
return false ;
// controllo dimY ( dHeight), se troppo estesa, non è un caso ottimizzato
if ( dPocketSize > dDiam + 50 * EPS_SMALL)
if ( dPocketSize > dDiam + TOLL)
return true ;
// inverto il frame attuale
Frame3d frRect ; frRect.Set( ptCen, Z_AX, vtDir) ;
if ( ! frRect.IsValid())
frTrap.Set( ptCen, Z_AX, vtDir) ;
if ( ! frTrap.IsValid())
return false ;
// creo il rettangolo del Box
pCrvTrap->AddPoint( Point3d( - 0.5 * dWidth, - 0.5 * dPocketSize, 0)) ;
@@ -14860,10 +14913,15 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
pCrvTrap->AddLine( Point3d( 0.5 * dWidth, 0.5 * dPocketSize, 0)) ;
pCrvTrap->AddLine( Point3d( - 0.5 * dWidth, 0.5 * dPocketSize, 0)) ;
pCrvTrap->Close() ;
pCrvTrap->ToGlob( frRect) ;
pCrvTrap->ToGlob( frTrap) ;
Point3d ptNewOrig ; pCrvTrap->GetStartPoint( ptNewOrig) ;
frTrap.Set( ptNewOrig, Z_AX, vtDir) ;
// imposto tutte le 4 curve come aperte
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u)
pCrvTrap->SetCurveTempProp( u, 1, 0) ;
// imposto le basi
nBase = 0 ;
nSecondBase = 2 ;
}
// se un lato aperto
else if ( nClosedSide == 1) {
@@ -14879,36 +14937,43 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
// prendo il punto iniziale
Point3d ptStart ; pCrvCurr->GetStartPoint( ptStart) ;
// creo il riferimento basato su questo tratto
Frame3d frCurr ;
frCurr.Set( ptStart, Z_AX, vtDir) ;
if ( ! frCurr.IsValid())
frTrap.Set( ptStart, Z_AX, vtDir) ;
if ( ! frTrap.IsValid())
return false ;
// porto la curva Compo ( clonandola) nel frame
PtrOwner<ICurveComposite> pCrvCompo_c( CloneCurveComposite( pCrvCompo_COffs)) ;
if ( IsNull( pCrvCompo_c))
return false ;
pCrvCompo_c->ToLoc( frCurr) ;
pCrvCompo_c->ToLoc( frTrap) ;
// ricavo il box complessivo in questo frame
BBox3d BBox ;
pCrvCompo_c->GetLocalBBox( BBox) ;
// controllo dimY ( se troppo grande o lato chiuso non sul bordo del box => caso non ottimizzato)
if ( BBox.GetDimY() > dDiam + 50 * EPS_SMALL || BBox.GetMin().y < - TOLL - EPS_SMALL)
return true ;
// creo il rettangolo del Box
Point3d ptNewMin = BBox.GetMin() ;
ptNewMin.y = 0. ;
pCrvTrap->AddPoint( ptNewMin) ;
pCrvTrap->AddLine( ptNewMin + BBox.GetDimX() * X_AX) ;
pCrvTrap->AddLine( BBox.GetMax()) ;
pCrvTrap->AddLine( BBox.GetMax() - BBox.GetDimX() * X_AX) ;
pCrvTrap->Close() ;
// porto in globale
pCrvTrap->ToGlob( frCurr) ;
// imposto tutte le curve come aperte tranne la prima ( estendo il solo lato chiuso come base del Box)
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u)
pCrvTrap->SetCurveTempProp( u, u == 0 ? 0 : 1, 0) ;
// memorizzo la dimensione Y
dPocketSize = BBox.GetDimY() ;
if (( BBox.GetDimY() < dDiam + TOLL || BBox.GetDimX() < dDiam + TOLL) && BBox.GetMin().y > - TOLL) {
// creo il rettangolo del Box
pCrvTrap->AddPoint( BBox.GetMin()) ;
pCrvTrap->AddLine( BBox.GetMin() + BBox.GetDimX() * X_AX) ;
pCrvTrap->AddLine( BBox.GetMax()) ;
pCrvTrap->AddLine( BBox.GetMax() - BBox.GetDimX() * X_AX) ;
pCrvTrap->Close() ;
// porto in globale
pCrvTrap->ToGlob( frTrap) ;
// imposto tutte le curve come aperte tranne la prima ( estendo il solo lato chiuso come base del Box)
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u)
pCrvTrap->SetCurveTempProp( u, u == 0 ? 0 : 1, 0) ;
// memorizzo la dimensione Y
dPocketSize = BBox.GetDimY() ;
if ( BBox.GetDimY() > dDiam + TOLL) {
dPocketSize = BBox.GetDimX() ;
pCrvTrap->ChangeStartPoint( 1.) ;
Point3d ptORIG ; pCrvTrap->GetStartPoint( ptORIG) ;
pCrvTrap->GetStartDir( vtDir) ;
frTrap.Set( ptORIG, Z_AX, vtDir) ;
}
}
// imposto le basi
nBase = 0 ;
nSecondBase = 2 ;
}
else {
// cerco la base
@@ -14917,14 +14982,12 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
// con dimY < dDiam e lato lineare come lato del box ( è possibile trovare una seconda base, come altro lato chiuso
// parallelo alla base principale con distanza da essa circa il dDiam)
bool bBaseFound = false ; // flag per individuare base principale
int nBase = -1 ; // indice base principale
int nSecondBase = -1 ; // indice base secondaria ( resta -1 se non esiste )
BBox3d BBox ; Frame3d frCurr ; // Box e Frame per base principale
BBox3d BBox ; // Box per base principale
// scorro i chiusi alla ricerca di una possibile base principale
for ( int i = 0 ; i < int( vIndClosedSides.size()) && ! bBaseFound ; ++ i) {
for ( int i = 0 ; i < pCrvCompo->GetCurveCount() && ! bBaseFound ; ++ i) {
nBase = i ; // aggiorno l'indice
// prendo la curva
const ICurve* pCrvCurr = pCrvCompo->GetCurve( vIndClosedSides[i]) ;
const ICurve* pCrvCurr = pCrvCompo->GetCurve( i) ;
if ( pCrvCurr == nullptr)
return false ;
// controllo se lineare, altrimenti passo alla successiva
@@ -14935,38 +14998,35 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
// prendo il punto iniziale
Point3d ptStart ; pCrvCurr->GetStartPoint( ptStart) ;
// creo il riferimento basato su questo tratto
frCurr.Set( ptStart, Z_AX, vtDir) ;
if ( ! frCurr.IsValid())
frTrap.Set( ptStart, Z_AX, vtDir) ;
if ( ! frTrap.IsValid())
return false ;
// porto la curva Compo ( clonandola) nel frame
PtrOwner<ICurveComposite> pCrvCompo_c( CloneCurveComposite( pCrvCompo)) ;
if ( IsNull( pCrvCompo_c))
return false ;
pCrvCompo_c->ToLoc( frCurr) ;
PtrOwner<ICurveComposite> pCrvCompo_COffs_frCurr( CloneCurveComposite( pCrvCompo_COffs)) ;
pCrvCompo_COffs_frCurr->ToLoc( frCurr) ;
pCrvCompo_COffs_frCurr->GetLocalBBox( BBox) ;
// controllo dimY ( se troppo grande o base principale non sul bordo del box => cerco un'altra base ammissibile)
if ( BBox.GetDimY() > dDiam + 50 * EPS_SMALL || BBox.GetMin().y < - TOLL - EPS_SMALL)
continue ;
bBaseFound = true ;
// cerco la base secondaria ( se esiste)
// scorro le altre curve lineari chiuse
for ( int u = 0 ; u < int( vIndClosedSides.size()) && nSecondBase == -1 ; ++ u) {
if ( vIndClosedSides[u] == nBase || pCrvCompo_c->GetCurve( vIndClosedSides[u])->GetType() != CRV_LINE)
continue ;
// recupero la direzione del tratto
Vector3d vtCurr_dir ; pCrvCompo_c->GetCurve( vIndClosedSides[u])->GetStartDir( vtCurr_dir) ;
// direzioni parallele ma opposte
if ( AreOppositeVectorApprox( vtCurr_dir, X_AX)) {
// se le direzioni sono compatibili, controllo che la distanza sia ammissibile,
// altrimenti non ho nè base secondaria nè primaria ( se non entro mai in questo controllo, allora
// ho solo la base principale)
Point3d ptS0, ptS1 ;
pCrvCurr->GetStartPoint( ptS0) ;
pCrvCompo_c->GetCurve( vIndClosedSides[u])->GetStartPoint( ptS1) ;
if ( abs( ptS1.y - dDiam) < 50 * EPS_SMALL)
nSecondBase = vIndClosedSides[u] ;
pCrvCompo_c.Set( pCrvCompo->Clone()) ;
pCrvCompo_c->ToLoc( frTrap) ;
// calcolo il box
pCrvCompo_c->GetLocalBBox( BBox) ;
// controllo dimY
if ( BBox.GetDimY() < dDiam + TOLL && BBox.GetMin().y > - TOLL) { // se valida...
bBaseFound = true ;
// cerco la base secondaria ( se esiste)
// scorro le altre curve lineari chiuse
for ( int u = 0 ; u < pCrvCompo_c->GetCurveCount() && nSecondBase == -1 ; ++ u) {
if ( u == nBase || pCrvCompo_c->GetCurve( u)->GetType() != CRV_LINE)
continue ;
// recupero la direzione del tratto
Vector3d vtCurr_dir ; pCrvCompo_c->GetCurve( u)->GetStartDir( vtCurr_dir) ;
// direzioni parallele ma opposte
if ( AreOppositeVectorApprox( vtCurr_dir, X_AX)) {
// se le direzioni sono compatibili, controllo che la distanza sia ammissibile,
// altrimenti non ho nè base secondaria nè primaria ( se non entro mai in questo controllo, allora
// ho solo la base principale)
Point3d ptS0, ptS1 ;
pCrvCurr->GetStartPoint( ptS0) ;
pCrvCompo_c->GetCurve( u)->GetStartPoint( ptS1) ;
if ( abs( ptS1.y - dDiam) < TOLL)
nSecondBase = u ;
}
}
}
}
@@ -14994,8 +15054,8 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
pCrvTest1->GetParamAtPoint( ptSB0, dUTrim1) ;
pCrvTest0->TrimStartEndAtParam( 1, dUTrim0) ;
pCrvTest1->TrimStartEndAtParam( 1, dUTrim1) ;
pCrvTest0->ToLoc( frCurr) ;
pCrvTest1->ToLoc( frCurr) ;
pCrvTest0->ToLoc( frTrap) ;
pCrvTest1->ToLoc( frTrap) ;
// controllo che la parte destra si uniforme per le TmpProp
for ( int u = 0 ; u < pCrvTest0->GetCurveCount() - 1 ; ++ u) {
int nPropAct, nPropSucc ;
@@ -15016,8 +15076,8 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
PtrOwner<ICurve> pCrvBase0( pCrvCompo->GetCurve( nBase)->Clone()) ;
PtrOwner<ICurve> pCrvBase1( pCrvCompo->GetCurve( nSecondBase)->Clone()) ;
// le porto nel sistema di riferimento corrente
pCrvBase0->ToLoc( frCurr) ;
pCrvBase1->ToLoc( frCurr) ;
pCrvBase0->ToLoc( frTrap) ;
pCrvBase1->ToLoc( frTrap) ;
// ricavo i nuovi estremi
Point3d ptEB0, ptEB1 ;
pCrvBase0->GetStartPoint( ptSB0) ;
@@ -15026,11 +15086,9 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
pCrvBase1->GetEndPoint( ptEB1) ;
// se lato destro aperto ( estendo il punto finale della base principale e il punto iniziale
// della base secondaria fino al lato destro del box)
Point3d ptNewMin = BBox.GetMin() ;
ptNewMin.y = 0. ;
bool bCopyRight = false ;
if ( pCrvTest0->GetCurve( 0)->GetTempProp( 0) == 1) {
ptEB0 = ptNewMin + X_AX * BBox.GetDimX() ;
ptEB0 = BBox.GetMin() + X_AX * BBox.GetDimX() ;
ptSB1 = ptEB0 + dDiam * Y_AX ;
}
// se lato destro chiuso
@@ -15040,14 +15098,15 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
// della base primaria dino al lato sinistro del box)
bool bCopyLeft = false ;
if ( pCrvTest1->GetCurve( 0)->GetTempProp( 0) == 1) {
ptSB0 = ptNewMin ;
ptEB1 = ptNewMin + dDiam * Y_AX ;
ptSB0 = BBox.GetMin() ;
ptEB1 = BBox.GetMin() + dDiam * Y_AX ;
}
// se lato sinistro chiuso
else
bCopyLeft = true ;
// creo la curva da restituire
nBase = 0 ;
pCrvTrap->AddPoint( ptSB0) ;
pCrvTrap->AddLine( ptEB0) ;
if ( bCopyRight)
@@ -15056,6 +15115,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
pCrvTrap->AddLine( ptSB1) ;
pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta
}
nSecondBase = pCrvTrap->GetCurveCount() ;
pCrvTrap->AddLine( ptEB1) ;
if ( bCopyLeft)
pCrvTrap->AddCurve( Release( pCrvTest1)) ;
@@ -15064,15 +15124,23 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta
}
pCrvTrap->ToGlob( frCurr) ;
pCrvTrap->ToGlob( frTrap) ;
// verifico dimensione x della svuotatura nel caso tutto chiuso
if ( bCopyLeft && bCopyRight) {
double dLen0 = 0, dLen1 = 0 ;
pCrvBase0->GetLength( dLen0) ;
pCrvBase1->GetLength( dLen1) ;
if ( dLen0 < dDiam - EPS_SMALL || dLen1 < dDiam - EPS_SMALL)
pCrvTrap->Clear() ;
}
}
// se non ho una base secondaria, i lati chiusi devono essere 3 e consecutivi
else if ( nClosedSide == 3) {
// prendo i 3 lati chiusi
const ICurve* pCrv0 = pCrvCompo->GetCurve( vIndClosedSides[0]) ;
const ICurve* pCrv1 = pCrvCompo->GetCurve( vIndClosedSides[1]) ;
const ICurve* pCrv2 = pCrvCompo->GetCurve( vIndClosedSides[2]) ;
const ICurve* pCrv0 = pCrvCompo_c->GetCurve( vIndClosedSides[0]) ;
const ICurve* pCrv1 = pCrvCompo_c->GetCurve( vIndClosedSides[1]) ;
const ICurve* pCrv2 = pCrvCompo_c->GetCurve( vIndClosedSides[2]) ;
if ( pCrv0 == nullptr || pCrv1 == nullptr || pCrv2 == nullptr)
return false ;
// prendo i punti iniziali e finali
@@ -15100,18 +15168,84 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
if ( vIndClosedSides[1] != nBase)
return true ;
// creo la curva
Point3d ptS0 ; pCrvCompo->GetCurve( vIndClosedSides[0])->GetStartPoint( ptS0) ;
// controllo se è possibile creare un trapezio
PtrOwner<ICurve> pEdge0( pCrvCompo_c->GetCurve( vIndClosedSides[0])->Clone()) ;
PtrOwner<ICurve> pEdge2( pCrvCompo_c->GetCurve( vIndClosedSides[2])->Clone()) ;
Point3d ptS0 ; pEdge0->GetStartPoint( ptS0) ;
Point3d ptE2 ; pEdge2->GetEndPoint( ptE2) ;
if ( abs( ptS0.y - BBox.GetDimY()) > TOLL) {
Vector3d vtDir ; pEdge0->GetStartDir( vtDir) ;
double dSinT = sqrt( 1 - vtDir.x * vtDir.x) ;
if ( dSinT > TOLL) {
pEdge0->ExtendStartByLen(( BBox.GetDimY() - ptS0.y) / dSinT) ;
pEdge0->GetStartPoint( ptS0) ;
}
}
if ( abs( ptE2.y - BBox.GetDimY()) > TOLL) {
Vector3d vtDir ; pEdge2->GetStartDir( vtDir) ;
double dSinT = sqrt( 1 - vtDir.x * vtDir.x) ;
if ( dSinT > TOLL) {
pEdge2->ExtendEndByLen(( BBox.GetDimY() - ptE2.y) / dSinT) ;
pEdge2->GetEndPoint( ptE2) ;
}
}
pCrvTrap->AddPoint( ptS0) ;
pCrvTrap->AddCurve( pCrvCompo->GetCurve( vIndClosedSides[0])->Clone()) ;
pCrvTrap->AddCurve( pCrvCompo->GetCurve( vIndClosedSides[1])->Clone()) ;
pCrvTrap->AddCurve( pCrvCompo->GetCurve( vIndClosedSides[2])->Clone()) ;
pCrvTrap->AddCurve( Release( pEdge0)) ;
pCrvTrap->AddCurve( pCrvCompo_c->GetCurve( vIndClosedSides[1])->Clone()) ;
pCrvTrap->AddCurve( Release( pEdge2)) ;
pCrvTrap->Close() ;
pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ;
pCrvTrap->ChangeStartPoint( 1.) ; // la base è sempre la curva 0
// imposto le basi
nBase = 0 ;
nSecondBase = 2 ;
// verifico dimensione x della svuotatura
double dLen0 = 0, dLen2 = 0 ;
pCrvTrap->GetCurve( 0)->GetLength( dLen0) ;
pCrvTrap->GetCurve( 2)->GetLength( dLen2) ;
if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL) {
pCrvTrap->Clear() ;
return true ;
}
// creo un piccolo Offset e controllo che il trapezio non intersechi la curva Compo
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvTrap, 50 * EPS_SMALL, ICurve::OFF_EXTEND)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCrvOffs))
return false ;
IntersCurveCurve IntCC( *pCrvOffs, *pCrvCompo_c) ;
CRVCVECTOR ccClass ;
if ( IntCC.GetRegionCurveClassification() != CCREGC_IN2)
pCrvTrap->Clear() ;
else {
pCrvTrap->Clear() ;
Point3d ptS0 ; pCrvCompo_c->GetCurve( vIndClosedSides[0])->GetStartPoint( ptS0) ;
pCrvTrap->AddPoint( ptS0) ;
pCrvTrap->AddCurve( pCrvCompo_c->GetCurve( vIndClosedSides[0])->Clone()) ;
pCrvTrap->AddCurve( pCrvCompo_c->GetCurve( vIndClosedSides[1])->Clone()) ;
pCrvTrap->AddCurve( pCrvCompo_c->GetCurve( vIndClosedSides[2])->Clone()) ;
pCrvTrap->Close() ;
pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ;
pCrvTrap->ChangeStartPoint( 1.) ; // la base è sempre la curva 0
pCrvTrap->ToGlob( frTrap) ;
}
}
else // ho più di 3 lati chiusi => non è ottimizzato
;
}
// se parametro MaxOptSize non compatibile => non è ottimizzato
double dMaxOptSize ;
FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxOptSize="), dMaxOptSize) ;
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxOptSize="), dMaxOptSize) && dPocketSize > dMaxOptSize)
pCrvTrap->Clear() ;
return true ;
}
+5 -4
View File
@@ -92,7 +92,7 @@ class Pocketing : public Machining
bool GetOptCrvIndex( const std::vector<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, int nStep, ISurfFlatRegion* pSrfChunkFinal,
int& nIndex) ;
bool GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam, ICurveComposite* pCrvTrap,
Vector3d& vtDir,double& dPocketSize) ;
Frame3d& frTrap,double& dPocketSize, int& nBase, int& nSecondBase) ;
// ===================================================================
// =========================== GREZZO e GEOMETRIE ====================
@@ -247,10 +247,11 @@ class Pocketing : public Machining
const ICurve* pCrvBound, ICurveComposite* pCrvLink) ;
bool CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad,
bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) ;
bool CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Vector3d& vtDir, double dPocketSize,
ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool& bOptimizedTrap) ;
bool CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double dPocketSize, int nBase,
int nSecondBase, ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool& bOptimizedTrap) ;
bool CalcTrapezoidSpiralLocalFrame( ICurveComposite * pCrvPocket, const Vector3d& vtDir, Frame3d& frLoc) ;
bool CalcTrapezoidSpiralXCoord( const ICurveComposite * pCrvPocket, bool bStart, double dYCoord, double& dXCoord, double dPocketSize) ;
bool CalcTrapezoidSpiralXCoord( const ICurveComposite * pCrvPocket, int nBase,int nSecondBase,
bool bStart, double dYCoord, double& dXCoord, double dPocketSize) ;
bool AdjustTrapezoidSpiralForAngles( ICurveComposite * pMCrv, const ICurveComposite * pCrvPocket, bool bStart) ;
bool SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveComposite* pCrvPocket) ;
bool AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite * pCompo, ICurveComposite * pRCrv, const Vector3d& vtTool,