diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 36cb139..0fc2ff2 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -722,7 +722,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo //---------------------------------------------------------------------------- static bool -AssignFeedSpiralOpt( const int nOptType, const PocketParams& PockParams, ICurveComposite* pCrv ) +AssignFeedSpiralOpt( int nOptType, const PocketParams& PockParams, ICurveComposite* pCrv ) { // controllo della curva corrente if ( pCrv == nullptr || ! pCrv->IsValid() || pCrv->GetCurveCount() == 0) @@ -732,24 +732,24 @@ AssignFeedSpiralOpt( const int nOptType, const PocketParams& PockParams, ICurveC if ( ! PockParams.bCalcFeed) return AssignMaxFeed( pCrv, PockParams) ; - switch ( PockParams.nType) { - case POCKET_SPIRALIN : - if ( nOptType == 0) { // Spirale dall'Esterno - for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { - if ( u == 0) // prima circonferenza - pCrv->SetCurveTempParam( 0, GetMinFeed( PockParams), 0) ; - else // semi cerchi in tangenza - pCrv->SetCurveTempParam( u, GetMaxFeed( PockParams), 0) ; - } + if ( PockParams.nType == POCKET_SPIRALIN || PockParams.nType == POCKET_CONFORMAL_ZIGZAG || + PockParams.nType == POCKET_CONFORMAL_ONEWAY) { + if ( nOptType == 0) { // Spirale dall'Esterno + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { + if ( u == 0) // prima circonferenza + pCrv->SetCurveTempParam( 0, GetMinFeed( PockParams), 0) ; + else // semi cerchi in tangenza + pCrv->SetCurveTempParam( u, GetMaxFeed( PockParams), 0) ; } - else if ( nOptType == 1) { // Trapezoidi - for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) - pCrv->SetCurveTempParam( u, GetMinFeed( PockParams), 0) ; - } - break ; + } + else if ( nOptType == 1) { // Trapezoidi + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempParam( u, GetMinFeed( PockParams), 0) ; + } + } /* NB. Essendo la funzione CalcSpiral richiamata sia per lo SpiralIN che per lo SpiralOUT le curve sono sempre orientate nello stesso modo, solamente alla fine viene invertita la curva finale per la svuotatura... */ - case POCKET_SPIRALOUT : + else { if ( nOptType == 0) { // Spiral verso l'esterno for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { if ( u > pCrv->GetCurveCount() - 3) // prime semi circonferenze @@ -762,9 +762,6 @@ AssignFeedSpiralOpt( const int nOptType, const PocketParams& PockParams, ICurveC for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) pCrv->SetCurveTempParam( u, GetMinFeed( PockParams), 0) ; } - break ; - default : - break ; } return true ; @@ -3625,6 +3622,91 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double return true ; } +//---------------------------------------------------------------------------- +static bool +GetZigZagOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& PockParam, + ICurveComposite* pCrvRes) +{ + // controllo dei parametri + if ( pSfrChunk == nullptr || ! pSfrChunk->IsValid()) + return false ; + pCrvRes->Clear() ; + + // ricavo la curva di bordo del chunk corrente + PtrOwner pCrvBorder( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, 0))) ; + if ( IsNull( pCrvBorder) || ! pCrvBorder->IsValid()) + return false ; + pCrvBorder->MergeCurves( 10. * EPS_SMALL, 10. * EPS_ANG_SMALL, true, true) ; + pCrvBorder->SetExtrusion( pSfrChunk->GetNormVersor()) ; + + /* TRAPEZI + - E' richiesto che una dimensione del box della curva sia compatibile con il primo Offset, il + quale sarebbe una singola curva aperta + */ + PtrOwner pCrvTrap( CreateCurveComposite()) ; + if ( IsNull( pCrvTrap)) + return false ; + Frame3d frTrap ; + double dPocketSize ; + int nBase, nSecondBase ; + bool bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ; + if ( bOkTrap && pCrvTrap->IsValid()) { + // se la base principale e secondaria sono entrambe chiuse, trascuro il SideStep + int nTmpProp = TEMP_PROP_INVALID ; + bool bBaseCL = ( pCrvTrap->GetCurveTempProp( nBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ; + bool bSecondBaseCL = ( pCrvTrap->GetCurveTempProp( nSecondBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ; + if ( ! bBaseCL || ! bSecondBaseCL) + bOkTrap = ( dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ; + } + if ( bOkTrap && pCrvTrap->IsValid()) { + pCrvTrap->SetExtrusion( Z_AX) ; + CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, PockParam, pCrvRes, bOkTrap) ; + if ( bOkTrap) { + // verifico che tale curva non interferisca con la regione limite + if ( PockParam.SfrLimit.IsValid()) { + double dOffsCheck = PockParam.dRad + PockParam.dRadialOffset - 50. * EPS_SMALL ; // restrittivo per sicurezza + PtrOwner pSfrToolShape( GetSurfFlatRegionFromFatCurve( pCrvRes->Clone(), dOffsCheck, false, false)) ; + bOkTrap = ( ! IsNull( pSfrToolShape) && pSfrToolShape->IsValid()) ; + if ( bOkTrap) { + bOkTrap = ( pSfrToolShape->Intersect( PockParam.SfrLimit) && + ! pSfrToolShape->IsValid()) ; + if ( ! bOkTrap) + pCrvRes->Clear() ; + } + } + if ( bOkTrap) { + // calcolo eventuali uscite e ingressi + if ( pCrvRes->GetTempProp( 0) > 0) { + // Recupero gli estremi della curva corrente e la inverto in base alla Testa + Point3d ptS ; pCrvRes->GetStartPoint( ptS) ; + Point3d ptE ; pCrvRes->GetEndPoint( ptE) ; + Point3d ptSGlob = GetToGlob( ptS, PockParam.frLocXY) ; + Point3d ptEGlob = GetToGlob( ptE, PockParam.frLocXY) ; + if ( ( PockParam.bAboveHead && ptEGlob.z > ptSGlob.z) || + ( ! PockParam.bAboveHead && ptEGlob.z < ptSGlob.z)) + pCrvRes->Invert() ; + if ( PockParam.bInvert) + pCrvRes->Invert() ; + // Assegno la Feed + AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ; + // Calcolo eventuale entrata da fuori + Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ; + vtRef.Invert() ; + bool bIsStartExtended = false ; + if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended)) + return false ; + } + else { + if ( PockParam.bInvert) + pCrvRes->Invert() ; + } + } + } + } + + return true ; +} + //---------------------------------------------------------------------------- static bool GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& PockParam, @@ -3714,8 +3796,15 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& Frame3d frTrap ; double dPocketSize ; int nBase, nSecondBase ; - bool bOkTrap = ( GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) && - dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ; + bool bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ; + if ( bOkTrap && pCrvTrap->IsValid()) { + // se la base principale e secondaria sono entrambe chiuse, trascuro il SideStep + int nTmpProp = TEMP_PROP_INVALID ; + bool bBaseCL = ( pCrvTrap->GetCurveTempProp( nBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ; + bool bSecondBaseCL = ( pCrvTrap->GetCurveTempProp( nSecondBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ; + if ( ! bBaseCL || ! bSecondBaseCL) + bOkTrap = ( dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ; + } if ( bOkTrap && pCrvTrap->IsValid()) { pCrvTrap->SetExtrusion( Z_AX) ; CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, PockParam, pCrvRes, bOkTrap) ; @@ -3745,6 +3834,8 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& pCrvRes->Invert() ; if ( PockParam.bInvert) pCrvRes->Invert() ; + // Assegno la Feed + AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ; // Calcolo eventuale entrata da fuori Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ; vtRef.Invert() ; @@ -3798,23 +3889,31 @@ GetPocketingOptimizedCurves( ISurfFlatRegion* pSfr, const PocketParams& PockPara PockParam.nType == POCKET_CONFORMAL_ZIGZAG || PockParam.nType == POCKET_CONFORMAL_ONEWAY) { // curva da resituire PtrOwner pCrvOptSpiral( CreateCurveComposite()) ; - if ( IsNull( pCrvOptSpiral) || - ! GetSpiralOptimizedCurves( pSfrChunk, PockParam, pCrvOptSpiral)) + if ( IsNull( pCrvOptSpiral) || + ! GetSpiralOptimizedCurves( pSfrChunk, PockParam, pCrvOptSpiral)) return false ; // se ho ricavato una curva ottimizzata if ( ! IsNull( pCrvOptSpiral) && pCrvOptSpiral->IsValid() && pCrvOptSpiral->GetCurveCount() > 0) { - vCrvOptCurves.emplace_back( Release( pCrvOptSpiral)) ; + vCrvOptCurves.emplace_back( Release( pCrvOptSpiral)) ; + pSfr->EraseChunk( nCurrChunk) ; + } + else + ++ nCurrChunk ; + } + else if ( PockParam.nType == POCKET_ZIGZAG || PockParam.nType == POCKET_ONEWAY) { + // curva da restituire + PtrOwner pCrvOptZigZag( CreateCurveComposite()) ; + if ( IsNull( pCrvOptZigZag) || + ! GetZigZagOptimizedCurves( pSfrChunk, PockParam, pCrvOptZigZag)) + return false ; + // se ho ricavato una curva ottimizzata + if ( ! IsNull( pCrvOptZigZag) && pCrvOptZigZag->IsValid() && pCrvOptZigZag->GetCurveCount() > 0) { + vCrvOptCurves.emplace_back( Release( pCrvOptZigZag)) ; pSfr->EraseChunk( nCurrChunk) ; } else ++ nCurrChunk ; } - // else if ( PockParam.nType == POCKET_ZIGZAG) - // ; - // else if ( PockParam.nType == POCKET_ONEWAY) - // ; - // else if ( PockParam.nType == POCKET_CONFORMAL_ONEWAY || PockParam.nType == POCKET_CONFORMAL_ZIGZAG) - // ; } return true ; @@ -8916,14 +9015,14 @@ CalcSpiralPocketing( const ISurfFlatRegion* pSfr, int nType, const PocketParams& // il tipo può essere solo SpiralIn o SpiralOut if ( nType != POCKET_SPIRALIN && nType != POCKET_SPIRALOUT) return false ; + PtrOwner pSfrLimit( PockParams.SfrLimit.IsValid() ? PockParams.SfrLimit.Clone() : CreateSurfFlatRegion()) ; // calcolo il percorso di svuotatura spiral return ( CalcPocketing( pSfr, PockParams.dRad, PockParams.dRadialOffset, PockParams.dSideStep, PockParams.dAngle, PockParams.dOpenMinSafe, nType, PockParams.bSmooth, PockParams.bCalcUnclearedRegs, PockParams.bInvert, PockParams.bAvoidOpt, PockParams.bAllowZigZagOneWayBorders, PockParams.bCalcFeed, PockParams.ptStart, - PockParams.SfrLimit.IsValid() ? PockParams.SfrLimit.Clone() : CreateSurfFlatRegion(), - PockParams.bAvoidOpt, PockParams.dMaxOptSize, PockParams.dLiTang, PockParams.nLiType, - vCrvCompoRes)) ; + pSfrLimit, PockParams.bAvoidOpt, PockParams.dMaxOptSize, PockParams.dLiTang, + PockParams.nLiType, vCrvCompoRes)) ; } //---------------------------------------------------------------------------- @@ -9218,9 +9317,10 @@ SmoothExtensionLinesByIntersection( ICRVCOMPOPOVECTOR& vCrvPaths, const PocketPa //---------------------------------------------------------------------------- bool CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double dStep, double dAngle, - double dOpenMinSafe, int nType, bool bSmooth, bool bCalcUnclReg, bool bInvert, bool bAvoidOpt, bool bAllowZigZagOneWayBorders, - bool bCalcFeed, const Point3d& ptEndPrec, const ISurfFlatRegion* pSfrLimit, bool bAllOffs, - double dMaxOptSize, double dLiTang, int nLiType, ICRVCOMPOPOVECTOR& vCrvCompoRes) + double dOpenMinSafe, int nType, bool bSmooth, bool bCalcUnclReg, bool bInvert, bool bAvoidOpt, + bool bAllowZigZagOneWayBorders, bool bCalcFeed, const Point3d& ptEndPrec, + const ISurfFlatRegion* pSfrLimit, bool bAllOffs, double dMaxOptSize, double dLiTang, + int nLiType, ICRVCOMPOPOVECTOR& vCrvCompoRes) { // controllo dei parametri if ( pSfr == nullptr || ! pSfr->IsValid() || diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index c8b0b3f..c19879f 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ