Merge commit 'a6a40e29731253e999424d40bebb7023209ba979'

This commit is contained in:
Dario Sassi
2025-05-15 17:04:25 +02:00
4 changed files with 340 additions and 180 deletions
+280 -93
View File
@@ -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<ICurveComposite> 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<ISurfFlatRegion> pSfrLimitLoc( CloneSurfFlatRegion( pSfrLimit)) ;
PtrOwner<ICurveLine> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ISurfFlatRegion> pSfrOffs( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid())
+28 -22
View File
@@ -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
} ;
+4 -4
View File
@@ -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 ;
}
+28 -61
View File
@@ -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<ISurfTriMesh> 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<ICurveComposite> 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<ICurveComposite> 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<ICurveComposite> 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<ICurveComposite> 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<ISurfFlatRegion> 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 ;
}
//----------------------------------------------------------------------------