From 0dfc9a38da3cf7b31b6599509e17ff9fe24b7b81 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Fri, 3 Nov 2023 18:17:26 +0100 Subject: [PATCH] EgtMachKernel : - primo codice di test da migliorare per Trapezi SpiralIn/Out. --- Pocketing.cpp | 716 ++++++++++++++++++++++++++++++-------------------- Pocketing.h | 9 +- 2 files changed, 430 insertions(+), 295 deletions(-) diff --git a/Pocketing.cpp b/Pocketing.cpp index 4ce188d..611b33b 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -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 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 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 pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ; - PtrOwner 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 pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ; + // PtrOwner 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 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 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 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 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& 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& 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 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 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 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 pCrvCompo_c( CloneCurveComposite( pCrvCompo)) ; - if ( IsNull( pCrvCompo_c)) - return false ; - pCrvCompo_c->ToLoc( frCurr) ; - PtrOwner 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 pCrvBase0( pCrvCompo->GetCurve( nBase)->Clone()) ; PtrOwner 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 pEdge0( pCrvCompo_c->GetCurve( vIndClosedSides[0])->Clone()) ; + PtrOwner 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 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 ; } \ No newline at end of file diff --git a/Pocketing.h b/Pocketing.h index 277b882..756cd27 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -92,7 +92,7 @@ class Pocketing : public Machining bool GetOptCrvIndex( const std::vector& 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,