diff --git a/Pocketing.cpp b/Pocketing.cpp index 611b33b..edd551d 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -102,6 +102,7 @@ static string KEY_OPEN = "OPEN" ; static const std::string BOX_NAME = "Box" ; static int LINK_CURVE_PROP = -3 ; static double FEED_DIVISOR = 1000.0 ; +static double TOLL_TRAPEZOID = 50 * EPS_SMALL ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), Pocketing) ; @@ -7553,7 +7554,7 @@ bool Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double dPocketSize, int nBase, int nSecondBase, ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool& bOptimizedTrap) { - // parametri + // 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 ; @@ -7562,30 +7563,44 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr bOptimizedTrap = false ; Vector3d vtExtr ; pCrvPocket->GetExtrusion( vtExtr) ; + // recupero le temp prop + 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() ; + } + // 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 pCrvPocket->ToLoc( frTrap) ; // calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso) - Point3d ptOrig ; - pCrvPocket->GetCurve( 1)->GetStartPoint( ptOrig) ; - Vector3d vtX ; - pCrvPocket->GetCurve( 1)->GetStartDir( vtX) ; - Frame3d frDim ; frDim.Set( ptOrig, Z_AX, vtX) ; frDim.Invert() ; - BBox3d b3Dim ; - pCrvPocket->GetBBox( frDim, b3Dim, BBF_EXACT) ; - double dMaxLarg = b3Dim.GetDimY() ; + double dLen0, dLen1, dLen2, dLen3 ; + pCrvPocket->GetCurve( nBase)->GetLength( dLen0) ; + pCrvPocket->GetCurve( nSecondBase)->GetLength( dLen2) ; + bool bRealTrap = pCrvPocket->GetCurveCount() == 4 ; + for ( int i = 0 ; i < 4 && bRealTrap ; ++ i) + bRealTrap = pCrvPocket->GetCurve( i)->GetType() == CRV_LINE ; + if ( bRealTrap) { + pCrvPocket->GetCurve( nBase + 1)->GetLength( dLen1) ; + pCrvPocket->GetCurve( nSecondBase + 1)->GetLength( dLen3) ; + } // 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 && - dMaxLarg > m_TParams.m_dDiam + 10 * EPS_SMALL && max( dLen0, dLen2) < 2 * m_TParams.m_dDiam + EPS_SMALL) { - if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket)) { + if ( bRealTrap && + ( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL) || + vnProp[1] != 0 && vnProp[3] != 0 && vnProp[0] == 0 && vnProp[2] == 0 && max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL) { + if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, vnProp[0] == 0, pCrvPocket)) { pMCrv->Clear() ; return false ; } } - else {*/ + else { // trovo la quota Y per centro del Tool double dYCoord ; if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 0) // se base principale chiusa @@ -7648,8 +7663,26 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 1 || pCrvPocket->GetCurve( nSecondBase)->GetTempProp( 0) == 1) { - if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 0) + Frame3d frOpen ; + bool bSwitch = false ; + // Base principale chiusa e base Secondaria aperta + if ( pCrvPocket->GetCurve( nBase)->GetTempProp( 0) == 0) { pCrvPocket->ChangeStartPoint( nSecondBase) ; + // oriento il Frame ( ho sempre l'origine nell'estremo superiore del lato aperto) + Vector3d vtDir ; pCrvPocket->GetStartDir( vtDir) ; + Point3d ptORIG ; + if ( vtDir.y > 0) + pCrvPocket->GetCurve( nBase)->GetEndPoint( ptORIG) ; + else + pCrvPocket->GetCurve( nBase)->GetStartPoint( ptORIG) ; + frOpen.Set( ptORIG, Z_AX, -X_AX) ; + if ( ! frOpen.IsValid()) + return false ; + pCrvPocket->ToLoc( frOpen) ; + pMCrv->ToLoc( frOpen) ; + pMCrv->Invert() ; + bSwitch = true ; + } if ( pCrvPocket->GetCurve( 3)->GetTempProp( 0) == 0 && ! AdjustTrapezoidSpiralForAngles( pMCrv, pCrvPocket, true)) { @@ -7661,24 +7694,24 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr pMCrv->Clear() ; return false ; } + + if ( bSwitch) { + pCrvPocket->ToGlob( frOpen) ; + pMCrv->ToGlob( frOpen) ; + pMCrv->Invert() ; + } + + } //} - //} + } if ( pMCrv->GetCurveCount() == 0) return true ; 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() ; @@ -7830,8 +7863,15 @@ Pocketing::CalcTrapezoidSpiralXCoord( const ICurveComposite* pCrvPocket, int nBa //---------------------------------------------------- bool -Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveComposite* pCrvPocket, bool bStart) +Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveComposite* pCrvPocket, + bool bStart) { + // 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 ; + PtrOwner pCompo( CreateCurveComposite()) ; if ( ! bStart) pMCrv->Invert() ; @@ -7844,7 +7884,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC int nCrvId = ( bStart ? 3 : 1) ; PtrOwner pLine( GetCurveLine( pCrvPocket->GetCurve( nCrvId)->Clone())) ; - pLine->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ; + pLine->SimpleOffset( - dRad) ; Point3d ptP1, ptP2 ; pLine->GetStartPoint( ptP1) ; @@ -7864,7 +7904,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC pCompo->AddLine( ptP1) ; // trovo il punto di pMCrv da cui ripartire per non lasciare aree residue - pLine->SimpleOffset( - 0.5 * m_TParams.m_dDiam) ; + pLine->SimpleOffset( - 0.5 * dDiam) ; pLine->ExtendStartByLen( EPS_SMALL) ; pLine->ExtendEndByLen( EPS_SMALL) ; IntersCurveCurve intCC( *pLine, *pCrvPocket) ; @@ -7872,7 +7912,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC return false ; IntCrvCrvInfo aInfo ; intCC.GetIntCrvCrvInfo( 0, aInfo) ; - double dDeltaX = sqrt( m_TParams.m_dDiam * m_TParams.m_dDiam / 4 - dYCoord * dYCoord) ; + double dDeltaX = sqrt( max( 0., dDiam * dDiam / 4 - dYCoord * dYCoord)) ; if ( ! bStart) dDeltaX *= -1 ; Point3d ptCrv( aInfo.IciA[0].ptI.x + dDeltaX, dYCoord) ; @@ -7956,7 +7996,7 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC pLine->GetStartDir( vtDir) ; if ( bStart) vtDir.Invert() ; - Point3d ptP2N = ptP2 - m_TParams.m_dDiam / 2 * abs( vtDir.x / vtDir.y) * vtDir ; + Point3d ptP2N = ptP2 - dDiam / 2 * abs( vtDir.x / vtDir.y) * vtDir ; if ( ptP2N.y < dYCoord) bStartPnt = pCompo->AddPoint( ptP2N) ; } @@ -7980,14 +8020,19 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC //---------------------------------------------------- bool -Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveComposite* pCrvPocket) +Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const bool bEvenClosed, const ICurveComposite* pCrvPocket) { + // 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 ; + // calcolo gli offset dei lati obliqui - PtrOwner pLineS( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ; - pLineS->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ; + PtrOwner pLineS( GetCurveLine( pCrvPocket->GetCurve( bEvenClosed ? 0 : 3)->Clone())) ; + pLineS->SimpleOffset( - dRad) ; pLineS->Invert() ; - PtrOwner pLineE( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ; - pLineE->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ; + PtrOwner pLineE( GetCurveLine( pCrvPocket->GetCurve( bEvenClosed ? 2 : 1)->Clone())) ; + pLineE->SimpleOffset( - dRad) ; pLineE->Invert() ; Point3d ptS, ptE ; @@ -8008,7 +8053,7 @@ Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const bool bUseBiArcs = false ; Vector3d vtDir, vtDir2 ; pLineLink->GetStartDir( vtDir) ; - pCrvPocket->GetStartDir( vtDir2) ; + pCrvPocket->GetCurve( bEvenClosed ? 1 : 0)->GetStartDir( vtDir2) ; if ( Dist( ptS, ptE) > 500 * EPS_SMALL && AreSameOrOppositeVectorApprox( vtDir, vtDir2)) { @@ -8019,11 +8064,12 @@ Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const // primo raccordo double dAng ; vtS.GetAngleXY( X_AX, dAng) ; - PtrOwner pBiArc1( GetBiArc( ptS, - dAng, ptCrv1, 0, 0.5)) ; + PtrOwner pBiArc1( GetBiArc( ptS, - dAng, ptCrv1, bEvenClosed ? 90 : 0, 0.5)) ; // secondo raccordo + vtE.Invert() ; vtE.GetAngleXY( X_AX, dAng) ; - PtrOwner pBiArc2( GetBiArc( ptE, dAng, ptCrv2, 180, 0.5)) ; + PtrOwner pBiArc2( GetBiArc( ptE, - dAng, ptCrv2, bEvenClosed ? - 90 : 180, 0.5)) ; pBiArc2->Invert() ; if ( ! IsNull( pBiArc1) && ! IsNull( pBiArc2)) { @@ -8035,7 +8081,7 @@ Pocketing::SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const } // se non è stato possibile creare raccordo, unisco linearmente - if ( ! bUseBiArcs) + if ( ! bUseBiArcs) pMCrv->AddCurve( Release( pLineLink)) ; if ( ! pMCrv->AddCurve( Release( pLineE))) @@ -14892,7 +14938,6 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam // tolleranza const double TOLL = 50 * EPS_SMALL ; - // se tutti lati aperti if ( nClosedSide == 0) { // ricavo il box minimo della curva aperta ( passo dalla polyLine) @@ -14923,7 +14968,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam nBase = 0 ; nSecondBase = 2 ; } - // se un lato aperto + // se un lato chiuso else if ( nClosedSide == 1) { // prendo l'unica curva chiusa const ICurve* pCrvCurr = pCrvCompo->GetCurve( vIndClosedSides[0]) ; @@ -14962,6 +15007,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam // memorizzo la dimensione Y dPocketSize = BBox.GetDimY() ; + // se il lato chiuso non può essere la base, allora sarà l'aperto ( del box) if ( BBox.GetDimY() > dDiam + TOLL) { dPocketSize = BBox.GetDimX() ; pCrvTrap->ChangeStartPoint( 1.) ; @@ -14971,7 +15017,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam } } - // imposto le basi + // imposto le basi nBase = 0 ; nSecondBase = 2 ; } @@ -14981,6 +15027,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam // lato lineare chiuso, box nella sua direzione con DimY < 1.5 dDiam, box dei restanti chiusi ( almeno 1) // 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 BBox3d BBox ; // Box per base principale // scorro i chiusi alla ricerca di una possibile base principale @@ -15006,239 +15053,52 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam 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 ; + // controllo dimY e dimX per il box + bool bDimYOk = BBox.GetDimY() < dDiam + TOLL && BBox.GetMin().y > - TOLL ; + bool bDimXOk = BBox.GetDimX() < dDiam + TOLL && BBox.GetMin().y > - TOLL ; + // se entrambe le dimensioni superano il diametro, questo lato non è la base, cerco il successivo + if ( !bDimXOk && !bDimYOk) + continue ; + // se dimY accettabile + if ( bDimYOk) { + bool bOk = false ; + if ( ! CheckTrapezoidClosedEdgePosition( pCrvCompo_c, i, BBox.GetDimY(), vIndClosedSides, bOk, pCrvTrap)) + return false ; + if ( bOk) { + // pCrvTrap contiene il trapezio + nBase = 0 ; + nSecondBase = 2 ; + dPocketSize = BBox.GetDimY() ; + pCrvTrap->ToGlob( frTrap) ; + bBaseFound = true ; + } + else { + // cerco la seconda base + if ( ! CheckSecondBaseTrapezoid( pCrvCompo_c, i, nSecondBase)) + return false ; + if ( nSecondBase != -1) { + // se ho trovato la seconda base + if ( ! PreparareTrapezoidTwoBases( pCrvCompo_c, BBox, i, nSecondBase, bOk, pCrvTrap)) + return false ; + if ( bOk) { + // pCrvTrap contiene il trapezio + nBase = 0 ; + dPocketSize = BBox.GetDimY() ; + pCrvTrap->ToGlob( frTrap) ; + bBaseFound = true ; + } } } } + // se dimX accettabile + if ( bDimYOk) { + // TODO : + } } // se non ho trovato una base principale => non è ottimizzato if ( ! bBaseFound) return true ; - - // imposto la dimensione della svuotatura come la DimY dell'ultimo box trovato ( quindi secondo la base principale) - dPocketSize = BBox.GetDimY() ; - - // se ho la base secondaria - if ( nSecondBase > -1) { - // le parti tra le due basi devono essere tutte omogenee ( o tutte aperte o tutte chiuse) - // pCrvTest0 sarà la parte destra, pCrvTest1 la parte sinistra - Point3d ptSB0, ptSB1 ; - PtrOwner pCrvTest0( CloneCurveComposite( pCrvCompo)) ; - PtrOwner pCrvTest1( CloneCurveComposite( pCrvCompo)) ; - pCrvCompo->GetCurve( nBase)->GetStartPoint( ptSB0) ; - pCrvCompo->GetCurve( nSecondBase)->GetStartPoint( ptSB1) ; - pCrvTest0->ChangeStartPoint( nBase) ; - pCrvTest1->ChangeStartPoint( nSecondBase) ; - double dUTrim0, dUTrim1 ; - pCrvTest0->GetParamAtPoint( ptSB1, dUTrim0) ; - pCrvTest1->GetParamAtPoint( ptSB0, dUTrim1) ; - pCrvTest0->TrimStartEndAtParam( 1, dUTrim0) ; - pCrvTest1->TrimStartEndAtParam( 1, dUTrim1) ; - 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 ; - if ( pCrvTest0->GetCurveTempProp( u, nPropAct, 0) && - pCrvTest0->GetCurveTempProp( u + 1, nPropSucc, 0) && - nPropAct != nPropSucc) - return true ; // se TmpProp diverse => non è un caso ottimizzato - } - // controllo che la parte sinistra sia uniforme per le TmpProp - for ( int u = 0 ; u < pCrvTest1->GetCurveCount() - 1 ; ++ u) { - int nPropAct, nPropSucc ; - if ( pCrvTest1->GetCurveTempProp( u, nPropAct, 0) && - pCrvTest1->GetCurveTempProp( u + 1, nPropSucc, 0) && - nPropAct != nPropSucc) - return true ; // se TmpProp diverse => non è un caso ottimizzato - } - // creo la base principale e secondaria - PtrOwner pCrvBase0( pCrvCompo->GetCurve( nBase)->Clone()) ; - PtrOwner pCrvBase1( pCrvCompo->GetCurve( nSecondBase)->Clone()) ; - // le porto nel sistema di riferimento corrente - pCrvBase0->ToLoc( frTrap) ; - pCrvBase1->ToLoc( frTrap) ; - // ricavo i nuovi estremi - Point3d ptEB0, ptEB1 ; - pCrvBase0->GetStartPoint( ptSB0) ; - pCrvBase0->GetEndPoint( ptEB0) ; - pCrvBase1->GetStartPoint( ptSB1) ; - 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) - bool bCopyRight = false ; - if ( pCrvTest0->GetCurve( 0)->GetTempProp( 0) == 1) { - ptEB0 = BBox.GetMin() + X_AX * BBox.GetDimX() ; - ptSB1 = ptEB0 + dDiam * Y_AX ; - } - // se lato destro chiuso - else - bCopyRight = true ; - // se lato sinistro aperto ( estendo il punto finale della base secondaria e il punto iniziale - // della base primaria dino al lato sinistro del box) - bool bCopyLeft = false ; - if ( pCrvTest1->GetCurve( 0)->GetTempProp( 0) == 1) { - 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) - pCrvTrap->AddCurve( Release( pCrvTest0)) ; - else { - pCrvTrap->AddLine( ptSB1) ; - pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta - } - nSecondBase = pCrvTrap->GetCurveCount() ; - pCrvTrap->AddLine( ptEB1) ; - if ( bCopyLeft) - pCrvTrap->AddCurve( Release( pCrvTest1)) ; - else { - pCrvTrap->Close() ; - pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta - } - - 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_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 - Point3d ptStart0 ; pCrv0->GetStartPoint( ptStart0) ; - Point3d ptEnd0 ; pCrv0->GetEndPoint( ptEnd0) ; - Point3d ptStart1 ; pCrv1->GetStartPoint( ptStart1) ; - Point3d ptEnd1 ; pCrv1->GetEndPoint( ptEnd1) ; - Point3d ptStart2 ; pCrv2->GetStartPoint( ptStart2) ; - Point3d ptEnd2 ; pCrv2->GetEndPoint( ptEnd2) ; - // controllo che siano consecutivi e cambio l'ordine se necessario - if ( AreSamePointApprox( ptEnd0, ptStart1) && AreSamePointApprox( ptEnd1, ptStart2)) - ; - else if ( AreSamePointApprox( ptEnd1, ptStart2) && AreSamePointApprox( ptEnd2, ptStart0)) { - swap( vIndClosedSides[0], vIndClosedSides[1]) ; - swap( vIndClosedSides[1], vIndClosedSides[2]) ; - } - else if ( AreSamePointApprox( ptEnd2, ptStart0) && AreSamePointApprox( ptEnd0, ptStart1)) { - swap( vIndClosedSides[0], vIndClosedSides[2]) ; - swap( vIndClosedSides[2], vIndClosedSides[1]) ; - } - else // se non consecutivi ? ( per ora esco) - return true ; - - // controllo per sicurezza - if ( vIndClosedSides[1] != nBase) - return true ; - - // 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( 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 @@ -15248,4 +15108,274 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam pCrvTrap->Clear() ; return true ; -} \ No newline at end of file +} + +//---------------------------------------------------------------------------- +bool +Pocketing::CheckTrapezoidClosedEdgePosition( const ICurveComposite* pCrvCompo, const int nCrvInd, const double dDimBoxY, + INTVECTOR& vIndClosedSides, bool& bOk, ICurveComposite* pCrvTrap) +{ + // controllo dei parametri + if ( pCrvCompo == nullptr) + return false ; + bOk = false ; + + // controllo che ci siano due o tre lati chiusi + int nClosedEdge = int( vIndClosedSides.size()) ; + if ( nClosedEdge != 3) + return true ; + + // TO DO se 2 chiusi consecutivi + gesitone archi + + // 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]) ; + if ( pCrv0 == nullptr || pCrv1 == nullptr || pCrv2 == nullptr) + return false ; + // controllo che siano lineari + if ( pCrv0->GetType() != CRV_LINE || pCrv1->GetType() != CRV_LINE || pCrv2->GetType() != CRV_LINE) + return true ; + // prendo i punti iniziali e finali + Point3d ptStart0 ; pCrv0->GetStartPoint( ptStart0) ; + Point3d ptEnd0 ; pCrv0->GetEndPoint( ptEnd0) ; + Point3d ptStart1 ; pCrv1->GetStartPoint( ptStart1) ; + Point3d ptEnd1 ; pCrv1->GetEndPoint( ptEnd1) ; + Point3d ptStart2 ; pCrv2->GetStartPoint( ptStart2) ; + Point3d ptEnd2 ; pCrv2->GetEndPoint( ptEnd2) ; + // controllo che siano consecutivi e cambio l'ordine se necessario + if ( AreSamePointApprox( ptEnd0, ptStart1) && AreSamePointApprox( ptEnd1, ptStart2)) + ; + else if ( AreSamePointApprox( ptEnd1, ptStart2) && AreSamePointApprox( ptEnd2, ptStart0)) { + swap( vIndClosedSides[0], vIndClosedSides[1]) ; + swap( vIndClosedSides[1], vIndClosedSides[2]) ; + } + else if ( AreSamePointApprox( ptEnd2, ptStart0) && AreSamePointApprox( ptEnd0, ptStart1)) { + swap( vIndClosedSides[0], vIndClosedSides[2]) ; + swap( vIndClosedSides[2], vIndClosedSides[1]) ; + } + else // se non consecutivi + return true ; + + // se sono consecuti, ma la base non è il lato centrale, esco ( la ritroverò successivamente) + if ( vIndClosedSides[1] != nCrvInd) + return true ; + + // parametri lavorazione + 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 ; + + // -------------- creo il bordo del trapezio estendendo i lati obliqui se possibile ------------------------ + // estendo + PtrOwner pEdge0( pCrvCompo->GetCurve( vIndClosedSides[0])->Clone()) ; + PtrOwner pEdge2( pCrvCompo->GetCurve( vIndClosedSides[2])->Clone()) ; + Point3d ptS0 ; pEdge0->GetStartPoint( ptS0) ; + Point3d ptE2 ; pEdge2->GetEndPoint( ptE2) ; + if ( abs( ptS0.y - dDimBoxY) > TOLL_TRAPEZOID) { + Vector3d vtDir ; pEdge0->GetStartDir( vtDir) ; + double dSinT = sqrt( 1 - vtDir.x * vtDir.x) ; + if ( dSinT > TOLL_TRAPEZOID) { + pEdge0->ExtendStartByLen(( dDimBoxY - ptS0.y) / dSinT) ; + pEdge0->GetStartPoint( ptS0) ; + } + } + if ( abs( ptE2.y - dDimBoxY) > TOLL_TRAPEZOID) { + Vector3d vtDir ; pEdge2->GetStartDir( vtDir) ; + double dSinT = sqrt( 1 - vtDir.x * vtDir.x) ; + if ( dSinT > TOLL_TRAPEZOID) { + pEdge2->ExtendEndByLen(( dDimBoxY - ptE2.y) / dSinT) ; + pEdge2->GetEndPoint( ptE2) ; + } + } + // creo il bordo del trapezio esteso + PtrOwner pCrvTrapBorder( CreateCurveComposite()) ; + if ( IsNull( pCrvTrapBorder)) + return false ; + pCrvTrapBorder->AddPoint( ptS0) ; + pCrvTrapBorder->AddCurve( Release( pEdge0)) ; + pCrvTrapBorder->AddCurve( pCrvCompo->GetCurve( vIndClosedSides[1])->Clone()) ; + pCrvTrapBorder->AddCurve( Release( pEdge2)) ; + pCrvTrapBorder->Close() ; + // ---------------------------------------------------------------------------------------------------------- + + // verifico dimensione x della svuotatura + double dLen0 = 0, dLen2 = 0 ; + pCrvTrapBorder->GetCurve( 0)->GetLength( dLen0) ; + pCrvTrapBorder->GetCurve( 2)->GetLength( dLen2) ; + if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL) + return true ; + + // creo un piccolo Offset e controllo che il trapezio non intersechi la curva Compo + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( pCrvTrapBorder, TOLL_TRAPEZOID, 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) ; + CRVCVECTOR ccClass ; + // se c'è intersezione, esco + if ( IntCC.GetRegionCurveClassification() != CCREGC_IN2) + return true ; + // costruisco il trapezio + pCrvCompo->GetCurve( vIndClosedSides[0])->GetStartPoint( ptS0) ; + 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->Close() ; + pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; + pCrvTrap->ChangeStartPoint( 1.) ; // la base è sempre la curva 0 + bOk = true ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::CheckSecondBaseTrapezoid( const ICurveComposite* pCrvCompo, const int nCrvInd, int& nSecondBase) +{ + // controllo parametri + if ( pCrvCompo == nullptr) + return false ; + + // parametri lavorazione + 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 ; + + nSecondBase = -1 ; + + // scorro le altre curve lineari chiuse + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() && nSecondBase == -1 ; ++ u) { + if ( u == nCrvInd || pCrvCompo->GetCurve( u)->GetType() != CRV_LINE) + continue ; + // recupero la direzione del tratto + Vector3d vtCurr_dir ; pCrvCompo->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 + const ICurve* pCrvCurr = pCrvCompo->GetCurve( nCrvInd) ; + Point3d ptS0, ptS1 ; + pCrvCurr->GetStartPoint( ptS0) ; + pCrvCompo->GetCurve( u)->GetStartPoint( ptS1) ; + if ( abs( ptS1.y - dDiam) < TOLL_TRAPEZOID) + nSecondBase = u ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::PreparareTrapezoidTwoBases( const ICurveComposite* pCrvCompo, BBox3d BBox, const int nBase, int& nSecondBase, + bool& bOk, ICurveComposite* pCrvTrap) +{ + // controllo parametri + if ( pCrvCompo == nullptr) + return false ; + bOk = false ; + + // le parti tra le due basi devono essere tutte omogenee ( o tutte aperte o tutte chiuse) + // pCrvTest0 sarà la parte destra, pCrvTest1 la parte sinistra + Point3d ptSB0, ptSB1 ; + PtrOwner pCrvTest0( CloneCurveComposite( pCrvCompo)) ; + PtrOwner pCrvTest1( CloneCurveComposite( pCrvCompo)) ; + pCrvCompo->GetCurve( nBase)->GetStartPoint( ptSB0) ; + pCrvCompo->GetCurve( nSecondBase)->GetStartPoint( ptSB1) ; + pCrvTest0->ChangeStartPoint( nBase) ; + pCrvTest1->ChangeStartPoint( nSecondBase) ; + double dUTrim0, dUTrim1 ; + pCrvTest0->GetParamAtPoint( ptSB1, dUTrim0) ; + pCrvTest1->GetParamAtPoint( ptSB0, dUTrim1) ; + pCrvTest0->TrimStartEndAtParam( 1, dUTrim0) ; + pCrvTest1->TrimStartEndAtParam( 1, dUTrim1) ; + // controllo che la parte destra si uniforme per le TmpProp + for ( int u = 0 ; u < pCrvTest0->GetCurveCount() - 1 ; ++ u) { + int nPropAct, nPropSucc ; + if ( pCrvTest0->GetCurveTempProp( u, nPropAct, 0) && + pCrvTest0->GetCurveTempProp( u + 1, nPropSucc, 0) && + nPropAct != nPropSucc) + return true ; // se TmpProp diverse => non è un caso ottimizzato + } + // controllo che la parte sinistra sia uniforme per le TmpProp + for ( int u = 0 ; u < pCrvTest1->GetCurveCount() - 1 ; ++ u) { + int nPropAct, nPropSucc ; + if ( pCrvTest1->GetCurveTempProp( u, nPropAct, 0) && + pCrvTest1->GetCurveTempProp( u + 1, nPropSucc, 0) && + nPropAct != nPropSucc) + return true ; // se TmpProp diverse => non è un caso ottimizzato + } + + // parametri lavorazione + 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 ; + + // creo la base principale e secondaria + PtrOwner pCrvBase0( pCrvCompo->GetCurve( nBase)->Clone()) ; + PtrOwner pCrvBase1( pCrvCompo->GetCurve( nSecondBase)->Clone()) ; + // ricavo i nuovi estremi + Point3d ptEB0, ptEB1 ; + pCrvBase0->GetStartPoint( ptSB0) ; + pCrvBase0->GetEndPoint( ptEB0) ; + pCrvBase1->GetStartPoint( ptSB1) ; + 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) + bool bCopyRight = false ; + if ( pCrvTest0->GetCurve( 0)->GetTempProp( 0) == 1) { + ptEB0 = BBox.GetMin() + X_AX * BBox.GetDimX() ; + ptSB1 = ptEB0 + dDiam * Y_AX ; + } + // se lato destro chiuso + else + bCopyRight = true ; + // se lato sinistro aperto ( estendo il punto finale della base secondaria e il punto iniziale + // della base primaria dino al lato sinistro del box) + bool bCopyLeft = false ; + if ( pCrvTest1->GetCurve( 0)->GetTempProp( 0) == 1) { + ptSB0 = BBox.GetMin() ; + ptEB1 = BBox.GetMin() + dDiam * Y_AX ; + } + // se lato sinistro chiuso + else + bCopyLeft = true ; + + // creo la curva da restituire + pCrvTrap->AddPoint( ptSB0) ; + pCrvTrap->AddLine( ptEB0) ; + if ( bCopyRight) + pCrvTrap->AddCurve( Release( pCrvTest0)) ; + else { + pCrvTrap->AddLine( ptSB1) ; + pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta + } + nSecondBase = pCrvTrap->GetCurveCount() ; + pCrvTrap->AddLine( ptEB1) ; + if ( bCopyLeft) + pCrvTrap->AddCurve( Release( pCrvTest1)) ; + else { + pCrvTrap->Close() ; + pCrvTrap->SetCurveTempProp( pCrvTrap->GetCurveCount() - 1, 1, 0) ; // aperta + } + + // 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() ; + return true ; + } + } + + bOk = true ; + return true ; +} + diff --git a/Pocketing.h b/Pocketing.h index 756cd27..08f21fc 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -92,7 +92,13 @@ 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, - Frame3d& frTrap,double& dPocketSize, int& nBase, int& nSecondBase) ; + Frame3d& frTrap, double& dPocketSize, int& nBase, int& nSecondBase) ; + bool CheckTrapezoidClosedEdgePosition( const ICurveComposite* pCrvCompo, const int nCrvInd, const double dDimBoxY, + INTVECTOR& vIndClosedSides, bool& bOk, + ICurveComposite* pCrvTrap) ; + bool CheckSecondBaseTrapezoid( const ICurveComposite* pCrvCompo, const int nCrvInd, int& nSecondBase) ; + bool PreparareTrapezoidTwoBases( const ICurveComposite* pCrvCompo, BBox3d BBox, const int nBase, int& nSecondBase, + bool& bOk, ICurveComposite* pCrvTrap) ; // =================================================================== // =========================== GREZZO e GEOMETRIE ==================== @@ -252,8 +258,9 @@ class Pocketing : public Machining bool CalcTrapezoidSpiralLocalFrame( ICurveComposite * pCrvPocket, const Vector3d& vtDir, Frame3d& frLoc) ; 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 AdjustTrapezoidSpiralForAngles( ICurveComposite * pMCrv, const ICurveComposite * pCrvPocket, + bool bStart) ; + bool SpecialAdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const bool bEven, const ICurveComposite* pCrvPocket) ; bool AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite * pCompo, ICurveComposite * pRCrv, const Vector3d& vtTool, double dDepth, int& nOutsideRaw) ; bool ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite * pCompo, const Vector3d& vtMainDir, bool bLeadIn, const Vector3d& vtTool, double dDepth,