From a6a40e29731253e999424d40bebb7023209ba979 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 15 May 2025 16:27:05 +0200 Subject: [PATCH] EgtMachKernel : - In Pocketing NT migliorate le entrate, i raccordi tra percorsi e aggiunto parametro MaxOptSize - In Sgrossature, correzione su Open Edges ed Offset radiali per regioni Silhouettes. --- PocketingNT.cpp | 373 ++++++++++++++++++++++++++++++++++------------ PocketingNT.h | 50 ++++--- SurfFinishing.cpp | 8 +- SurfRoughing.cpp | 89 ++++------- 4 files changed, 340 insertions(+), 180 deletions(-) diff --git a/PocketingNT.cpp b/PocketingNT.cpp index d80bca8..7409f0a 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -54,11 +54,13 @@ static string KEY_OPEN = "OPEN" ; static string KEY_THICK = "THICK" ; static int LINK_CURVE_PROP = -3 ; static double EXTRA_ELEV = 5. ; +static double SAFETY_LINK_COS = cos( - ( 175 * DEGTORAD)) ; // Parametri avanzati da UserNotes const string UN_MAXELEV = "MaxElev" ; const string UN_OPEN = "Open" ; const string UN_OPENOUTRAW = "OpenOutRaw" ; const string UN_OPENMINSAFE = "OpenMinSafe" ; +const string UN_MAXOPTSIZE = "MaxOptSize" ; //------------------------------ Errors -------------------------------------- // 2401 = "Error in PocketingNT : UpdateToolData failed" @@ -112,7 +114,8 @@ const string UN_OPENMINSAFE = "OpenMinSafe" ; #define DEBUG_FLATREGIONS 0 #define DEBUG_SFR_RAW 0 #define DEBUG_GLIDE 0 -#if DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_FLATREGIONS || DEBUG_SFR_RAW || DEBUG_GLIDE +#define DEBUG_SAFETY_LINK 0 +#if DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_FLATREGIONS || DEBUG_SFR_RAW || DEBUG_GLIDE || DEBUG_SAFETY_LINK #include "EgtDev/Include/EGkGeoPoint3d.h" #include "EgtDev/Include/EGkFrame3d.h" #endif @@ -3285,13 +3288,20 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) // del percorso successivo) Point3d ptEndLastPath = P_INVALID ; + // controllo parametri per casi ottimizzati + double dMaxOptSize = m_Params.m_dSideStep ; + GetValInNotes( m_Params.m_sUserNotes, UN_MAXOPTSIZE, dMaxOptSize) ; + + // se non richiesto controllo con il grezzo, elimino la superficie limite + + // scorro gli indici delle superfici for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) { // calcolo i percorsi di Pocketing ICRVCOMPOPOVECTOR vCrvPaths ; if ( ! CalcPocketing( vStepInfo[i].pSfrPock, m_TParams.m_dDiam / 2, GetOffsR(), m_Params.m_dSideStep, m_Params.m_dSideAngle, m_dOpenMinSafe, m_Params.m_nSubType, true, m_Params.m_bInvert, - false, true, true, ptEndLastPath, vStepInfo[i].pSfrLimit, false, vCrvPaths)) { + false, true, true, ptEndLastPath, vStepInfo[i].pSfrLimit, false, dMaxOptSize, vCrvPaths)) { m_pMchMgr->SetLastError( 3028, "Error in PocketingNT : Error in CalcPocketing") ; return false ; } @@ -3309,7 +3319,10 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) // controllo se il percorso ha un ingresso presso un lato aperto vStepInfo[i].vPaths[j].bOutStart = ( vCrvPaths[j]->GetCurveCount() > 0 && vCrvPaths[j]->GetFirstCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ; - + if ( ! vStepInfo[i].vPaths[j].bOutStart && ! LeadInRawIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; + } // controllo se il percorso ha un'uscita presso un lato aperto vStepInfo[i].vPaths[j].bOutEnd = ( vCrvPaths[j]->GetCurveCount() > 0 && vCrvPaths[j]->GetLastCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ; @@ -3357,6 +3370,49 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) return true ; } +//---------------------------------------------------------------------------- +bool +PocketingNT::ManageSmoothLink( const PathInfoPO& currPath, const PathInfoPO& nextPath, bool bSamePlane, + bool& bSmoothEnd, bool& bForceLinear) +{ + // definizione smusso finale a seconda del tipo di lavorazioni + bSmoothEnd = true ; + bForceLinear = false ; + switch ( m_Params.m_nSubType) + { + case POCKET_SUB_SPIRALIN : + case POCKET_SUB_SPIRALOUT : + // ... se devo scendere allo step successivo presso un lato aperto + if ( ! bSamePlane && nextPath.bOutStart) { + // ... non smusso il percorso finale + bSmoothEnd = false ; + return true ; + } + break ; + case POCKET_SUB_ZIGZAG : + case POCKET_SUB_ONEWAY : + // ... se sono sullo stesso piano e passo da un tratto finale aperto ad un tratto iniziale aperto... + if ( bSamePlane && currPath.bOutEnd && nextPath.bOutStart) { + // .. smusso sia inizio che fine + return true ; + } + bForceLinear = true ; + break ; + case POCKET_SUB_CONFORMAL_ONEWAY : + case POCKET_SUB_CONFORMAL_ZIGZAG : + // ... se devo scendere allo step successivo presso un lato aperto + if ( ! bSamePlane && nextPath.bOutStart) { + // ... non smusso il percorso finale + bSmoothEnd = false ; + return true ; + } + break ; + default: + break ; + } + return true ; +} + //---------------------------------------------------------------------------- bool PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dElev, double dStep, bool bSplitArcs) @@ -3375,7 +3431,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; // elevazione sopra al punto attuale - double dCurrElev ; + double dCurrElev = 0. ; // punto finale del percorso precedente al corrente Point3d ptEnd = P_INVALID ; @@ -3415,22 +3471,8 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou } // determino l'elevazione sull'inizio dell'attacco della prima curva globale bool bAbsFirst = ( i == 0 && j == 0) ; - if ( bAbsFirst) { - // l'elevazione è il massimo tra lo Step e l'elevazione calcolata mediante intersezione con grezzo - // ( per gestire le collisioni con i movimenti in rapido ) - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dCurrElev)) - dCurrElev = - currStep.dDepth + 10 * EPS_SMALL ; - else - dCurrElev = max( dCurrElev, - currStep.dDepth + 10 * EPS_SMALL) ; - bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dCurrElev) ; - bool bUhAboveRaw = ! m_bAboveHead && - GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtTool, dCurrElev) ; - if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) - dCurrElev = max( dCurrElev, dStep) ; - } + if ( bAbsFirst) + CalcFirstElevation( ptStart, ptP1, vtTool, currStep, dSafeZ, dStep, dCurrElev) ; dCurrElev -= ( ptP1 - ptStart) * vtTool ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco if ( GetLeadInType() != POCKET_LI_NONE) { @@ -3457,6 +3499,9 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou } // aggiungo attacco SetFeed( GetStartFeed()) ; + Point3d ptCurr ; GetCurrPos( ptCurr) ; + if ( ! AreSamePointApprox( ptP1, ptCurr)) + AddLinearMove( ptP1) ; bool bNoneForced = ( currPath.bOutStart || currPath.bSingleCrv || ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && ! currPath.bIsZigZagOneWayBorder) || ( m_Params.m_nSubType == POCKET_SUB_ONEWAY && ! currPath.bIsZigZagOneWayBorder)) ; @@ -3505,82 +3550,76 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou else { // ricavo il punto che devo raggiungere e controllo la posizione del percorso successivo bool bSamePlane = ( j < int( currStep.vPaths.size()) - 1) ; - bool bNextIsBelow = true ; - Point3d ptDest ; - if ( bSamePlane) { - // se entrata a scivolo ammissibile, allora la destinazione è l'inizio dello scivolo (nel piano) - if ( GetLeadInType() == POCKET_LI_GLIDE && currStep.vPaths[j+1].pCrvGlideIn != nullptr && - currStep.vPaths[j+1].pCrvGlideIn->IsValid()) - currStep.vPaths[j+1].pCrvGlideIn->GetStartPoint( ptDest) ; - // altrimenti è l'inizio del percorso - else - currStep.vPaths[j+1].pCrvPath->GetStartPoint( ptDest) ; + const PathInfoPO& PathToGo = ( bSamePlane ? currStep.vPaths[j+1] : + vStepInfo[i+1].vPaths.front()) ; + Point3d ptDest ; Vector3d vtDest ; + // se entrata a scivolo ammissibile, allora la destinazione è l'inizio dello scivolo (nel piano) + if ( GetLeadInType() == POCKET_LI_GLIDE && ( PathToGo.pCrvGlideIn != nullptr && + PathToGo.pCrvGlideIn->IsValid())) { + PathToGo.pCrvGlideIn->GetStartPoint( ptDest) ; + PathToGo.pCrvGlideIn->GetStartDir( vtDest) ; } + // altrimenti è l'inizio del percorso else { - // se entrata a scivolo ammissibile, allora la destinazione è l'inizio dello scivolo (nel piano) - if ( GetLeadInType() == POCKET_LI_GLIDE && vStepInfo[i+1].vPaths.front().pCrvGlideIn != nullptr && - vStepInfo[i+1].vPaths.front().pCrvGlideIn->IsValid()) - vStepInfo[i+1].vPaths.front().pCrvGlideIn->GetStartPoint( ptDest) ; - // altrimenti è l'inizio del percorso - else - vStepInfo[i+1].vPaths.front().pCrvPath->GetStartPoint( ptDest) ; - bNextIsBelow = ( ( ptDest - ptEnd) * vtTool < - 50 * EPS_SMALL) ; + PathToGo.pCrvPath->GetStartPoint( ptDest) ; + PathToGo.pCrvPath->GetStartDir( vtDest) ; } - // determino se un collegamento lineare tra i punti proiettati nel piano attuale è ammissibile + // determino se un collegamento tra i punti proiettati nel piano attuale è ammissibile bool bSafeLimit = false ; - bool bSafePock = false ; - if ( ! CheckSafetyLinearLink( ptEnd, - ( bSamePlane ? currStep.pSfrLimit : - ( bNextIsBelow ? currStep.pSfrLimit : vStepInfo[i+1].pSfrLimit)), - vtTool, ptDest, bSafeLimit)) + bool bSmoothEnd = true ; + bool bForceLinear = false ; + ManageSmoothLink( currPath, PathToGo, bSamePlane, bSmoothEnd, bForceLinear) ; + PtrOwner pCrvLink( CreateCurveComposite()) ; + if ( IsNull( pCrvLink)) return false ; - if ( ! CheckSafetyLinearLink( ptEnd, - ( bSamePlane ? currStep.pSfrPock : - ( bNextIsBelow ? currStep.pSfrPock : vStepInfo[i+1].pSfrPock)), - vtTool, ptDest, bSafePock)) - return false ; - + if ( ! bForceLinear) { + if ( ! CheckSafetyLink( ptEnd, vtEnd, ptDest, vtDest, currStep.pSfrLimit, vtTool, + bSmoothEnd, bSafeLimit, pCrvLink)) + return false ; + } // determino l'elevazione sul punto corrente e sul punto di destinazione dCurrElev = 0. ; double dNextElev = 0. ; + // se il collegamento non rovina il grezzo... if ( bSafeLimit) { if ( bSamePlane) { + // ... ed è sullo stesso piano di svuotatura if ( ( ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) && ! vStepInfo[i].vPaths[j+1].bOutStart) || - ( m_Params.m_nSubType != POCKET_SUB_SPIRALIN && m_Params.m_nSubType != POCKET_SUB_SPIRALOUT)) { - dCurrElev -= bSafePock ? 0. : currStep.dRelativeDepth ; + ( m_Params.m_nSubType != POCKET_SUB_SPIRALIN && m_Params.m_nSubType != POCKET_SUB_SPIRALOUT && + m_Params.m_nSubType != POCKET_CONFORMAL_ZIGZAG && m_Params.m_nSubType != POCKET_SUB_CONFORMAL_ONEWAY)) { + dCurrElev -= currStep.dRelativeDepth ; dNextElev = dCurrElev ; } } - else if ( bNextIsBelow) { - dNextElev += ( ptEnd - ptDest) * vtTool ; - if ( bSafePock) - dNextElev = max( 0., dNextElev - EXTRA_ELEV) ; - } else { - dCurrElev += ( ptDest - ptEnd) * vtTool - currStep.dRelativeDepth ; - dNextElev -= currStep.dRelativeDepth ; + // ... ed è al piano di svuotatura sottostante + dNextElev += ( ptEnd - ptDest) * vtTool ; } } + // se il collegamento rovina il grezzo else { dCurrElev -= currStep.dDepth ; - if ( bSamePlane) - dNextElev -= currStep.dDepth ; - else - dNextElev -= vStepInfo[i+1].dDepth ; + dNextElev -= ( bSamePlane ? currStep.dDepth : vStepInfo[i+1].dDepth) ; } - // tratto lineare sopra al punto corrente ( leggermente alzato) + // End Feed SetFeed( GetEndFeed()) ; - if ( abs( dCurrElev) < EPS_SMALL && abs( dNextElev) < EPS_SMALL && bSafeLimit && bSafePock) - AddLinearMove( ptDest, bSplitArcs) ; - else { - Point3d ptCheck ; - double dExtraElev = ( bSafeLimit ? 0. : EXTRA_ELEV) ; - if ( GetCurrPos( ptCheck) && ! AreSamePointApprox( ptCheck, ptEnd + vtTool * dCurrElev)) - AddLinearMove( ptEnd + vtTool * ( dCurrElev + dExtraElev), bSplitArcs) ; - // tratto lineare sopra a ptDest - if ( GetCurrPos( ptCheck) && ! AreSamePointApprox( ptCheck, ptDest + vtTool * dNextElev)) - AddLinearMove( ptDest + vtTool * ( dNextElev + dExtraElev), bSplitArcs) ; + // per non passare a filo dello step precedente ( quindi nel caso si isole a filo delle stesse) + // aggiungo una elevazione extra nel caso di violazione della regione limite + dCurrElev += ( bSafeLimit ? 0. : EXTRA_ELEV) ; + dNextElev += ( bSafeLimit ? 0. : EXTRA_ELEV) ; + // se devo salire lungo vtTool da vtEnd, mi alzo + if ( dCurrElev > EPS_SMALL) + AddLinearMove( ptEnd + dCurrElev * vtTool, bSplitArcs) ; + // mi dirigo sopra a ptDest + Point3d ptCheck ; + if ( GetCurrPos( ptCheck) && ! AreSamePointApprox( ptCheck, ptDest + dNextElev * vtTool)) { + if ( pCrvLink->IsValid()) { + pCrvLink->Translate( dCurrElev * vtTool) ; + AddCurveMove( pCrvLink, bSplitArcs) ; + } + else + AddLinearMove( ptDest + dNextElev * vtTool, bSplitArcs) ; } // aggiorno le elevazioni dCurrElev = dNextElev ; @@ -3595,6 +3634,28 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou return true ; } +//---------------------------------------------------------------------------- +bool +PocketingNT::CalcFirstElevation( const Point3d& ptStart, const Point3d& ptP1, const Vector3d& vtTool, const StepInfoPO& currStep, + double dSafeZ, double dStep, double& dCurrElev) +{ + // l'elevazione è il massimo tra lo Step e l'elevazione calcolata mediante intersezione con grezzo + // ( per gestire le collisioni con i movimenti in rapido ) + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dCurrElev)) + dCurrElev = - currStep.dDepth + 10 * EPS_SMALL ; + else + dCurrElev = max( dCurrElev, - currStep.dDepth + 10 * EPS_SMALL) ; + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dCurrElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dCurrElev) ; + if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) + dCurrElev = max( dCurrElev, dStep) ; + return true ; +} + //---------------------------------------------------------------------------- double PocketingNT::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) @@ -4578,38 +4639,165 @@ PocketingNT::AdjustContourStart( ICurveComposite* pCompo) //---------------------------------------------------------------------------- bool -PocketingNT::CheckSafetyLinearLink( const Point3d& ptCurr, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool, - const Point3d& ptDest, bool& bSafe) +PocketingNT::CheckSafetyLink( const Point3d& ptCurr, const Vector3d& vtCurr, + const Point3d& ptDest, const Vector3d& vtDest, + const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool, + bool bSmoothEnd, bool& bSafeLimit, ICurveComposite* pCrvSafeLink) { // controllo dei parametri - if ( ! ptCurr.IsValid() || ! ptDest.IsValid() || ! vtTool.IsValid()) + if ( ! ptCurr.IsValid() || ! ptDest.IsValid() || ! vtCurr.IsValid() || ! vtDest.IsValid()) return false ; - bSafe = true ; + pCrvSafeLink->Clear() ; + bSafeLimit = true ; // porto ptDest alla stessa quota di ptCurr secondo vtTool Plane3d plProj ; if ( ! plProj.Set( ptCurr, vtTool)) return false ; Point3d ptDestProj = ProjectPointOnPlane( ptDest, plProj) ; + // se coicidenti allora non devo creare alcun link if ( AreSamePointApprox( ptCurr, ptDestProj)) return true ; - // controllo se la retta che collega ptCurr a ptDesProj è interna o esterna alla regione limite - // devo prima creare un frame Locale XY - if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) { - PtrOwner pSfrLimitLoc( CloneSurfFlatRegion( pSfrLimit)) ; - PtrOwner pLineLoc( CreateCurveLine()) ; - Frame3d frLoc ; - if ( IsNull( pSfrLimitLoc) || ! frLoc.Set( ptCurr, vtTool) || - ! ptDestProj.ToLoc( frLoc) || ! pSfrLimitLoc->ToLoc( frLoc) || - ! pSfrLimitLoc->Offset( m_TParams.m_dDiam / 2 - 10 * EPS_SMALL, ICurve::OFF_FILLET) || - ! pLineLoc->Set( ORIG, ptDestProj)) + // definisco frame locale ( intersezioni nel piano XY) + Frame3d frLoc ; + if ( ! frLoc.Set( ptCurr, vtTool)) + return false ; + + // porto i punti nel piano locale + Point3d ptS = ORIG ; + Point3d ptE = GetToLoc( ptDestProj, frLoc) ; + Vector3d vtS = GetToLoc( vtCurr, frLoc) ; + Vector3d vtE = GetToLoc( vtDest, frLoc) ; + + // ----------------------------- definisco il collegamento ----------------------------- + PtrOwner pCrvLink( CreateCurveComposite()) ; + if ( IsNull( pCrvLink)) + return false ; + bool bLinkLinear = ( ! pCrvLink->AddPoint( ptS) || + ! pCrvLink->AddLine( ptS + ( m_TParams.m_dDiam / 4.) * vtS)) ; + if ( bSmoothEnd) { + // ZigZag tra ptS e ptE mediante vtS e - vtE + bLinkLinear = ( bLinkLinear || + ! pCrvLink->AddLine( ptE - ( m_TParams.m_dDiam / 4.) * vtE) || + ! pCrvLink->AddLine( ptE) || + ( ! pCrvLink->IsValid() && pCrvLink->GetCurveCount() == 3)) ; + } + else { + // evito tratto ZigZag finale + bLinkLinear = ( bLinkLinear || + ! pCrvLink->AddLine( ptE) || + ( ! pCrvLink->IsValid() && pCrvLink->GetCurveCount() == 2)) ; + } + if ( ! bLinkLinear) { + SelfIntersCurve SIC( *pCrvLink) ; + bLinkLinear = ( SIC.GetCrossOrOverlapIntersCount() > 0) ; + } + if ( bLinkLinear) { + pCrvLink->Clear() ; + pCrvLink->AddPoint( ptS) ; + pCrvLink->AddLine( ptE) ; + if ( ! pCrvLink->IsValid()) return false ; - for ( int nC = 0 ; nC < pSfrLimitLoc->GetChunkCount() && bSafe ; ++ nC) { - CRVCVECTOR ccClass ; - bSafe = ( pSfrLimitLoc->GetCurveClassification( *pLineLoc, EPS_SMALL, ccClass) && - int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ; + } + else { + // controllo variazioni angolari delle curve + Vector3d vtStart ; pCrvLink->GetCurve( 0)->GetStartDir( vtStart) ; + Vector3d vtMid ; pCrvLink->GetCurve( 1)->GetStartDir( vtMid) ; + Vector3d vtEnd ; + if ( bSmoothEnd) + pCrvLink->GetCurve( 2)->GetStartDir( vtEnd) ; + if ( vtStart * vtMid < SAFETY_LINK_COS) { + if ( bSmoothEnd) { + delete( pCrvLink->RemoveFirstOrLastCurve( false)) ; + delete( pCrvLink->RemoveFirstOrLastCurve( false)) ; + pCrvLink->AddLine( ptS, false) ; + pCrvLink->GetStartDir( vtMid) ; + } + else + pCrvLink->Clear() ; } + if ( bSmoothEnd) { + if ( vtEnd * vtMid < SAFETY_LINK_COS) { + delete( pCrvLink->RemoveFirstOrLastCurve( true)) ; + delete( pCrvLink->RemoveFirstOrLastCurve( true)) ; + if ( ! pCrvLink->IsValid()) + pCrvLink->AddPoint( ptS) ; + pCrvLink->AddLine( ptE) ; + } + } + if ( ! pCrvLink->IsValid()) { + pCrvLink->Clear() ; + pCrvLink->AddPoint( ptS) ; + pCrvLink->AddLine( ptE) ; + if ( ! pCrvLink->IsValid()) + return false ; + } + } + #if DEBUG_SAFETY_LINK + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Safety_Link") ; + m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ; + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCrvLink->Clone()) ; + m_pGeomDB->SetMaterial( _a, LIME) ; + #endif + + // Smusso il Link secondo i parametri richiesti + CalcSmoothCurve( pCrvLink, m_TParams.m_dDiam / 8., m_TParams.m_dDiam / 8., false) ; + #if DEBUG_SAFETY_LINK + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCrvLink->Clone()) ; + m_pGeomDB->SetMaterial( _a, RED) ; + #endif + + // controllo eventuale interferenza con la regione limite + PtrOwner pSfrLimitLoc( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrLimitLoc)) + return false ; + if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) { + pSfrLimitLoc.Set( CloneSurfFlatRegion( pSfrLimit)) ; + if ( IsNull( pSfrLimitLoc) || ! pSfrLimitLoc->IsValid() || + ! pSfrLimitLoc->ToLoc( frLoc) || + ! pSfrLimitLoc->Offset( m_TParams.m_dDiam / 2. + GetOffsR() - 10 * EPS_SMALL, ICurve::OFF_FILLET)) + return false ; + #if DEBUG_SAFETY_LINK + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrLimitLoc->Clone()) ; + m_pGeomDB->SetMaterial( _a, Color( .5, .5, .5, .35)) ; + #endif + for ( int nC = 0 ; nC < pSfrLimitLoc->GetChunkCount() && bSafeLimit ; ++ nC) { + CRVCVECTOR ccClass ; + bSafeLimit = ( pSfrLimitLoc->GetCurveClassification( *pCrvLink, EPS_SMALL, ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ; + } + } + + // se Link smussato ammissibile + if ( bSafeLimit) { + pCrvSafeLink->CopyFrom( pCrvLink) ; + pCrvSafeLink->ToGlob( frLoc) ; + return true ; + } + // se interferenza con la regione limite, allora provo con link lineare + else if ( ! IsNull( pSfrLimitLoc) && pSfrLimitLoc->IsValid()) { + pCrvLink->Clear() ; + pCrvLink->AddPoint( ptS) ; + pCrvLink->AddLine( ptE) ; + if ( ! pCrvLink->IsValid()) + return false ; + #if DEBUG_SAFETY_LINK + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCrvLink->Clone()) ; + m_pGeomDB->SetMaterial( _a, YELLOW) ; + #endif + bSafeLimit = true ; + for ( int nC = 0 ; nC < pSfrLimitLoc->GetChunkCount() && bSafeLimit ; ++ nC) { + CRVCVECTOR ccClass ; + bSafeLimit = ( pSfrLimitLoc->GetCurveClassification( *pCrvLink, EPS_SMALL, ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ; + } + } + if ( bSafeLimit) { + pCrvSafeLink->CopyFrom( pCrvLink) ; + pCrvSafeLink->ToGlob( frLoc) ; } return true ; @@ -4664,7 +4852,6 @@ PocketingNT::VerifyLeadInOutGlide( const ISurfFlatRegion* pSfr, const ICurveComp // controllo validità dei parametri if ( pSfr == nullptr || ! pSfr->IsValid()) return false ; - Vector3d vtN = pSfr->GetNormVersor() ; // Offset della regione PtrOwner pSfrOffs( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid()) diff --git a/PocketingNT.h b/PocketingNT.h index 6cce3b1..fd56ab5 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -113,11 +113,11 @@ class PocketingNT : public Machining bool GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const ; bool ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) ; bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) ; - bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double dLen, double& dElev) ; bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ; bool GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) ; + bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ; bool CalcPaths( STEPINFOPOVECTOR& vStepInfo) ; bool CalcLeadInOutGlide( const PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath, bool bInVsOut, ICurveComposite* pCrvGlide) ; @@ -136,6 +136,8 @@ class PocketingNT : public Machining double dElev, double dAppr, bool bSplitArcs) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, double dElev, double dAppr, bool bSplitArcs) ; + bool CalcFirstElevation( const Point3d& ptStart, const Point3d& ptP1, const Vector3d& vtTool, const StepInfoPO& currStep, + double dSafeZ, double dStep, double& dCurrElev) ; bool CalcLeadInStart( Point3d& ptStart, const Vector3d& vtTool, const ICurveComposite* pCrvPath, Point3d& ptP1) ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, const ISurfFlatRegion* pSfr, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, @@ -147,8 +149,12 @@ class PocketingNT : public Machining bool GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMid, Vector3d& vtMidOut) ; bool AdjustContourWithOpenEdges( ICurveComposite* pCompo) ; bool AdjustContourStart( ICurveComposite* pCompo) ; - bool CheckSafetyLinearLink( const Point3d& ptCurr, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool, - const Point3d& ptDest, bool& bSafe) ; + bool ManageSmoothLink( const PathInfoPO& currPath, const PathInfoPO& nextPath, bool bSamePlane, + bool& bSmoothEnd, bool& bForceLinear) ; + bool CheckSafetyLink( const Point3d& ptCurr, const Vector3d& vtCurr, + const Point3d& ptDest, const Vector3d& vtDest, + const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool, + bool bSmoothEnd, bool& bSafeLimit, ICurveComposite* pCrvSafeLink) ; bool VerifyLeadInHelix( const ISurfFlatRegion* pSfr, const Point3d& ptStart, const Point3d& ptCen, double dHelixRad) ; bool VerifyLeadInZigZag( const ISurfFlatRegion* pSfr, const Point3d& ptStart, const Point3d& ptPa, const Point3d& ptPb) ; bool VerifyLeadInOutGlide( const ISurfFlatRegion* pSfr, const ICurveComposite* pCrvGlide) ; @@ -193,24 +199,24 @@ class PocketingNT : public Machining return m_Params.m_nLeadOutType ; } private : - SELVECTOR m_vId ; // identificativi entità geometriche da lavorare - PocketingData m_Params ; // parametri lavorazione - ToolData m_TParams ; // parametri utensile - double m_dTHoldBase ; // posizione base del porta-utensile - double m_dTHoldLen ; // lunghezza del porta-utensile - double m_dTHoldDiam ; // diametro del porta-utensile - double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi - int m_nStatus ; // stato di aggiornamento della lavorazione - int m_nPockets ; // numero di percorsi di svuotatura generati - bool m_bTiltingTab ; // flag utilizzo tavola basculante - Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante - bool m_bAboveHead ; // flag utilizzo testa da sopra - bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto - Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto - AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto - bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo - double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto + SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + PocketingData m_Params ; // parametri lavorazione + ToolData m_TParams ; // parametri utensile + double m_dTHoldBase ; // posizione base del porta-utensile + double m_dTHoldLen ; // lunghezza del porta-utensile + double m_dTHoldDiam ; // diametro del porta-utensile + double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi + int m_nStatus ; // stato di aggiornamento della lavorazione + int m_nPockets ; // numero di percorsi di svuotatura generati + bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante + bool m_bAboveHead ; // flag utilizzo testa da sopra + bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto + Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto + AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto + bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo + double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto double m_dOpenInRawExtension ; // estensione dei tratti aperti dentro al grezzo - bool m_bAllClose ; // flag per forzare i lati come tutti chiusi - bool m_bRunning ; // flag di calcoli in corso + bool m_bAllClose ; // flag per forzare i lati come tutti chiusi + bool m_bRunning ; // flag di calcoli in corso } ; \ No newline at end of file diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 2786187..2628e21 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -1802,7 +1802,7 @@ SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., - POCKET_ZIGZAG, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { + POCKET_ZIGZAG, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -2003,7 +2003,7 @@ SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., - POCKET_ONEWAY, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { + POCKET_ONEWAY, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -2205,7 +2205,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons int nType = ( bInVsOut ? POCKET_SPIRALIN : POCKET_SPIRALOUT) ; ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., - nType, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { + nType, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } @@ -4502,7 +4502,7 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // lavorazione Spiral ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrSpiral, m_Params.m_dSideStep, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., - POCKET_SPIRALIN, false, false, true, false, false, P_INVALID, nullptr, true, vpCrvs)) { + POCKET_SPIRALIN, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep, vpCrvs)) { m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 6eb94e9..5e95cdb 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -1691,7 +1691,7 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) return false ; if ( pStmLimit->IsValid() && pStmLimit->GetTriangleCount() > 0) { pSfrOutCompo.Set( GetSfrByStmIntersection( IPPStm1, dSfrDepth + GetOffsL(), 0)) ; - if ( IsNull( pSfrRaw)) { + if ( IsNull( pSfrOutCompo)) { m_pMchMgr->SetLastError( 3027, "Error in SurfRoughing : Slicing Raw failed") ; return false ; } @@ -1716,11 +1716,12 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; return false ; } - pSfrSil_Hypothetical.Set( CloneSurfFlatRegion( pSfrSil)) ; // regione di silhouette ipotetica + pSfrSil_Hypothetical.Set( CloneSurfFlatRegion( pSfrSilCheck)) ; // regione di silhouette ipotetica // sottraggo le parti da non lavorare if ( ! pSfr->Subtract( *pSfrSilCheck)) { // se non riesco, provo con un Offset di tipo Fillet pSfrSil->Offset( GetOffsR(), ICurve::OFF_FILLET) ; + pSfrSil_Hypothetical.Set( CloneSurfFlatRegion( pSfrSil)) ; // regione di silhouette ipotetica if ( ! pSfr->Subtract( *pSfrSil)) return false ; } @@ -1882,12 +1883,12 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) } } - // se si tratta di un SottoStep, chiudo tutti i lati aperti troppo corti + // chiudo tutti i lati aperti troppo corti + if ( ! CloseOpenEdgesUnderTolerance( pSfr, m_TParams.m_dDiam - 200 * EPS_SMALL)) { + m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ; + return false ; + } if ( it->bSubStep) { - if ( ! CloseOpenEdgesUnderTolerance( pSfr, m_TParams.m_dDiam - 200 * EPS_SMALL)) { - m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ; - return false ; - } // rimuovo tutti i Chunk snelli RemoveChunksUnderTolerance( pSfr, m_dSubStepToler, pSfrLimit) ; // se dopo la semplificazione non rimane nulla, allora passo allo step successivo @@ -2106,7 +2107,7 @@ SurfRoughing::GetStmOutSideSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid()) return nullptr ; - // definisco il vettore delle curve dei i bordi della regione + // definisco il vettore delle curve dei bordi della regione CICURVEPVECTOR vpCrv ; bool bOk = true ; @@ -2122,7 +2123,7 @@ SurfRoughing::GetStmOutSideSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* } } - // definisco la TrimMesh limite (inizialmente vuota) + // definisco la TrimMesh limite PtrOwner pStmLimit( CloneSurfTriMesh( pStmRaw)) ; bOk = bOk && ( ! IsNull( pStmLimit) && pStmLimit->IsValid()) ; @@ -2408,7 +2409,7 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf ICRVCOMPOPOVECTOR vCrvPaths ; if ( ! CalcPocketing( vStepInfo[nInd].pSfrPock, m_TParams.m_dDiam / 2, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5., vStepInfo[nInd].nSubType, true, vStepInfo[nInd].bInverted, - false, true, true, ptEndLastPath, vStepInfo[nInd].pSfrLimit, false, vCrvPaths)) { + false, true, true, ptEndLastPath, vStepInfo[nInd].pSfrLimit, false, m_Params.m_dSideStep, vCrvPaths)) { if ( vStepInfo[nInd].bIsExtraStep) { string sWarn = "Warning in SurfRoughing : CalcPocketing failed with substep (" + ToString( vStepInfo[nInd].dDepth, 1) + ")" ; m_pMchMgr->SetWarning( 3055, sWarn) ; @@ -3256,74 +3257,36 @@ SurfRoughing::CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler PtrOwner pCrvLoop( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ; if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) return false ; - // ------------- ricavo tratti di proprietà uniformi ------------- - ICRVCOMPOPOVECTOR vpCrvs ; // vettore tratti aperti e chiusi alternati tra gli indici - int nCurrTempProp ; - int nParStart = 0 ; - for ( int i = 0 ; i < pCrvLoop->GetCurveCount() ; ++ i) { // per ogni curva del loop - int nTempProp ; - pCrvLoop->GetCurveTempProp( i, nTempProp) ; - if ( i == 0) { - nCurrTempProp = nTempProp ; - nParStart = i ; - } - else if ( nCurrTempProp != nTempProp) { // se TempProp0 differente dalla curva precedente - // ricavo il tratto di curva - PtrOwner pCrv( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, i))) ; - if ( IsNull( pCrv)) - return false ; - pCrv->SetTempProp( nCurrTempProp) ; - vpCrvs.emplace_back( Release( pCrv)) ; - nCurrTempProp = nTempProp ; - nParStart = i ; - } - } - // ultima curva ( se esiste) - if ( nParStart < pCrvLoop->GetCurveCount()) { - PtrOwner pCrvLast( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, pCrvLoop->GetCurveCount()))) ; - if ( IsNull( pCrvLast) || ! pCrvLast->IsValid()) - return false ; - pCrvLast->SetTempProp( nCurrTempProp) ; - if ( vpCrvs.empty()) - vpCrvs.emplace_back( Release( pCrvLast)) ; // la curva originale aveva tutte propietà uniformi - else { - if ( vpCrvs[0]->GetTempProp( 0) == nCurrTempProp) - vpCrvs[0]->AddCurve( Release( pCrvLast), false) ; - else - vpCrvs.emplace_back( Release( pCrvLast)) ; - } - } - // -------------------------------------------------------------------- - + // ricavo tratti di proprietà uniformi ------------- + ICRVCOMPOPOVECTOR vpCrvs ; + GetHomogeneousParts( pCrvLoop, vpCrvs) ; // memorizzo i tratti Closed ICRVCOMPOPOVECTOR vCrvClose ; for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) vCrvClose.emplace_back( CloneCurveComposite( vpCrvs[i])) ; } - // scorro tutti i tratti aperti e riconcateno il loop PtrOwner pCrvNewLoop( CreateCurveComposite()) ; if ( IsNull( pCrvNewLoop)) return false ; - for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { // se tratto aperto e non coincidente con tutta la curva if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE && int( vpCrvs.size()) != 1) { // semplifico il loop per avere curve più uniformi SimplifyCurve( vpCrvs[i], vCrvClose) ; // riporto le proprietà - vpCrvs[i]->SetTempProp( 1) ; + vpCrvs[i]->SetTempProp( TEMP_PROP_OPEN_EDGE) ; for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) - vpCrvs[i]->SetCurveTempProp( j, 1, 0) ; + vpCrvs[i]->SetCurveTempProp( j, TEMP_PROP_OPEN_EDGE, 0) ; // controllo la lunghezza delle curve double dLen = EPS_SMALL ; vpCrvs[i]->GetLength( dLen) ; // se più corto della tolleranza if ( dLen < dToler) { - vpCrvs[i]->SetTempProp( 0, 0) ; + vpCrvs[i]->SetTempProp( TEMP_PROP_CLOSE_EDGE, 0) ; for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) - vpCrvs[i]->SetCurveTempProp( j, 0, 0) ; + vpCrvs[i]->SetCurveTempProp( j, TEMP_PROP_CLOSE_EDGE, 0) ; } } pCrvNewLoop->AddCurve( Release( vpCrvs[i])) ; @@ -3335,10 +3298,15 @@ SurfRoughing::CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler bOk = bOk && pSfrTest->AddIntLoop( Release( pCrvNewLoop)) ; } // se il chunk è stato creato correttamente, allora lo aggiungo - if ( bOk) { + if ( bOk && pSfrTest->IsValid()) { if ( pSfrRegular->IsValid() && pSfrRegular->GetChunkCount() > 0) { - if ( ! pSfrRegular->Add( *pSfrTest)) - return false ; + if ( ! pSfrRegular->Add( *pSfrTest)) { + PtrOwner pSfrChunkCL( CloneSurfFlatRegion( pSfr->CloneChunk( nC))) ; + if ( IsNull( pSfrChunkCL) || ! pSfrChunkCL->IsValid()) + return false ; + if ( ! pSfrRegular->Add( *pSfrChunkCL)) + return false ; + } } else { if ( ! pSfrRegular.Set( pSfrTest)) @@ -3351,11 +3319,11 @@ SurfRoughing::CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler if ( IsNull( pSfrChunkCL) || ! pSfrChunkCL->IsValid()) return false ; if ( pSfrRegular->IsValid() && pSfrRegular->GetChunkCount() > 0) { - if ( ! pSfrRegular->Add( *pSfrTest)) + if ( ! pSfrRegular->Add( *pSfrChunkCL)) return false ; } else { - if ( ! pSfrRegular.Set( pSfrTest)) + if ( ! pSfrRegular.Set( pSfrChunkCL)) return false ; } } @@ -3657,7 +3625,6 @@ SurfRoughing::GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPO } return true ; - } //----------------------------------------------------------------------------