diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj
index 1fcec9e..fbdcd73 100644
--- a/EgtMachKernel.vcxproj
+++ b/EgtMachKernel.vcxproj
@@ -100,7 +100,7 @@
Disabled
ProgramDatabase
true
- WIN32;_WINDOWS;I_AM_EMK;_DEBUG;%(PreprocessorDefinitions)
+ WIN32;_WINDOWS;I_AM_EMK;_VRONI;_DEBUG;%(PreprocessorDefinitions)
false
false
Use
diff --git a/Pocketing.cpp b/Pocketing.cpp
index 7e3ab2a..2998865 100644
--- a/Pocketing.cpp
+++ b/Pocketing.cpp
@@ -44,6 +44,7 @@
#include "/EgtDev/Include/EGkFilletChamfer.h"
#include "/EgtDev/Include/EGkCurveBezier.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
+#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
@@ -99,6 +100,7 @@ using namespace std ;
//----------------------------------------------------------------------------
static string KEY_OPEN = "OPEN" ;
+static string KEY_TOOL = "VTTOOL" ;
static int LINK_CURVE_PROP = -3 ;
static double FEED_DIVISOR = 1000.0 ;
static double TOLL_TRAPEZOID = 50 * EPS_SMALL ;
@@ -710,8 +712,12 @@ Pocketing::Apply( bool bRecalc, bool bPostApply)
// lavoro ogni singola catena
bool bOk = true ;
- if ( ! ProcessPath( nAuxId, GDB_ID_NULL, nClId))
- bOk = false ;
+ int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ;
+ while ( nPathId != GDB_ID_NULL) {
+ if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId))
+ bOk = false ;
+ nPathId = m_pGeomDB->GetNextGroup( nPathId) ;
+ }
if ( ! bOk)
return false ;
@@ -1094,8 +1100,9 @@ Pocketing::VerifyGeometry( SelData Id, int& nSubs, int& nType)
//----------------------------------------------------------------------------
bool
-Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
+Pocketing::GetCurvesAndPartialVolume( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp, Vector3d& vtN)
{
+
// ammessi : curve, testi, facce di trimesh o regioni
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ;
if ( pGObj == nullptr)
@@ -1106,6 +1113,8 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
return false ;
// se curva
if (( pGObj->GetType() & GEO_CURVE) != 0) {
+ // Thickness
+ double dThick = 0. ;
PtrOwner pCurve ;
// se direttamente curva
if ( Id.nSub == SEL_SUB_ALL) {
@@ -1113,6 +1122,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
const ICurve* pOriCurve = ::GetCurve( pGObj) ;
if ( pOriCurve == nullptr)
return false ;
+ pOriCurve->GetThickness( dThick) ;
pCurve.Set( pOriCurve->Clone()) ;
}
// altrimenti sottocurva di composita
@@ -1121,6 +1131,7 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
const ICurveComposite* pCompo = GetCurveComposite( pGObj) ;
if ( pCompo == nullptr)
return false ;
+ pCompo->GetThickness( dThick) ;
// recupero la curva semplice
const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ;
if ( pOriCurve == nullptr)
@@ -1140,9 +1151,9 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall())
pCurve->SetExtrusion( Z_AX) ;
// corenza con vtTool
- if ( ! m_vtNormal.IsValid())
- m_vtNormal = vtExtr ;
- else if ( ! AreSameVectorApprox( vtExtr, m_vtNormal))
+ if ( ! vtN.IsValid())
+ vtN = vtExtr ;
+ else if ( ! AreSameVectorApprox( vtExtr, vtN))
return false ;
// verifico sia piana e se necessario la appiattisco
PtrOwner pFlatCrv( FlattenCurve( *pCurve, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ;
@@ -1154,8 +1165,14 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ;
return false ;
}
+ // ricavo la Depth
+ double dDepth = 0. ;
+ if ( ! CalcDepth( Id.nId, vtExtr, dThick, dDepth))
+ return false ;
+ // affondo
+ pFlatCrv->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtExtr) ;
// aggiungo alla lista
- lstPC.emplace_back( Release( pCurve)) ;
+ lstPC.emplace_back( Release( pFlatCrv)) ;
return true ;
}
// se altrimenti testo
@@ -1177,19 +1194,28 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
if ( ! pCrv->GetExtrusion( vtExtr) || vtExtr.IsSmall())
pCrv->SetExtrusion( Z_AX) ;
// corenza con vtTool
- if ( ! m_vtNormal.IsValid())
- m_vtNormal = vtExtr ;
- else if ( ! AreSameVectorApprox( vtExtr, m_vtNormal))
+ if ( ! vtN.IsValid())
+ vtN = vtExtr ;
+ else if ( ! AreSameVectorApprox( vtExtr, vtN))
return false ;
// tutte le curve sono chiuse
ResetCurveAllTempProp( pCrv) ;
+ // ricavo la Depth
+ double dDepth = 0. ;
+ if ( ! CalcDepth( Id.nId, vtExtr, 0., dDepth))
+ return false ;
+ // affondo
+ pCrv->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtExtr) ;
lstPC.push_back( pCrv) ;
}
return true ;
}
// se altrimenti superficie
else if ( pGObj->GetType() == SRF_TRIMESH) {
- // recupero la trimesh
+ // inversione del tool non ammessa
+ if ( m_Params.m_bToolInvert)
+ return false ;
+ // recupero la trimesh
const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ;
if ( pSurf == nullptr)
return false ;
@@ -1200,19 +1226,38 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
pStm->ToGlob( frGlob) ;
// recupero l'indice della faccia
int nFacet = (( Id.nSub == SEL_SUB_ALL) ? 0 : Id.nSub) ;
- // recupero la normale esterna della faccia
- Vector3d vtN ;
- if ( ! pStm->GetFacetNormal( nFacet, vtN))
+ // recupero la normale esterna della faccia e il suo punto centrale
+ Vector3d vtN_tm ;
+ Point3d ptCenter ;
+ if ( ! pStm->GetFacetCenter( nFacet, ptCenter, vtN_tm))
return false ;
- if ( ! m_vtNormal.IsValid())
- m_vtNormal = vtN ;
- else if ( ! AreSameVectorApprox( vtN, m_vtNormal))
+ if ( ! vtN.IsValid())
+ vtN = vtN_tm ;
+ else if ( ! AreSameVectorEpsilon( vtN, vtN_tm, 5 * EPS_SMALL))
return false ;
// inverto per definire il volume di pocketing
pStm->Invert() ;
+ // la superficie diventa il suo volume di svuotatura
+ if ( ! SetPocketingVolume( ptCenter, pStm))
+ return false ;
+ // ricavo la Depth
+ double dDepth = 0. ;
+ if ( ! CalcDepth( Id.nId, vtN_tm, 0., dDepth))
+ return false ;
+ // creo il piano di taglio alla quota della faccia
+ Plane3d plCut ; plCut.Set( ptCenter + vtN_tm * ( - dDepth) , - vtN_tm) ;
+ if ( ! plCut.IsValid())
+ return false ;
+ // taglio il volume alla quota di taglio
+ if ( ! pStm->Cut( plCut, true))
+ return false ;
+ // chiudo
+ if ( ! SewingMissingFacesOnPlanes( pStm, plCut))
+ return false ;
// aggiungo la Trimesh
if ( ! pStmTmp->Add( *pStm))
return false ;
+
return true ;
}
// se altrimenti regione
@@ -1227,12 +1272,12 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
// porto in globale
pSfr->ToGlob( frGlob) ;
// recupero la normale della regione
- Vector3d vtN = pSfr->GetNormVersor() ;
- if ( vtN.IsSmall())
+ Vector3d vtN_fr = pSfr->GetNormVersor() ;
+ if ( vtN_fr.IsSmall())
return false ;
- if ( ! m_vtNormal.IsValid())
- m_vtNormal = vtN ;
- else if ( ! AreSameVectorApprox( vtN, m_vtNormal))
+ if ( ! vtN.IsValid())
+ vtN = vtN_fr ;
+ else if ( ! AreSameVectorApprox( vtN, vtN_fr))
return false ;
// determino intervallo di chunk
int nCstart = 0 ;
@@ -1254,6 +1299,12 @@ Pocketing::GetCurves( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp)
AdjustCurveFromSurf( pCrvLoop, TOOL_ORTHO, FACE_CONT, 0) ;
// tutte le curve sono chiuse
ResetCurveAllTempProp( pCrvLoop) ;
+ // ricavo la Depth
+ double dDepth = 0. ;
+ if ( ! CalcDepth( Id.nId, vtN_fr, 0., dDepth))
+ return false ;
+ // affondo
+ pCrvLoop->Translate(( m_Params.m_bToolInvert ? 1. : -1.) * dDepth * vtN_fr) ;
// aggiungo il loop al vettore di curve
lstPC.emplace_back( Release( pCrvLoop)) ;
}
@@ -1327,11 +1378,38 @@ Pocketing::ResetCurveAllTempProp( ICurve* pCurve)
return true ;
}
+//----------------------------------------------------------------------------
+bool
+Pocketing::CalcDepth( const int nId, const Vector3d& vtExtr, double dThick, double& dDepth)
+{
+ // recupero distanza da fondo dei grezzi interessati dal percorso
+ double dRbDist = 0. ;
+ if ( AreSameVectorApprox( vtExtr, Z_AX)) {
+ if ( ! GetDistanceFromRawBottom( m_nPhase, nId, m_TParams.m_dTDiam, dRbDist))
+ return false ;
+ }
+ // se inversione del Tool
+ if ( m_Params.m_bToolInvert)
+ dThick = - dThick ;
+ // valuto l'espressione dell'affondamento
+ ExeLuaSetGlobNumVar( "TH", abs( dThick)) ;
+ ExeLuaSetGlobNumVar( "RB", dRbDist) ;
+ string sMyDepth = m_Params.m_sDepth ;
+ if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) {
+ m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ;
+ return false ;
+ }
+ // se spessore positivo, lo sottraggo dal risultato
+ if ( dThick > 0)
+ dDepth -= dThick ;
+
+ return true ;
+}
+
//----------------------------------------------------------------------------
bool
Pocketing::Chain( int nGrpDestId)
{
-
// vettore puntatori alle curve
ICURVEPOVECTOR vpCrvs ;
vpCrvs.reserve( m_vId.size()) ;
@@ -1341,12 +1419,14 @@ Pocketing::Chain( int nGrpDestId)
PtrOwner pStm_tmp( CreateSurfTriMesh()) ;
if ( IsNull( pStm_tmp) || ! pStm_tmp->AdjustTopology())
return false ;
+ // estrusione e spessore
+ Vector3d vtExtr = V_INVALID ;
// scorro tutti gli id
for ( const auto& Id : m_vId) {
// vettore contente tutte le curve selezionate
ICURVEPLIST lstPC ;
- // prendo le curve e aggiorno la TriMesh di pocketing originale
- if ( ! GetCurves( Id, lstPC, pStm_tmp)) {
+ // prendo le curve e/o aggiorno la TriMesh di pocketing originale
+ if ( ! GetCurvesAndPartialVolume( Id, lstPC, pStm_tmp, vtExtr)) {
string sInfo = "Warning in Pocketing : Skipped entity " + ToString( Id) ;
m_pMchMgr->SetWarning( 2451, sInfo) ;
}
@@ -1356,9 +1436,69 @@ Pocketing::Chain( int nGrpDestId)
}
}
- // vettore di curve composite concatenate
- ICRVCOMPOPOVECTOR vCrvCompo ;
+ // se inversione del Tool, allora inversione dell'estrusione
+ if ( m_Params.m_bToolInvert)
+ vtExtr.Invert() ;
+ // se ho trovato delle curve...
+ if ( int( vpCrvs.size()) > 0) {
+
+ // concateno le curve se necessario
+ ICRVCOMPOPOVECTOR vCrvCompo ;
+ if ( ! ChainCurveArray( vInds, vpCrvs, vCrvCompo))
+ return false ;
+
+ // verifico che siano curve chiuse ( devono delimitare l'area da svuotare)
+ for ( int u = 0 ; u < int( vCrvCompo.size()) ; ++ u) {
+ if ( ! vCrvCompo[u]->IsClosed()) {
+ m_pMchMgr->SetLastError( 2402, "Error in Pocketing : Open Contour") ;
+ return false ;
+ }
+ }
+
+ // ricavo il centro della prima curva
+ Point3d ptInside ;
+ if ( ! vCrvCompo[0]->GetCentroid( ptInside))
+ return false ;
+
+ // creazione della TriMesh di pocketing
+ PtrOwner pStmCurve_Volume( CreateSurfTriMesh()) ;
+ if ( IsNull( pStmCurve_Volume) ||
+ ! pStmCurve_Volume->AdjustTopology() ||
+ ! CreateStmForIntersection( pStmCurve_Volume, vCrvCompo, vtExtr))
+ return false ;
+
+ // intersezione della Trimesh con il finito -> rivavo il volume di svuotatura
+ if ( ! SetPocketingVolume( ptInside, pStmCurve_Volume))
+ return false ;
+
+ if ( pStm_tmp->IsValid())
+ if ( ! pStm_tmp->Add( *pStmCurve_Volume))
+ return false ;
+ }
+
+ // per ogni part rivata dal volume di svuotatura...
+ for ( int p = 0 ; p < pStm_tmp->GetPartCount() ; ++ p) {
+ // creo nuovo gruppo
+ int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ;
+ if ( nPathId == GDB_ID_NULL)
+ return false ;
+ m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( p + 1)) ;
+ // inserisco la Part (p)-esima nel gruppo destinazione
+ int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, pStm_tmp->ClonePart( p)) ;
+ if ( nNewId == GDB_ID_NULL)
+ return false ;
+ // memorizzo la direzione di estrusione
+ m_pGeomDB->SetInfo( nPathId, KEY_TOOL, vtExtr) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::ChainCurveArray( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo)
+{
// preparo i dati per il concatenamento
bool bFirst = true ;
Point3d ptNear = ORIG ;
@@ -1431,45 +1571,17 @@ Pocketing::Chain( int nGrpDestId)
pCrvCompo->SetThickness( dThick) ;
// aggiorno il nuovo punto vicino
pCrvCompo->GetEndPoint( ptNear) ;
- // se utile, approssimo con archi
- //if ( ! ApproxWithArcsIfUseful( pCrvCompo, true))
- // return false ;
- // recupero eventuali lati aperti
- INTVECTOR vOpen ;
- for ( int i = 0 ; i < int( pCrvCompo->GetCurveCount()) ; ++ i) {
- int nProp = 0 ;
- if ( pCrvCompo->GetCurveTempProp( i, nProp) && nProp == 1)
- vOpen.emplace_back( i) ;
- }
// aggiungo la curva al vettore di curve composite concatenate
vCrvCompo.emplace_back( Release( pCrvCompo)) ;
}
- // ricavo un punto interno per il finito corrente
- Point3d ptInside ;
- if ( pStm_tmp->GetTriangleCount() > 0)
- pStm_tmp->GetCentroid( ptInside) ;
- else if ( int( vCrvCompo.size() > 0))
- vCrvCompo[0]->GetCentroid( ptInside) ;
- else
- return false ;
-
- // creazione della TriMesh di pocketing
- if ( ! CreateStmForIntersection( pStm_tmp, vCrvCompo))
- return false ;
-
- // intersezione della Trimesh con il finito -> rivavo il volume di svuotatura
- if ( ! SetPocketingVolume( ptInside, pStm_tmp))
- return false ;
-
- // QUIIIIIIIIIIIIIII
- return false ;
return true ;
+
}
//----------------------------------------------------------------------------
bool
-Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo)
+Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo, const Vector3d& vtN)
{
// se non ho entità esco
if ( int( vCrvCompo.size()) == 0)
@@ -1480,7 +1592,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv
if ( ! vCrvCompo[0]->GetCentroid( ptOrig))
if ( ! vCrvCompo[0]->GetStartPoint( ptOrig))
return false ;
- Frame3d frHeight ; frHeight.Set( ptOrig, m_vtNormal) ;
+ Frame3d frHeight ; frHeight.Set( ptOrig, vtN) ;
if ( ! frHeight.IsValid())
return false ;
@@ -1532,7 +1644,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv
PtrOwner pSfrCurr( sfrBC.GetSurf()) ;
while ( ! IsNull( pSfrCurr) && pSfrCurr->IsValid()) {
// inverto se necessario
- if ( AreOppositeVectorApprox( m_vtNormal, pSfrCurr->GetNormVersor()))
+ if ( AreOppositeVectorApprox( vtN, pSfrCurr->GetNormVersor()))
pSfrCurr->Invert() ;
if ( ! pSfrFinal->IsValid())
pSfrFinal.Set( Release( pSfrCurr)) ;
@@ -1557,7 +1669,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv
if ( IsNull( pCrvLoopExt) || ! pCrvLoopExt->IsValid())
return false ;
// allargo il loop esterno presso i chiusi
- if ( ! GetExtendedLoopToFitStmVolume( pCrvLoopExt))
+ if ( ! GetExtendedLoopToFitStmVolume( pCrvLoopExt, vtN))
return false ;
// inserisco la curva nel vettore
vCrv.emplace_back( Release( pCrvLoopExt)) ;
@@ -1565,12 +1677,15 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv
for ( int l = 1 ; l < vSfrByQuotes[s]->GetLoopCount( c) ; ++ l)
vCrv.emplace_back( vSfrByQuotes[s]->GetLoop( c, l)) ;
// creo la TriMesh per l'intersezione con il finito
- PtrOwner pStmTmp( GetSurfTriMeshByRegionExtrusion( vCrv, 3000 * m_vtNormal)) ;
+ PtrOwner pStmTmp( GetSurfTriMeshByRegionExtrusion( vCrv, 3000 * vtN)) ;
+ for ( int m = 0 ; m < int( vCrv.size()) ; ++ m)
+ delete( vCrv[m]) ;
if ( IsNull( pStmTmp) || ! pStmTmp->IsValid())
return false ;
// aggiungo questa regione a quella passata come parametro alla funzione
if ( ! pStm->Add( *pStmTmp))
return false ;
+
}
}
@@ -1579,7 +1694,7 @@ Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrv
//----------------------------------------------------------------------------
bool
-Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
+Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop, const Vector3d& vtN)
{
// controllo del parametro
if ( pCrvLoop == nullptr || ! pCrvLoop->IsValid())
@@ -1591,15 +1706,16 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
int nTmpProp1 = pCrvLoop->GetTempProp( 1) ;
// ricavo i tratti omogenei ( campio il punto iniziale della curva nel punto medio del chiuso più lungo se presente)
- ICURVEPOVECTOR vCrvOpen, vCrvClose ;
- if ( ! GetHomogeneousParts( pCrvLoop, vCrvOpen, vCrvClose, true))
+ ICRVCOMPOPOVECTOR vpCrvs ;
+ if ( ! GetHomogeneousParts( pCrvLoop, vpCrvs))
return false ;
- // se curva tutta chiusa -> non devo estendere
- if ( int( vCrvOpen.size()) == 0)
- return true ;
- // se curva tutta aperta -> Offset ed esco
- else if ( int( vCrvClose.size()) == 0) {
+ // se curva tutta omogonea
+ if ( int( vpCrvs.size()) == 1 ) {
+ // se tutta chiusa, non devo estendere nulla
+ if ( vpCrvs[0]->GetTempProp() == 0)
+ return true ;
+ // se tutta aperta -> Offset
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvLoop, 3000, ICurve::OFF_EXTEND)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
@@ -1611,26 +1727,32 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
// porto tutto nel piano XY ( per le intersezioni in futuro)
Point3d ptOrig ; pCrvLoop->GetCentroid( ptOrig) ;
- Frame3d frZ ; frZ.Set( ptOrig, m_vtNormal) ;
+ Frame3d frZ ; frZ.Set( ptOrig, vtN) ;
if ( ! frZ.IsValid())
return false ;
- pCrvLoop->ToLoc( frZ) ;
- for ( int i = 0 ; i < int( vCrvOpen.size()) ; ++ i)
- vCrvOpen[i]->ToLoc( frZ) ;
- for ( int i = 0 ; i < int( vCrvClose.size()) ; ++ i)
- vCrvClose[i]->ToLoc( frZ) ;
+ for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i)
+ vpCrvs[i]->ToLoc( frZ) ;
- // scorro i tratti chusi ( se presenti sono almeno due)
- for ( int cl = 0 ; cl < int( vCrvClose.size()) - 1 ; ++ cl) {
+ // pulisco la curva
+ pCrvLoop->Clear() ;
+
+ // scorro i tratti
+ for ( int i = 0 ; i < int( vpCrvs.size()); ++ i) {
+ // determino se il tratto è chiuso o aperto
+ int nCurrTmpProp = vpCrvs[i]->GetTempProp() ;
+ if ( nCurrTmpProp == 0) {
+ pCrvLoop->AddCurve( vpCrvs[i]->Clone()) ;
+ continue ;
+ }
// linea di estensione sulla parte finale
- Point3d ptSL1 ; vCrvClose[cl]->GetEndPoint( ptSL1) ;
- Vector3d vtSL1 ; vCrvClose[cl]->GetEndDir( vtSL1) ;
+ Point3d ptSL1 ; vpCrvs[i-1]->GetEndPoint( ptSL1) ;
+ Vector3d vtSL1 ; vpCrvs[i-1]->GetEndDir( vtSL1) ;
PtrOwner pLineS( CreateCurveLine()) ;
if ( IsNull( pLineS) || ! pLineS->SetPVL( ptSL1, vtSL1, 30000))
return false ;
// linea di estensione sulla parte finale
- Point3d ptSL2 ; vCrvClose[cl+1]->GetStartPoint( ptSL2) ;
- Vector3d vtSL2 ; vCrvClose[cl+1]->GetStartDir( vtSL2) ; vtSL2.Invert() ;
+ Point3d ptSL2 ; vpCrvs[i+1]->GetStartPoint( ptSL2) ;
+ Vector3d vtSL2 ; vpCrvs[i+1]->GetStartDir( vtSL2) ; vtSL2.Invert() ;
PtrOwner pLineE( CreateCurveLine()) ;
if ( IsNull( pLineE) || ! pLineE->SetPVL( ptSL2, vtSL2, 30000))
return false ;
@@ -1642,30 +1764,16 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
if ( ! IntCC.GetIntCrvCrvInfo( 0, aInfo))
return false ;
Point3d ptInters( aInfo.IciA[0].ptI) ;
- // modifico la curva inzile, raccordandola linearmente al punto di intersezione
- double dUS, dUE ;
- pCrvLoop->GetParamAtPoint( ptSL1, dUS) ;
- pCrvLoop->GetParamAtPoint( ptSL2, dUE) ;
- // tratto precedente
- PtrOwner pCrvPrec( CloneCurveComposite( pCrvLoop)) ;
- if ( IsNull( pCrvPrec) || ! pCrvPrec->TrimEndAtParam( dUS))
- return false ;
- // tratto successivo
- PtrOwner pCrvSucc( CloneCurveComposite( pCrvLoop)) ;
- if ( IsNull( pCrvSucc) || ! pCrvSucc->TrimStartAtParam( dUE))
- return false ;
- pCrvLoop->Clear() ;
- if ( ! pCrvLoop->AddCurve( Release( pCrvPrec)) ||
- ! pCrvLoop->AddLine( ptInters) ||
- ! pCrvLoop->AddLine( ptSL2) ||
- ! pCrvLoop->AddCurve( Release( pCrvSucc)))
+ // aggiungo il tratto nuovo
+ if ( ! pCrvLoop->AddLine( ptInters) ||
+ ! pCrvLoop->AddLine( ptSL2))
return false ;
}
// se invece non ci sono intersezioni tra le linee
else if ( IntCC.GetIntersCount() == 0) {
// estendo il tratto aperto con un Offset
OffsetCurve OffsCrv ;
- if ( ! OffsCrv.Make( vCrvOpen[cl], 300, ICurve::OFF_EXTEND)) {
+ if ( ! OffsCrv.Make( vpCrvs[i], 300, ICurve::OFF_EXTEND)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
@@ -1676,7 +1784,7 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
if ( ! pCrvOffs->ExtendStartByLen( 30000) ||
! pCrvOffs->ExtendEndByLen( 30000))
return false ;
- // intersecon questa curva con le rette
+ // interseco con questa curva con le rette
IntersCurveCurve IntCC_S( *pLineS, *pCrvOffs) ;
IntersCurveCurve IntCC_E( *pLineE, *pCrvOffs) ;
Point3d ptInters_S, ptInters_E ;
@@ -1702,27 +1810,10 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
pCrvOffs->GetParamAtPoint( ptInters_E, dUE) ;
if ( ! pCrvOffs->TrimStartEndAtParam( dUS, dUE))
return false ;
- // modifico la curva inzile, raccordandola linearmente al trim dell'Offset
- pCrvLoop->GetParamAtPoint( ptSL1, dUS) ;
- pCrvLoop->GetParamAtPoint( ptSL2, dUE) ;
- // tratto precedente
- PtrOwner pCrvPrec( CloneCurveComposite( pCrvLoop)) ;
- if ( IsNull( pCrvPrec) || ! pCrvPrec->TrimEndAtParam( dUS))
- return false ;
- // tratto successivo
- PtrOwner pCrvSucc( CloneCurveComposite( pCrvLoop)) ;
- if ( IsNull( pCrvSucc) || ! pCrvSucc->TrimStartAtParam( dUE))
- return false ;
- pCrvLoop->Clear() ;
- if ( ! pCrvLoop->AddCurve( Release( pCrvPrec)))
- return false ;
- if ( ! pCrvLoop->AddLine( ptInters_S))
- return false ;
- if ( ! pCrvLoop->AddCurve( Release( pCrvOffs)))
- return false ;
- if ( ! pCrvLoop->AddLine( ptSL2))
- return false ;
- if ( ! pCrvLoop->AddCurve( Release( pCrvSucc)))
+ // aggiungo il tratto nuovo
+ if ( ! pCrvLoop->AddLine( ptInters_S) ||
+ ! pCrvLoop->AddCurve( Release( pCrvOffs)) ||
+ ! pCrvLoop->AddLine( ptSL2))
return false ;
}
else // non definito
@@ -1736,37 +1827,25 @@ Pocketing::GetExtendedLoopToFitStmVolume( ICurveComposite* pCrvLoop)
//----------------------------------------------------------------------------
bool
-Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm)
+Pocketing::GetCurrentPart( const Point3d& ptInside, ISurfTriMesh* pStmPart)
{
- // controllo parametro
- if ( pStm == nullptr || ! pStm->IsValid())
- return false ;
-
- // controllo MachManager e database geometrico
+ // controllo MachManager e database geometrico
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
- // TriMesh del finito
- PtrOwner pStmCurrRawPart( CreateSurfTriMesh()) ;
- if ( IsNull( pStmCurrRawPart))
- return false ;
-
- // flag per RawPart trovata
- bool bFound = false ;
-
// considero tutte le superfici dei pezzi nei grezzi attivi della fase
int nRawId = m_pMchMgr->GetFirstRawPart() ;
- while ( nRawId != GDB_ID_NULL && !bFound) {
+ while ( nRawId != GDB_ID_NULL) {
if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) {
// ciclo sui pezzi del grezzo
int nPartId = m_pMchMgr->GetFirstPartInRawPart( nRawId) ;
- while ( nPartId != GDB_ID_NULL && !bFound) {
+ while ( nPartId != GDB_ID_NULL) {
// ciclo sui layer dei pezzi
int nLayId = m_pGeomDB->GetFirstGroupInGroup( nPartId) ;
- while ( nLayId != GDB_ID_NULL && !bFound) {
+ while ( nLayId != GDB_ID_NULL) {
// ciclo sulle entità del layer
int nEntId = m_pGeomDB->GetFirstInGroup( nLayId) ;
- while ( nEntId != GDB_ID_NULL && !bFound) {
+ while ( nEntId != GDB_ID_NULL) {
// se entità superficie e visibile, la aggiungo
int nStat ;
if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH) {
@@ -1788,12 +1867,10 @@ Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm)
// controllo se il punto è interno a tale Part
double dElev = 0. ;
DistPointSurfTm DistPtStm( ptInside, *pStmRawPart) ;
- if ( DistPtStm.IsPointInside()) {
- pStmCurrRawPart->CopyFrom( pStmRawPart) ;
- if ( ! pStmCurrRawPart->IsValid())
- return false ;
- bFound = true ;
- break ;
+ double dDist ; DistPtStm.GetDist( dDist) ;
+ if ( DistPtStm.IsPointInside() || DistPtStm.IsSmall()) {
+ pStmPart->CopyFrom( pStmRawPart) ;
+ return pStmPart->IsValid() && pStmPart->GetTriangleCount() > 0 ;
}
}
}
@@ -1808,28 +1885,124 @@ Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm)
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
- // parte non trovata
- if ( ! bFound)
- return false ;
-
- // interseco la TriMesh complessiva di pocketing con il finito, ottenendo il volume di svuotatura
- m_pStmVolPocket.Set( Release( pStmCurrRawPart)) ;
- if ( IsNull( m_pStmVolPocket) || ! m_pStmVolPocket->IsValid())
- return false ;
- if ( ! m_pStmVolPocket->Intersect( *pStm)) // intersezione
- return false ;
- int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, m_pStmVolPocket->Clone()) ;
- m_pGeomDB->SetMaterial( b, BLUE) ;
-
- return m_pStmVolPocket->IsValid() && m_pStmVolPocket->GetTriangleCount() > 0 ;
+ return false ;
}
//----------------------------------------------------------------------------
bool
-Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
+Pocketing::SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm)
{
- // ========= GRUPPO TMP ===================
- // recupero gruppo per geometria temporanea ( Gruppo TMP )
+ // controllo parametro
+ if ( pStm == nullptr || ! pStm->IsValid())
+ return false ;
+
+ // recupero il Current Part
+ PtrOwner pStmCurrRawPart( CreateSurfTriMesh()) ;
+ if ( IsNull( pStmCurrRawPart) ||
+ ! GetCurrentPart( ptInside, pStmCurrRawPart))
+ return false ;
+
+ // interseco la TriMesh complessiva di pocketing con il finito, ottenendo il volume di svuotatura
+ if ( ! pStmCurrRawPart->Intersect( *pStm)) // intersezione
+ return false ;
+
+ // aggiorno la superficie
+ pStm->CopyFrom( pStmCurrRawPart) ;
+ return pStm->IsValid() && pStm->GetTriangleCount() > 0 ;
+}
+
+//---------------------------------------------------------------------------
+bool
+Pocketing::AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Vector3d& vtTool)
+{
+ // controllo dei parametri
+ if ( pStmVolPart == nullptr || ! pStmVolPart->IsValid())
+ return false ;
+
+ // NB. Il controllo delle normali delle entitità che sono state selezionate presenta una laggera tolleranza;
+ // Questa tolleranza potrebbe rendere la superficie da svuotare non completamente piana ( ma come sovrapposizione
+ // di superfici piane leggermente inclinate tra loro;
+ const double TOLL = 500 * EPS_SMALL ;
+
+ // creo un frame centrato nel centroide della parte
+ Frame3d frElevation ;
+ Point3d ptC ; pStmVolPart->GetCentroid( ptC) ;
+ frElevation.Set( ptC, vtTool) ;
+ if ( ! frElevation.IsValid())
+ return false ;
+
+ // porto il la parte di volume in questo frame
+ pStmVolPart->ToLoc( frElevation) ;
+
+ // ricavo quindi il Box
+ BBox3d BBox ; pStmVolPart->GetLocalBBox( BBox) ;
+ // il su cui iniziare a svuotare è quello che si trova a Z minima
+ double dZ_min = BBox.GetMin().z ;
+
+ // riporto il volume nel suo frame Originario
+ pStmVolPart->ToGlob( frElevation) ;
+
+ // porto il frame alla minima Z ( sarà negativa) di svuotatura
+ frElevation.Set( ptC + vtTool * dZ_min, vtTool) ;
+ if ( ! frElevation.IsValid())
+ return false ;
+
+ // porto il volume in questo frame
+ pStmVolPart->ToLoc( frElevation) ;
+ // NB. ora il nostro volume è appoggiato al piano Z = 0 centrato sopra all'Origine
+
+ // devo controllare se ci sono delle facce contenute tra il piano Z = 0 e Z = TOLL
+ // 1) creo i due piani
+ Plane3d plZ0 ;
+ plZ0.Set( ORIG, -Z_AX) ;
+ if ( ! plZ0.IsValid())
+ return false ;
+
+ Plane3d plZTOLL ;
+ plZTOLL.Set( ORIG + Z_AX * TOLL, Z_AX) ;
+ if ( ! plZTOLL.IsValid())
+ return false ;
+
+ // 2) taglio una copia del volume tra i due piani
+ PtrOwner pStmVolPart_between( CloneSurfTriMesh( pStmVolPart)) ;
+ if ( IsNull( pStmVolPart_between) || ! pStmVolPart_between->IsValid())
+ return false ;
+ if ( ! pStmVolPart_between->Cut( plZ0, false) || // tolgo la faccia a Z = 0
+ ! pStmVolPart_between->Cut( plZTOLL, false))
+ return false ;
+
+ // 3) controllo tutte le facce che ho attenuto ; se ho ottenuto almeno una faccia con normale simile a Z_AX
+ // allora traslo il piano di svuotatura a Z = TOLL
+ bool bExistFaces = false ;
+ for ( int f = 0 ; f < pStmVolPart_between->GetFacetCount() && !bExistFaces ; ++ f) {
+ Point3d ptC ; Vector3d vtC ;
+ if ( ! pStmVolPart_between->GetFacetCenter( f, ptC, vtC))
+ return false ;
+ bExistFaces = AreSameVectorEpsilon( vtC, - Z_AX, 5 * EPS_SMALL) ;
+ }
+
+ // se non ho trovato nessuna faccia, allora il volume andava già bene
+ if ( ! bExistFaces) {
+ pStmVolPart->ToGlob( frElevation) ; // riportato in posizione originale
+ return true ;
+ }
+
+ // dato che ho trovato almeno una faccia, il mio nuovo volume si restringe leggermente su Z = TOLL
+ plZTOLL.Invert() ;
+ if ( ! pStmVolPart->Cut( plZTOLL, false) ||
+ ! SewingMissingFacesOnPlanes( pStmVolPart, plZTOLL))
+ return false ;
+
+ pStmVolPart->ToGlob( frElevation) ; // riportato in posizione originale
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::ProcessPath( int nPathId, int nPvId, int nClId)
+{
+
+ // recupero gruppo per geometria temporanea ( Gruppo Temp)
const string GRP_TEMP = "Temp" ;
int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ;
// se non c'è, lo aggiungo
@@ -1845,194 +2018,55 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
// in ogni caso lo dichiaro temporaneo e non visibile
m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ;
m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ;
- // =======================================
- // recupero eventuale flag di lato aperto forzato fuori dal grezzo
- int nOpenOutRaw ;
- m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ;
-
- // creo una superificie temporanea generata da tutte le curve ( curve modificate se valide )
- SurfFlatRegionByContours SrfByC ; // superificie totale generata da tutte le curve concatenate
- Plane3d plAux ; bool bFirstPlane = true ; // piano Ausiliario per verificare che le curve siano complanari
- Vector3d vtExtr ;
- double dThick = -INFINITO ; // spessore più grande tra le curve
- int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ;
-
- // indici da associare alla SurfFlatRegion da svuotare :
- // Ogni curva che definirà un loop nella flat Region avrà la seguente struttura :
- // { nProp0, nProp1 } = { Id elemento selezionato, Id faccia adiacente (solo per Trimesh) }
- // Per ogni curva di questi loop ( CurveCompo) avrò :
- // { nProp0, nProp1 } = { (0 -> chiuso, 1 -> aperto) , id faccia adiacente ( solo per Trimesh)}
-
- int nProp0 = -1 ;
- int nProp1 = -1 ;
-
- while ( nPathId != GDB_ID_NULL) { // Scorro tutte le curve concatenate per creare la superficie da lavorare
-
- int nPi = m_pGeomDB->GetFirstInGroup( nPathId) ;
- if ( m_pGeomDB->GetGeoType( nPi) != CRV_COMPO)
- return false ;
- const ICurve* pOriCurve = ::GetCurve( m_pGeomDB->GetGeoObj( nPi)) ;
- if ( pOriCurve == nullptr)
- return false ;
- PtrOwner pCompoOriCrv( GetCurveComposite( pOriCurve->Clone())) ;
- if ( IsNull( pCompoOriCrv))
- return false ;
-
- // ricavo le proprietà della curva
- nProp0 = pCompoOriCrv->GetTempProp( 0) ; // Id selezionato
- nProp1 = pCompoOriCrv->GetTempProp( 1) ; // lato adiancente per Trimesh
-
- // annullo i flag di tratto aperto
- for ( int i = 0 ; i < int( pCompoOriCrv->GetCurveCount()) ; ++i)
- pCompoOriCrv->SetCurveTempProp( i, 0, 0) ; // alla sottocurva
-
- bool bSomeOpen ; // = m_pGeomDB->ExistsInfo( nPi, KEY_OPEN) ;
- SetCurveAllTempProp( nPi, GetForcedClosed(), pCompoOriCrv, &bSomeOpen) ;
- // unisco le parti allineate (tranne inizio-fine se chiusa)
- if ( ! pCompoOriCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false, true))
- return false ;
-
- // recupero estrusione e spessore
- Vector3d vtExtr_p = Z_AX ;
- pCompoOriCrv->GetExtrusion( vtExtr_p) ;
- double dThick_p ;
- pCompoOriCrv->GetThickness( dThick_p) ;
-
- // verifico sia piana e se necessario la appiattisco
- PtrOwner pFlatCrv( FlattenCurve( *pCompoOriCrv, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ;
- if ( IsNull( pFlatCrv)) {
- Plane3d plPlane ;
- if ( ! pCompoOriCrv->IsFlat( plPlane, true, 50 * EPS_SMALL))
- m_pMchMgr->SetLastError( 2403, "Error in Pocketing : Contour Not Flat") ;
- else
- m_pMchMgr->SetLastError( 2404, "Error in Pocketing : Tool Not Perpendicular to Flat Area") ;
- return false;
- }
- pFlatCrv->GetExtrusion( vtExtr_p) ;
- pCompoOriCrv->Clear() ;
- pCompoOriCrv->AddCurve( Release( pFlatCrv)) ;
- pCompoOriCrv->SetExtrusion( vtExtr_p) ;
- pCompoOriCrv->SetThickness( dThick_p) ;
-
- // setto come proprietà temperanea il suo Id
- pCompoOriCrv->SetTempProp( nProp0, 0) ; // a tutta la curva ( id selezionato)
- pCompoOriCrv->SetTempProp( nProp1, 1) ; // a tutta la curva ( se Trimesh, faccia adiacente)
-
- // controllo che le curve siano complanari e con stessa estrusione ( la prima come riferimento)
- Plane3d plAct ;
- pCompoOriCrv->IsFlat( plAct) ;
- if ( bFirstPlane) {
- plAux = plAct ;
- bFirstPlane = false ;
- pCompoOriCrv->GetThickness( dThick_p) ;
- dThick = dThick_p ; // prima come riferimento
- vtExtr = vtExtr_p ; // prima come riferimento
- SrfByC.AddCurve( pCompoOriCrv->Clone()) ;
- }
- else {
- Vector3d vtN1, vtN2 ;
- if ( abs( plAct.GetDist() - plAux.GetDist()) < 5 * EPS_SMALL
- && AreSameOrOppositeVectorApprox( plAct.GetVersN(), plAux.GetVersN()) // se stessa normale
- && AreSameVectorApprox( vtExtr, vtExtr_p)) { // se stessa estrusione
- PtrOwner pCrvProjected( ProjectCurveOnPlane( *pCompoOriCrv, plAux)) ;
- pCrvProjected->SetExtrusion( vtExtr) ;
- // prendo Thickness Massima tra tutte le curve dei chunks
- double dCurrThick ;
- pCompoOriCrv->GetThickness( dCurrThick) ;
- if ( dCurrThick > dThick)
- dThick = dCurrThick ;
- pCrvProjected->SetThickness( dCurrThick) ;
- SrfByC.AddCurve( pCrvProjected->Clone()) ;
- }
- }
-
- nPathId = m_pGeomDB->GetNextGroup( nPathId) ; // aggiorno il PathId con il successivo nel gruppo
- }
-
- // creazione della superficie da lavorare completa ( dall'unione di tutte le curve concatenate)
- PtrOwner pSrfPock( SrfByC.GetSurf()) ;
- if ( IsNull( pSrfPock) || pSrfPock->GetChunkCount() == 0)
+ // recupero l'entità ( Part del volume di svuotatura)
+ double dDepth = 0. ;
+ Vector3d vtTool ; m_pGeomDB->GetInfo( nPathId, KEY_TOOL, vtTool) ;
+ PtrOwner pStm_PartVolume( CreateSurfTriMesh()) ;
+ if ( IsNull( pStm_PartVolume))
+ return false ;
+ int nId = m_pGeomDB->GetFirstInGroup( nPathId) ;
+ if ( m_pGeomDB->GetGeoType( nId) != SRF_TRIMESH)
+ return false ;
+ pStm_PartVolume.Set( CloneSurfTriMesh( m_pGeomDB->GetGeoObj( nId))) ;
+ if ( IsNull( pStm_PartVolume) || ! pStm_PartVolume->IsValid())
return false ;
- // normale della superifice finale || extrusione prima curva selezionata
- if ( AreOppositeVectorApprox( vtExtr, pSrfPock->GetNormVersor()))
- pSrfPock->Invert() ;
+ // recupero nome del path
+ string sPathName ;
+ m_pGeomDB->GetName( nPathId, sPathName) ;
- if ( m_Params.m_bToolInvert) {
- // eventuale inversione direzione utensile
- vtExtr.Invert() ;
- pSrfPock->Invert() ;
- dThick = - dThick ;
- }
-
- // controllo se la superificie contiene lati aperti interni al grezzo
- #if 0
- // 1) recupero la Trimesh del grezzo
- PtrOwner pStmRaw( CreateSurfTriMesh()) ;
- if ( IsNull( pStmRaw))
- return false ;
- pStmRaw->DoCompacting() ;
- if ( ! GetStmRawPart( nProp0, pStmRaw))
- return false ;
- // 2) Imposto TmpProp1 = -2 a tutti i lati aperti ( TmpProp0 = 1 ) interno al grezzo
- if ( ! DetectOpenEdgeInsideRaw ( pSrfPock, pStmRaw))
- return false ;
- #endif
-
- // recupero il box del grezzo in globale
+ // recupero il Box del grezzo globale
BBox3d b3Raw ;
- BBox3d b3Chunk ; pSrfPock->GetBBox( GLOB_FRM, b3Chunk) ;
- if ( ! GetRawGlobBox( m_nPhase, b3Chunk, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) {
+ if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) {
m_pMchMgr->SetLastError( 2405, "Error in Pocketing : Empty RawBox") ;
return false ;
}
- // recupero distanza da fondo dei grezzi interessati dal percorso
- double dRbDist = 0 ; double dAllRbDist = 0 ;
- if ( AreSameVectorApprox( vtExtr, Z_AX)) {
- if ( ! GetDistanceFromRawBottom( m_nPhase, b3Chunk, m_TParams.m_dTDiam, dRbDist, dAllRbDist))
- return false ;
- }
-
- // valuto l'espressione dell'affondamento
- ExeLuaSetGlobNumVar( "TH", abs( dThick)) ;
- ExeLuaSetGlobNumVar( "RB", dRbDist) ;
- double dDepth ;
- string sMyDepth = m_Params.m_sDepth ;
- if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) {
- m_pMchMgr->SetLastError( 2406, "Error in Pocketing : Depth not computable") ;
+ // recupero la Part in cui è contenuto il volume
+ Point3d ptC ; pStm_PartVolume->GetCentroid( ptC) ;
+ PtrOwner pStm_Part( CreateSurfTriMesh()) ;
+ if ( IsNull( pStm_Part) ||
+ ! GetCurrentPart( ptC, pStm_Part))
return false ;
- }
- // se spessore positivo, lo sottraggo dal risultato
- if ( dThick > 0)
- dDepth -= dThick ;
- // sottraggo eventuale offset longitudinale
- dDepth -= GetOffsL() ;
- // assegno il versore fresa
- Vector3d vtTool = vtExtr ;
-
- m_bAggrBottom = false ;
-
- // calcolo l'elevazione massima
- double dElev = -INFINITO ;
- for ( int c = 0; c < pSrfPock->GetChunkCount() ; c++) {
- double dCurrElev ;
- PtrOwner pCvrCompo( GetCurveComposite( pSrfPock->GetLoop( c,0))) ;
- if ( CalcRegionElevation( pCvrCompo, vtTool, dDepth, 0.5 * m_TParams.m_dDiam, dCurrElev)) {
- if ( dCurrElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) {
- BBox3d b3Crv ;
- pSrfPock->GetLoop( c, 0)->GetLocalBBox( b3Crv) ;
- dCurrElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z + min(0., dThick) + dDepth) ;
- }
- if ( dCurrElev > dElev)
- dElev = dCurrElev ;
- }
- else
- return false ;
- }
+ // rendo il volume accettabile per la svuotatura...
+ if ( ! AdjustPocketingSideForVolumePart( pStm_PartVolume, vtTool))
+ return false ;
+ // devo calcolare l'Elevazione...
+ Frame3d frElevation ;
+ frElevation.Set( ptC, vtTool) ;
+ if ( ! frElevation.IsValid())
+ return false ;
+ pStm_PartVolume->ToLoc( frElevation) ;
+ // ricavo quindi il Box
+ BBox3d BBox ; pStm_PartVolume->GetLocalBBox( BBox) ;
+ // il su cui iniziare a svuotare è quello che si trova a Z minima
+ double dZ_min = BBox.GetMin().z ;
+ pStm_PartVolume->ToGlob( frElevation) ;
+ // calcolo l'elevazione massima ( è la lunghezza Z del Box con asse Z uguale a vtTool)
+ double dElev = BBox.GetDimZ() ;
// eventuale imposizione massima elevazione da note utente
double dMaxElev ;
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev)
@@ -2049,26 +2083,26 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
// verifico che il massimo materiale dell'utensile sia sensato
const double MIN_MAXMAT = 1.0 ;
- if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) {
- string sInfo = "Error in Pocketing : Tool MaxMaterial too small (" + ToString(m_TParams.m_dMaxMat, 2) + ")" ;
+ if ( m_TParams.m_dMaxMat < dElev && m_TParams.m_dMaxMat < MIN_MAXMAT) {
+ string sInfo = "Error in Pocketing : Tool MaxMaterial too small (" + ToString( m_TParams.m_dMaxMat, 2) + ")" ;
m_pMchMgr->SetLastError( 2422, sInfo) ;
return false ;
}
- // verifico di non superare il massimo materiale
- // se lo step supera la capacità dell'utensile
+ // verifico di non superare il massimo materiale se lo step supera la capacità dell'utensile
if ( m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL) {
dOkStep = m_TParams.m_dMaxMat + EPS_SMALL ;
- string sInfo = "Warning in Pocketing : machining step (" + ToString( m_Params.m_dStep, 1) + ") bigger than MaxMaterial ("
- + ToString( m_TParams.m_dMaxMat, 1) + ")" ;
+ string sInfo = "Warning in Pocketing : machining step (" + ToString( m_Params.m_dStep, 1) +
+ ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ;
m_pMchMgr->SetWarning( 2457, sInfo) ;
}
- // se lavorazione singola
+
+ // se lavorazione singola
if ( dOkStep < EPS_SMALL || dOkStep > dElev) {
- // se l'elevazione supera la capacità dell'utensile
- if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL ) {
- string sInfo = "Warning in Pocketing : machining depth (" + ToString(dElev, 1) +
- ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ;
+ // se l'elevazione supera la capacità dell'utensile
+ if ( dElev > m_TParams.m_dMaxMat + EPS_SMALL) {
+ string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) +
+ ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ;
m_pMchMgr->SetWarning( 2458, sInfo) ;
dDepth -= dElev - m_TParams.m_dMaxMat ;
dElev = m_TParams.m_dMaxMat ;
@@ -2082,7 +2116,7 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
if ( dElev > dMaxDepth + EPS_SMALL) {
// segnalo, riduco e continuo
string sInfo = "Warning in Pocketing : machining depth (" + ToString( dElev, 1) +
- ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ;
+ ") bigger than MaxDepth (" + ToString( dMaxDepth, 1) + ")" ;
m_pMchMgr->SetWarning( 2458, sInfo) ;
dDepth -= dElev - dMaxDepth ;
dElev = dMaxDepth ;
@@ -2091,18 +2125,20 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
// verifico se tavola basculante
bool bTiltTab = false ;
- m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ;
+ m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ;
// verifico se testa da sopra (Z+)
m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ;
// verifiche per svuotature dal basso
- m_bAggrBottom = false ;
- if ( ! VerifyPathFromBottom( pSrfPock, vtTool))
- return false ;
+ m_bAggrBottom = false ;
+ //if ( ! VerifyPathFromBottom( pCompo, vtTool)) {
+ // return false ;
+ //}
- // recupero nome del path
- string sPathName = "P1" ;
+ // recupero eventuale flag di lato aperto forzato fuori dal grezzo
+ int nOpenOutRaw ;
+ m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ;
// recupero eventuale minima lunghezza di attacco su lato aperto
FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenMinSafe="), m_dOpenMinSafe) ;
@@ -2116,8 +2152,8 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
m_pGeomDB->SetName( nPxId, sPathName) ;
m_pGeomDB->SetMaterial( nPxId, GREEN) ;
// creo l'anteprima del percorso
- if ( ! GeneratePocketingPv( nPxId, pSrfPock))
- return false ;
+ //if ( ! GeneratePocketingPv( nPxId, pCompo))
+ // return false ;
}
// se richiesta lavorazione
@@ -2131,9 +2167,9 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
// verifico se archi vanno approssimati con segmenti di retta
int nSplitArcs = m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() ;
- bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS ||
- ( nSplitArcs == SPLAR_NO_XY_PLANE && !vtExtr.IsZplus()) ||
- ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ;
+ bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS ||
+ ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtTool.IsZplus()) ||
+ ( nSplitArcs == SPLAR_GEN_PLANE && vtTool.IsGeneric())) ;
// assegno il vettore estrazione al gruppo del percorso
m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ;
@@ -2144,33 +2180,775 @@ Pocketing::ProcessPath( int nAuxId, int nPvId, int nClId)
SetPathId( nPxId) ;
SetToolDir( vtTool) ;
- // Eseguo la lavorazione della superificie finale
+ // determino numero e affondamento degli step
+ int nStep = 1 ;
+ nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ;
+ double dStep = dElev / nStep ;
+
+ // porto il frame alla minima Z ( sarà negativa) di svuotatura
+ frElevation.Set( ptC + vtTool * dZ_min, vtTool) ;
+ if ( ! frElevation.IsValid())
+ return false ;
+
+ // porto il volume e la Part che lo contiene in questo frame
+ pStm_PartVolume->ToLoc( frElevation) ;
+ pStm_Part->ToLoc( frElevation) ;
+
+ // creo i parametri utili per la svuotatura
+ ISURFFRPOVECTOR vSrfSliced ; // vettore delle superficie ricavate ( per ogni step)
+ vector vCrvOEWithFlags; // vettore delle relative curve originali ( per ogni step)
+ BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi
+ VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature
+
+ // ricavo le superfici di svuotatura
+ if ( ! SliceVolume( pStm_PartVolume, pStm_Part, vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, nStep, vtTool, dElev, dDepth, dStep))
+ return false ;
+
+ // riporto il volume nel frame globale
+ pStm_PartVolume->ToGlob( frElevation) ;
+
+ // riporto le superfici nel frame globale
+ for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s)
+ vSrfSliced[s]->ToGlob( frElevation) ;
+
+ for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s) {
+ PtrOwner pSrf_toDraw( CloneSurfFlatRegion( vSrfSliced[s])) ;
+ //int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ;
+ //m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ;
+ for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) {
+ for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) {
+ PtrOwner pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ;
+ for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
+ int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ;
+ int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ;
+ int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ;
+ m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
+ }
+ }
+ }
+ }
+
+ //return false ;
+
+ // riporto le curve per i casi ottimizzati nel frame globale
+ for ( int u = 0 ; u < int( vCrvOEWithFlags.size()) ; ++ u)
+ for ( int uu = 0 ; uu < int( vCrvOEWithFlags[u].size()) ; ++ uu)
+ vCrvOEWithFlags[u][uu]->ToGlob( frElevation) ;
+
+ // riporto i vettori di traslazione nel frame globale
+ for ( int v = 0 ; v < int( vVtTrasl.size()) ; ++ v)
+ vVtTrasl[v].ToGlob( frElevation) ;
+
+ // Eseguo la lavorazione a seconda del tipo
switch ( m_Params.m_nSubType) {
- case POCKET_SUB_ZIGZAG:
- if ( ! AddZigZag( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs))
+ case POCKET_SUB_ZIGZAG :
+ if ( ! AddZigZag( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev,
+ dMaxElev, dOkStep, bSplitArcs))
return false ;
break ;
- case POCKET_SUB_ONEWAY:
- if ( ! AddOneWay( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs))
- return false ;
- break ;
- case POCKET_SUB_SPIRALIN:
- if ( ! AddSpiralIn( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs))
- return false ;
- break ;
- case POCKET_SUB_SPIRALOUT:
- if ( ! AddSpiralOut( pSrfPock, vtTool, vtExtr, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs))
- return false ;
+ case POCKET_SUB_ONEWAY :
+ if ( ! AddOneWay( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev,
+ dMaxElev, dOkStep, bSplitArcs))
+ return false ;
+ break ;
+ case POCKET_SUB_SPIRALIN :
+ if ( ! AddSpiralIn( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev,
+ dMaxElev, dOkStep, bSplitArcs))
+ return false ;
+ break ;
+ case POCKET_SUB_SPIRALOUT :
+ if ( ! AddSpiralOut( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev,
+ dMaxElev, dOkStep, bSplitArcs))
+ return false ;
break ;
}
}
- m_nPockets++ ;
+ // incremento numero di svuotature
+ ++ m_nPockets ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStmPart, const ISurfTriMesh* pStmVol, ISurfFlatRegion* pSfrProj)
+{
+ // controllo i parametri
+ if ( pStmPart == nullptr || ! pStmPart->IsValid() ||
+ pStmVol == nullptr || ! pStmVol->IsValid())
+ return false ;
+
+ // ricavo la parte di grezzo da non rovinare
+ PtrOwner pStmToNotRuin( CloneSurfTriMesh( pStmPart)) ;
+ if ( IsNull( pStmToNotRuin) ||
+ ! pStmToNotRuin->IsValid() ||
+ ! pStmToNotRuin->Subtract( *pStmVol) ||
+ ! pStmToNotRuin->IsValid())
+ return false ;
+
+ // NB. La parte vera a propria di interesse è quella sopra la piano Z = 0
+ // creo il piano Z = 0
+ Plane3d plZ0 ;
+ plZ0.Set( ORIG, - Z_AX) ;
+ if ( ! plZ0.IsValid())
+ return false ;
+
+ // taglio la supericie
+ if ( ! pStmToNotRuin->Cut( plZ0, true))
+ return false ;
+
+ // se non ho ottenuto nulla, esco
+ if ( ! pStmToNotRuin->IsValid() || pStmToNotRuin->GetTriangleCount() == 0)
+ return true ;
+
+ // Proietto la TriMesh
+ plZ0.Invert() ;
+ PtrOwner pSfrLimitH( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrLimitH) ||
+ ! ProjectStmOnPlane( pStmToNotRuin, plZ0, pSfrLimitH))
+ return false ;
+
+ // controllo per estrema sicurezza la coerenza con le normali
+ if ( AreOppositeVectorApprox( pSfrLimitH->GetNormVersor(), Z_AX))
+ pSfrLimitH->Invert() ;
+
+ // ritorno la superficie
+ pSfrProj->CopyFrom( pSfrLimitH) ;
+ return pSfrProj->IsValid() && pSfrProj->GetChunkCount() > 0 ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced,
+ std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec,
+ VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool,
+ const double dElev, const double dDepth, const double dStep)
+{
+ // controllo dei parametri
+ if ( pStmVol == nullptr || ! pStmVol->IsValid() ||
+ pStm_Part == nullptr || ! pStm_Part->IsValid())
+ return false ;
+
+ // NB. Ogni volta che esco dal volume di svuotura rischio con il Tool di rovinare delle parti al di fuori del volume
+ // di svuotatura...
+ // -> quando proeitto la parte di volume compresa tra lo step attuale e lo step precedente ( ProjectVolume)
+ // -> quando mi estendo presso i lati aperti ( ModifySurfByOpenEdges)
+ // Devo limitare la mia regione si svuotatura estesa mediante la proeizione della parte di grezzo che non voglio
+ // svuotare
+ PtrOwner pSfrLimit( CreateSurfFlatRegion()) ;
+ if ( ! GetProjectionOfStmToNotPocket( pStm_Part, pStmVol, pSfrLimit))
+ return false ;
+
+ vVtTrasl.clear() ;
+ // creazione di un vettore con gli step ( caso base)
+ for ( int j = 1 ; j <= nStep ; ++ j)
+ vVtTrasl.push_back( -Z_AX * ( dDepth - dElev + j * dStep)) ;
+
+ // calcolo di eventuali Step Extra
+ // W.I.P
+
+ // aggirno le dimensioni dei vettori da restituire in base agli step calcolati
+ vCrvOEWithFlags.clear() ;
+ vCrvOEWithFlags.resize( int( vVtTrasl.size())) ;
+ vbChangedPrec.clear() ;
+ vbChangedPrec.resize( int( vVtTrasl.size())) ;
+
+ // per ogni step ricavato...
+ for ( int j = 1 ; j <= int( vVtTrasl.size()) ; ++ j) {
+ // porto la regione limite allo step attuale
+ if ( pSfrLimit->IsValid())
+ pSfrLimit->Translate( vVtTrasl[j-1]) ;
+ // taglio il volume con il piano di svuotatura attuale
+ PtrOwner pSfrCurr( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrCurr) ||
+ ! CutVolumeByPlane( pStmVol, pStm_Part, vVtTrasl[j-1], pSfrCurr))
+ return false ;
+ // tolgo/aggiungo eventuali proiezioni
+ if ( ! ProjectVolume( pStmVol, pStm_Part, vVtTrasl[j-1], j == 1 ? V_INVALID : vVtTrasl[j-2], pSfrLimit, pSfrCurr))
+ return false ;
+ // ricavo le proprietà di lato aperto/chiuso
+ if ( ! ChooseCloseOrOpenEdge( pSfrCurr, pStm_Part))
+ return false ;
+ // salvo le curve originali per casi ottimizzati
+ if ( ! GetCurvesForOptimizedPocketing( pSfrCurr, vCrvOEWithFlags[j-1]))
+ return false ;
+ // modifico la supericie in base alle proprietà di lato aperto/chiuso
+ if ( ! ModifySurfByOpenEdges( pSfrCurr, pSfrLimit))
+ return false ;
+ // inserisco la superficie nel vettore
+ vSrfSliced.emplace_back( Release( pSfrCurr)) ;
+
+ // controllo se la superficie è uguale a quella inserita nello step precedente
+ // ... W.I.P ...
+ vbChangedPrec[j-1] = true ;
+ // ...
+
+ // controllo se la superficie deriva da una lavorazione precedente
+ // ... W.I.P
+ // ...
+ // ...
+
+ // porto la regione limite nel piano Z = 0
+ if ( pSfrLimit->IsValid())
+ pSfrLimit->Translate( -vVtTrasl[j-1]) ;
+
+
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlane)
+{
+ // controllo dei parametri
+ if ( pStm == nullptr || ! pStm->IsValid() ||
+ ! plPlane.IsValid())
+ return false ;
+
+ // recupero tutti i Loop ( se presenti)
+ POLYLINEVECTOR vPL ;
+ pStm->GetLoops( vPL) ;
+ for ( int p = 0 ; p < ( int)vPL.size() ; ++ p) {
+ // controllo la PolyLine è contenuta nel piano dove svuoto, altrimenti non la considero
+ Plane3d plCheck ; double dArea ; Point3d ptCheck ;
+ if ( vPL[p].IsClosedAndFlat( plCheck, dArea)) {
+ if ( vPL[p].GetPointNbr() > 0) {
+ if ( vPL[p].GetFirstPoint( ptCheck)) {
+ double dDist = DistPointPlane( ptCheck, plPlane) ;
+ if ( abs( dDist) > 50 * EPS_SMALL)
+ continue ;
+ }
+ }
+ }
+ // recupero la curva
+ PtrOwner pCrvLoop( CreateCurveComposite()) ;
+ if ( IsNull( pCrvLoop) ||
+ ! pCrvLoop->FromPolyLine( vPL[p]) ||
+ ! pCrvLoop->IsValid())
+ return false ;
+ // creo la TriMesh della faccia mancante
+ PtrOwner pStmMissingFace( GetSurfTriMeshByFlatContour( pCrvLoop)) ;
+ if ( IsNull( pStmMissingFace) || ! pStmMissingFace->IsValid())
+ return false ;
+ // controllo che sia orintata correttamente ( il volume deve essere interno)
+ Vector3d vtN_f ; pStmMissingFace->GetFacetNormal( 0, vtN_f) ;
+ if ( AreOppositeVectorApprox( plPlane.GetVersN(), vtN_f))
+ pStmMissingFace->Invert() ;
+ // unisco
+ if ( ! pStm->DoSewing( *pStmMissingFace))
+ return false ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl,
+ ISurfFlatRegion* pSfrResult)
+{
+ // controllo dei parametri
+ if ( pStmVol == nullptr || ! pStmVol->IsValid() ||
+ pStm_Part == nullptr || ! pStm_Part->IsValid())
+ return false ;
+ pSfrResult->Clear() ;
+
+ // creo un piano allo step attuale
+ Point3d ptCenter = ORIG + vtTrasl ;
+ Vector3d vtN = vtTrasl.IsSmall() ? Z_AX : vtTrasl ; vtN.Normalize() ;
+ Plane3d plCut ; plCut.Set( ptCenter, -vtN) ;
+ if ( ! plCut.IsValid())
+ return false ;
+
+ // taglio il volume con il piano attuale
+ PtrOwner pStmSlice( CloneSurfTriMesh( pStmVol)) ;
+ if ( IsNull( pStmSlice) ||
+ ! pStmSlice->IsValid() ||
+ ! pStmSlice->Cut( plCut, false)) // non salvo quelli sullo stesso livello del piano !
+ return false ;
+
+ // se non ho ricavato nulla, esco
+ if ( ! pStmSlice->IsValid() || pStmSlice->GetTriangleCount() == 0)
+ return true ;
+
+ // aggiungo le facce mancanti dovute al taglio
+ if ( ! SewingMissingFacesOnPlanes( pStmSlice, plCut))
+ return false ;
+
+ // FlatRegion con lati flag di lato Aperto/Chiuso
+ SurfFlatRegionByContours SfrBC_final ;
+
+ // scorro tutte le facce della TriMesh ricavata
+ for ( int f = 0 ; f < pStmSlice->GetFacetCount() ; ++ f) {
+ // le facce che formeranno la FlatRegion di svuotatura sono quelle alla quota definita da vtTrasl
+ Point3d ptCentroid ; Vector3d vtNormal ;
+ if ( ! pStmSlice->GetFacetCenter( f, ptCentroid, vtNormal) ||
+ abs( ptCentroid.z - ptCenter.z) > 300 * EPS_SMALL || // se faccia non sul piano di taglio...
+ ! AreOppositeVectorApprox( Z_AX, vtNormal)) // ... o con diversa normale....
+ continue ; // ... controllo la successiva
+
+ // recupero i contorni della faccia
+ POLYLINEVECTOR vPL ;
+ pStmSlice->GetFacetLoops( f, vPL) ;
+ if ( vPL.empty())
+ return false ;
+
+ // scorro i loop trovati
+ for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
+ // creo la curva a partire dalla PolyLine
+ PtrOwner pCrvCompo( CreateCurveComposite()) ;
+ pCrvCompo->FromPolyLine( vPL[i]) ;
+ if ( ! pCrvCompo->IsValid())
+ return false ;
+ // reset proprietà temporanee
+ ResetCurveAllTempProp( pCrvCompo) ;
+ // la proietto sul piano per maggiore sicurezza
+ PtrOwner pCrvProj( ProjectCurveOnPlane( *pCrvCompo, plCut)) ;
+ if ( IsNull( pCrvProj))
+ return false ;
+ if ( pCrvProj->IsValid())
+ pCrvCompo.Set( ConvertCurveToComposite( Release( pCrvProj))) ;
+ // abbellisco
+ pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
+ // aggiorno la curva alla FlatRegion finale
+ SfrBC_final.AddCurve( Release( pCrvCompo)) ;
+ }
+ }
+
+ // recupero la FlatRegion da restituire ( per approssimazione potrei avere piccoli sfalsamenti lungo Z_AX)
+ PtrOwner pSfr_Final( SfrBC_final.GetSurf()) ;
+ while( ! IsNull( pSfr_Final) && pSfr_Final->IsValid()) {
+ // controllo che sia orientata come Z_AX
+ if ( AreOppositeVectorApprox( Z_AX, pSfr_Final->GetNormVersor()))
+ pSfr_Final->Invert() ;
+ // prendo la supercicie e aggiorno quella da restituire
+ if ( ! pSfrResult->IsValid())
+ pSfrResult->CopyFrom( pSfr_Final) ;
+ else
+ if ( ! pSfrResult->Add( * pSfr_Final))
+ return false ;
+ pSfr_Final.Set( SfrBC_final.GetSurf()) ;
+ }
+
+ // restituisco
+ return ! ( pSfrResult == nullptr || ! pSfrResult->IsValid()) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl,
+ const Vector3d& vtTrasl1, ISurfFlatRegion* pSfrLimit, ISurfFlatRegion* pSfr)
+{
+ // controllo dei parametri
+ if ( pStmVol == nullptr || ! pStmVol->IsValid() ||
+ pStm_Part == nullptr || ! pStm_Part->IsValid() ||
+ pSfr == nullptr || ! pSfr->IsValid())
+ return false ;
+
+ // controllo se il tool ha un SideAngle
+ if ( m_TParams.m_dSideAng != 0) {
+ // ... controllo che gli angoli delle facce siano coerenti al tool selezionato
+ // ...
+ // ...
+ // ...
+ return true ;
+ }
+
+ /*
+ Vengono creati due piano di Taglio : plNear e plFar
+ 1) plNear : piano di taglio allo step attuale con normale Z_AX
+ 2) plFar : piano di taglio riferito allo step successivo ( se lo step è il primo allora è impostato ad una quota alta)
+
+ Ogni faccia del volume di svuotatura ( stm) è classificata come Aperta ( A) o Chiusa ( C)
+ A : questa faccia corrisponde ad una faccia della Part
+ C : questa faccia deriva dalla TriMesh selezionata ( o curve, vedi funzione GetCurvesAndPartialVolume())
+
+ * le facce C vanno proiettate sul piano di svuotatura attuale e sottratte alla *pSfr
+ -> si usa solo il plNear
+
+ * le facce A sono quelle che verranno utilizzate per la proiezione della Part sul piano di svuotatura attuale
+ -> si usa sia il plNear che il plFar
+ * il volume di svuotatura viene tagliato dal plNear e plFar, ottenendo la parte compresa tra i due piani
+ * ( in questo modo la proiezione sul piano di svuotatura considera svuotato tutto ciò che è sopra
+ allo step precedente, quindi con quota Z maggiore di esso )
+ * la proiezione consiste quindi nel proiettare le facce A di questa parte di Volume di Pocketing.
+ */
+
+ // plNear
+ Point3d ptNear = ORIG + vtTrasl ;
+ Vector3d vtN = Z_AX ;
+ Plane3d plNear ; plNear.Set( ptNear, -vtN) ;
+ if ( ! plNear.IsValid())
+ return false ;
+
+ // plFar
+ Point3d ptFar = ORIG + ( vtTrasl1.IsValid() ? vtTrasl1 : 5000 * Z_AX) ;
+ Plane3d plFar ; plFar.Set( ptFar, vtN) ;
+ if ( ! plFar.IsValid())
+ return false ;
+
+ // ricavo il volume di svuotatura sopra al piano plNear
+ PtrOwner pStmAbove_Near( CloneSurfTriMesh( pStmVol)) ;
+ if ( IsNull( pStmAbove_Near) ||
+ ! pStmAbove_Near->IsValid() ||
+ ! pStmAbove_Near->Cut( plNear, false)) // non salvo quelli sullo stesso livello del piano !
+ return false ;
+
+ // se non ho ricavato nulla, esco
+ if ( ! pStmAbove_Near->IsValid() || pStmAbove_Near->GetTriangleCount() == 0)
+ return true ;
+
+ // ricavo il volume di svuotatura tra plNear e PlFar
+ PtrOwner pStmBetween_Planes( CloneSurfTriMesh( pStmAbove_Near)) ;
+ if ( IsNull( pStmBetween_Planes) ||
+ ! pStmBetween_Planes->IsValid() ||
+ ! pStmBetween_Planes->Cut( plFar, false))
+ return false ;
+
+ // se non ho ricavato nulla, esco
+ if ( ! pStmAbove_Near->IsValid() || pStmBetween_Planes->GetTriangleCount() == 0)
+ return true ;
+
+ // --------------------------------------------------------------------------------------------------
+
+ // per la superficie tra i due piani ricavo gli indici dei triangoli delle facce C ( tutti questi triangoli andranno
+ // rimossi lasciando quindi solo le facce A)
+ // NB. sul piano far la TriMesh non presenta facce, bisogna riaggiungerle
+ if ( ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plFar) ||
+ ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plNear))
+ return false ;
+
+ INTVECTOR vAllTria_C_between ;
+ for ( int f = 0 ; f < pStmBetween_Planes->GetFacetCount() ; ++ f) {
+ // ricavo i parametri della faccia
+ Point3d ptC_f ; Vector3d vtN_f ;
+ if ( ! pStmBetween_Planes->GetFacetCenter( f, ptC_f, vtN_f))
+ return false ;
+ // controllo se si tratta di una faccia interna alla Part
+ DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ;
+ if ( distPtStm.IsPointInside()) {
+ // se faccia interna, prendo tutti i suoi tringoli ...
+ INTVECTOR vT ;
+ if ( ! pStmBetween_Planes->GetAllTriaInFacet( f, vT))
+ return false ;
+ // ... e li aggiungo i loro indici al vettore
+ for ( int t = 0 ; t < int( vT.size()) ; ++ t)
+ vAllTria_C_between.push_back( vT[t]) ;
+ }
+ }
+ // dalla superficie tra i due piani rimouovo i triangoli ottenuti
+ for ( int t = 0 ; t < int( vAllTria_C_between.size()) ; ++ t)
+ if ( ! pStmBetween_Planes->RemoveTriangle( vAllTria_C_between[t]))
+ return false ;
+ pStmBetween_Planes->DoCompacting() ;
+
+ // se non ho ricavato nulla, allora significa che tutte le facce del volume di svuotatura comprese tra plNear e
+ // plFar sono chiuse, quindi non ho nulla da proiettare
+ PtrOwner pSfr_ExtendProjection( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfr_ExtendProjection))
+ return false ;
+ if ( pStmBetween_Planes->IsValid() || pStmBetween_Planes->GetTriangleCount() > 0) {
+ // tutta questa superficie contiene solo facce A, le proietto sul piano plNear
+ if ( ! ProjectStmOnPlane( pStmBetween_Planes, plNear, pSfr_ExtendProjection))
+ return false ;
+ // controllo ( per estrema sicurezza) la coerenza con le normali
+ if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfr_ExtendProjection->GetNormVersor()))
+ pSfr_ExtendProjection->Invert() ;
+ // NB. Questa superficie esce dal volume definito, devo stare attento a non rovinare parti di grezzo
+ if ( pSfrLimit->IsValid() && pSfr_ExtendProjection->IsValid()) {
+ if ( ! pSfr_ExtendProjection->Subtract( *pSfrLimit))
+ return false ;
+ }
+ }
+
+ // -------------------------------------------------------------------------------------------------
+
+ // per pStmAbove_Near ricavo gli indici dei triangoli delle facce A ( tutti questi triangoli andranno rimossi
+ // lasciando quindi solo le facce C)
+ INTVECTOR vAllTria_A ;
+ for ( int f = 0 ; f < pStmAbove_Near->GetFacetCount() ; ++ f) {
+ // ricavo i parametri della faccia
+ Point3d ptC_f ; Vector3d vtN_f ;
+ if ( ! pStmAbove_Near->GetFacetCenter( f, ptC_f, vtN_f))
+ return false ;
+ // controllo se si tratta di una faccia interna alla Part
+ DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ;
+ if ( ! distPtStm.IsPointInside()) {
+ // se faccia interna, prendo tutti i suoi tringoli ...
+ INTVECTOR vT ;
+ if ( ! pStmAbove_Near->GetAllTriaInFacet( f, vT))
+ return false ;
+ // ... e li aggiungo i loro indici al vettore
+ for ( int t = 0 ; t < int( vT.size()) ; ++ t)
+ vAllTria_A.push_back( vT[t]) ;
+ }
+ }
+ // dalla superficie sopra al piano di svuotatura rimouovo i triangoli ottenuti
+ for ( int t = 0 ; t < int( vAllTria_A.size()) ; ++ t)
+ if ( ! pStmAbove_Near->RemoveTriangle( vAllTria_A[t]))
+ return false ;
+ pStmAbove_Near->DoCompacting() ;
+
+ // se non ho ricavato nulla, significa che il volume di svuotatura ( tagliato con il piano, e quindi senza le
+ // facce da svuotare) descrive la stessa geometria della Part ( quindi ogni faccia è sulla Part)
+ // ---> non c'è nulla da proiettare
+ PtrOwner pSfrProjection( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrProjection))
+ return false ;
+ if ( pStmAbove_Near->IsValid() && pStmAbove_Near->GetTriangleCount() > 0) {
+ // tutta questa superficie contiene solo facce C, le proietto sul piano plNear
+ if ( ! ProjectStmOnPlane( pStmAbove_Near, plNear, pSfrProjection))
+ return false ;
+ // controllo ( per estrema sicurezza) la coerenza con le normali
+ if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfrProjection->GetNormVersor()))
+ pSfrProjection->Invert() ;
+ }
+
+ // -------------------------------------------------------------------------------------------------
+
+ // 1) La superficie con le facce A tra i due piani plNear e plFar indentificano una proeizione che estende la
+ // superficie attuale da svuotare
+ // 2) La superficie con le facce C al di sopra del piano plNear identificano una proeizione che riduce la
+ // superficie attuale da svuotare
+
+ // 1) ricavo la superificie da svuotare come addizione tra la ( *Sfr) e la ( *pSfr_ExtendProjection)
+ if ( pSfr_ExtendProjection->IsValid())
+ if ( ! pSfr->Add( *pSfr_ExtendProjection))
+ return false ;
+ // 2) ricavo la superficie da svuotare come sottrazione tra la ( *pSfr) e la ( *pSfrProjection)
+ if ( pSfr->IsValid() && pSfrProjection->IsValid())
+ if ( ! pSfr->Subtract( *pSfrProjection))
+ return false ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm_Part)
+{
+ // controllo parametri :
+ if ( pSfr == nullptr || ! pSfr->IsValid())
+ return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati
+ if ( pStm_Part == nullptr || ! pStm_Part->IsValid())
+ return false ;
+
+ // per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti.
+ // se tali punti risultano TUTTI non interni alla Part, allora il lato viene considerato aperto
+ // NB. Aggiungendo delle aree proiettando le parti aperte del volume di Pocketing, alcuni tratti possono risultare
+ // in parte interni ed in parte esterni alla Part... ( questi lati rimangono chiusi, infatti lasciandoli aperti
+ // rischierei di rovinare la part al di fuori del volume di svuotatura.
+ const int NUM_POINTS = 4 ;
+ PtrOwner pSfrWithTmpProps( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrWithTmpProps))
+ return false ;
+
+ // scorro tutti i loop
+ for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
+ for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++l) {
+ // recupero la curva composita del Loop
+ PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ;
+ if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid())
+ return false ;
+ // abbellisco
+ pCrvCompoLoop->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
+ // scorro ogni sua sottocurva
+ for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) {
+ // recupero la sottocurva
+ const ICurve* pCrv = pCrvCompoLoop->GetCurve( u) ;
+ if ( pCrv == nullptr)
+ return false ;
+ // recupero i 4 punti
+ bool bIsClosed = false ; // <-- assumo che la curva sia Aperta
+ for ( int p = 0 ; p < NUM_POINTS + 1 && ! bIsClosed ; ++ p) {
+ double dPar = ( 1. / ( 1. * NUM_POINTS)) * p ;
+ Point3d ptPar ;
+ if ( ! pCrv->GetPointD1D2( dPar, ICurve::FROM_PLUS, ptPar))
+ return false ;
+ DistPointSurfTm distPtStm( ptPar, *pStm_Part) ;
+ bIsClosed = distPtStm.IsPointInside() ;
+ }
+ pCrvCompoLoop->SetCurveTempProp( u, int( ! bIsClosed), 0) ;
+ }
+ // aggiungo il Loop con Flag di lato Aperto/Chiuso alla superficie
+ if ( l == 0) {
+ if ( ! pSfrWithTmpProps->AddExtLoop( *pCrvCompoLoop))
+ return false ;
+ }
+ else
+ if ( ! pSfrWithTmpProps->AddIntLoop( *pCrvCompoLoop))
+ return false ;
+ }
+ }
+
+ // sostituisco la superficie da restituire
+ if ( ! pSfrWithTmpProps->IsValid() ||
+ ! pSfr->Clear() ||
+ ! pSfr->CopyFrom( pSfrWithTmpProps))
+ return false ;
+
+ return pSfr->IsValid() && pSfr->GetChunkCount() != 0 ;
+}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::GetCurvesForOptimizedPocketing( ISurfFlatRegion* pSfr, ICRVCOMPOPOVECTOR& vCrvOEWithFlags)
+{
+ vCrvOEWithFlags.clear() ;
+
+ // controllo parametri :
+ if ( pSfr == nullptr || ! pSfr->IsValid()) {
+ vCrvOEWithFlags.emplace_back( CreateCurveComposite()) ;
+ return true ; // <- se superficie non valida, allora non ho curve da salvare
+ }
+
+ // ricavo tutti i Loop esterni della superficie con i lati Aperti/Chiusi
+ for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
+ PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, 0))) ;
+ if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid())
+ return false ;
+ vCrvOEWithFlags.emplace_back( Release( pCrvCompoLoop)) ;
+ }
return true ;
}
+
+//----------------------------------------------------------------------------
+bool
+Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrLimit)
+{
+ // controllo parametri :
+ if ( pSfr == nullptr || ! pSfr->IsValid())
+ return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati
+
+ // NB. Tutti i Loop che presentano dei lati aperti possono essere estesi ; sia per loop esterni che per isole...
+ // I lati aperti vanno estesi seguendo lo geometria dei lati chiusi adiacenti e tenendo conto delle isole chiuse
+ // vicine ad essi
+
+ // creo la superifcie da restituire... ( questa superficie sarà estesa presso i lati aperti)
+ PtrOwner pSrfFinal( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSrfFinal))
+ return false ;
+
+ // per ogni Chunck della superificie ottenuta...
+ for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
+
+ // vettore delle isole che userò ( le isole aperte piccole sono trascurate)
+ ICRVCOMPOPOVECTOR vCrvToTIsland ;
+ // Flag per sapere se c'è stata almeno una modifica in un loop
+ bool bIsChunkModified = false ;
+
+ // 1) ricavo il Loop esterno
+ PtrOwner pCrvEL( ConvertCurveToComposite( pSfr->GetLoop( c, 0))) ;
+ if ( IsNull( pCrvEL) || ! pCrvEL->IsValid())
+ return false ;
+
+ // 2) creo un vettore di curve con le isole del Chunk
+ ICRVCOMPOPOVECTOR vCrvIsl ;
+ for ( int l = 1 ; l < pSfr->GetLoopCount( c) ; ++ l) {
+ PtrOwner pCrvIL( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ;
+ if ( IsNull( pCrvIL) || ! pCrvIL->IsValid())
+ return false ;
+ vCrvIsl.emplace_back( Release( pCrvIL)) ;
+ }
+
+ // 3) se la curva esterna presenta dei lati aperti -> devo modificarla
+ bool bSomeOpen = false ;
+ int nProp0 = -1 ;
+ for ( int u = 0 ; u < pCrvEL->GetCurveCount() && ! bSomeOpen ; ++ u)
+ if ( pCrvEL->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1)
+ bSomeOpen = true ;
+ if ( bSomeOpen) { // se trovo dei lati aperti
+ // 3.1) sistemo la superificie
+ if ( ! AdjustContourWithOpenEdges( pCrvEL, vCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam,
+ m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(),
+ m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(),
+ pSfrLimit)) {
+ m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ;
+ return false ;
+ }
+ bIsChunkModified = true ; // la curva è stata modificata
+ }
+
+ // 4) Controllo i bordi delle isole ottenute e modifico quelli in cui sono presenti lati aperti
+ for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) {
+ bSomeOpen = false ;
+ nProp0 = -1 ;
+ PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ;
+ for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bSomeOpen ; ++ u) {
+ if ( pCrvIsl->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1)
+ bSomeOpen = true ;
+ }
+ if ( bSomeOpen) { // se trovo dei lati aperti ...
+ // 4.1) se l'isola è tutta aperta e "trascurabile" la talgo
+ bool bRemove = false ;
+ if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam,
+ bRemove))
+ return false ;
+ if ( bRemove) // se si può trascurare passo alla successiva
+ continue ;
+ // 4.2) sistemo la superificie
+ ICRVCOMPOPOVECTOR vCrvNULL ;
+ if ( ! AdjustContourWithOpenEdges( pCrvIsl, vCrvNULL, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam,
+ m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(),
+ m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(),
+ pSfrLimit)) {
+ m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ;
+ return false ;
+ }
+ bIsChunkModified = true ; // la curva è stata modificata
+ }
+ vCrvToTIsland.emplace_back( pCrvIsl->Clone()) ;
+ }
+
+ // 6) Se c'è stata almeno una modifica di lato aperto al chunk (c-esimo), devo ricreare il Chunk
+ // nuovi loop ricavati ( Chunk dopo Chunk creo la superficie finale)
+ if ( bIsChunkModified) {
+
+ SurfFlatRegionByContours SfrBC ; // per sicurezza analizzo ancora i Loop
+ pCrvEL->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
+ SfrBC.AddCurve( Release( pCrvEL)) ; // <--- Loop esterno
+ for ( int i = 0 ; i < ( int)vCrvToTIsland.size() ; ++ i) {
+ vCrvToTIsland[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
+ SfrBC.AddCurve( Release( vCrvToTIsland[i])) ; // <--- isole "valide"
+ }
+
+ // ricavo il nuovo Chunk
+ PtrOwner pNewChunk( SfrBC.GetSurf()) ;
+ if ( IsNull( pNewChunk) || ! pNewChunk->IsValid())
+ return false ;
+
+ // aggiungo il Chunk alla superficie finale
+ if ( pSrfFinal->GetChunkCount() == 0)
+ pSrfFinal.Set( pNewChunk) ;
+ else
+ if ( ! pSrfFinal->Add( *pNewChunk))
+ return false ;
+ }
+ // se il Chunk c-esimo non è mai stato modificato...
+ else {
+ // aggiungo il Chunk alla superficie finale
+ if ( pSrfFinal->GetChunkCount() == 0)
+ pSrfFinal.Set( pSfr->CloneChunk( c)) ;
+ else
+ if ( ! pSrfFinal->Add( *pSfr->CloneChunk( c)))
+ return false ;
+ }
+ }
+
+ // restituisco la superficie aggiornata ricavata
+ if ( ! pSrfFinal->IsValid())
+ return false ;
+ pSfr->Clear() ;
+ pSfr->CopyFrom( pSrfFinal) ;
+
+ return pSrfFinal->IsValid() && pSrfFinal->GetChunkCount() > 0 ;
+}
+
//----------------------------------------------------------------------------
bool
Pocketing::DetectOpenEdgeInsideRaw( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw)
@@ -2572,24 +3350,19 @@ GetCurveRadius( const ICurve* pCrv)
//----------------------------------------------------------------------------
bool
-Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr,
+Pocketing::AddZigZag( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec,
+ VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs)
{
-
// recupero distanze di sicurezza
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
-
- // determino numero e affondamento degli step
- int nStep = 1 ;
- nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ;
- double dStep = dElev / nStep ;
-
+ // ricavo il numero degli step
+ int nStep = int( vSfr.size()) ;
// raggio utensile
double dTRad = m_TParams.m_dDiam / 2 ;
-
// Offset della regione per curva ZigZag
double dOffs = dTRad + GetOffsR() ;
double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ;
@@ -2611,260 +3384,226 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
Frame3d frFrame = GLOB_FRM ;
double dOptZigZagOffs = 0. ;
} ;
+ // dichiarazione vettori info per steps
+ vector vCrvInfo ;
+ vector vChunkInfo ;
- // ciclo su tutti i chunks della superificie originale
- for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) {
-
- // copio il chunk c-esimo
- PtrOwner pSrfChunk(( pSrfPock->CloneChunk( c))) ;
- if ( IsNull( pSrfChunk))
+ // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo)
+ for ( int j = 1 ; j <= nStep ; ++ j) {
+ // se superficie non valida, passo alla prossima
+ if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid())
+ continue ;
+ // superficie per ingressi ed uscite
+ PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ;
+ if ( IsNull( pSrfLeanInOut))
return false ;
- ISURFFRPOVECTOR vSrfSliced( nStep) ; // vettore delle superficie ricavate ( per ogni step)
- vector vCrvOEWithFlags( nStep) ; // vettore delle relative curve originali ( per ogni step)
- BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi
- VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature
+ // se la superficie è cambiata ( o sono al primo step), reset dei parametri step precedente e ricalcolo
+ if ( vbChangedPrec[j-1] || j == 1) {
+ vCrvInfo.clear() ;
+ vChunkInfo.clear() ;
+ vChunkInfo.resize( vSfr[j-1]->GetChunkCount()) ;
- // modifico il Chunk (c)-esimo in base alla geometria
- if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk,
- nStep, vtTool, dElev, dDepth, dStep))
- return false ;
+ // ciclo sui chunk della superificie da svuotare
+ for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) {
+ // copio il chunk c-esimo
+ PtrOwner pSrfChunk(( vSfr[j-1]->CloneChunk( c))) ;
+ if ( IsNull( pSrfChunk))
+ return false ;
- // dichiarazione vettori info per steps
- vector vCrvInfo ;
- vector vChunkInfo ;
+ // cerco la curva originale del chunk (cc)-esimo ( per casi ottimizzati)
+ int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk (cc)-esimo
+ if ( ! GetOptCrvIndex( vCrvOrig, j, pSrfChunk, nInd))
+ return false ;
- // ciclo su tutti gli step
- for ( int j = 1 ; j <= nStep ; ++j) {
+ // determino il riferimento in base alla svuotatura ( per poter orientare il frame per m_dSideAngle)
+ Frame3d frPocket ;
+ Point3d ptCen ; pSrfChunk->GetCentroid( ptCen) ;
+ frPocket.Set( ptCen, vtExtr) ;
+ frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ;
- // se superificie non valida, salto allo step successivo
- if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
- vSrfSliced[j-1].Set( pSrfChunk->Clone()) ;
- continue ;
- }
+ // porto la superificie nel nuovo sistema di riferimento
+ pSrfChunk->ToLoc( frPocket) ;
- PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j - 1])) ;
- if ( IsNull( pSrfFinal))
- return false ;
+ // verifico se si tratta di caso ottimizzato
+ bool bOptimizedZigZag = false ;
+ ICRVCOMPOPOVECTOR vpCrvs ; // vettore con i paths a ZigZag per il Chunk (cc)-esimo allo step (j)-esimo
+ ICRVCOMPOPOVECTOR vCrvIslMergeBorders ; // vettore delle possibili isole mergiate per il Chunk (cc)-esimo allo step (j)-esimo
+ double dOptZigZagOffs = 0. ; // Offset per uscita dal grezzo nel caso di ottimizzazione
+ int nClosedSides = 0 ; // se caso ottimizzato, numero di lati chiusi
+ bool bTwoOpposite = false ; // se caso otimizzato, flag per lati chiusi opposti
+ if ( ! OptimizedZigZag( pSrfChunk, vtTool, dDepth, dSafeZ, frPocket, vCrvOrig[j-1][nInd],
+ bOptimizedZigZag, vpCrvs, vCrvIslMergeBorders, dOptZigZagOffs, nClosedSides,
+ bTwoOpposite))
+ return false ;
- // superficie per ingressi ed uscite
- PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfFinal)) ;
- if ( IsNull( pSrfLeanInOut))
- return false ;
+ // aggiorno le informazioni sul chunk attuale ( potrebbero essere usate per il successivo)
+ vChunkInfo[c].bOptZigZag = bOptimizedZigZag ;
+ vChunkInfo[c].nOptClosedSides = nClosedSides ;
+ vChunkInfo[c].bOptTwoOpposite = bTwoOpposite ;
+ vChunkInfo[c].frFrame = frPocket ;
+ vChunkInfo[c].dOptZigZagOffs = dOptZigZagOffs ;
- // se la superficie è cambiata ( o sono al primo step), reset dei parametri step precedente e ricalcolo
- if ( vbChangedPrec[j-1] || j == 1) {
- vCrvInfo.clear() ;
- vChunkInfo.clear() ;
- vChunkInfo.resize( vSrfSliced[j-1]->GetChunkCount()) ;
-
- // ciclo su tutti i chunk della superificie ( chunk (cc)-esimo per lo step (j)-esimo)
- for ( int cc = 0 ; cc < vSrfSliced[j-1]->GetChunkCount() ; ++cc) {
-
- // copio il Chunk (cc)-esimo allo step (j)-esimo
- PtrOwner pSrfChunkFinal(( vSrfSliced[j-1]->CloneChunk( cc))) ;
- if ( IsNull( pSrfChunkFinal))
- return false ;
-
- // cerco la curva originale del chunk (cc)-esimo ( per casi ottimizzati)
- int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk (cc)-esimo
- if ( ! GetOptCrvIndex( vCrvOEWithFlags, j, pSrfChunkFinal, nInd))
- return false ;
-
- // determino il riferimento in base alla svuotatura ( per poter orientare il frame per m_dSideAngle)
- Frame3d frPocket ;
- Point3d ptCen ; pSrfChunkFinal->GetCentroid( ptCen) ;
- frPocket.Set( ptCen, vtExtr) ;
- frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ;
-
- // porto la superificie nel nuovo sistema di riferimento
- pSrfChunkFinal->ToLoc( frPocket) ;
-
- // verifico se si tratta di caso ottimizzato
- bool bOptimizedZigZag = false ;
- ICRVCOMPOPOVECTOR vpCrvs ; // vettore con i paths a ZigZag per il Chunk (cc)-esimo allo step (j)-esimo
- ICRVCOMPOPOVECTOR vCrvIslMergeBorders ; // vettore delle possibili isole mergiate per il Chunk (cc)-esimo allo step (j)-esimo
- double dOptZigZagOffs = 0. ; // Offset per uscita dal grezzo nel caso di ottimizzazione
- int nClosedSides = 0 ; // se caso ottimizzato, numero di lati chiusi
- bool bTwoOpposite = false ; // se caso otimizzato, flag per lati chiusi opposti
- if ( ! OptimizedZigZag( pSrfChunkFinal, vtTool, dDepth, dSafeZ, frPocket, vCrvOEWithFlags[j-1][nInd],
- bOptimizedZigZag, vpCrvs, vCrvIslMergeBorders, dOptZigZagOffs, nClosedSides,
- bTwoOpposite))
- return false ;
-
- // aggiorno le informazioni sul chunk attuale ( potrebbero essere usate per il successivo)
- vChunkInfo[cc].bOptZigZag = bOptimizedZigZag ;
- vChunkInfo[cc].nOptClosedSides = nClosedSides ;
- vChunkInfo[cc].bOptTwoOpposite = bTwoOpposite ;
- vChunkInfo[cc].frFrame = frPocket ;
- vChunkInfo[cc].dOptZigZagOffs = dOptZigZagOffs ;
-
- // se caso ottimizzato e vettore di curve ZigZag valido
- if ( bOptimizedZigZag) {
- vCrvInfo.resize( int( vpCrvs.size()) + int( vCrvIslMergeBorders.size())) ;
- // aggiorno le curve per lo step attuale ( potrebbero essere usate per il successivo)
- for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) {
- vCrvInfo[x].pCrvCompo.Set( vpCrvs[x]->Clone()) ;
- Point3d ptS ;
- vCrvInfo[x].pCrvCompo->GetStartPoint( ptS) ;
- vCrvInfo[x].ptStart = ptS ;
- vCrvInfo[x].nChunk = cc ;
+ // se CASO OTTIMIZZATO e vettore di curve ZigZag valido
+ if ( bOptimizedZigZag) {
+ vCrvInfo.resize( int( vpCrvs.size()) + int( vCrvIslMergeBorders.size())) ;
+ // aggiorno le curve per lo step attuale ( potrebbero essere usate per il successivo)
+ for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) {
+ vCrvInfo[x].pCrvCompo.Set( vpCrvs[x]->Clone()) ;
+ Point3d ptS ;
+ vCrvInfo[x].pCrvCompo->GetStartPoint( ptS) ;
+ vCrvInfo[x].ptStart = ptS ;
+ vCrvInfo[x].nChunk = c ;
+ }
+ // creo localmente i parametri della funzione
+ VCT3DVECTOR vVtMidOut(( int)vCrvIslMergeBorders.size()) ;
+ BOOLVECTOR vbMidOut(( int)vCrvIslMergeBorders.size()) ;
+ PNTVECTOR vPtStart(( int)vCrvIslMergeBorders.size()) ;
+ // se la superficie è cambiata, allora ricalcolo i parametri
+ for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) {
+ // se richisto, inverto
+ if ( m_Params.m_bInvert)
+ vCrvIslMergeBorders[x]->Invert() ;
+ // setto la Feed per la curva di contorno
+ //AssignFeedForEdgeCleaning( vCrvIslMergeBorders[x], vCrvOEWithFlags[j-1], nInd) ;
+ if ( vCrvIslMergeBorders[x]->IsClosed()) {
+ bool bOutTmp = false ;
+ if ( ! SetBetterPtStartForSubChunks( vCrvIslMergeBorders[x], pSrfChunk,
+ vPtStart[x], vVtMidOut[x], bOutTmp))
+ return false ;
+ vbMidOut[x] = bOutTmp ; // vector::reference da Bit a Bool
}
- // creo localmente i parametri della funzione
- VCT3DVECTOR vVtMidOut(( int)vCrvIslMergeBorders.size()) ;
- BOOLVECTOR vbMidOut(( int)vCrvIslMergeBorders.size()) ;
- PNTVECTOR vPtStart(( int)vCrvIslMergeBorders.size()) ;
+ else {
+ vCrvIslMergeBorders[x]->GetStartPoint( vPtStart[x]) ;
+ vbMidOut[x] = false ; // ... migliorabile
+ vVtMidOut[x] = V_NULL ; // ... migliorabile
+ }
+ }
+ // guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag
+ // e riordino le curve ( e i relativi vettori) in base alla vicinanza
+ // ( piccola ottimizzazione per l'ordine dei percorsi sui bordi )
+ Point3d ptEnd ;
+ if ( vpCrvs.size() > 0)
+ vpCrvs.back()->GetEndPoint( ptEnd) ;
- // se la superficie è cambiata, allora ricalcolo i parametri
- for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) {
+ if ( int( vCrvIslMergeBorders.size()) != 0 &&
+ ! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut))
+ return false ;
- // se richisto, inverto
- if ( m_Params.m_bInvert)
- vCrvIslMergeBorders[x]->Invert() ;
-
- // setto la Feed per la curva di contorno
- AssignFeedForEdgeCleaning( vCrvIslMergeBorders[x], vCrvOEWithFlags[j-1], nInd) ;
-
- if ( vCrvIslMergeBorders[x]->IsClosed()) {
- bool bOutTmp = false ;
- if ( ! SetBetterPtStartForSubChunks( vCrvIslMergeBorders[x], pSrfChunkFinal,
- vPtStart[x], vVtMidOut[x], bOutTmp))
+ int nOff_index = int( vpCrvs.size()) ;
+ for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) {
+ vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ;
+ vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ;
+ vCrvInfo[nOff_index + x].ptStart = vPtStart[x] ;
+ vCrvInfo[nOff_index + x].bMidOut = vbMidOut[x] ;
+ vCrvInfo[nOff_index + x].vtMidOut = vVtMidOut[x] ;
+ vCrvInfo[nOff_index + x].nChunk = c ;
+ }
+ }
+ // se CASO NON OTTIMIZZATO
+ else {
+ // effettuo il primo Offset della regione e controllo quanti Chunks ottengo...
+ // l'Offset contiene una quantità Extra, per stare leggermente più staccato dal bordo
+ PtrOwner pSrfZigZag( CloneSurfFlatRegion( pSrfChunk)) ;
+ if ( ! pSrfZigZag->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) {
+ m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ return false ;
+ }
+ // effettuo un secondo Offset per ottenere le curve di contorno per ripulire la svuotatura a ZigZag
+ // Questo offset serve per ricavare le curve che l'utensile dovrà percorrere dopo aver svuotato a ZigZag
+ // Curva esterna ( non percorsa nel caso a ZigZag ottimizzato)
+ // Curve interne ( le isole, queste vanno percorse anche nei casi ottimizzati)
+ // Per le curve interne, questo Offset viene sempre fatto ( a prescindere dai casi ottimizzati )
+ PtrOwner pSrfForCrv( CloneSurfFlatRegion( pSrfChunk)) ;
+ if ( ! pSrfForCrv->Offset( - dOffs, ICurve::OFF_FILLET)) {
+ m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ return false ;
+ }
+ if ( ! pSrfForCrv->IsValid()) {
+ pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunk)) ;
+ if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) {
+ m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ return false ;
+ }
+ }
+ // Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove
+ // superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e,
+ // per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti.
+ for ( int cfc = 0 ; cfc < pSrfForCrv->GetChunkCount() ; ++ cfc) { // scorro i chunk della superificie per i bordi
+ for ( int cfz = 0 ; cfz < pSrfZigZag->GetChunkCount() ; ++ cfz) { // scorro i chunk della superificie per i percorsi ZigZag
+ // e la regione è dentro al Chunk per i contorni
+ if ( pSrfZigZag->GetChunkSimpleClassification( cfz, *pSrfForCrv, cfc) == REGC_IN1) {
+ // svuoto il vettore delle curve ( potrebbe essere riempito dal percorso precedente
+ vpCrvs.clear() ;
+ // Calcolo il percorso a ZigZag
+ PtrOwner pSrfZigZagChunk( pSrfZigZag->CloneChunk( cfz)) ;
+ if ( ! CalcZigZag( pSrfZigZagChunk, vpCrvs))
return false ;
- vbMidOut[x] = bOutTmp ; // vector::reference da Bit a Bool
- }
- else {
- vCrvIslMergeBorders[x]->GetStartPoint( vPtStart[x]) ;
- vbMidOut[x] = false ; // migliorabile
- vVtMidOut[x] = V_NULL ; // migliorabile
+ // memorizzo le curve ( per lo step successivo)
+ int nIndex_offs = int( vCrvInfo.size()) ;
+ vCrvInfo.resize( int( vpCrvs.size()) + nIndex_offs) ;
+ for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) {
+ vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vpCrvs[x])) ;
+ vCrvInfo[ nIndex_offs + x].nChunk = c ;
+ }
}
+ // se la regione non è dentro alla curva esterna allora la ignoro
+ // ( la ritroverò interna ad un'altra curva per i bordi successivamante o l'ho già considerata in precedenza)
+ else
+ continue ;
+ }
+
+ // se lucidatura non aggiungo contorno
+ if ( m_TParams.m_nType == TT_MILL_POLISHING)
+ continue ;
+
+ // Una volta percorse le curve di ZigZag devo aggiungere le curve per il bordo
+ // creo un vettore con tutti i loop formati, aggiustando i loro punti iniziali
+ // e portandoli nel frame della svuotatura
+ ICRVCOMPOPOVECTOR vAllCrv ;
+ VCT3DVECTOR vVtMidOut( pSrfForCrv->GetLoopCount( cfc)) ;
+ BOOLVECTOR vbMidOut( pSrfForCrv->GetLoopCount( cfc)) ;
+ PNTVECTOR vPtStart( pSrfForCrv->GetLoopCount( cfc)) ;
+ for ( int l = 0 ; l < pSrfForCrv->GetLoopCount( cfc) ; ++ l) {
+ PtrOwner pCrvLoop( ConvertCurveToComposite( pSrfForCrv->GetLoop( cfc, l))) ;
+ if ( IsNull( pCrvLoop))
+ return false ;
+
+ bool bOutTmp = false ;
+
+ if ( ! SetBetterPtStartForSubChunks( pCrvLoop, pSrfChunk, vPtStart[l], vVtMidOut[l], bOutTmp))
+ return false ;
+ vbMidOut[l] = bOutTmp ; // vector::reference da Bit a Bool
+
+ // se richiesto, la inverto
+ if ( m_Params.m_bInvert)
+ pCrvLoop->Invert() ;
+
+ // setto la Feed per la curva di contorno
+ //AssignFeedForEdgeCleaning( pCrvLoop, vCrvOEWithFlags[j-1], nInd) ;
+
+ // inserisco la curva nel vettore
+ vAllCrv.emplace_back( Release( pCrvLoop)) ;
}
// guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag
- // e riordino le curve ( e i relativi vettori) in base alla vicinanza
+ // e le riordino le curve ( e i relativi vettori ) in base alla vicinanza
// ( piccola ottimizzazione per l'ordine dei percorsi sui bordi )
Point3d ptEnd ;
if ( vpCrvs.size() > 0)
- vpCrvs.back()->GetEndPoint( ptEnd) ;
+ vCrvInfo.back().pCrvCompo->GetEndPoint( ptEnd) ;
- if ( int( vCrvIslMergeBorders.size()) != 0 &&
- ! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut))
+ // riordino le curve
+ if ( ! OrderCurvesByLastPntOfPath( vAllCrv, ptEnd, vPtStart, vVtMidOut, vbMidOut))
return false ;
- int nOff_index = int( vpCrvs.size()) ;
- for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) {
- vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ;
- vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ;
- vCrvInfo[nOff_index + x].ptStart = vPtStart[x] ;
- vCrvInfo[nOff_index + x].bMidOut = vbMidOut[x] ;
- vCrvInfo[nOff_index + x].vtMidOut = vVtMidOut[x] ;
- vCrvInfo[nOff_index + x].nChunk = cc ;
- }
- }
- // se caso non ottimizzato
- else {
- // effettuo il primo Offset della regione e controllo quanti Chunks ottengo...
- // l'Offset contiene una quantità Extra, per stare leggermente più staccato dal bordo
- PtrOwner pSrfZigZag( CloneSurfFlatRegion( pSrfChunkFinal)) ;
- if ( ! pSrfZigZag->Offset( - dOffs - dExtra, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
- // effettuo un secondo Offset per ottenere le curve di contorno per ripulire la svuotatura a ZigZag
- // Questo offset serve per ricavare le curve che l'utensile dovrà percorrere dopo aver svuotato a ZigZag
- // Curva esterna ( non percorsa nel caso a ZigZag ottimizzato)
- // Curve interne ( le isole, queste vanno percorse anche nei casi ottimizzati)
- // Per le curve interne, questo Offset viene sempre fatto ( a prescindere dai casi ottimizzati )
- PtrOwner pSrfForCrv( CloneSurfFlatRegion( pSrfChunkFinal)) ;
- if ( ! pSrfForCrv->Offset( - dOffs, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
- if ( ! pSrfForCrv->IsValid()) {
- pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunkFinal)) ;
- if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
- }
- // Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove
- // superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e,
- // per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti.
- for ( int cfc = 0 ; cfc < pSrfForCrv->GetChunkCount() ; ++ cfc) { // scorro i chunk della superificie per i bordi
- for ( int cfz = 0 ; cfz < pSrfZigZag->GetChunkCount() ; ++ cfz) { // scorro i chunk della superificie per i percorsi ZigZag
- // e la regione è dentro al Chunk per i contorni
- if ( pSrfZigZag->GetChunkSimpleClassification( cfz, *pSrfForCrv, cfc) == REGC_IN1) {
- // svuoto il vettore delle curve ( potrebbe essere riempito dal percorso precedente
- vpCrvs.clear() ;
- // Calcolo il percorso a ZigZag
- PtrOwner pSrfZigZagChunk( pSrfZigZag->CloneChunk( cfz)) ;
- if ( ! CalcZigZag( pSrfZigZagChunk, vpCrvs))
- return false ;
- // memorizzo le curve ( per lo step successivo)
- int nIndex_offs = int( vCrvInfo.size()) ;
- vCrvInfo.resize( int( vpCrvs.size()) + nIndex_offs) ;
- for ( int x = 0 ; x < int( vpCrvs.size()) ; ++ x) {
- vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vpCrvs[x])) ;
- vCrvInfo[ nIndex_offs + x].nChunk = cc ;
- }
- }
- // se la regione non è dentro alla curva esterna allora la ignoro
- // ( la ritroverò interna ad un'altra curva per i bordi successivamante o l'ho già considerata in precedenza)
- else
- continue ;
- }
-
- // se lucidatura non aggiungo contorno
- if ( m_TParams.m_nType == TT_MILL_POLISHING)
- continue ;
-
- // Una volta percorse le curve di ZigZag devo aggiungere le curve per il bordo
- // creo un vettore con tutti i loop formati, aggiustando i loro punti iniziali
- // e portandoli nel frame della svuotatura
- ICRVCOMPOPOVECTOR vAllCrv ;
- VCT3DVECTOR vVtMidOut( pSrfForCrv->GetLoopCount( cfc)) ;
- BOOLVECTOR vbMidOut( pSrfForCrv->GetLoopCount( cfc)) ;
- PNTVECTOR vPtStart( pSrfForCrv->GetLoopCount( cfc)) ;
- for ( int l = 0 ; l < pSrfForCrv->GetLoopCount( cfc) ; ++ l) {
- PtrOwner pCrvLoop( ConvertCurveToComposite( pSrfForCrv->GetLoop( cfc, l))) ;
- if ( IsNull( pCrvLoop))
- return false ;
-
- bool bOutTmp = false ;
-
- if ( ! SetBetterPtStartForSubChunks( pCrvLoop, pSrfChunkFinal,
- vPtStart[l], vVtMidOut[l], bOutTmp))
- return false ;
- vbMidOut[l] = bOutTmp ; // vector::reference da Bit a Bool
-
- // se richiesto, la inverto
- if ( m_Params.m_bInvert)
- pCrvLoop->Invert() ;
-
- // setto la Feed per la curva di contorno
- AssignFeedForEdgeCleaning( pCrvLoop, vCrvOEWithFlags[j-1], nInd) ;
-
- // inserisco la curva nel vettore
- vAllCrv.emplace_back( Release( pCrvLoop)) ;
- }
- // guardo il punto finale in cui si trova la fresa dopo al percorso a ZigZag
- // e le riordino le curve ( e i relativi vettori ) in base alla vicinanza
- // ( piccola ottimizzazione per l'ordine dei percorsi sui bordi )
- Point3d ptEnd ;
- if ( vpCrvs.size() > 0)
- vCrvInfo.back().pCrvCompo->GetEndPoint( ptEnd) ;
-
- // riordino le curve
- if ( ! OrderCurvesByLastPntOfPath( vAllCrv, ptEnd, vPtStart, vVtMidOut, vbMidOut))
- return false ;
-
- int nIndex_offs = int( vCrvInfo.size()) ;
- vCrvInfo.resize( int( vAllCrv.size()) + nIndex_offs) ;
- for ( int x = 0 ; x < int( vAllCrv.size()) ; ++ x) {
- vCrvInfo[ nIndex_offs + x].pCrvCompo.Set( Release( vAllCrv[x])) ;
- vCrvInfo[ nIndex_offs + x].nCrvType = CRV_BORDER ;
- vCrvInfo[ nIndex_offs + x].bMidOut = vbMidOut[x] ;
- vCrvInfo[ nIndex_offs + x].ptStart = vPtStart[x] ;
- vCrvInfo[ nIndex_offs + x].vtMidOut = vVtMidOut[x] ;
- }
+ int nIndex_offs = int( vCrvInfo.size()) ;
+ vCrvInfo.resize( int( vAllCrv.size()) + nIndex_offs) ;
+ for ( int x = 0 ; x < int( vAllCrv.size()) ; ++ x) {
+ vCrvInfo[nIndex_offs + x].pCrvCompo.Set( Release( vAllCrv[x])) ;
+ vCrvInfo[nIndex_offs + x].nCrvType = CRV_BORDER ;
+ vCrvInfo[nIndex_offs + x].bMidOut = vbMidOut[x] ;
+ vCrvInfo[nIndex_offs + x].ptStart = vPtStart[x] ;
+ vCrvInfo[nIndex_offs + x].vtMidOut = vVtMidOut[x] ;
}
}
}
@@ -2930,7 +3669,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
}
}
- // Spostare dentro caso ottimizzato (?)
// se due lati chiusi consecutivi o tre lati chiusi...
else if (( nClosedSide == 2 || nClosedSide == 3) && ! bOptTwoOpposite) {
// inverto il percorso
@@ -2950,7 +3688,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
// estendo la fine del percorso
- //if ( ! ( nClosedSide == 3 && bOptTwoOpposite))
if (( nClosedSide == 2 && ! bOptTwoOpposite) || ( nClosedSide == 3 && ! bOptTwoOpposite))
pCrvCurr->ExtendEndByLen( max( m_TParams.m_dDiam / 4 - dOffsOpt, 0.0)) ;
@@ -3006,7 +3743,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
PtrOwner pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false;
- pCurve->Translate( vVtTrasl[j-1]) ;
// --- se PRIMA ENTITA' ---
if ( i == 0) {
// dati inizio entità
@@ -3151,8 +3887,6 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
PtrOwner pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false ;
- // traslo nello step richiesto
- pCurve->Translate( vVtTrasl[j-1]) ;
// --- se PRIMA ENTITA' ---
if ( i == 0) {
// dati inizio entità
@@ -3187,8 +3921,9 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
m_pMchMgr->SetLastError(2415, "Error in Pocketing : LeadIn not computable");
return false;
}
- }
- // elaborazioni sulla curva corrente
+ }
+
+ // elaborazioni sulla curva corrente
double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
@@ -3241,9 +3976,9 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
}
}
- } // fine ciclo sulle curve da disegnare
- } // fine ciclo sugli step
- } // fine ciclo sui chunk della superficie originale ( prima di operazioni con il grezzo
+ }
+ }
+ }
return true ;
}
@@ -4418,15 +5153,17 @@ Pocketing::CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB)
//----------------------------------------------------------------------------
bool
-Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr,
+Pocketing::AddOneWay( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec,
+ VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs)
{
-
// recupero distanze di sicurezza
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
+ // ricavo il numero di Step
+ int nStep = int( vSfr.size()) ;
// se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore
if ( m_TParams.m_nType == TT_MILL_NOTIP) {
@@ -4436,83 +5173,34 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
}
- // determino numero e affondamento degli step
- int nStep = 1 ;
- nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ;
- double dStep = dElev / nStep ;
-
+ // determino i paramtri per la lavorazione
double dTRad = 0.5 * m_TParams.m_dDiam ;
double dOffs = dTRad + GetOffsR() ;
double dExtra = min( 0.1 * m_TParams.m_dDiam, 1.0) ;
- // copio la regione da svuotare
- PtrOwner pSrfToPock( pSrfPock->Clone()) ;
- if ( IsNull( pSrfToPock))
- return false ;
-
- // creo le regioni ideali --------------------------------------------
- // creo un frame di riferimento della svuotatura
- Frame3d frLoc ;
- Point3d ptC ; pSrfToPock->GetCentroid( ptC) ;
- Vector3d vtN = pSrfPock->GetNormVersor() ;
- frLoc.Set( ptC, vtN) ;
- pSrfToPock->ToLoc( frLoc) ;
-
- ISURFFRPOVECTOR vSrfFlat ; // vettore delle regioni ideali
- if ( ! OptimizeChunkOneWay( pSrfToPock, vSrfFlat))
- return false ;
-
- // riporto le superifici ideali nel sistema di riferimento globale ( Ogni chunk verrà poi messo nel suo frame)
- for ( int i = 0 ; i < (int )vSrfFlat.size() ; ++ i)
- vSrfFlat[i]->ToGlob( frLoc) ;
- // ------------------------------------------------------------------
-
- // scorro le regioni ideali
- for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) {
-
- // copio la superificie ideale
- PtrOwner pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ;
- if ( IsNull( pSrfIdeal))
- return false ;
-
- // adatto la superficie alla sua geometria e al grezzo
- ISURFFRPOVECTOR vSrfSliced( nStep) ;
- vector vCrvOEWithFlags( nStep) ;
- BOOLVECTOR vbChangedPrec( nStep, false) ;
- VCT3DVECTOR vVtTrasl( nStep, V_NULL) ;
- if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfIdeal,
- nStep, vtTool, dElev, dDepth, dStep))
- return false ;
-
- Point3d ptP1 ; // per LeadIn
- for ( int j = 1 ; j <= nStep ; ++ j) { // ... per ogni step
-
- // se superificie non valida, salto allo step successivo
- if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
- vSrfSliced[j-1].Set( vSrfFlat[nIs]->Clone()) ;
- continue ;
- }
-
- // per entrate ed uscite
- PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSrfSliced[j-1])) ;
+ // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo)
+ for ( int j = 1 ; j <= nStep ; ++ j) {
+ // se superficie non valida, passo alla prossima
+ if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid())
+ continue ;
+ // ciclo sui chunk della superificie da svuotare
+ for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) {
+ // copio il chunk c-esimo
+ PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ;
+ if ( IsNull( pSrfChunk))
+ return false ;
+
+ // per entrate ed uscite
+ PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ;
if ( IsNull( pSrfLeanInOut) || pSrfLeanInOut->GetChunkCount() == 0)
return false ;
- // NB. Effettuando il primo Offset, il numero di chunk qui potrebbe cambiare...
- PtrOwner pSrfFirstOffs( CloneSurfFlatRegion( vSrfSliced[j-1])) ;
- if ( IsNull( pSrfFirstOffs) || ! pSrfFirstOffs->IsValid())
- return false ;
- if ( ! pSrfFirstOffs->Offset( - dOffs, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
-
// creo un frame di riferimento per ogni superificie da svuotare
Frame3d frLocI ;
- Point3d ptC ; pSrfToPock->GetCentroid( ptC) ;
- Vector3d vtN = pSrfToPock->GetNormVersor() ;
+ Point3d ptC ; pSrfChunk->GetCentroid( ptC) ;
+ Vector3d vtN = pSrfChunk->GetNormVersor() ;
frLocI.Set( ptC, vtN) ;
- vSrfSliced[j-1]->ToLoc( frLocI) ;
+ pSrfChunk->ToLoc( frLocI) ;
// salvo tutte le curve di Offset in un vettore per poi ordinarle e sistemare i punti iniziali
ICRVCOMPOPOVECTOR vAllCrv ;
@@ -4524,25 +5212,18 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
// regioni non svuotate ( come soluzione interseco ogni segmento di OneWay con questa superificie Offsettata di
// -dOffs e tagliando ogni segmento, lo accorcio sia all'inizio che alla fine della quantità dExtra
- // organizzo i Chunck ( MIGLIORABILE AVENDO UNA TEMP_PROP3 CHE MI DICE L'OFFSET DA QUALE CHUNK DISCENDE)
- for ( int c = 0 ; c < vSrfSliced[j-1]->GetChunkCount() ; ++ c) {
- PtrOwner pSrfChuck_c( vSrfSliced[j-1]->CloneChunk( c)) ;
- if ( IsNull( pSrfChuck_c))
- return false ;
-
- if ( ! pSrfChuck_c->Offset( - dOffs, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
-
- for ( int cc = 0 ; cc < pSrfChuck_c->GetChunkCount() ; ++ cc) {
- for ( int l = 0 ; l < pSrfChuck_c->GetLoopCount( cc) ; ++ l) {
- PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSrfChuck_c->GetLoop( cc, l))) ;
- if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid())
- return false ;
- vAllCrv.emplace_back( Release( pCrvCompoLoop)) ;
- vInd.emplace_back( c) ;
- }
+ PtrOwner pSfrBorder( pSrfChunk->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
+ if ( IsNull( pSfrBorder)) {
+ m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ return false ;
+ }
+ for ( int cc = 0 ; cc < pSfrBorder->GetChunkCount() ; ++ cc) {
+ for ( int l = 0 ; l < pSfrBorder->GetLoopCount( cc) ; ++ l) {
+ PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfrBorder->GetLoop( cc, l))) ;
+ if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid())
+ return false ;
+ vAllCrv.emplace_back( Release( pCrvCompoLoop)) ;
+ vInd.emplace_back( c) ;
}
}
@@ -4562,7 +5243,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
bool bOutTmp = false ;
// ricavo il chunk da vui deriva -> vInd
- PtrOwner pSrfCurrChunk( vSrfSliced[j-1]->CloneChunk( vInd[u])) ;
+ PtrOwner pSrfCurrChunk( vSfr[j-1]->CloneChunk( vInd[u])) ;
if ( IsNull( pSrfCurrChunk))
return false ;
// imposto un punto valido per l'entrata
@@ -4571,12 +5252,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
return false ;
vbMidOut[u] = bOutTmp ; // vector::reference da Bit a Bool
- PtrOwner pOffs( CreateCurveComposite()) ; // copio la curva ...
- if ( IsNull( pOffs) || ! pOffs->AddCurve( vAllCrv[u]->Clone())) {
- m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
- return false ;
- }
-
// riporto i valori nel sistema di riferimento corretto
vPtStart[u].ToGlob( frLocI) ;
vVtMidOut[u].ToGlob( frLocI) ;
@@ -4587,7 +5262,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
vAllCrv[u]->Invert() ;
// setto la Feed per la curva di contorno
- AssignFeedForEdgeCleaning( vAllCrv[u], vCrvOEWithFlags[j-1]) ;
+ //AssignFeedForEdgeCleaning( vAllCrv[u], vCrvOEWithFlags[j-1]) ;
// se la curva è valida per entrata da fuori, aggiungo un piccolo tratto lineare
if ( vbMidOut[u]) {
@@ -4627,7 +5302,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ;
// ---------------------------- Disegno le curve di contorno ----------------------
- for ( int u = 0 ; u < int( vAllCrv.size()) ; ++ u) { // percorro tutte le curve ( ordinate )
+ for ( int u = 0 ; u < int( vAllCrv.size()) ; ++ u) { // percorro tutte le curve ( ordinate)
// recupero la prima curva di offset disponibile
PtrOwner pOffs( CreateCurveComposite());
@@ -4638,7 +5313,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
// aggiungo la lavorazione di questa curva
Point3d ptP1 ;
- double dStElev ;
// ciclo sulle curve elementari
int nMaxInd = pOffs->GetCurveCount() - 1 ;
for ( int i = 0 ; i <= nMaxInd ; ++i) {
@@ -4648,8 +5322,6 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
PtrOwner pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false ;
- // aggiungo affondamento
- pCurve->Translate( vVtTrasl[j-1]) ;
// SE PRIMA ENTITA'
if ( i == 0) {
// dati inizio entità
@@ -4658,28 +5330,14 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
pCurve->GetStartPoint( ptStart) ;
pCurve->GetStartDir( vtStart) ;
Point3d ptForElev = ptStart ;
- if( vbMidOut[u] || vbForcedOutStart[u])
+ if ( vbMidOut[u] || vbForcedOutStart[u])
pCurve->GetEndPoint( ptForElev) ;
- // se primo step o la superificie rispetto allo step prima non è cambiata o il numero
- // di chunk è maggiore di 1, approccio e affondo
- //if ( true || j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1) {
- // determino inizio attacco
+ // determino inizio attacco
if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, nullptr, ptP1))
return false ;
// determino elevazione su inizio attacco
- //double dStElev ;
- dStElev = dSink ;
- /*if ( ! GetElevation( m_nPhase, ptForElev - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev))
- dStElev = j * dStep ;
- bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab &&
- GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- bool bUhAboveRaw = ! m_bAboveHead &&
- GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
- dStElev = max( dStElev, j * dStep) ;
- dStElev -= ( ptP1 - ptStart) * vtExtr ;*/
+ double dStElev = dSink ;
+ dStElev -= ( ptP1 - ptStart) * vtExtr ;
// se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
GetLeadInType() == POCKET_LI_HELIX ||
@@ -4687,7 +5345,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ;
dStElev = -LIO_ELEV_TOL ;
}
- // approccio al punto iniziale // false sempre ?
+ // approccio al punto iniziale
if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, vbMidOut[u] || vbForcedOutStart[u])) {
m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
return false ;
@@ -4700,7 +5358,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
}
// elaborazioni sulla curva corrente
- // elaborazioni sulla curva corrente
+ // elaborazioni sulla curva corrente
double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
@@ -4725,52 +5383,42 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
// SE ULTIMA ENTITA'
if ( i == nMaxInd) {
// se ultimo step, uscita e retrazione di collegamento
- // dati fine entità
- Point3d ptEnd ;
- pCurve->GetEndPoint( ptEnd) ;
- Vector3d vtEnd ;
- pCurve->GetEndDir( vtEnd) ;
- // aggiungo uscita
- double dEndElev = dSink ;
- /*if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev))
- dEndElev = j * dStep ;
- dEndElev = max( dEndElev, j * dStep) ;*/
- SetFeed( GetEndFeed()) ;
- if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev, false)) {
- m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
- return false ;
- }
- // aggiungo retrazione
- if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
- m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
- return false ;
- }
- // }
+ // dati fine entità
+ Point3d ptEnd ;
+ pCurve->GetEndPoint( ptEnd) ;
+ Vector3d vtEnd ;
+ pCurve->GetEndDir( vtEnd) ;
+ // aggiungo uscita
+ double dEndElev = dSink ;
+ SetFeed( GetEndFeed()) ;
+ if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev, false)) {
+ m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
+ return false ;
+ }
+ // aggiungo retrazione
+ if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
+ m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
+ return false ;
+ }
}
}
-
-
} // fine ciclo sulle curve di Offset i-esime
// ===== SEGMENTI =========
- // determino il riferimento in base alla svuotatura ( Serve per Orientare i segmenti in base al m_dSideAngle )
- Frame3d frPocket ;
- Point3d ptCen ; pSrfFirstOffs->GetCentroid( ptCen) ;
- frPocket.Set( ptCen, vtExtr) ;
- frPocket.Rotate ( ptCen, vtExtr, m_Params.m_dSideAngle) ;
- pSrfFirstOffs->ToLoc( frPocket) ;
- BBox3d b3Pocket ; pSrfFirstOffs->GetLocalBBox( b3Pocket) ;
- Point3d ptMin ; double dDimX, dDimY, dDimZ ;
+ // determino il riferimento in base alla svuotatura ( Serve per Orientare i segmenti in base al m_dSideAngle)
+ BBox3d b3Pocket ; pSfrBorder->GetLocalBBox( b3Pocket) ;
+ Point3d ptMin ;
+ double dDimX, dDimY, dDimZ ;
b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
// passi in Y
int nYStep = static_cast( ceil(( dDimY + 2 * dExtra) / GetSideStep())) ;
double dYStep = ( nYStep > 0 ? ( dDimY + 2 * dExtra) / nYStep : 0) ;
- --nYStep ;
+ -- nYStep ;
// vettore dei segmenti al di sotto della linea corrente ( per la Feed)
ICURVEPOVECTOR vLineUnder ;
- ICURVEPOVECTOR vLineAbove ; // in questo caso sempre vuoto
+ ICURVEPOVECTOR vLineAbove ; // in questo caso sempre vuoto
ICRVCOMPOPOVECTOR vCrvLink ; // in questo caso sempre vuoto
// calcolo le linee di svuotatura
@@ -4785,7 +5433,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
return false ;
}
- // linea come composita per Feed ( la dovrò spezzare)
+ // linea come composita per Feed ( la dovrò spezzare a seconda dei tratti di Feed differenti)
PtrOwner pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
@@ -4795,13 +5443,14 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
// riempio il vettore di segmenti
CRVCVECTOR ccClassSeg ;
- pSrfFirstOffs->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ;
+ pSfrBorder->GetCurveClassification( *pLine, EPS_SMALL, ccClassSeg) ;
for ( int w = 0 ; w < int( ccClassSeg.size()) ; ++w) {
if ( ccClassSeg[w].nClass == CRVC_IN) {
+ // creo la Linea tra i bordi
PtrOwner pCrvSeg( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ;
double duF, dLen ;
- // accorcio leggermente il segmento per non toccare la prima curva di Offset
+ // accorcio leggermente il segmento per non toccare la prima curva di Offset ( di dExtra)
if ( ! pCrvSeg->GetLength( dLen) ||
dLen < 2 * dExtra ||
! pCrvSeg->GetParamAtLength( dLen - dExtra, duF) ||
@@ -4809,37 +5458,27 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
! pCrvSeg->TrimEndAtParam( duF))
pCrvSeg.Set( GetCurveLine( pLine->CopyParamRange( ccClassSeg[w].dParS, ccClassSeg[w].dParE))) ;
- Point3d ptS, ptE ;
+ // punto iniziale
+ Point3d ptS ;
pCrvSeg->GetStartPoint( ptS) ;
// imposto la Feed
pCrvCompo->Clear() ;
pCrvCompo->AddCurve( pCrvSeg->Clone()) ;
vAddedLines.emplace_back( pCrvCompo->Clone()) ;
- if ( ! AssignFeedZigZagOneWay( pCrvCompo, false, vLineAbove, vLineUnder, vCrvLink))
- return false ;
+ //if ( ! AssignFeedZigZagOneWay( pCrvCompo, false, vLineAbove, vLineUnder, vCrvLink))
+ // return false ;
// INIZIO
- ptS.ToGlob( frPocket) ;
- ptS.Translate( vVtTrasl[j-1]) ;
+ ptS.ToGlob( frLocI) ;
+ //ptS.Translate( vVtTrasl[j-1]) ;
// determino inizio attacco
Point3d ptP ;
- if ( ! CalcLeadInStart( ptS, frPocket.VersX(), vtExtr, nullptr, ptP))
+ if ( ! CalcLeadInStart( ptS, frLocI.VersX(), vtExtr, nullptr, ptP))
return false ;
// determino elevazione su inizio attacco
double dStElev = dSink ;
- /*double dStElev ;
- if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev))
- dStElev = j * dStep ;
- bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab &&
- GetAhPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- bool bUhAboveRaw = ! m_bAboveHead &&
- GetUhPointAboveRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- if( bAhUnderRaw || bUhAboveRaw || ( i == 1 && w == 1))
- dStElev = max( dStElev, j * dStep) ;
- dStElev -= ( ptP - ptS) * vtExtr ;*/
+ dStElev -= ( ptP - ptS) * vtExtr ;
// sempre approccio di collegamento
if ( ! AddLinkApproach( ptP, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr)) {
m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
@@ -4847,17 +5486,21 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
// aggiungo attacco (forzato ad essere lineare)
SetFeed( GetStartFeed()) ;
- if ( ! AddLeadIn( ptP, ptS, frPocket.VersX(), vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs, true)) {
+ if ( ! AddLeadIn( ptP, ptS, frLocI.VersX(), vtExtr, pSrfLeanInOut, nullptr, !m_Params.m_bInvert, bSplitArcs, true)) {
m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
return false ;
}
- for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
+ // punto finale
+ Point3d ptE ;
+ // per ogni sotto-tratto ( della feed) del tratto lineare ( per ora sempre 1)
+ for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
+ // ricavo la singola entità curva
const ICurve* pCurve( pCrvCompo->GetCurve( u)) ;
pCurve->GetEndPoint( ptE) ;
- ptE.ToGlob( frPocket) ;
- ptE.Translate( vVtTrasl[j-1]) ;
+ ptE.ToGlob( frLocI) ;
+ //ptE.Translate( vVtTrasl[j-1]) ;
// movimento al punto finale
// elaborazioni sulla curva corrente
@@ -4867,22 +5510,17 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
SetFeed( dFeed) ;
if ( AddLinearMove( ptE) == GDB_ID_NULL)
return false ;
-
}
// FINE
Point3d ptQ ;
- //double dEndElev = dElev ;
double dEndElev = dSink ;
- /*if ( ! GetElevation( m_nPhase, ptE - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev))
- dEndElev = j * dStep ;
- dEndElev = max( dEndElev, j * dStep) ;*/
SetFeed( GetEndFeed()) ;
- if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, true, ptQ, dEndElev)) {
+ if ( ! AddLeadOut( ptE, frLocI.VersX(), vtExtr, nullptr, bSplitArcs, true, ptQ, dEndElev)) {
m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
return false ;
}
-
+ dEndElev -= ( ptE - ptQ) * vtExtr ;
// se ultimo movimento di ultima area, aggiungo retrazione globale
if ( j == nStep && i == nYStep && w == ( int)ccClassSeg.size() - 2) {
if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
@@ -4892,6 +5530,7 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
// altrimenti aggiungo retrazione di collegamento
else {
+ dEndElev = dSink ;
if ( ! AddLinkRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
return false ;
@@ -4903,8 +5542,8 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
for ( int u = 0 ; u < ( int)vAddedLines.size() ; ++ u)
vLineUnder.emplace_back( vAddedLines[u]->Clone()) ;
}
- } // fine ciclo sugli step
- } // fine ciclo sulle superifici ideali
+ }
+ }
return true ;
}
@@ -4912,63 +5551,40 @@ Pocketing::AddOneWay( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
//----------------------------------------------------------------------------
bool
-Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr,
+Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& vCrvOrig, BOOLVECTOR& vbChangedPrec,
+ VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs)
{
-
// recupero distanze di sicurezza
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
+ // ricavo il numero di Step
+ int nStep = int( vSfr.size()) ;
- // determino numero e affondamento degli step
- int nStep = 1 ;
- nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ;
- double dStep = dElev / nStep ;
-
- // ciclo sui chunk della superificie da svuotare
- for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) {
-
- // copio il chunk c-esimo
- PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ;
- if ( IsNull( pSrfChunk))
- return false ;
-
-
- // modifico le superifici in base alla geometria del grezzo e alla geometria dell'entità selezionata
- ISURFFRPOVECTOR vSrfSliced( nStep) ;
- vector vCrvOEWithFlags( nStep) ;
- BOOLVECTOR vbChangedPrec( nStep, false) ;
- VCT3DVECTOR vVtTrasl( nStep, V_NULL) ;
- if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk,
- nStep, vtTool, dElev, dDepth, dStep))
- return false ;
-
- Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
- BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
- ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
- ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
- vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente
- INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
- BOOLVECTOR vbOptTrap_prec ; // flags per caso ottimizzato svuotratura dello step precedente
- int nOffs_act = 0 ; // Shift indice dei vettori causato da nReg
-
- // ciclo su tutti gli step
- for ( int j = 1 ; j <= nStep ; ++ j) {
-
- // se superificie non valida, salto allo step successivo
- if ( IsNull( vSrfSliced[j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
- vSrfSliced[j-1].Set( pSrfChunk->Clone()) ;
- continue ;
- }
-
- // la superificie che lavoro è quella ottenuta in precedenza allo step j-esimo
- PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j-1])) ;
- if ( IsNull( pSrfFinal))
+ // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo)
+ for ( int j = 1 ; j <= nStep ; ++ j) {
+ // se superficie non valida, passo alla prossima
+ if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid())
+ continue ;
+ // ciclo sui chunk della superificie da svuotare
+ for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) {
+ // copio il chunk c-esimo
+ PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ;
+ if ( IsNull( pSrfChunk))
return false ;
- nOffs_act = 0 ; // reset indice dei vettori per step precedenti
+ Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
+ BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
+ ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
+ ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
+ vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente
+ INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
+ BOOLVECTOR vbOptTrap_prec ; // flags per caso ottimizzato svuotratura dello step precedente
+ int nOffs_act = 0 ; // Shift indice dei vettori causato da nReg
+ nOffs_act = 0 ; // reset indice dei vettori per step precedenti
+
if ( vbChangedPrec[j-1]) {
// se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente
vMCrv_step_prec.clear() ;
@@ -4979,310 +5595,302 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
vbOptTrap_prec.clear() ;
}
- for ( int cc = 0 ; cc < pSrfFinal->GetChunkCount() ; ++cc) { // per ogni suo chunk cc-esimo...
- // il numero di chunk dopo aver intersecato e proiettato può cambiare
+ const int MAX_REGS = 50 ;
+ int nReg = 0 ; // chunk nuovo corrente da svuotare
- // essendo una svuotatura a spirale, facendo il primo offset del chunk cc-esimo potrei ottenere
- // ulteriori chunks ( ad esempio se la superificie presenta delle parti molto strette)
- // MAX_REGS = 50 -> numero massimo di Chunks nuovi accettati
- const int MAX_REGS = 50 ;
- int nReg = 0 ; // chunk nuovo corrente da svuotare
+ // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo
+ while ( nReg < MAX_REGS) {
- PtrOwner pSrfChunkFinal( pSrfFinal->CloneChunk( cc)) ;
+ // superifice per ingressi ed uscite
+ PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ;
+ if ( IsNull( pSrfLeanInOut))
+ return false ;
- // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo
- while ( nReg < MAX_REGS) {
-
- // superifice per ingressi ed uscite
- PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunkFinal)) ;
- if ( IsNull( pSrfLeanInOut))
+ // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine
+ PtrOwner pMCrv( CreateCurveComposite()) ; // percorso di svuotatura
+ PtrOwner pRCrv( CreateCurveComposite()) ; // percorso di ritorno
+ if ( IsNull( pMCrv) || IsNull( pRCrv)) {
+ m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
+ return false ;
+ }
+
+ int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
+ bool bOutStart ; // flag per entrata da fuori per lo step attuale
+ bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
+
+ Point3d ptStart ; // punto iniziale del percorso
+ Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral)
+ bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step)
+
+ bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio
+
+ // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
+ // ( non c'è bisogno di ricalcolare tutti i percorsi)
+ if ( ! vbChangedPrec[j-1] && j != 1) {
+ if ( nOffs_act > int( vMCrv_step_prec.size()) - 1)
+ break ;
+ pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
+ pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
+ nRegTot = vnRegTot_prec[nOffs_act] ;
+ bMidOut = vbMidOutPrec[nOffs_act] ;
+ vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ;
+ vtMidOut = vvtMidOutPrec[nOffs_act] ;
+ bOptimizedTrap = vbOptTrap_prec[nOffs_act] ;
+ }
+ else {
+ // se lucidatura con epicicli
+ if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
+ // verifico che i parametri lucidatura siano sensati
+ if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
+ m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ return false ;
+ }
+ // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli
+ m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
+ }
+
+ // cerco la curva originale del chunk cc-esimo ( per casi ottimizzati)
+ int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
+ if ( ! GetOptCrvIndex( vCrvOrig, j, pSrfChunk, nInd))
return false ;
- // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine
- PtrOwner pMCrv( CreateCurveComposite()) ; // percorso di svuotatura
- PtrOwner pRCrv( CreateCurveComposite()) ; // percorso di ritorno
- if ( IsNull( pMCrv) || IsNull( pRCrv)) {
- m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
+ nRegTot = nReg ;
+ // calcolo il percorso di svuotatura
+ if ( ! CalcSpiral( pSrfChunk, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
+ vCrvOrig[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1], bOptimizedTrap))
+ return false ;
+
+ // se terminate le regioni, esco
+ if ( pMCrv->GetCurveCount() == 0)
+ break ; // passo al chunk originale successivo
+
+ if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
+ // riporto il diametro dell'utensile al valore originale
+ m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
+ // aggiorno i percorsi di svuotatura con epicicli
+ if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
+ m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ return false ;
+ }
+ }
+
+ // memorizzo le curve create e modificate per lo step successivo
+ vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
+ vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
+ // memorizzo i Flag per le entrate
+ vbMidOutPrec.push_back( bMidOut) ;
+ // memorizzo il numero delle regioni create dal primo Offset
+ vnRegTot_prec.push_back( nRegTot) ;
+ // memorizzo il versore di uscita calcolato
+ vvtMidOutPrec.push_back( vtMidOut) ;
+ // memorizzo caso ottimizzato
+ vbOptTrap_prec.push_back( bOptimizedTrap) ;
+ }
+
+ // controlli per entrate da fuori al grezzo
+ // NB. Anche se la superficie è rimasta invariata le entrate vanno controllate caso per caso
+ bOutStart = bMidOut ;
+ if ( bOutStart && ! bOptimizedTrap) {
+ // calcolo il punto fuori per il LeadIn
+ Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + max( dSafeZ, m_dOpenMinSafe)) ;
+ ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente
+ double dStElev ;
+ // controllo l'elevazione
+ bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ;
+ if ( bOutStart || m_bOpenOutRaw) {
+ // aggiungo al ritorno l'uscita
+ if ( pRCrv->GetCurveCount() == 0) {
+ Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ;
+ pRCrv->AddPoint( ptStart) ;
+ }
+ ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva
+ // aggiungo un tratto lineare all'inizio del percorso di svuotatura
+ pMCrv->AddLine( ptOut, false) ;
+ // assegno la sua Feed
+ //AssignFeedForLineInOut( pMCrv, true) ;
+ // aggiungo un tratto lineare alla fine del percorso di svuotatura
+ pRCrv->AddLine( ptOut, true) ;
+ // assegno la sua Feed
+ //AssignFeedForLineInOut( pRCrv, false) ;
+ }
+ }
+
+ // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato
+ int nOutsideRaw = 0 ;
+ if ( bOptimizedTrap) {
+ AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
+ bOutStart = ( nOutsideRaw > 0) ;
+ // imposto la Feed
+ //AssignFeedSpiralOpt( 1, pMCrv) ;
+ //AssignFeedForReturnPath( pRCrv) ;
+ }
+
+ // verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro
+ bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ;
+
+ // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
+ if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) {
+ if ( ! LeadInRawIsOk()) {
+ m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
return false ;
}
+ }
+
+ // se sono nel caso ottimizzato per Trapezi e ho attacco e uscita entrambi dentro/fuori dal grezzo,
+ // ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva
+ // non è cambiata
+ if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSfr[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1]
+ && ( j % 2 == 0))
+ pMCrv->Invert() ;
- int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
- bool bOutStart ; // flag per entrata da fuori per lo step attuale
- bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
+ ++nReg ; // incremento del numero di regioni trovate
+ ++ nOffs_act ; // shift indice
- Point3d ptStart ; // punto iniziale del percorso
- Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral)
- bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step)
+ int nMaxInd = pMCrv->GetCurveCount() - 1 ;
+ int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
- bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio
+ // determino l'affondamento attuale
+ double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ;
- // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
- // ( non c'è bisogno di ricalcolare tutti i percorsi)
- if ( ! vbChangedPrec[j-1] && j != 1) {
- if ( nOffs_act > int( vMCrv_step_prec.size()) - 1)
- break ;
- pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
- pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
- nRegTot = vnRegTot_prec[nOffs_act] ;
- bMidOut = vbMidOutPrec[nOffs_act] ;
- vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ;
- vtMidOut = vvtMidOutPrec[nOffs_act] ;
- bOptimizedTrap = vbOptTrap_prec[nOffs_act] ;
- }
- else {
- // se lucidatura con epicicli
- if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
- // verifico che i parametri lucidatura siano sensati
- if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
- m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ // ciclo sulle curve elementari
+ for ( int i = 0 ; i <= nMaxInd ; ++ i) {
+ // curva corrente
+ const ICurve* pCrvC = pMCrv->GetCurve( i) ;
+ // copio la curva
+ PtrOwner pCurve( pCrvC->Clone()) ;
+ if ( IsNull( pCurve))
+ return false ;
+ // aggiungo affondamento
+ //pCurve->Translate( vVtTrasl[j-1]) ;
+ // se prima entità
+ if ( i == 0) {
+ // dati inizio entità
+ Point3d ptStart ;
+ pCurve->GetStartPoint( ptStart) ;
+ Vector3d vtStart ;
+ pCurve->GetStartDir( vtStart) ;
+ // Entrata ...
+ if ( j == 1 || vbChangedPrec[j-1] || vSfr[j-2]->GetChunkCount() > 1 || nRegTot > 1) {
+ // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando :
+ // 1) sono nel primo Step o ...
+ // 2) la superificie è diversa da quello dello step precedente o ...
+ // 3) il numero di chunk allo step precedente è maggiore di 1 o ...
+ // 4) dal primo offset del chunk cc-esimo ottengo più regioni
+
+ if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) {
+ m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
return false ;
}
- // modifico il diametro dell'utensile per tenere conto anche del diametro degli epicicli
- m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
- }
- // cerco la curva originale del chunk cc-esimo ( per casi ottimizzati)
- int nInd = 0 ; // indice del vettore delle curve esterne relativo al chunk cc-esimo
- if ( ! GetOptCrvIndex( vCrvOEWithFlags, j, pSrfChunkFinal, nInd))
- return false ;
-
- // ------------------------------------------------------------------------------------
- nRegTot = nReg ;
- // calcolo il percorso di svuotatura
- if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
- vCrvOEWithFlags[j-1][nInd], j == 1 ? true : vbChangedPrec[j-1],
- bOptimizedTrap))
- return false ;
-
- // se terminate le regioni, esco
- if ( pMCrv->GetCurveCount() == 0)
- break ; // passo al chunk originale successivo
-
- if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
- // riporto il diametro dell'utensile al valore originale
- m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
- // aggiorno i percorsi di svuotatura con epicicli
- if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
- m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ // determino elevazione su inizio attacco
+ double dStElev = dSink ;
+ dStElev -= ( ptP1 - ptStart) * vtExtr ;
+ // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
+ if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
+ GetLeadInType() == POCKET_LI_HELIX ||
+ GetLeadInType() == POCKET_LI_GLIDE) {
+ ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ;
+ dStElev = -LIO_ELEV_TOL ;
+ }
+ // approccio al punto iniziale
+ if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) {
+ m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
+ return false ;
+ }
+ // aggiungo attacco
+ SetFeed( GetStartFeed()) ;
+ if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) {
+ m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
return false ;
}
}
-
- // memorizzo le curve create e modificate per lo step successivo
- vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
- vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
- // memorizzo i Flag per le entrate
- vbMidOutPrec.push_back( bMidOut) ;
- // memorizzo il numero delle regioni create dal primo Offset
- vnRegTot_prec.push_back( nRegTot) ;
- // memorizzo il versore di uscita calcolato
- vvtMidOutPrec.push_back( vtMidOut) ;
- // memorizzo caso ottimizzato
- vbOptTrap_prec.push_back( bOptimizedTrap) ;
- }
-
- // controlli per entrate da fuori al grezzo
- // NB. Anche se la superficie è rimasta invariata le entrate vanno controllate caso per caso
- bOutStart = bMidOut ;
- if ( bOutStart && ! bOptimizedTrap) {
- // calcolo il punto fuori per il LeadIn
- Point3d ptOut = ptStart + vtMidOut * ( 0.5 * m_TParams.m_dDiam + max( dSafeZ, m_dOpenMinSafe)) ;
- ptOut.Translate( vVtTrasl[j-1]) ; // lo traslo allo step corrente
- double dStElev ;
- // controllo l'elevazione
- bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ;
- if ( bOutStart || m_bOpenOutRaw) {
- // aggiungo al ritorno l'uscita
- if ( pRCrv->GetCurveCount() == 0) {
- Point3d ptStart ; pMCrv->GetStartPoint( ptStart) ;
- pRCrv->AddPoint( ptStart) ;
- }
- ptOut.Translate( -vVtTrasl[j-1]) ; // lo ritraslo sulla curva
- // aggiungo un tratto lineare all'inizio del percorso di svuotatura
- pMCrv->AddLine( ptOut, false) ;
- // assegno la sua Feed
- AssignFeedForLineInOut( pMCrv, true) ;
- // aggiungo un tratto lineare alla fine del percorso di svuotatura
- pRCrv->AddLine( ptOut, true) ;
- // assegno la sua Feed
- AssignFeedForLineInOut( pRCrv, false) ;
- }
- }
-
- // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato
- int nOutsideRaw = 0 ;
- if ( bOptimizedTrap) {
- AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
- bOutStart = ( nOutsideRaw > 0) ;
- // imposto la Feed
- AssignFeedSpiralOpt( 1, pMCrv) ;
- AssignFeedForReturnPath( pRCrv) ;
- }
-
- // verifico se l'ingresso è da considerare fuori dal grezzo anche se dentro
- bForcedOutStart = ( bMidOut && m_bOpenOutRaw) ;
-
- // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
- if ( m_TParams.m_nType == TT_MILL_NOTIP && ! ( bOutStart || bForcedOutStart)) {
- if ( ! LeadInRawIsOk()) {
- m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
- return false ;
- }
- }
-
- // se sono nel caso ottimizzato per Trapezi e ho attacco e uscita entrambi dentro/fuori dal grezzo,
- // ad ogni step pari inverto la direzione della curva solamente se ho un solo chunk e la superificie successiva
- // non è cambiata
- if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1 && vSrfSliced[j-2]->GetChunkCount() == 1 && ! vbChangedPrec[j-1]
- && ( j % 2 == 0))
- pMCrv->Invert() ;
-
- ++nReg ; // incremento del numero di regioni trovate
- ++ nOffs_act ; // shift indice
- int nMaxInd = pMCrv->GetCurveCount() - 1 ;
- int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
-
- // determino l'affondamento attuale
- double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ;
-
- // ciclo sulle curve elementari
- for ( int i = 0 ; i <= nMaxInd ; ++ i) {
- // curva corrente
- const ICurve* pCrvC = pMCrv->GetCurve( i) ;
- // copio la curva
- PtrOwner pCurve( pCrvC->Clone()) ;
- if ( IsNull( pCurve))
- return false ;
- // aggiungo affondamento
- pCurve->Translate( vVtTrasl[j-1]) ;
- // se prima entità
- if ( i == 0) {
- // dati inizio entità
- Point3d ptStart ;
- pCurve->GetStartPoint( ptStart) ;
- Vector3d vtStart ;
- pCurve->GetStartDir( vtStart) ;
- // Entrata ...
- if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegTot > 1) {
- // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando :
- // 1) sono nel primo Step o ...
- // 2) la superificie è diversa da quello dello step precedente o ...
- // 3) il numero di chunk allo step precedente è maggiore di 1 o ...
- // 4) dal primo offset del chunk cc-esimo ottengo più regioni
-
- if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1))
- return false ;
-
- // determino elevazione su inizio attacco
- double dStElev = dSink ;
- dStElev -= ( ptP1 - ptStart) * vtExtr ;
- // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
- if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
- GetLeadInType() == POCKET_LI_HELIX ||
- GetLeadInType() == POCKET_LI_GLIDE) {
- ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ;
- dStElev = -LIO_ELEV_TOL ;
- }
- // approccio al punto iniziale
- if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart || bForcedOutStart)) {
- m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
- return false ;
- }
- // aggiungo attacco
- SetFeed( GetStartFeed()) ;
- if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) {
- m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
- return false ;
- }
- }
- // altrimenti solo collegamento
- else {
- SetFeed( GetStartFeed()) ;
- GetCurrPos( ptP1) ;
- if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) {
- m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
- return false ;
- }
- }
- }
- // elaborazioni sulla curva corrente
- double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
- double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
- GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
- // DrawColoredCrvForFeedTest( pCurve, dFeed) ;
- SetFeed( dFeed) ; // <---
- if ( pCurve->GetType() == CRV_LINE) {
- ICurveLine* pLine = GetCurveLine( pCurve) ;
- Point3d ptP3 = pLine->GetEnd() ;
- // SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; // <----
- if ( AddLinearMove( ptP3) == GDB_ID_NULL)
+ // altrimenti solo collegamento
+ else {
+ SetFeed( GetStartFeed()) ;
+ GetCurrPos( ptP1) ;
+ if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, !m_Params.m_bInvert, bSplitArcs, bOutStart || bForcedOutStart)) {
+ m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
return false ;
+ }
}
- else if ( pCurve->GetType() == CRV_ARC) {
- ICurveArc* pArc = GetCurveArc( pCurve) ;
- Point3d ptCen = pArc->GetCenter() ;
- double dAngCen = pArc->GetAngCenter() ;
- Vector3d vtN = pArc->GetNormVersor() ;
- Point3d ptP3 ;
- pArc->GetEndPoint( ptP3) ;
- //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ;
- if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
- return false ;
- }
- // se ultima entità -> passo al chunk cc successivo o allo step sotto
- if ( i == nMaxInd) {
- // Uscita ...
- if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && ! vbChangedPrec[j] && nRegTot == 1) {
- // Effettuo l'uscita quando :
- // 1) non sono nello step intermedio e ...
- // 2) il numero di Chunk allo step attuale è 1 e ...
- // 3) la superificie non è cambiata dalla precedente e ...
- // 4) dal primo offset del chunk cc-esimo non si sono create altre regioni da svuotare
+ }
+ // elaborazioni sulla curva corrente
+ double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
+ double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
+ GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
+ // DrawColoredCrvForFeedTest( pCurve, dFeed) ;
+ SetFeed( dFeed) ; // <---
+ if ( pCurve->GetType() == CRV_LINE) {
+ ICurveLine* pLine = GetCurveLine( pCurve) ;
+ Point3d ptP3 = pLine->GetEnd() ;
+ // SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ; // <----
+ if ( AddLinearMove( ptP3) == GDB_ID_NULL)
+ return false ;
+ }
+ else if ( pCurve->GetType() == CRV_ARC) {
+ ICurveArc* pArc = GetCurveArc( pCurve) ;
+ Point3d ptCen = pArc->GetCenter() ;
+ double dAngCen = pArc->GetAngCenter() ;
+ Vector3d vtN = pArc->GetNormVersor() ;
+ Point3d ptP3 ;
+ pArc->GetEndPoint( ptP3) ;
+ //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ;
+ if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
+ return false ;
+ }
+ // se ultima entità -> passo al chunk cc successivo o allo step sotto
+ if ( i == nMaxInd) {
+ // Uscita ...
+ if ( j < nStep && vSfr[j-1]->GetChunkCount() == 1 && ! vbChangedPrec[j] && nRegTot == 1) {
+ // Effettuo l'uscita quando :
+ // 1) non sono nello step intermedio e ...
+ // 2) il numero di Chunk allo step attuale è 1 e ...
+ // 3) la superificie non è cambiata dalla precedente e ...
+ // 4) dal primo offset del chunk cc-esimo non si sono create altre regioni da svuotare
- // se necessario ritorno all'inizio
- if ( nMaxRInd >= 0) {
- // copio la curva di ritorno
- PtrOwner pRet( pRCrv->Clone()) ;
- if ( IsNull( pRet))
- return false ;
- // aggiungo affondamento
- pRet->Translate( vVtTrasl[j-1]) ;
- // se attacco a scivolo, accorcio della lunghezza dell'attacco
- if ( GetLeadInType() == POCKET_LI_GLIDE) {
- double dLen ; pRet->GetLength( dLen) ;
- if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) {
- if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang))
- pRet->Clear() ;
- }
- else
+ // se necessario ritorno all'inizio
+ if ( nMaxRInd >= 0) {
+ // copio la curva di ritorno
+ PtrOwner pRet( pRCrv->Clone()) ;
+ if ( IsNull( pRet))
+ return false ;
+ // aggiungo affondamento
+ pRet->Translate( vVtTrasl[j-1]) ;
+ // se attacco a scivolo, accorcio della lunghezza dell'attacco
+ if ( GetLeadInType() == POCKET_LI_GLIDE) {
+ double dLen ; pRet->GetLength( dLen) ;
+ if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL) {
+ if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang))
pRet->Clear() ;
}
- // emetto
- SetFeed( GetFeed()) ;
- if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL)
- return false ;
+ else
+ pRet->Clear() ;
}
+ // emetto
+ SetFeed( GetFeed()) ;
+ if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL)
+ return false ;
}
- // atrimenti ultimo step, uscita e retrazione
- else {
- // dati fine entità
- Point3d ptEnd ;
- pCurve->GetEndPoint( ptEnd) ;
- Vector3d vtEnd ;
- pCurve->GetEndDir( vtEnd) ;
- // aggiungo uscita
- Point3d ptP1 ;
- double dEndElev = dSink ;
- SetFeed( GetEndFeed()) ;
- if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptP1, dEndElev, true)) {
- m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
- return false ;
- }
- // aggiungo retrazione
- if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
- m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ;
- return false ;
- }
+ }
+ // atrimenti ultimo step, uscita e retrazione
+ else {
+ // dati fine entità
+ Point3d ptEnd ;
+ pCurve->GetEndPoint( ptEnd) ;
+ Vector3d vtEnd ;
+ pCurve->GetEndDir( vtEnd) ;
+ // aggiungo uscita
+ Point3d ptP1 ;
+ double dEndElev = dSink ;
+ SetFeed( GetEndFeed()) ;
+ if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptP1, dEndElev, true)) {
+ m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
+ return false ;
+ }
+ // aggiungo retrazione
+ if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
+ m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ;
+ return false ;
}
}
}
@@ -5296,7 +5904,8 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
//----------------------------------------------------------------------------
bool
-Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, const Vector3d& vtExtr,
+Pocketing::AddSpiralOut( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec,
+ VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs)
{
// recupero distanze di sicurezza
@@ -5304,53 +5913,30 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
+ // ricavo il numero di Step
+ int nStep = int( vSfr.size()) ;
- // determino numero e affondamento degli step
- int nStep = 1 ;
- nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ;
- double dStep = dElev / nStep ;
-
- // ciclo sui chunk della superificie da svuotare
- for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) {
-
- // copio il chunk c-esimo
- PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ;
- if ( IsNull( pSrfChunk))
- return false ;
-
- // modifico le superifici in base alla geometria del grezzo e alla geometria dell'entità selezionata
- ISURFFRPOVECTOR vSrfSliced( nStep) ;
- vector vCrvOEWithFlags( nStep) ;
- BOOLVECTOR vbChangedPrec( nStep, false) ;
- VCT3DVECTOR vVtTrasl( nStep, V_NULL) ;
- if ( ! GetParamsAtEachStep( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, pSrfChunk,
- nStep, vtTool, dElev, dDepth, dStep))
- return false ;
-
- Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
- bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo
- BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
- ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
- ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
- vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente
- INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
- int nOffs_act = 0 ;
-
- // ciclo su tutti gli step
- for ( int j = 1 ; j <= nStep ; ++ j) {
-
- // se superificie non valida, salto allo step successivo
- if ( IsNull( vSrfSliced[ j-1]) || vSrfSliced[j-1]->GetChunkCount() == 0) {
- vSrfSliced[j-1].Set( pSrfChunk->Clone()) ;
- continue ;
- }
-
- // la superificie che lavoro è quella ottenuta in precedenza allo step j-esimo
- PtrOwner pSrfFinal( CloneSurfFlatRegion( vSrfSliced[j - 1])) ;
- if( IsNull( pSrfFinal))
+ // scorro il vettore delle FlatRegion ( calcolate per ogni step j-esimo)
+ for ( int j = 1 ; j <= nStep ; ++ j) {
+ // se superficie non valida, passo alla prossima
+ if ( IsNull( vSfr[j-1]) || ! vSfr[j-1]->IsValid())
+ continue ;
+ // ciclo sui chunk della superificie da svuotare
+ for ( int c = 0 ; c < vSfr[j-1]->GetChunkCount() ; ++ c) {
+ // copio il chunk c-esimo
+ PtrOwner pSrfChunk( GetSurfFlatRegion( vSfr[j-1]->CloneChunk( c))) ;
+ if ( IsNull( pSrfChunk))
return false ;
- nOffs_act = 0 ; // reset indice dei vettori per step precedenti
+ Point3d ptP1, ptStartPrec ; // per LeadIn attuale e precedente
+ bool bMidOutPrec ; // flag per entrata precedente da fuori dal grezzo
+ BOOLVECTOR vbMidOutPrec ; // flags per effettiva entrata precedente da fuori dal grezzo
+ ICRVCOMPOPOVECTOR vMCrv_step_prec ; // vettore delle curve dei percorsidi svuotatura dello step precedente
+ ICRVCOMPOPOVECTOR vRCrv_step_prec ; // vettore delle curve dei percorsi di ritorno dello step precedente
+ vector vvtMidOutPrec ; // vettore dei versori delle direzioni di uscita dello step precedente
+ INTVECTOR vnRegTot_prec ; // vettore dei numeri delle regioni formate dal primo Offset nello step precedente
+ int nOffs_act = 0 ;
+
if ( vbChangedPrec[j-1]) {
// se lo step attuale è cambiato rispetto al precedente -> Flush info step precedente
vMCrv_step_prec.clear() ;
@@ -5360,278 +5946,271 @@ Pocketing::AddSpiralOut( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool
vvtMidOutPrec.clear() ;
}
- for ( int cc = 0 ; cc < ( int)pSrfFinal->GetChunkCount() ; ++ cc) { // per ogni suo chunk cc-esimo...
+ const int MAX_REGS = 50 ;
+ int nReg = 0 ; // chunk nuovo corrente da svuotare
- const int MAX_REGS = 50 ;
- int nReg = 0 ;
+ // ciclo su tutte le regioni che posso ottenere col primo Offset del chunk cc-esimo
+ while ( nReg < MAX_REGS) {
- PtrOwner pSrfChunkFinal(( pSrfFinal->CloneChunk( cc))) ;
+ // superificie per ingressi ed uscite
+ PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( vSfr[j-1])) ;
+ if( IsNull( pSrfLeanInOut))
+ return false ;
+
+ // calcolo la spirale dall'interno all'esterno
+ PtrOwner pMCrv( CreateCurveComposite()) ;
+ PtrOwner pRCrv( CreateCurveComposite()) ;
+ if ( IsNull( pMCrv) || IsNull( pRCrv)) {
+ m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
+ return false ;
+ }
- while ( nReg < MAX_REGS) {
-
- // superificie per ingressi ed uscite
- PtrOwner pSrfLeanInOut( CloneSurfFlatRegion( pSrfChunkFinal)) ;
- if( IsNull( pSrfLeanInOut))
+ int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
+ bool bOutStart ; // flag per entrata da fuori per lo step attuale
+ bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
+
+ Point3d ptStart ; // punto iniziale del percorso
+ Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral)
+ bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step)
+
+ bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio
+
+ // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
+ // ( non c'è bisogno di ricalcolare tutti i percorsi)
+ if ( ! vbChangedPrec[j-1] && j != 1) {
+ if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1)
+ break ;
+ pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
+ pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
+ nRegTot = vnRegTot_prec[nOffs_act] ;
+ bMidOut = vbMidOutPrec[nOffs_act] ;
+ vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ;
+ vtMidOut = vvtMidOutPrec[nOffs_act] ;
+ }
+ else {
+ // se lucidatura con epicicli
+ if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
+ // verifico che parametri lucidatura siano sensati
+ if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
+ m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ return false ;
+ }
+ // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli
+ m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
+ }
+
+ bool bOptimizedTrap = false ;
+
+ int nInd = 0 ;
+ if ( ! GetOptCrvIndex( vCrvOrig, j, pSrfChunk, nInd))
+ return false ;
+
+ nRegTot = nReg ;
+
+ if ( ! CalcSpiral( pSrfChunk, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
+ vCrvOrig[j-1][nInd], vbChangedPrec[j-1], bOptimizedTrap))
+ return false ;
+
+ // se terminate le regioni, esco
+ if ( pMCrv->GetCurveCount() == 0)
+ break ;
+
+ if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
+ // riporto il diametro dell'utensile al valore originale
+ m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
+ // aggiorno i percorsi di svuotatura con epicicli
+ if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
+ m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ return false ;
+ }
+ }
+
+ // memorizzo le curve create e modificate per lo step successivo
+ vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
+ vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
+ // memorizzo i Flag per le entrate
+ vbMidOutPrec.push_back( bMidOut) ;
+ // memorizzo il numero delle regioni create dal primo Offset
+ vnRegTot_prec.push_back( nRegTot) ;
+ // memorizzo il versore di uscita calcolato
+ vvtMidOutPrec.push_back( vtMidOut) ;
+ }
+
+ // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo
+ bOutStart = false ;
+ int nOutsideRaw = 0 ;
+ if ( bOptimizedTrap) {
+ AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
+ bOutStart = ( nOutsideRaw > 0) ;
+ AssignFeedSpiralOpt( 1, pMCrv) ;
+ AssignFeedForReturnPath( pRCrv) ;
+ }
+
+ // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
+ if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) {
+ if ( ! LeadInRawIsOk()) {
+ m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
+ return false ;
+ }
+ }
+
+ // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato)
+ if ( ! bOptimizedTrap) {
+ pMCrv->Invert() ;
+ pRCrv->Invert() ;
+ }
+
+ // inversione per caso ottimizzato
+ if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1)
+ pMCrv->Invert() ;
+
+ ++ nReg ;
+ ++ nOffs_act ;
+ int nMaxInd = pMCrv->GetCurveCount() - 1 ;
+ int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
+
+ // determino l'affondamento attuale
+ double dSink = dElev - dDepth + dMaxElev - vVtTrasl[j-1].Len() ;
+
+ // ciclo sulle curve elementari
+ for ( int i = 0 ; i <= nMaxInd ; ++ i) {
+ // curva corrente
+ const ICurve* pCrvC = pMCrv->GetCurve( i) ;
+ // copio la curva
+ PtrOwner pCurve( pCrvC->Clone()) ;
+ if ( IsNull( pCurve))
return false ;
-
- // calcolo la spirale dall'interno all'esterno
- PtrOwner pMCrv( CreateCurveComposite()) ;
- PtrOwner pRCrv( CreateCurveComposite()) ;
- if ( IsNull( pMCrv) || IsNull( pRCrv)) {
- m_pMchMgr->SetLastError( 2411, "Error in Pocketing : toolpath allocation failed") ;
- return false ;
- }
-
- int nRegTot ; // numero di regioni create dal primo Offset per lo step attuale
- bool bOutStart ; // flag per entrata da fuori per lo step attuale
- bool bForcedOutStart ; // flag per forzare l'entrata da fuori allo step attuale
-
- Point3d ptStart ; // punto iniziale del percorso
- Vector3d vtMidOut ; // vettore verso l'esterno nel caso di entrata da fuori ammissibile ( -> da CalcSpiral)
- bool bMidOut ; // ammissibilità entrata da fuori ( da calcolare step per step)
-
- bool bOptimizedTrap = false ; // se ho un caso spirale o trapezio
-
- // NB. se la superficie è rimasta la stessa, utilizzo pMCrv e pRCrv dello step precedente
- // ( non c'è bisogno di ricalcolare tutti i percorsi)
- if ( ! vbChangedPrec[j-1] && j != 1) {
- if ( nOffs_act > ( int)vMCrv_step_prec.size() - 1)
- break ;
- pMCrv.Set( vMCrv_step_prec[nOffs_act]->Clone()) ;
- pRCrv.Set( vRCrv_step_prec[nOffs_act]->Clone()) ;
- nRegTot = vnRegTot_prec[nOffs_act] ;
- bMidOut = vbMidOutPrec[nOffs_act] ;
- vMCrv_step_prec[nOffs_act]->GetStartPoint( ptStart) ;
- vtMidOut = vvtMidOutPrec[nOffs_act] ;
- }
- else {
- // se lucidatura con epicicli
- if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
- // verifico che parametri lucidatura siano sensati
- if ( m_Params.m_dEpicyclesDist < 100 * EPS_SMALL) {
- m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ // se prima entità
+ if ( i == 0) {
+ // dati inizio entità
+ Point3d ptStart ;
+ pCurve->GetStartPoint( ptStart) ;
+ Vector3d vtStart ;
+ pCurve->GetStartDir( vtStart) ;
+ // se primo step, approccio e affondo
+ if ( j == 1 || vbChangedPrec[j-1] || vSfr[j-2]->GetChunkCount() > 1 || nRegTot > 1) {
+ // Ricalcolo il punto di attacco sopra al PtStart ( modificato in precedenza dal PtOut) quando :
+ // 1) sono nel primo Step o ...
+ // 2) la superificie è diversa da quello dello step precedente o ...
+ // 3) il numero di chunk allo step precedente è maggiore di 1 o ...
+ // 4) dal primo offset del chunk cc-esimo ottengo più regioni
+ if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) {
+ m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
return false ;
}
- // modifico il diametro dell'utensile per tenere conto anche del raggio degli epicicli
- m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ;
- }
-
- bool bOptimizedTrap = false ;
-
- int nInd = 0 ;
- if ( ! GetOptCrvIndex( vCrvOEWithFlags, j, pSrfChunkFinal, nInd))
- return false ;
-
- nRegTot = nReg ;
-
- if ( ! CalcSpiral( pSrfChunkFinal, nRegTot, ptStart, vtMidOut, bMidOut, bSplitArcs, pMCrv, pRCrv,
- vCrvOEWithFlags[j-1][nInd], vbChangedPrec[j-1], bOptimizedTrap))
- return false ;
-
- // se terminate le regioni, esco
- if ( pMCrv->GetCurveCount() == 0)
- break ;
-
- if ( m_TParams.m_nType == TT_MILL_POLISHING && m_Params.m_dEpicyclesRad > EPS_SMALL) {
- // riporto il diametro dell'utensile al valore originale
- m_TParams.m_dDiam -= 2 * m_Params.m_dEpicyclesRad ;
- // aggiorno i percorsi di svuotatura con epicicli
- if ( ! ComputePolishingPath( pMCrv, pRCrv, bSplitArcs)) {
- m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
+ // determino elevazione su inizio attacco
+ double dStElev = dSink ;
+ dStElev -= ( ptP1 - ptStart) * vtExtr ;
+ // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
+ if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
+ GetLeadInType() == POCKET_LI_HELIX ||
+ GetLeadInType() == POCKET_LI_GLIDE) {
+ ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ;
+ dStElev = -LIO_ELEV_TOL ;
+ }
+ // approccio al punto iniziale
+ if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) {
+ m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
+ return false ;
+ }
+ // aggiungo attacco
+ SetFeed( GetStartFeed()) ;
+ if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) {
+ m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
return false ;
}
}
-
- // memorizzo le curve create e modificate per lo step successivo
- vMCrv_step_prec.emplace_back( pMCrv->Clone()) ;
- vRCrv_step_prec.emplace_back( pRCrv->Clone()) ;
- // memorizzo i Flag per le entrate
- vbMidOutPrec.push_back( bMidOut) ;
- // memorizzo il numero delle regioni create dal primo Offset
- vnRegTot_prec.push_back( nRegTot) ;
- // memorizzo il versore di uscita calcolato
- vvtMidOutPrec.push_back( vtMidOut) ;
- }
-
- // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo
- bOutStart = false ;
- int nOutsideRaw = 0 ;
- if ( bOptimizedTrap) {
- AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ;
- bOutStart = ( nOutsideRaw > 0) ;
- AssignFeedSpiralOpt( 1, pMCrv) ;
- AssignFeedForReturnPath( pRCrv) ;
- }
-
- // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
- if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) {
- if ( ! LeadInRawIsOk()) {
- m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ;
- return false ;
- }
- }
-
- // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato)
- if ( ! bOptimizedTrap) {
- pMCrv->Invert() ;
- pRCrv->Invert() ;
- }
-
- // inversione per caso ottimizzato
- if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1)
- pMCrv->Invert() ;
-
- ++ nReg ;
- ++ nOffs_act ;
- int nMaxInd = pMCrv->GetCurveCount() - 1 ;
- int nMaxRInd = pRCrv->GetCurveCount() - 1 ;
-
- // ciclo sulle curve elementari
- for ( int i = 0 ; i <= nMaxInd ; ++ i) {
- // curva corrente
- const ICurve* pCrvC = pMCrv->GetCurve( i) ;
- // copio la curva
- PtrOwner pCurve( pCrvC->Clone()) ;
- if ( IsNull( pCurve))
- return false ;
- // aggiungo affondamento
- pCurve->Translate( vVtTrasl[j-1]) ;
- // se prima entità
- if ( i == 0) {
- // dati inizio entità
- Point3d ptStart ;
- pCurve->GetStartPoint( ptStart) ;
- Vector3d vtStart ;
- pCurve->GetStartDir( vtStart) ;
- // se primo step, approccio e affondo
- if ( j == 1 || vbChangedPrec[j-1] || vSrfSliced[j-2]->GetChunkCount() > 1 || nRegTot > 1) {
- // determino inizio attacco
- if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, pRCrv, ptP1)) {
- m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
- return false ;
- }
- // determino elevazione su inizio attacco
- double dStElev ;
- if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev))
- dStElev = dStep ;
- bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab &&
- GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- bool bUhAboveRaw = ! m_bAboveHead &&
- GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(),
- m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ;
- //if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab)
- dStElev = max( dStElev, j * dStep) ;
- dStElev -= ( ptP1 - ptStart) * vtExtr ;
- // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco
- if ( GetLeadInType() == POCKET_LI_ZIGZAG ||
- GetLeadInType() == POCKET_LI_HELIX ||
- GetLeadInType() == POCKET_LI_GLIDE) {
- ptP1 += vtExtr * ( dStElev + LIO_ELEV_TOL) ;
- dStElev = -LIO_ELEV_TOL ;
- }
- // approccio al punto iniziale
- if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, false)) {
- m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
- return false ;
- }
- // aggiungo attacco
- SetFeed( GetStartFeed()) ;
- if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) {
- m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
- return false ;
- }
- }
- // altrimenti solo collegamento
- else {
- SetFeed( GetStartFeed()) ;
- GetCurrPos( ptP1) ;
- if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) {
- m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
- return false ;
- }
- }
- }
- // elaborazioni sulla curva corrente
- double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
- double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
- GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
- //DrawColoredCrvForFeedTest( pCurve, dFeed) ;
- SetFeed( dFeed) ;
- if ( pCurve->GetType() == CRV_LINE) {
- ICurveLine* pLine = GetCurveLine( pCurve) ;
- Point3d ptP3 = pLine->GetEnd() ;
- //SetFeed( GetFeed()) ;
- //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ;
- if ( AddLinearMove( ptP3) == GDB_ID_NULL)
+ // altrimenti solo collegamento
+ else {
+ SetFeed( GetStartFeed()) ;
+ GetCurrPos( ptP1) ;
+ if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pSrfLeanInOut, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) {
+ m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ;
return false ;
- }
- else if ( pCurve->GetType() == CRV_ARC) {
- ICurveArc* pArc = GetCurveArc( pCurve) ;
- Point3d ptCen = pArc->GetCenter() ;
- double dAngCen = pArc->GetAngCenter() ;
- Vector3d vtN = pArc->GetNormVersor() ;
- Point3d ptP3 ;
- pArc->GetEndPoint( ptP3) ;
- //SetFeed( GetFeed());
- //SetFeed( pCurve->GetTempProp( 0 ) / FEED_DIVISOR) ;
- if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
- return false ;
- }
- // se ultima entità
- if ( i == nMaxInd) {
- // se step intermedio
- if ( j < nStep && vSrfSliced[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegTot == 1) {
- // se necessario ritorno all'inizio
- if ( nMaxRInd >= 0) {
- // copio la curva di ritorno
- PtrOwner pRet( pRCrv->Clone()) ;
- if ( IsNull( pRet))
- return false ;
- // aggiungo affondamento
- pRet->Translate( vVtTrasl[j-1]) ;
- // se attacco a scivolo, accorcio della lunghezza dell'attacco
- if ( GetLeadInType() == POCKET_LI_GLIDE) {
- double dLen ; pRet->GetLength( dLen) ;
- if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL)
- if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang))
- pRet->Clear() ;
- else
- pRet->Clear() ;
- }
- // emetto
- SetFeed( GetFeed()) ;
- if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL)
- return false ;
- }
- }
- // atrimenti ultimo step, uscita e retrazione
- else {
- // dati fine entità
- Point3d ptEnd ;
- pCurve->GetEndPoint( ptEnd) ;
- Vector3d vtEnd ;
- pCurve->GetEndDir( vtEnd) ;
- // aggiungo uscita
- Point3d ptQ ;
- double dEndElev = dElev ;
- SetFeed( GetEndFeed()) ;
- if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptQ, dEndElev, false)) {
- m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
- return false ;
- }
- // aggiungo retrazione
- if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
- m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ;
- return false ;
- }
}
}
}
- }
- }
+ // elaborazioni sulla curva corrente
+ double dMinFeed = GetFeed() * GetSideStep() / m_TParams.m_dDiam ;
+ double dFeed = pCurve->GetTempProp( 0) / FEED_DIVISOR < dMinFeed - 50 * EPS_SMALL ?
+ GetFeed() : pCurve->GetTempProp( 0) / FEED_DIVISOR ;
+ //DrawColoredCrvForFeedTest( pCurve, dFeed) ;
+ SetFeed( dFeed) ;
+ if ( pCurve->GetType() == CRV_LINE) {
+ ICurveLine* pLine = GetCurveLine( pCurve) ;
+ Point3d ptP3 = pLine->GetEnd() ;
+ //SetFeed( GetFeed()) ;
+ //SetFeed( pCurve->GetTempProp( 0) / FEED_DIVISOR) ;
+ if ( AddLinearMove( ptP3) == GDB_ID_NULL)
+ return false ;
+ }
+ else if ( pCurve->GetType() == CRV_ARC) {
+ ICurveArc* pArc = GetCurveArc( pCurve) ;
+ Point3d ptCen = pArc->GetCenter() ;
+ double dAngCen = pArc->GetAngCenter() ;
+ Vector3d vtN = pArc->GetNormVersor() ;
+ Point3d ptP3 ;
+ pArc->GetEndPoint( ptP3) ;
+ //SetFeed( GetFeed());
+ //SetFeed( pCurve->GetTempProp( 0 ) / FEED_DIVISOR) ;
+ if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
+ return false ;
+ }
+ // se ultima entità
+ if ( i == nMaxInd) {
+ // se step intermedio
+ if ( j < nStep && vSfr[j-1]->GetChunkCount() == 1 && !vbChangedPrec[j] && nRegTot == 1) {
+ // se necessario ritorno all'inizio
+ if ( nMaxRInd >= 0) {
+ // copio la curva di ritorno
+ PtrOwner pRet( pRCrv->Clone()) ;
+ if ( IsNull( pRet))
+ return false ;
+ // aggiungo affondamento
+ pRet->Translate( vVtTrasl[j-1]) ;
+ // se attacco a scivolo, accorcio della lunghezza dell'attacco
+ if ( GetLeadInType() == POCKET_LI_GLIDE) {
+ double dLen ; pRet->GetLength( dLen) ;
+ if ( dLen > m_Params.m_dLiTang + 10 * EPS_SMALL)
+ if ( ! pRet->TrimEndAtLen( dLen - m_Params.m_dLiTang))
+ pRet->Clear() ;
+ else
+ pRet->Clear() ;
+ }
+ // emetto
+ SetFeed( GetFeed()) ;
+ if ( pRet->GetCurveCount() > 0 && AddCurveMove( pRet) == GDB_ID_NULL)
+ return false ;
+ }
+ }
+ // atrimenti ultimo step, uscita e retrazione
+ else {
+ // dati fine entità
+ Point3d ptEnd ;
+ pCurve->GetEndPoint( ptEnd) ;
+ Vector3d vtEnd ;
+ pCurve->GetEndDir( vtEnd) ;
+ // aggiungo uscita
+ Point3d ptQ ;
+ double dEndElev = dElev ;
+ SetFeed( GetEndFeed()) ;
+ if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptQ, dEndElev, false)) {
+ m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ;
+ return false ;
+ }
+ // aggiungo retrazione
+ if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) {
+ m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ;
+ return false ;
+ }
+ }
+ }
+ }
+ }
+
}
}
+
return true ;
}
@@ -5653,9 +6232,9 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
// recupero il versore normale della superificie, ruotandola nel piano XY
PtrOwner pSrfToWork( pSrfPock->Clone()) ;
if ( IsNull( pSrfToWork) || pSrfToWork->GetChunkCount() == 0)
- return false;
+ return false ;
- // porto il Chunk c-esimo nel sistema di riferimento locale (assieme al punto inziale)
+ // porto il Chunk c-esimo nel sistema di riferimento locale
Vector3d vtExtr = pSrfToWork->GetNormVersor() ;
Point3d ptCen ; pSrfToWork->GetCentroid( ptCen) ;
Frame3d frPocket ; frPocket.Set( ptCen, vtExtr) ;
@@ -5698,12 +6277,13 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
PtrOwner pCrvTrap( CreateCurveComposite()) ;
if ( IsNull( pCrvTrap))
return false ;
- pCrvOEWithFlags->ToLoc( frPocket) ;
Frame3d frTrap ;
double dPocketSize ;
int nBase, nSecondBase ;
+ pCrvOEWithFlags->ToLoc( frPocket) ;
if ( ! GetTrapezoidFromShape( pCrvOEWithFlags, pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase))
return false ;
+ pCrvOEWithFlags->ToGlob( frPocket) ;
if ( pCrvTrap->IsValid()) {
pCrvTrap->SetExtrusion( vtExtr) ;
if ( nReg == 0) {
@@ -5726,77 +6306,77 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
// ciclo di offset verso l'interno
const int MAX_ITER = 1000 ;
int nIter = 0 ;
- ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset
+ ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset
ICRVCOMPOPOVECTOR vOffsFirstCurve ; // curve di primo offset
PtrOwner pSrfAct( CloneSurfFlatRegion( pSrfToWork)) ; // regione attuale
- PtrOwner pSrfPrec( CloneSurfFlatRegion( pSrfToWork)) ; // regione precedente
- if( IsNull( pSrfAct) || IsNull( pSrfPrec) || pSrfAct->GetChunkCount() == 0 || pSrfPrec->GetChunkCount() == 0)
+ if ( IsNull( pSrfAct) || pSrfAct->GetChunkCount() == 0)
return false ;
+ double dOffsPrec = 0. ;
while ( nIter < MAX_ITER) {
- // salvo la regione
- pSrfPrec.Set( pSrfAct->Clone()) ;
- if ( ! pSrfAct->Offset( - dOffs, ICurve::OFF_FILLET)) {
- //int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ;
- //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ;
- return false ;
- }
- if ( ! pSrfAct->IsValid()) {
- // VRONOI ?
- pSrfAct.Set( pSrfPrec->Clone()) ;
- if ( ! pSrfAct->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) {
- //int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ;
- //m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ;
- return false ;
- }
+ // ricavo la regione piana da VRONI
+ PtrOwner pSfrOffsVR( pSrfAct->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
+ if ( IsNull( pSfrOffsVR))
+ return false ;
+ if ( ! pSfrOffsVR->IsValid()) {
+ pSfrOffsVR.Set( pSrfAct->CreateOffsetSurf( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) ;
+ if ( IsNull( pSfrOffsVR))
+ return false ;
}
- // estraggo il contorno della FlatRegion (ciclo i Chunks e prendo i rispettivi Loops)
+ // alla prima iterazione svuoto la regione nReg-esima passata alla funzione CalcSpiral
if ( nIter == 0) {
- PtrOwner pSrfChunknReg( pSrfAct->CloneChunk( nReg)) ;
- nReg = pSrfAct->GetChunkCount() ; // modifico nReg per le uscite
- if ( IsNull( pSrfChunknReg)) // se supero i chunk ottenuti
+ PtrOwner pSrfChunknReg( pSfrOffsVR->CloneChunk( nReg)) ;
+ nReg = pSfrOffsVR->GetChunkCount() ; // aggiorno il nuovo valore delle regioni
+ if ( IsNull( pSrfChunknReg)) // se supero i chunk ottenuti
return true ;
- pSrfAct.Set( pSrfChunknReg) ;
}
- int nChunks = pSrfAct->GetChunkCount() ;
+ // ricavo il numero di Chunk ottenuti dall'Offset
+ int nChunks = pSfrOffsVR->GetChunkCount() ;
+ // ciclo sui Chunks
for ( int i = 0 ; i < nChunks ; ++ i) {
// per ogni chunk...
- int nLoops = pSrfAct->GetLoopCount( i) ;
+ int nLoops = pSfrOffsVR->GetLoopCount( i) ;
for ( int j = 0 ; j < nLoops ; ++ j) {
// per ogni loop...
- PtrOwner ptoCCBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ;
- if ( j > 0) // inverto l'orientamento delle curve interne (offset delle isole trovate)
- ptoCCBorder->Invert() ;
+ PtrOwner pCrvCompoBorder( ConvertCurveToComposite( pSfrOffsVR->GetLoop( i, j))) ;
+ if ( IsNull( pCrvCompoBorder) || ! pCrvCompoBorder->IsValid())
+ return false ;
+ if ( j > 0) // inverto l'orientamento delle curve interne ( offset delle isole trovate)
+ pCrvCompoBorder->Invert() ;
// controllo quali regioni di Offset possono essere sostituite
bool bInsert = true ;
- if ( ! CheckIfOffsetIsNecessary( ptoCCBorder, dOffs, ( int)vOffs.size(), nIter, vtExtr, bInsert))
+ if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, ( int)vOffs.size(), nIter, vtExtr, bInsert))
return false ;
- if ( bInsert) {
- vOffs.emplace_back( Release( ptoCCBorder)) ;
- }
- PtrOwner ptoCCExtBorder( GetCurveComposite( pSrfAct->GetLoop( i, j))) ;
+ if ( bInsert)
+ vOffs.emplace_back( Release( pCrvCompoBorder)) ;
if ( nIter == 0) { // salvo il bordo per i link (non invertiti)
- vOffsFirstCurve.emplace_back( Release( ptoCCExtBorder)) ;
+ PtrOwner pCrvCompoExtBorder( ConvertCurveToComposite( pSfrOffsVR->GetLoop( i, j))) ;
+ vOffsFirstCurve.emplace_back( Release( pCrvCompoExtBorder)) ;
}
}
}
- bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ;
+ // controllo se serve un raggio più piccolo di svuotatura
+ bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs - dOffsPrec < dTRad + EPS_ZERO) ;
- if ( nChunks > 0)
- dOffs = GetSideStep() ;
- else if ( ! bSmallRad) {
- pSrfAct.Set( pSrfPrec) ;
- dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ;
- }
+ // se ho trovato dei chunk, allora aggiorno l'Offset per la passata successiva
+ if ( nChunks > 0) {
+ // memorizzo il valore di Offset per l'iterazione successiva
+ dOffsPrec = dOffs ;
+ dOffs += GetSideStep() ;
+ }
+ // se devo usare un Offset più piccolo...
+ else if ( ! bSmallRad)
+ dOffs = dOffsPrec + ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ;
+ // altrimenti ho finito la regione da svuotare...
else
break ;
- ++ nIter ;
+ ++ nIter ; // aggiorno l'iterazione
}
// se non ho trovato curve di Offset allora esco
@@ -5820,7 +6400,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
for ( int i = 0 ; i < ( int)vOffs.size() && m_Params.m_bInvert ; ++ i)
vOffs[i]->Invert() ;
-
// smusso le curve di offset ( ad eccezione della prima)
ICRVCOMPOPOVECTOR vOffsClosedCurves( vOffs.size()) ; // vettore con tutte le curve di Offset Chiuse
@@ -5872,7 +6451,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
ptHelp.Set( ptE.x, ptE.y, ptE.z) ;
}
}
- // avendo la curva più vicina ...
+ // avendo la curva più vicina ...
// 1) scambio la curva i con la curva nClosestInd
if ( nClosestInd != i + 1) {
@@ -8679,12 +9258,12 @@ Pocketing::AddEpicycles( ICurveComposite* pCompo, ICurveComposite * pCrv, ICurve
if ( IsNull( pCrvOffs))
return false ;
- // verifico se devo resitituire la curva offsettata
+ // verifico se devo resitituire la curva offsettata
if ( pCrvBound)
pCrvBound->AddCurve( pCrvOffs->Clone()) ;
pCrv->Clear() ;
- double dParPrec = 0 ;
+ double dParPrec = 0 ;
for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) {
// calcolo distanza epicili specifica per quel tratto
@@ -9281,364 +9860,285 @@ Pocketing::GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOV
//----------------------------------------------------------------------------
bool
-Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo, ICRVCOMPOPOVECTOR& vCrvIsl,
- double dTool_Diam, double dOffR, double dSideStep, const Vector3d& vtTrasl,
- ISurfTriMesh* pStmRaw, bool bInVsOut)
+Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const double dDiam,
+ const double dOffR, const double dStep, const ISurfFlatRegion* pSfrLimit)
{
+ // controllo dei parametri
+ if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid())
+ return false ;
- // vettore estrusione
- Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ;
- // calcolo riferimento nel piano della svuotatura
- Frame3d frPocket ;
- Point3d ptStart ; pCompo->GetStartPoint( ptStart) ;
- frPocket.Set( ptStart, vtExtr) ;
- // sposto l'inizio a metà del tratto più lungo
- AdjustContourStart( pCompo, vCrvIsl) ;
// raggio di riferimento per offset
- double dOutEdge = 0.5 * dTool_Diam ;
+ double dOutEdge = 0.5 * dDiam ;
if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN || m_Params.m_nSubType == POCKET_SUB_ZIGZAG)
- dOutEdge = max( dOutEdge, dTool_Diam - dSideStep) ;
+ dOutEdge = max( dOutEdge, dDiam - dStep) ;
double dRad = dOutEdge + dOffR ;
- // estraggo parti con proprietà uniforme in un vettore
- ICURVEPOVECTOR vpCrvs ;
- int nCurrTempProp ;
- int nParStart = 0 ;
- for ( int i = 0 ; i < pCompo->GetCurveCount() ; ++ i) {
- int nTempProp ;
- pCompo->GetCurveTempProp( i, nTempProp) ;
- if ( i == 0) {
- nCurrTempProp = nTempProp ;
- nParStart = i ;
- }
- else if ( nCurrTempProp != nTempProp) {
- PtrOwner pCrv( pCompo->CopyParamRange( nParStart, i)) ;
- if ( IsNull( pCrv))
- return false ;
- pCrv->SetTempProp( nCurrTempProp) ;
- pCrv->SetExtrusion( vtExtr) ;
- vpCrvs.emplace_back( Release( pCrv)) ;
- nCurrTempProp = nTempProp ;
- nParStart = i ;
- }
- }
- PtrOwner pCrv( pCompo->CopyParamRange( nParStart, pCompo->GetCurveCount())) ;
- if ( IsNull( pCrv))
- return false ;
- pCrv->SetTempProp( nCurrTempProp) ;
- pCrv->SetExtrusion( vtExtr) ;
- vpCrvs.emplace_back( Release( pCrv)) ;
- // offsetto del raggio le curve aperte
- for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
- if ( vpCrvs[i]->GetTempProp() == 1) {
- OffsetCurve OffsCrv ;
- if ( ! OffsCrv.Make( vpCrvs[i], dRad, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
- int nCrv_offs = OffsCrv.GetCurveCount() ;
- if ( nCrv_offs == 0) {
- // GESTIONE SPECIALE DEGLI APERTI CHE OFFSETTATI NON GENERANO CURVE -----------------------------------
- // se un lato aperto è formato da più curve e l'offset di tale composita sparisce, la superficie può
- // estendersi fino all'intersezione delle due curva ad amo che determinano l'immagine del tool nello svuotare
- // i lati chiusi adiacenti
- if ( i == 0)
- continue ;
- // determino la curva ad amo
- Point3d ptEnd ; vpCrvs[i-1]->GetEndPoint( ptEnd) ;
- Vector3d vtTg ; vpCrvs[i-1]->GetEndDir( vtTg) ;
- Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ;
- Point3d ptArc = ptEnd + ( 1.05 * dTool_Diam + 2 * dOffR ) * vtOrt ;
- PtrOwner pCrvArc( CreateCurveArc()) ;
- if ( IsNull( pCrvArc))
- return false ;
- pCrvArc->SetExtrusion( vtExtr) ;
- pCrvArc->Set2PVN( ptEnd, ptArc, vtTg, vtExtr) ;
- PtrOwner pJCrv( CreateCurveComposite()) ;
- if ( IsNull( pJCrv))
- return false ;
- pJCrv->AddCurve( Release( pCrvArc)) ;
- // determino la curva ad amo
- vpCrvs[i+1]->GetStartPoint( ptStart) ;
- vpCrvs[i+1]->GetStartDir( vtTg) ;
- vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ;
- ptArc = ptStart + ( 1.05 * dTool_Diam + 2 * dOffR ) * vtOrt ;
- Point3d ptLine = ptArc + 5 * ( 1.05 * dTool_Diam + 2 * dOffR ) * vtTg ;
- PtrOwner pJCrv1( CreateCurveComposite()) ;
- if ( IsNull( pJCrv1))
- return false ;
- pJCrv1->SetExtrusion( vtExtr) ;
- pJCrv1->AddPoint( ptLine) ;
- pJCrv1->AddLine( ptArc) ;
- pJCrv1->AddArcTg( ptStart) ;
- // intersezione
- pJCrv->ToLoc( frPocket) ;
- pJCrv1->ToLoc( frPocket) ;
- IntersCurveCurve intCC( *pJCrv, *pJCrv1) ;
- pJCrv->ToGlob( frPocket) ;
- pJCrv1->ToGlob( frPocket) ;
- // classificazione
- IntCrvCrvInfo aInfo ;
- if ( intCC.GetIntersCount() > 0) {
- if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) {
- PtrOwner pCrvFinal( CreateCurveComposite()) ;
- PtrOwner PJ_Cut( pJCrv->CopyParamRange( 0, aInfo.IciA[0].dU)) ;
- PtrOwner PJ1_Cut( pJCrv1->CopyParamRange( aInfo.IciB[0].dU, 1)) ;
- //PJ1_Cut->Invert() ;
- pCrvFinal->AddCurve( Release( PJ_Cut)) ;
- pCrvFinal->AddCurve( Release( PJ1_Cut)) ;
- for ( int u = 0 ; u < pCrvFinal->GetCurveCount() ; ++ u)
- pCrvFinal->SetCurveTempProp( u, 0, 0) ;
- vpCrvs[i].Set( Release( pCrvFinal)) ;
- vpCrvs[i]->SetTempProp( 0) ;
- }
- }
- else
- continue ;
- }
- // -----------------------------------------------------------------------------------------
- // GESTIONE SPECIALE DEGLI APERTI CHE GENERANO ISOLE APERTE --------------------------------
- // dall'offset di un lato aperto posso generare più curva composite...
- PtrOwner pCrvlonger( OffsCrv.GetLongerCurve()) ;
- while ( ! IsNull( pCrvlonger)) {
- // le chiuse mi entrano nel vettore delle isole
- if ( pCrvlonger->IsClosed() && nCrv_offs > 1) {
- PtrOwner pCrvCompo( CreateCurveComposite()) ;
- pCrvCompo->AddCurve( Release( pCrvlonger)) ;
- for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u)
- pCrvCompo->SetCurveTempProp( u, 1, 0) ;
- vCrvIsl.emplace_back( pCrvCompo->Clone()) ;
- }
- else // le aperte rimangono tali
- vpCrvs[i].Set( Release( pCrvlonger)) ;
- pCrvlonger.Set( OffsCrv.GetLongerCurve()) ;
- }
- // imposto le curva ottenute come aperte ( nuove isole comprese)
- PtrOwner pCrvRange( CreateCurveComposite()) ;
- pCrvRange->AddCurve( vpCrvs[i]->Clone()) ;
- for ( int j = 0 ; j < pCrvRange->GetCurveCount() ; ++ j)
- pCrvRange->SetCurveTempProp( j, 1, 0) ;
- vpCrvs[i].Set( pCrvRange) ;
- vpCrvs[i]->SetTempProp( 1) ;
- }
- // -----------------------------------------------------------------------------------------
- }
- // clono la pCompo
- PtrOwner pCompo_clone( CloneCurveComposite( pCompo)) ;
- if ( IsNull( pCompo_clone))
+ // ricavo i tratti omogenei
+ ICRVCOMPOPOVECTOR vpCrvs ;
+ if ( ! GetHomogeneousParts( pCrvCompo, vpCrvs))
return false ;
- // reinserisco le curve, chiudendo eventuali gap
- pCompo->Clear() ;
- pCompo->SetExtrusion( vtExtr) ;
- bool bOpenCurr = false ;
- double dDiam = 1.05 * dTool_Diam + 2 * dOffR ;
+ // Offset esterno per CurveJ
+ double dDiamJ = 1.05 * dDiam + 2 * dOffR ;
+ // NB. 1.05 serve per eccedere leggermente, in modo che il contro-offset della prima curva di svuotatura presenti
+ // dei piccoli archi tra i chiusi e gli aperti ( in modo da svuotare bene lungo il chiuso)
+ // curva finale da restituire
+ PtrOwner pCrvCompo_final( CreateCurveComposite()) ;
+ if ( IsNull( pCrvCompo_final))
+ return false ;
+
+ // parametro iniziale del tratto corrente, sulla curva originale
+ double dParS = 0. ;
+ // scorro tutti i tratti omogenei nel vettore
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
- // stato curve
- bool bOpenPrev = bOpenCurr ;
- bOpenCurr = ( vpCrvs[i]->GetTempProp() != 0) ;
- PtrOwner pCrv_Check( vpCrvs[i]->Clone()) ;
- // chiudo eventuale gap
- if ( i > 0) {
- Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ;
- Point3d ptStart ; vpCrvs[i]->GetStartPoint( ptStart) ;
- if ( ! AreSamePointEpsilon( ptEnd, ptStart, 10 * EPS_SMALL)) {
- // se passo da chiuso ad aperto
- if ( ! bOpenPrev && bOpenCurr) {
- // -----------------------------------------------------------------------------------
- // creazione della curva di bordo mediante Offset dei chiusi ( per ripulire angoli stretti)
- PtrOwner pCrvCompo_i( CreateCurveComposite()) ;
- pCrvCompo_i->AddCurve( vpCrvs[i]->Clone()) ;
- Point3d ptS ; pCompo->GetEndPoint( ptS) ;
- Point3d ptE ; vpCrvs[i+1]->GetStartPoint( ptE) ;
- PtrOwner pCrvNew( CreateCurveComposite()) ;
- if ( ! bInVsOut &&
- AdjustPathOutsideRawForOpenEdges( pCompo_clone, vCrvIsl, pCrvCompo_i, ptS, ptE, dRad, dDiam,
- pCrvNew, vtTrasl, pStmRaw, bInVsOut)) {
- vpCrvs[i].Set( Release( pCrvNew)) ;
- vpCrvs[i]->GetStartPoint( ptStart) ;
- }
- // -----------------------------------------------------------------------------------
- // determino la curva ad amo
- Vector3d vtTg ; pCompo->GetEndDir( vtTg) ;
- Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ;
- Point3d ptArc = ptEnd + dDiam * vtOrt ;
- //Point3d ptLine = ptArc - 5 * dDiam * vtTg ;
- PtrOwner pCrvArc( CreateCurveArc()) ;
- if ( IsNull( pCrvArc))
- return false ;
- pCrvArc->SetExtrusion( vtExtr) ;
- pCrvArc->Set2PVN( ptEnd, ptArc, vtTg, vtExtr) ;
- PtrOwner pJCrv( CreateCurveComposite()) ;
- if ( IsNull( pJCrv))
- return false ;
- pJCrv->AddCurve( Release( pCrvArc)) ;
- // assegno alle sue sottocurve la proprietà di curva aperta
- for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u)
- pJCrv->SetCurveTempProp( u, 1, 0) ;
-
- // ------- controllo degli overlap tra la curva ad amo e la nuova curva di lato aperto ottenuta ------
- bool bSucc = false ;
- PtrOwner pNewCrv( CreateCurveComposite()) ;
- PtrOwner pCrvOffsOri( CreateCurveComposite()) ;
- pCrvOffsOri->AddCurve( vpCrvs[i]->Clone()) ;
- if ( ! CheckOpenEdgeOverlapParts( pJCrv, vpCrvs[i], true, bSucc, pNewCrv))
- return false ;
- if ( bSucc)// se "overlap Trovato", modifico la vpCrvs[i]
- vpCrvs[i].Set( Release( pNewCrv)) ;
- // ---------------------------------------------------------------------------------------------------
-
- // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta
- pJCrv->ToLoc( frPocket) ;
- vpCrvs[i]->ToLoc( frPocket) ;
- IntersCurveCurve intCC( *pJCrv, *vpCrvs[i]) ;
- pJCrv->ToGlob( frPocket) ;
- vpCrvs[i]->ToGlob( frPocket) ;
-
- // taglio opportunamente le curve
- bool bFound = false ;
- IntCrvCrvInfo aInfo ;
- if ( intCC.GetIntersCount() > 0 && !bInVsOut) {
- // cerco la prima intersezione che entra nella curva aperta
- for ( int j = 0 ; j < intCC.GetIntersCount() ; ++ j) {
- if ( intCC.GetIntCrvCrvInfo( j, aInfo) && ( bSucc || aInfo.IciA[0].nPrevTy == ICCT_OUT)) {
- bFound = true ;
- break ;
- }
- }
- }
- if ( bFound) {
- if ( ! pJCrv->TrimEndAtParam( aInfo.IciA[0].dU))
- pJCrv->Clear() ;
- vpCrvs[i]->TrimStartAtParam( aInfo.IciB[0].dU) ;
- pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ;
- }
- else {
- vpCrvs[i].Set( Release( pCrvOffsOri)) ;
- pCompo->AddLine( ptStart) ;
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, bInVsOut ? 0 : 1, 0) ; // segmento aggiunto
- if ( bInVsOut)
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare
- }
- }
- // se passo da aperto a chiuso
- else if ( bOpenPrev && ! bOpenCurr) {
- // determino la curva ad amo
- Vector3d vtTg ; vpCrvs[i]->GetStartDir( vtTg) ;
- Vector3d vtOrt = vtTg ; vtOrt.Rotate( vtExtr, 0, 1) ;
- Point3d ptArc = ptStart + dDiam * vtOrt ;
- Point3d ptLine = ptArc + 5 * dDiam * vtTg ;
- PtrOwner pJCrv( CreateCurveComposite()) ;
- if ( IsNull( pJCrv))
- return false ;
- pJCrv->SetExtrusion( vtExtr) ;
- pJCrv->AddPoint( ptLine) ;
- pJCrv->AddLine( ptArc) ;
- pJCrv->AddArcTg( ptStart) ;
- PtrOwner pCrvRemoved( pJCrv->RemoveFirstOrLastCurve( false)) ;
- if ( IsNull( pCrvRemoved))
- return false ;
-
- // assegno alle sue sottocurve la proprietà di curva aperta
- for ( int u = 0 ; u < pJCrv->GetCurveCount() ; ++ u)
- pJCrv->SetCurveTempProp( u, 1, 0) ;
-
- // prendo le ultime due curve ( sono sufficienti) della composita attuale per verificare l'intersezione
- // con la curva ad amo
- PtrOwner pLCrv( CreateCurveComposite()) ;
- if ( IsNull( pLCrv))
- return false ;
- pLCrv->AddCurve( pCompo->GetLastCurve()->Clone()) ;
- if ( pCompo->GetCurveCount() >= 2)
- pLCrv->AddCurve( pCompo->GetPrevCurve()->Clone(), false) ;
- double dUL = pLCrv->GetCurveCount() ;
-
- // ------- controllo degli overlap tra la curva ad amo e la nuova curva di lato aperto ottenuta ------
- bool bSucc = false ;
- PtrOwner pNewCrv( CreateCurveComposite()) ;
- PtrOwner pCrvOffsOri( CreateCurveComposite()) ;
- pCrvOffsOri->AddCurve( vpCrvs[i]->Clone()) ;
- if ( ! CheckOpenEdgeOverlapParts( pJCrv, pLCrv, false, bSucc, pNewCrv))
- return false ;
- if ( bSucc) { // se "overlap Trovato", modifico la vpCrvs[i]
- pLCrv.Set( pNewCrv->Clone()) ;
- double dUS_tmp, dUE_tmp ;
- pCompo->GetDomain( dUS_tmp, dUE_tmp) ;
- if ( dUE_tmp >= 2) { // sempre ( ho sempre un pezzo di chiuso e il tratto aperto)
- pCompo->TrimEndAtParam( dUE_tmp - dUL) ;
- pCompo->AddCurve( pLCrv->Clone()) ;
- }
- }
- dUL = pLCrv->GetCurveCount() ;
- // ---------------------------------------------------------------------------------------------------
-
- // calcolo l'intersezione nel piano della svuotatura dell'amo con la curva aperta
- pJCrv->ToLoc( frPocket) ;
- pLCrv->ToLoc( frPocket) ;
- IntersCurveCurve intCC( *pJCrv, *pLCrv) ;
- pJCrv->ToGlob( frPocket) ;
- pLCrv->ToGlob( frPocket) ;
-
- // taglio opportunamente le curve
- IntCrvCrvInfo aInfo ;
- if ( intCC.GetIntCrvCrvInfo( 0, aInfo) && !bInVsOut) {
- double dUs, dUe ; pCompo->GetDomain( dUs, dUe) ;
- if ( ! pCompo->TrimEndAtParam( dUe - dUL + aInfo.IciB[0].dU))
- pCompo->Clear() ;
- if ( ! pJCrv->TrimStartAtParam( aInfo.IciA[0].dU))
- pJCrv->Clear() ;
- pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ;
- }
- else {
- vpCrvs[i].Set( Release( pCrvOffsOri)) ;
- pCompo->AddLine( ptStart) ;
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, bInVsOut ? 0 : 1, 0) ; // segmento come curva aperta
- if ( bInVsOut)
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare
- }
- }
- else {
- vpCrvs[i].Set( Release( pCrv_Check)) ;
- pCompo->AddLine( ptStart) ;
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, 1, 0) ; // segmento come curva aperta
- if ( bInVsOut)
- pCompo->SetCurveTempProp( pCompo->GetCurveCount() - 1, -99 , 1) ; // linea da controllare
- }
- }
+ // recupero la proprietà della curva composita
+ int nCurrTmpProp = vpCrvs[i]->GetTempProp() ;
+ // aggiorno i parametri del lato aperto corrente sulla curva originale
+ double dParE = dParS + 1. * vpCrvs[i]->GetCurveCount() ;
+ // se aperta
+ if ( nCurrTmpProp == 1) {
+ if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, dRad, dDiamJ, pSfrLimit, vpCrvs[i]))
+ return false ;
}
- // aggiungo la curva
- pCompo->AddCurve( ::Release( vpCrvs[i]), true, 10 * EPS_SMALL) ;
- // NB. Se ho solo una curva esterna e all'interno ho almeno un'isola chiusa più vicina del raggio del tool,
- // non andrò mai a creare regioni di incidenza, quindi genererei 0 o più chunks dove il Tool non riesce a passare...
- if ( i == 0 && ( int)vpCrvs.size() > 0 && ( int)vCrvIsl.size() > 0) {
- Point3d ptS ; pCompo->GetEndPoint( ptS) ;
- Point3d ptE ; pCompo->GetStartPoint( ptE) ;
- bool bIsAllOpen = true ;
- for ( int u = 0 ; u < pCompo->GetCurveCount() && bIsAllOpen ; ++ u) {
- int nP = 0 ;
- if ( pCompo->GetCurveTempProp( u, nP, 0) && nP == 0)
- bIsAllOpen = false ;
- }
- if ( bIsAllOpen) {
- PtrOwner pCrvNew( CreateCurveComposite()) ;
- if ( ! bInVsOut &&
- AdjustPathOutsideRawForOpenEdges( pCompo_clone, vCrvIsl, pCompo, ptS, ptE, dRad, dDiam,
- pCrvNew, vtTrasl, pStmRaw, bInVsOut)) {
- pCompo->Clear() ;
- pCompo->CopyFrom( pCrvNew) ;
- }
- }
+ // assegno le proprietà di lato Aperto/Chiuso per la curva corrente
+ for ( int u = 0 ; u < vpCrvs[i]->GetCurveCount() ; ++ u)
+ vpCrvs[i]->SetCurveTempProp( u, nCurrTmpProp, 0) ;
+ // aggiungo la curva ricavata
+ if ( ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone())) {
+ Point3d ptH ; vpCrvs[i]->GetStartPoint( ptH) ;
+ if ( ! pCrvCompo_final->AddLine( ptH) ||
+ ! pCrvCompo_final->SetCurveTempProp( pCrvCompo_final->GetCurveCount() - 1, 1, 0) ||
+ ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone()))
+ return false ;
}
-
+ // aggiorno
+ dParS = dParE ;
}
// non dovrebbe esserci un gap, ma meglio prevenire problemi
- pCompo->Close() ;
+ pCrvCompo_final->Close() ;
+ // sostituisco
+ pCrvCompo->Clear() ;
+ pCrvCompo->CopyFrom( pCrvCompo_final) ;
return true ;
}
-bool
+//----------------------------------------------------------------------------
+bool
+Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvIsland,
+ const double dParS, const double dParE, const double dRad, const double dDiamJ,
+ const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvBorder)
+{
+ /* parametri :
+ pCrvCompo -> curva originaria di bordo
+ vCrvIsland -> vettore delle isole all'interno di pCrvCompo
+ pCrvOpenOffs -> tratto aperto corrente già Offsettato verso l'esterno
+ dParS -> parametro sulla pCrvCompo per l'inizio del tratto aperto
+ dParE -> parametro sulla pCrvCompo per la fine del tratto aperto
+ dRad -> raggio di Offset per la regione di incidenza
+ dDiamJ -> ampiezza delle curve a fagiolo per estendere la regione di incidenza
+ pCrvRes -> curva da restituire ( inizialmente è il tratto aperto sulla pCrvCompo ;
+ questa curva sarà l'estensione del lato aperto, adattandosi alla geometria
+ dei chiusi ( non posso vedere solo i chiusi adiacenti all'aperto, devo considerare TUTTI i chiusi
+ della pCrvCompo
+ pStmVol -> Volume di svuotatura
+ pStm_Part -> Part corrente
+ */
+
+ // controllo la validtà dei parametri
+ if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0 ||
+ pCrvBorder == nullptr || ! pCrvBorder->IsValid() || pCrvBorder->GetCurveCount() == 0)
+ return false ;
+
+ // definisco la regione di incidenza
+ PtrOwner pSfrInc( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrInc) ||
+ ! CreateSurfFrIncidence( pCrvBorder, dRad, pSfrLimit, pSfrInc))
+ return false ;
+
+ // creo un vettore con tutte le curve che potrebbero cadere in parte nella regione di incidenza
+ ICRVCOMPOPOVECTOR vCrvToCheck ;
+ for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i)
+ vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ; // aggiungo le isole
+
+ // se la curva originale non è tutta Aperta -> devo aggiungere anche essa nelle curve da controllare
+ bool bIsAllOpen = abs( abs( dParE - dParS) - pCrvCompo->GetCurveCount()) < EPS_SMALL ;
+ if ( ! bIsAllOpen) {
+ // recupero il tratto di curva prima e dopo dell'aperto corrente
+ PtrOwner pCompoOther( ConvertCurveToComposite( pCrvCompo->CopyParamRange( dParE, dParS))) ;
+ if ( IsNull( pCompoOther) || ! pCompoOther->IsValid())
+ return false ;
+ vCrvToCheck.emplace_back( Release( pCompoOther)) ;
+ }
+
+ // scorro il vettore creato...
+ for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) {
+ // 1) recupero la curva corrente
+ PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ;
+ if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
+ return false ;
+ // 2) classifico la curva con la superficie
+ CRVCVECTOR ccClass ;
+ if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) {
+ // 3) scorro tutte le classificazioni per cercare i tratti interni
+ for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) {
+ if ( ccClass[i].nClass == CRVC_IN) {
+ // 4) se il tratto è interno, recupero tutti i suoi tratti omogenei
+ PtrOwner pCrvCurrPartIn( ConvertCurveToComposite( pCrvCurr->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ;
+ if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
+ return false ;
+ ICRVCOMPOPOVECTOR vpCrvs ;
+ if ( ! GetHomogeneousParts( pCrvCurrPartIn, vpCrvs))
+ return false ;
+ // 5) considero solo i tratti chiusi
+ for ( int cl = 0 ; cl < int( vpCrvs.size()) ; ++ cl) {
+ if ( vpCrvs[cl]->GetTempProp() == 1)
+ continue ;
+ // 6) effettuo l'Offset della curva di metà dDiamJ
+ OffsetCurve OffsCrv ;
+ if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5, ICurve::OFF_FILLET)) {
+ m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ return false ;
+ }
+ // 7) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti
+ PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
+ while ( ! IsNull( pOffLongestCrv)) {
+ // 8) tengo solo le curve che non si chiudono su loro stesse
+ if ( ! pOffLongestCrv->IsClosed()) {
+ // 9) creo la regione di incidenza di tale curva ( "Curva a fagiolo")
+ PtrOwner pSfrBean( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrv), dDiamJ * 0.5, false, false)) ;
+ if ( IsNull( pSfrBean) || ! pSfrBean->IsValid())
+ return false ;
+ // inverto se necessario
+ if ( AreOppositeVectorApprox( pSfrBean->GetNormVersor(), pSfrInc->GetNormVersor()))
+ pSfrBean->Invert() ;
+ // 10) aggiorno la regione di incidenza
+ if ( ! pSfrInc->Add( *pSfrBean))
+ return false ;
+ }
+ pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ;
+ }
+ }
+ }
+ }
+ }
+ else
+ return false ;
+ }
+
+ // recupero la curva di bordo del lato aperto corrente
+ PtrOwner pCrvNewBorder( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 0))) ;
+ if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
+ return false ;
+ // imposto la curva come tutta aperta
+ for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u)
+ pCrvNewBorder->SetCurveTempProp( u, 1, 0) ;
+
+ // se la curva originale era tutta aperta, allora tengo solo il nuovo loop esterno della regione di incidenza
+ if ( bIsAllOpen) {
+ // pulisco la curva originale
+ pCrvBorder->Clear() ;
+ return pCrvBorder->AddCurve( Release( pCrvNewBorder)) ;
+ }
+
+ // altrimenti la spezzo il loop della regione di incidenza nei punti iniziali e finali della curva aperta originale
+ Point3d ptStart ; pCrvBorder->GetStartPoint( ptStart) ;
+ Point3d ptEnd ; pCrvBorder->GetEndPoint( ptEnd) ;
+ double dUTrimS, dUTrimE ;;
+ pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 300 * EPS_SMALL) ;
+ pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 300 * EPS_SMALL) ;
+ // pulisco la curva originale
+ pCrvBorder->Clear() ;
+ if ( ! pCrvBorder->AddCurve( pCrvNewBorder->CopyParamRange( dUTrimS, dUTrimE)) ||
+ ! pCrvBorder->IsValid())
+ return false ;
+
+ return true ;
+
+}
+
+//---------------------------------------------------------------------------
+bool
+Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, const ISurfFlatRegion* pSfrLimit,
+ ISurfFlatRegion* pSfrInc)
+{
+ // controllo dei parametri
+ if ( pCrv == nullptr || ! pCrv->IsValid())
+ return false ;
+ pSfrInc->Clear() ;
+
+ // creo la Fat Curve dalla curva *pCrv
+ PtrOwner pSfrInc_tmp( GetSurfFlatRegionFromFatCurve( pCrv->Clone(), dRad + EPS_SMALL, false, false)) ;
+ if ( IsNull( pSfrInc_tmp) || ! pSfrInc_tmp->IsValid())
+ return false ;
+ pSfrInc->CopyFrom( pSfrInc_tmp) ;
+
+ // La regione di incidenza non deve avere un bordo distante dRad dagli estremi del tratto aperto
+ // per questo motivo, creo due FlatRegion a rettangolo che andrò a sottrarre alla pSfrInc_tmp
+
+ if ( pCrv->IsClosed()) {
+ pSfrInc->CopyFrom( pSfrInc_tmp) ;
+ return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ;
+ }
+
+ // Rettangolo all'inizio
+ Vector3d vtTanS ; pCrv->GetStartDir( vtTanS) ;
+ Point3d ptS ; pCrv->GetStartPoint( ptS) ;
+ Vector3d vtOut = vtTanS ; vtOut.Rotate( Z_AX, -90) ;
+ PtrOwner pCrvRectSBorder( CreateCurveComposite()) ;
+ if ( IsNull( pCrvRectSBorder))
+ return false ;
+ pCrvRectSBorder->AddPoint( ptS + ( dRad + 500 * EPS_SMALL) * vtOut) ;
+ pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut) ;
+ pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ;
+ pCrvRectSBorder->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ;
+ pCrvRectSBorder->Close() ;
+ PtrOwner pSfrRectStart( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrRectStart) ||
+ ! pSfrRectStart->AddExtLoop( Release( pCrvRectSBorder)) ||
+ ! pSfrRectStart->IsValid())
+ return false ;
+ if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectStart->GetNormVersor()))
+ pSfrRectStart->Invert() ;
+
+ // Rettangolo alla fine
+ Vector3d vtTanE ; pCrv->GetEndDir( vtTanE) ;
+ Point3d ptE ; pCrv->GetEndPoint( ptE) ;
+ vtOut = vtTanE ; vtOut.Rotate( Z_AX, -90) ;
+ PtrOwner pCrvRectEBorder( CreateCurveComposite()) ;
+ if ( IsNull( pCrvRectEBorder))
+ return false ;
+ pCrvRectEBorder->AddPoint( ptE + ( dRad + 500 * EPS_SMALL) * vtOut) ;
+ pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut) ;
+ pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ;
+ pCrvRectEBorder->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ;
+ pCrvRectEBorder->Close() ;
+ PtrOwner pSfrRectEnd( CreateSurfFlatRegion()) ;
+ if ( IsNull( pSfrRectEnd) ||
+ ! pSfrRectEnd->AddExtLoop( Release( pCrvRectEBorder)) ||
+ ! pSfrRectEnd->IsValid())
+ return false ;
+ if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectEnd->GetNormVersor()))
+ pSfrRectEnd->Invert() ;
+
+ // alla superficie di incidenza, sottraggo i due rettangoli ricavati
+ if ( ! pSfrInc->Subtract( *pSfrRectStart) ||
+ ! pSfrInc->Subtract( *pSfrRectEnd))
+ return false ;
+
+ // ATTENZIONE !
+ // L'algoritmo di allargamento presso i lati aperti è Euristico; io mi estendo a seconda della geometria del
+ // lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di
+ // esso !
+ if ( ! pSfrInc->Subtract( *pSfrLimit))
+ return false ;
+
+ return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ;
+}
+
+//---------------------------------------------------------------------------
+bool
Pocketing::CheckOpenEdgeOverlapParts( const ICurve* pCrvJ, const ICurve* pCrvOffBorder, bool bCloseToOpen, bool& bSucc,
ICurveComposite* pCrvFinal)
{
@@ -9767,257 +10267,257 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons
const double dDiam, ICurveComposite* pNewCrv, const Vector3d& vtTrasl,
ISurfTriMesh* pStmRaw, bool bInVsOut)
{
- // controllo la validtà dei parametri
- if ( pCompo == nullptr || ! pCompo->IsValid() || pCompo->GetCurveCount() == 0 ||
- pCrvOpenOffs == nullptr || ! pCrvOpenOffs->IsValid() || pCrvOpenOffs->GetCurveCount() == 0)
- return false ;
+ //// controllo la validtà dei parametri
+ // if ( pCompo == nullptr || ! pCompo->IsValid() || pCompo->GetCurveCount() == 0 ||
+ // pCrvOpenOffs == nullptr || ! pCrvOpenOffs->IsValid() || pCrvOpenOffs->GetCurveCount() == 0)
+ // return false ;
- // recupero l'estrusione della curva di bordo
- Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ;
+ //// recupero l'estrusione della curva di bordo
+ // Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ;
- // -------------- RECUPERO DELLA CURVA ESTERNA PRIMA E DOPO IL LATO APERTO CORRENTE --------------
- double dUTrimS, dUTrimE ;
- PtrOwner pCompo_Prec( CloneCurveComposite( pCompo)) ;
- PtrOwner pCompo_Succ( CloneCurveComposite( pCompo)) ;
- PtrOwner pCrvOpen( CloneCurveComposite( pCompo)) ;
- if ( ! AreSamePointApprox( ptCrvOpenS, ptCrvOpenE)) {
- // se inizio e fine diversi...
- pCompo_Prec->GetParamAtPoint( ptCrvOpenS, dUTrimS) ;
- if ( ! pCompo_Prec->TrimEndAtParam( dUTrimS))
- pCompo_Prec->Clear() ;
-
- pCompo_Succ->GetParamAtPoint( ptCrvOpenE, dUTrimE) ;
- if ( ! pCompo_Succ->TrimStartAtParam( dUTrimE))
- pCompo_Succ->Clear() ;
-
- if ( ! pCrvOpen->TrimStartEndAtParam( dUTrimS, dUTrimE))
- pCrvOpen->Clear() ;
- }
- else {
- // se l'inizio coincide con la fine, allora la curva è tutta aperta
- pCrvOpen.Set( pCompo->Clone()) ;
- pCompo_Prec->Clear() ;
- pCompo_Succ->Clear() ;
- }
+ //// -------------- RECUPERO DELLA CURVA ESTERNA PRIMA E DOPO IL LATO APERTO CORRENTE --------------
+ // double dUTrimS, dUTrimE ;
+ // PtrOwner pCompo_Prec( CloneCurveComposite( pCompo)) ;
+ // PtrOwner pCompo_Succ( CloneCurveComposite( pCompo)) ;
+ // PtrOwner pCrvOpen( CloneCurveComposite( pCompo)) ;
+ // if ( ! AreSamePointApprox( ptCrvOpenS, ptCrvOpenE)) {
+ // // se inizio e fine diversi...
+ // pCompo_Prec->GetParamAtPoint( ptCrvOpenS, dUTrimS) ;
+ // if ( ! pCompo_Prec->TrimEndAtParam( dUTrimS))
+ // pCompo_Prec->Clear() ;
+ //
+ // pCompo_Succ->GetParamAtPoint( ptCrvOpenE, dUTrimE) ;
+ // if ( ! pCompo_Succ->TrimStartAtParam( dUTrimE))
+ // pCompo_Succ->Clear() ;
+ //
+ // if ( ! pCrvOpen->TrimStartEndAtParam( dUTrimS, dUTrimE))
+ // pCrvOpen->Clear() ;
+ // }
+ // else {
+ // // se l'inizio coincide con la fine, allora la curva è tutta aperta
+ // pCrvOpen.Set( pCompo->Clone()) ;
+ // pCompo_Prec->Clear() ;
+ // pCompo_Succ->Clear() ;
+ // }
- PtrOwner pCompo_noOpenCrv( CloneCurveComposite( pCompo_Succ)) ;
- pCompo_noOpenCrv->AddCurve( pCompo_Prec->Clone()) ;
+ // PtrOwner pCompo_noOpenCrv( CloneCurveComposite( pCompo_Succ)) ;
+ // pCompo_noOpenCrv->AddCurve( pCompo_Prec->Clone()) ;
- // recupero i punti e i vettori tangenti iniziali e finali del lato aperto
- Point3d ptSTART ; pCrvOpenOffs->GetStartPoint( ptSTART) ;
- Point3d ptEND ; pCrvOpenOffs->GetEndPoint( ptEND) ;
- Vector3d vtSTART ; pCrvOpenOffs->GetStartDir( vtSTART) ;
- Vector3d vtEND ; pCrvOpenOffs->GetEndDir( vtEND) ;
+ //// recupero i punti e i vettori tangenti iniziali e finali del lato aperto
+ // Point3d ptSTART ; pCrvOpenOffs->GetStartPoint( ptSTART) ;
+ // Point3d ptEND ; pCrvOpenOffs->GetEndPoint( ptEND) ;
+ // Vector3d vtSTART ; pCrvOpenOffs->GetStartDir( vtSTART) ;
+ // Vector3d vtEND ; pCrvOpenOffs->GetEndDir( vtEND) ;
- // -------------- CREAZIONE DELLA REGIONE DI INFLUENZA --------------
- // 1) Creo una copia della curva
- PtrOwner pCrvOpen_clone( CloneCurveComposite( pCrvOpen)) ;
- if ( IsNull( pCrvOpen_clone) || ! pCrvOpen_clone->IsValid())
- return false ;
- // 2) Controllo la lunghezza della curva
- double dLen ;
- if ( ! pCrvOpen_clone->GetLength( dLen) || dLen < dDiam + EPS_SMALL)
- return false ;
- // 3) Accorcio l'inizio e la fine del raggio dell'utensile
- double dUS, dUE ;
- pCrvOpen_clone->GetParamAtLength( dRad, dUS) ;
- pCrvOpen_clone->GetParamAtLength( dLen - dRad, dUE) ;
- if ( ! pCrvOpen_clone->TrimStartEndAtParam( dUS, dUE))
- pCrvOpen->Clear() ;
- bool bOk = true ;
- // 4) Creo regione squadrata da questa curva
- PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad , true, false)) ;
- if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) {
- Point3d ptE ;
- pCrvOpenOffs->GetEndPoint( ptE) ;
- PtrOwner pCrv_CompoHelp( CreateCurveComposite()) ;
- pCrv_CompoHelp->AddCurve( pCrvOpen->Clone()) ;
- pCrv_CompoHelp->AddLine( ptE) ;
- PtrOwner pCrvOpenOffs_Clone( CloneCurveComposite( pCrvOpenOffs)) ;
- pCrvOpenOffs_Clone->Invert() ;
- pCrv_CompoHelp->AddCurve( Release( pCrvOpenOffs_Clone)) ;
- pCrvOpen->GetStartPoint( ptE) ;
- pCrv_CompoHelp->AddLine( ptE) ;
- pSfrInc.Set( CreateSurfFlatRegion()) ;
- pSfrInc->AddExtLoop( Release( pCrv_CompoHelp)) ;
- bOk = false ;
- if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
- return false ;
- }
+ //// -------------- CREAZIONE DELLA REGIONE DI INFLUENZA --------------
+ // // 1) Creo una copia della curva
+ // PtrOwner pCrvOpen_clone( CloneCurveComposite( pCrvOpen)) ;
+ // if ( IsNull( pCrvOpen_clone) || ! pCrvOpen_clone->IsValid())
+ // return false ;
+ // // 2) Controllo la lunghezza della curva
+ // double dLen ;
+ // if ( ! pCrvOpen_clone->GetLength( dLen) || dLen < dDiam + EPS_SMALL)
+ // return false ;
+ // // 3) Accorcio l'inizio e la fine del raggio dell'utensile
+ // double dUS, dUE ;
+ // pCrvOpen_clone->GetParamAtLength( dRad, dUS) ;
+ // pCrvOpen_clone->GetParamAtLength( dLen - dRad, dUE) ;
+ // if ( ! pCrvOpen_clone->TrimStartEndAtParam( dUS, dUE))
+ // pCrvOpen->Clear() ;
+ // bool bOk = true ;
+ // // 4) Creo regione squadrata da questa curva
+ // PtrOwner pSfrInc( GetSurfFlatRegionFromFatCurve( Release( pCrvOpen_clone), dRad , true, false)) ;
+ // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid()) {
+ // Point3d ptE ;
+ // pCrvOpenOffs->GetEndPoint( ptE) ;
+ // PtrOwner pCrv_CompoHelp( CreateCurveComposite()) ;
+ // pCrv_CompoHelp->AddCurve( pCrvOpen->Clone()) ;
+ // pCrv_CompoHelp->AddLine( ptE) ;
+ // PtrOwner pCrvOpenOffs_Clone( CloneCurveComposite( pCrvOpenOffs)) ;
+ // pCrvOpenOffs_Clone->Invert() ;
+ // pCrv_CompoHelp->AddCurve( Release( pCrvOpenOffs_Clone)) ;
+ // pCrvOpen->GetStartPoint( ptE) ;
+ // pCrv_CompoHelp->AddLine( ptE) ;
+ // pSfrInc.Set( CreateSurfFlatRegion()) ;
+ // pSfrInc->AddExtLoop( Release( pCrv_CompoHelp)) ;
+ // bOk = false ;
+ // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
+ // return false ;
+ // }
- // -------------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA --------------
- // creo un vettore con la pCompo senza lato aperto e le isole contenute al suo interno
- ICRVCOMPOPOVECTOR vCrvToCheck ;
- vCrvToCheck.emplace_back( pCompo_noOpenCrv->Clone()) ; // la curva esterna in prima posizione
- for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i)
- vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ;
+ //// -------------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA --------------
+ //// creo un vettore con la pCompo senza lato aperto e le isole contenute al suo interno
+ // ICRVCOMPOPOVECTOR vCrvToCheck ;
+ // vCrvToCheck.emplace_back( pCompo_noOpenCrv->Clone()) ; // la curva esterna in prima posizione
+ // for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i)
+ // vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ;
- // scorro il vettore creato...
- for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) {
- // 1) recupero la curva corrente
- PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ;
- if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
- continue ;
+ //// scorro il vettore creato...
+ // for ( int c = 0 ; c < ( int)vCrvToCheck.size() ; ++ c) {
+ // // 1) recupero la curva corrente
+ // PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ;
+ // if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
+ // continue ;
- CRVCVECTOR ccClass ;
- if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) {
- for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) {
- if ( ccClass[i].nClass == CRVC_IN) {
- // 2) Trovo il tratto di curva interno
- PtrOwner pCrvCurrPartIn_( CloneCurveComposite( pCrvCurr)) ;
- if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
- return false ;
- if ( ! pCrvCurrPartIn_->TrimStartEndAtParam( ccClass[i].dParS, ccClass[i].dParE))
- pCrvCurrPartIn_->Clear() ;
- if ( IsNull( pCrvCurrPartIn_) || ! pCrvCurrPartIn_->IsValid())
- continue ;
+ // CRVCVECTOR ccClass ;
+ // if ( pSfrInc->GetCurveClassification( *pCrvCurr, EPS_SMALL, ccClass)) {
+ // for ( int i = 0 ; i < ( int)ccClass.size() ; ++ i) {
+ // if ( ccClass[i].nClass == CRVC_IN) {
+ // // 2) Trovo il tratto di curva interno
+ // PtrOwner pCrvCurrPartIn_( CloneCurveComposite( pCrvCurr)) ;
+ // if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
+ // return false ;
+ // if ( ! pCrvCurrPartIn_->TrimStartEndAtParam( ccClass[i].dParS, ccClass[i].dParE))
+ // pCrvCurrPartIn_->Clear() ;
+ // if ( IsNull( pCrvCurrPartIn_) || ! pCrvCurrPartIn_->IsValid())
+ // continue ;
- // Cerco solo i tratti di curva che sono chiusi
- ICURVEPOVECTOR vCrvOpen, vCrvClose ;
- if ( ! GetHomogeneousParts( pCrvCurrPartIn_, vCrvOpen, vCrvClose))
- return false ;
+ // // Cerco solo i tratti di curva che sono chiusi
+ // ICURVEPOVECTOR vCrvOpen, vCrvClose ;
+ // if ( ! GetHomogeneousParts( pCrvCurrPartIn_, vCrvOpen, vCrvClose))
+ // return false ;
- for ( int t_Open = 0 ; t_Open < ( int)vCrvClose.size() ; ++ t_Open) {
- PtrOwner pCrvCurrPartIn( CreateCurveComposite()) ;
- pCrvCurrPartIn->AddCurve( vCrvClose[t_Open]->Clone()) ;
- if ( IsNull( pCrvCurrPartIn) || ! pCrvCurrPartIn->IsValid())
- continue ;
- pCrvCurrPartIn->SetExtrusion( vtExtr) ;
- PtrOwner pCrvCurrPartIn_Clone( CloneCurveComposite( pCrvCurrPartIn)) ;
- if ( IsNull( pCrvCurrPartIn_Clone) || ! pCrvCurrPartIn_Clone->IsValid())
- continue ;
+ // for ( int t_Open = 0 ; t_Open < ( int)vCrvClose.size() ; ++ t_Open) {
+ // PtrOwner pCrvCurrPartIn( CreateCurveComposite()) ;
+ // pCrvCurrPartIn->AddCurve( vCrvClose[t_Open]->Clone()) ;
+ // if ( IsNull( pCrvCurrPartIn) || ! pCrvCurrPartIn->IsValid())
+ // continue ;
+ // pCrvCurrPartIn->SetExtrusion( vtExtr) ;
+ // PtrOwner pCrvCurrPartIn_Clone( CloneCurveComposite( pCrvCurrPartIn)) ;
+ // if ( IsNull( pCrvCurrPartIn_Clone) || ! pCrvCurrPartIn_Clone->IsValid())
+ // continue ;
- // 3) ricavo il punto iniziale e il punto finale, assieme ai vettori tangenti
- Point3d ptS1 ; pCrvCurrPartIn->GetStartPoint( ptS1) ;
- Point3d ptE1 ; pCrvCurrPartIn->GetEndPoint( ptE1) ;
- Vector3d vtS1 ; pCrvCurrPartIn->GetStartDir( vtS1) ;
- Vector3d vtE1 ; pCrvCurrPartIn->GetEndDir( vtE1) ;
+ // // 3) ricavo il punto iniziale e il punto finale, assieme ai vettori tangenti
+ // Point3d ptS1 ; pCrvCurrPartIn->GetStartPoint( ptS1) ;
+ // Point3d ptE1 ; pCrvCurrPartIn->GetEndPoint( ptE1) ;
+ // Vector3d vtS1 ; pCrvCurrPartIn->GetStartDir( vtS1) ;
+ // Vector3d vtE1 ; pCrvCurrPartIn->GetEndDir( vtE1) ;
- // 4) effettuo l'Offset della curva del diametro del tool
- OffsetCurve OffsCrv ;
- if ( ! OffsCrv.Make( pCrvCurrPartIn_Clone, - dDiam, ICurve::OFF_FILLET)) {
- m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
- return false ;
- }
+ // // 4) effettuo l'Offset della curva del diametro del tool
+ // OffsetCurve OffsCrv ;
+ // if ( ! OffsCrv.Make( pCrvCurrPartIn_Clone, - dDiam, ICurve::OFF_FILLET)) {
+ // m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
+ // return false ;
+ // }
- // 5) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti
- PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
- while ( ! IsNull( pOffLongestCrv)) {
- // 6) escludo le curve che si chiudono su se stesse dopo l'Offset
- if ( ! pOffLongestCrv->IsClosed()) {
- // 7) trasformo la curva in composita
- PtrOwner pCompoPartInOffs( CreateCurveComposite()) ;
- pCompoPartInOffs->AddCurve( pOffLongestCrv->Clone()) ;
- // 8) creo due archi che collegano i punti iniziali e finali della curva originale e di quella con offset
- PtrOwner pArcS( CreateCurveArc()) ;
- PtrOwner pArcE( CreateCurveArc()) ;
- if ( IsNull( pArcS) || IsNull( pArcE))
- return false ;
- Point3d ptS2 ; pCompoPartInOffs->GetStartPoint( ptS2) ;
- Point3d ptE2 ; pCompoPartInOffs->GetEndPoint( ptE2) ;
- Vector3d vtS2 ; pCompoPartInOffs->GetStartDir( vtS2) ;
- Vector3d vtE2 ; pCompoPartInOffs->GetEndDir( vtE2) ;
- pArcS->Set2PVN( ptS1, ptS2, - vtS1, - vtExtr) ;
- pArcE->Set2PVN( ptE2, ptE1, vtE2, - vtExtr) ;
- // 9) creo il loop esterno della regione da aggiungere
- PtrOwner pCrvExtBorder( CreateCurveComposite()) ;
- if ( IsNull( pCrvExtBorder))
- return false ;
- pCrvExtBorder->AddCurve( Release( pArcS)) ; // primo tratto lineare
- pCrvExtBorder->AddCurve( Release( pCompoPartInOffs)) ; // tratto di offset
- pCrvExtBorder->AddCurve( Release( pArcE)) ; // secondo tratto lineare
- pCrvCurrPartIn->Invert() ; // inversione del tratto interno
- pCrvExtBorder->AddCurve( pCrvCurrPartIn->Clone()) ; // aggiunta del tratto interno
+ // // 5) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti
+ // PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
+ // while ( ! IsNull( pOffLongestCrv)) {
+ // // 6) escludo le curve che si chiudono su se stesse dopo l'Offset
+ // if ( ! pOffLongestCrv->IsClosed()) {
+ // // 7) trasformo la curva in composita
+ // PtrOwner pCompoPartInOffs( CreateCurveComposite()) ;
+ // pCompoPartInOffs->AddCurve( pOffLongestCrv->Clone()) ;
+ // // 8) creo due archi che collegano i punti iniziali e finali della curva originale e di quella con offset
+ // PtrOwner pArcS( CreateCurveArc()) ;
+ // PtrOwner pArcE( CreateCurveArc()) ;
+ // if ( IsNull( pArcS) || IsNull( pArcE))
+ // return false ;
+ // Point3d ptS2 ; pCompoPartInOffs->GetStartPoint( ptS2) ;
+ // Point3d ptE2 ; pCompoPartInOffs->GetEndPoint( ptE2) ;
+ // Vector3d vtS2 ; pCompoPartInOffs->GetStartDir( vtS2) ;
+ // Vector3d vtE2 ; pCompoPartInOffs->GetEndDir( vtE2) ;
+ // pArcS->Set2PVN( ptS1, ptS2, - vtS1, - vtExtr) ;
+ // pArcE->Set2PVN( ptE2, ptE1, vtE2, - vtExtr) ;
+ // // 9) creo il loop esterno della regione da aggiungere
+ // PtrOwner pCrvExtBorder( CreateCurveComposite()) ;
+ // if ( IsNull( pCrvExtBorder))
+ // return false ;
+ // pCrvExtBorder->AddCurve( Release( pArcS)) ; // primo tratto lineare
+ // pCrvExtBorder->AddCurve( Release( pCompoPartInOffs)) ; // tratto di offset
+ // pCrvExtBorder->AddCurve( Release( pArcE)) ; // secondo tratto lineare
+ // pCrvCurrPartIn->Invert() ; // inversione del tratto interno
+ // pCrvExtBorder->AddCurve( pCrvCurrPartIn->Clone()) ; // aggiunta del tratto interno
- if ( pCrvExtBorder->IsClosed()) {
- // 9) Creo la nuova regione da aggiungere a quella di influenza
- PtrOwner pSfrExpan( CreateSurfFlatRegion()) ;
- if ( IsNull( pSfrExpan))
- return false ;
- pSfrExpan->AddExtLoop( Release( pCrvExtBorder)) ;
- if ( pSfrExpan->IsValid()) {
- if ( AreOppositeVectorApprox( pSfrExpan->GetNormVersor(), vtExtr))
- pSfrExpan->Invert() ;
+ // if ( pCrvExtBorder->IsClosed()) {
+ // // 9) Creo la nuova regione da aggiungere a quella di influenza
+ // PtrOwner pSfrExpan( CreateSurfFlatRegion()) ;
+ // if ( IsNull( pSfrExpan))
+ // return false ;
+ // pSfrExpan->AddExtLoop( Release( pCrvExtBorder)) ;
+ // if ( pSfrExpan->IsValid()) {
+ // if ( AreOppositeVectorApprox( pSfrExpan->GetNormVersor(), vtExtr))
+ // pSfrExpan->Invert() ;
- // ----------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA ----------
- PtrOwner pSfrInc_c( CloneSurfFlatRegion( pSfrInc)) ;
- if ( IsNull( pSfrInc_c))
- return false ;
- if ( pSfrInc_c->Subtract( *pSfrExpan)) {
- pSfrInc->Clear() ;
- for ( int cc = 0 ; cc < pSfrInc_c->GetChunkCount() ; ++ cc) {
- CRVCVECTOR ccClass_cc ;
- PtrOwner pSfrChunk_cc( pSfrInc_c->CloneChunk( cc)) ;
- if ( pSfrChunk_cc->GetCurveClassification( *pCrvOpen, EPS_SMALL, ccClass_cc)) {
- for ( int jj = 0 ; jj < ( int)ccClass_cc.size() ; ++ jj) {
- if ( ccClass_cc[jj].nClass == CRVC_IN) {
- if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
- pSfrInc.Set( pSfrChunk_cc->Clone()) ;
- else
- pSfrInc->Add( *pSfrChunk_cc) ;
- break ;
- }
- }
- }
- }
- }
- pSfrInc->Add( *pSfrExpan) ;
- }
- }
- }
- pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ;
- }
- }
- }
- }
- }
- else
- return false ;
- }
+ // // ----------- AGGIORNAMENTO DELLA REGIONE DI INFLUENZA ----------
+ // PtrOwner pSfrInc_c( CloneSurfFlatRegion( pSfrInc)) ;
+ // if ( IsNull( pSfrInc_c))
+ // return false ;
+ // if ( pSfrInc_c->Subtract( *pSfrExpan)) {
+ // pSfrInc->Clear() ;
+ // for ( int cc = 0 ; cc < pSfrInc_c->GetChunkCount() ; ++ cc) {
+ // CRVCVECTOR ccClass_cc ;
+ // PtrOwner pSfrChunk_cc( pSfrInc_c->CloneChunk( cc)) ;
+ // if ( pSfrChunk_cc->GetCurveClassification( *pCrvOpen, EPS_SMALL, ccClass_cc)) {
+ // for ( int jj = 0 ; jj < ( int)ccClass_cc.size() ; ++ jj) {
+ // if ( ccClass_cc[jj].nClass == CRVC_IN) {
+ // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
+ // pSfrInc.Set( pSfrChunk_cc->Clone()) ;
+ // else
+ // pSfrInc->Add( *pSfrChunk_cc) ;
+ // break ;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // pSfrInc->Add( *pSfrExpan) ;
+ // }
+ // }
+ // }
+ // pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // else
+ // return false ;
+ // }
- // recupero il Grezzo e sottraggo tutto ciò che sta nella regione
- if ( pStmRaw != nullptr) {
- bool bIsChanged ;
- if ( m_bIntersRaw) {
- PtrOwner pSrfInc_Copy( CloneSurfFlatRegion( pSfrInc)) ;
- int nChunkBef = pSfrInc->GetChunkCount() ;
- if ( ! IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false))
- return false ;
- if ( IsNull( pSfrInc) || ! pSfrInc->IsValid() || pSfrInc->GetChunkCount() == 0 ||
- ( nChunkBef < pSfrInc->GetChunkCount()))
- pSfrInc.Set( pSrfInc_Copy) ;
- }
- }
- if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
- return false ;
+ //// recupero il Grezzo e sottraggo tutto ciò che sta nella regione
+ // if ( pStmRaw != nullptr) {
+ // bool bIsChanged ;
+ // if ( m_bIntersRaw) {
+ // PtrOwner pSrfInc_Copy( CloneSurfFlatRegion( pSfrInc)) ;
+ // int nChunkBef = pSfrInc->GetChunkCount() ;
+ // if ( ! IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false))
+ // return false ;
+ // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid() || pSfrInc->GetChunkCount() == 0 ||
+ // ( nChunkBef < pSfrInc->GetChunkCount()))
+ // pSfrInc.Set( pSrfInc_Copy) ;
+ // }
+ // }
+ // if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
+ // return false ;
- // RECUPERO DELLA CURVA DI BORDO ESTERNA DA AGGIUNGERE ALLA SVUOTATURA
- PtrOwner pCrvNewBorder( GetCurveComposite( pSfrInc->GetLoop( 0, 0))) ;
- if ( IsNull( pCrvNewBorder))
- return false ;
+ //// RECUPERO DELLA CURVA DI BORDO ESTERNA DA AGGIUNGERE ALLA SVUOTATURA
+ // PtrOwner pCrvNewBorder( GetCurveComposite( pSfrInc->GetLoop( 0, 0))) ;
+ // if ( IsNull( pCrvNewBorder))
+ // return false ;
- if ( ! AreSamePointApprox( ptCrvOpenE, ptCrvOpenS)) {
- double dUSTART ;
- if ( ! pCrvNewBorder->GetParamAtPoint( ptSTART, dUSTART, 5000 * EPS_SMALL)) {
- int nFlag ;
- if ( ! DistPointCurve( ptSTART, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUSTART, nFlag))
- return false ;
- }
- pCrvNewBorder->ChangeStartPoint( dUSTART) ;
- double dUEND ;
- if ( ! pCrvNewBorder->GetParamAtPoint( ptEND, dUEND, 5000 * EPS_SMALL)) {
- int nFlag ;
- if ( ! DistPointCurve( ptEND, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUEND, nFlag))
- return false ;
- }
- if ( ! pCrvNewBorder->TrimEndAtParam( dUEND))
- pCrvNewBorder->Clear() ;
- }
+ // if ( ! AreSamePointApprox( ptCrvOpenE, ptCrvOpenS)) {
+ // double dUSTART ;
+ // if ( ! pCrvNewBorder->GetParamAtPoint( ptSTART, dUSTART, 5000 * EPS_SMALL)) {
+ // int nFlag ;
+ // if ( ! DistPointCurve( ptSTART, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUSTART, nFlag))
+ // return false ;
+ // }
+ // pCrvNewBorder->ChangeStartPoint( dUSTART) ;
+ // double dUEND ;
+ // if ( ! pCrvNewBorder->GetParamAtPoint( ptEND, dUEND, 5000 * EPS_SMALL)) {
+ // int nFlag ;
+ // if ( ! DistPointCurve( ptEND, *pCrvNewBorder).GetParamAtMinDistPoint( 0, dUEND, nFlag))
+ // return false ;
+ // }
+ // if ( ! pCrvNewBorder->TrimEndAtParam( dUEND))
+ // pCrvNewBorder->Clear() ;
+ // }
- pNewCrv->Clear() ;
- pNewCrv->AddCurve( Release( pCrvNewBorder)) ;
- for ( int u = 0 ; u < pNewCrv->GetCurveCount() ; ++ u)
- pNewCrv->SetCurveTempProp( u, 1, 0) ;
+ // pNewCrv->Clear() ;
+ // pNewCrv->AddCurve( Release( pCrvNewBorder)) ;
+ // for ( int u = 0 ; u < pNewCrv->GetCurveCount() ; ++ u)
+ // pNewCrv->SetCurveTempProp( u, 1, 0) ;
return true ;
}
@@ -10029,8 +10529,8 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR&
{
// se cerco semplicemente il tratto lineare chiuso più lungo ...
if ( ! bOrder) {
- // cerco il tratto lineare più lungo che non sia aperto
- int i = 0 ;
+ // la priorità è essagnata ai tratti lineari chiusi
+ int i = 0 ; // <--- indice della curva corrente
int nMax = - 1 ;
double dLenMax = 0 ;
const ICurve* pCrv = pCompo->GetFirstCurve() ;
@@ -10043,7 +10543,7 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR&
++ i ;
pCrv = pCompo->GetNextCurve() ;
}
- // se non trovato o troppo corto, cerco il tratto generico più lungo
+ // se non trovato o troppo corto, cerco il tratto chiuso più lungo in generale
if ( nMax < 0 || dLenMax < 2 * m_TParams.m_dDiam) {
i = 0 ;
pCrv = pCompo->GetFirstCurve() ;
@@ -10057,15 +10557,26 @@ Pocketing::AdjustContourStart( ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR&
pCrv = pCompo->GetNextCurve() ;
}
}
+ // controllo che il tratto chiuso più lungo trovato sia sufficientemente lungo
+ if ( dLenMax < 10 * EPS_SMALL) {
+ // se troppo piccolo allora lo imposto aperto
+ pCompo->SetCurveTempProp( nMax, 0, 1) ;
+ // spezzo la curva nel primo tratto aperto sufficientemente lungo
+ for ( int u = 0 ; u < pCompo->GetCurveCount() ; ++ u) {
+ double dLen ; pCompo->GetCurve( u)->GetLength( dLen) ;
+ if ( dLen > 10 * EPS_SMALL) {
+ nMax = u ;
+ continue ;
+ }
+ }
+ }
- const ICurve* pCrvClone( pCompo->GetCurve( nMax)) ;
- double dPar ;
- if ( GetParamForPtStartOnEdge( pCrvClone, pCompo, vCrvIsl, dPar))
- pCompo->ChangeStartPoint( nMax + dPar) ;
- else
- // sposto inizio a metà
- if ( nMax >= 0)
- pCompo->ChangeStartPoint( nMax + 0.5) ;
+ // se non trovato, imposto il punto iniziale a mentà del primo tratto
+ if ( nMax == -1) {
+ pCompo->ChangeStartPoint( 0.5) ;
+ return true ;
+ }
+ pCompo->ChangeStartPoint( nMax + 0.5) ;
}
// se invece sto cercando di entrare da un lato chiuso per una svuotatura, allora riordino i lati
// chiusi a seconda della lunghezza, e a partire dal più lungo cerco un parametro su tale curva che mi consenta
@@ -10982,7 +11493,9 @@ Pocketing::ProjectStmOnPlane( const ISurfTriMesh* pStmAbove, const Plane3d plPoc
else // se Up non valida -> copio
pSfrProj->CopyFrom( pSfrUp1) ;
}
-
+ // se nessuna delle due è valida, non ritorno nulla
+ if ( ! pSfrUp->IsValid() && ! pSfrUp1->IsValid())
+ return true ;
return pSfrProj != nullptr && pSfrProj->IsValid() && pSfrProj->GetChunkCount() != 0 ;
}
@@ -11246,349 +11759,350 @@ bool
Pocketing::AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSfrOrig, const ISurfTriMesh* pStmRaw,
const Vector3d vtTrasl, bool bFromProj)
{
- //if ( ! bFromProj)
+ // //if ( ! bFromProj)
+ // return true ;
+
+ //// controllo dei parametri
+ // if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0)
+ // return false ;
+ // if ( pStmRaw == nullptr) // se non c'è grezzo...
+ // return true ;
+
+ //// recupero le tmpProp, vettore estrusione e spessore
+ // int nTmpProp0 = pCrvCompo->GetTempProp() ;
+ // int nTmpProp1 = pCrvCompo->GetTempProp( 1) ;
+ // Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ;
+ // double dThick ; pCrvCompo->GetThickness( dThick) ;
+
+ //// -------------------- TAGLIO IL GREZZO CON IL PIANO DEFINITO ALLO STEP ATTUALE -------------
+ // // 1) CREAZIONE DEL PIANO
+ // Plane3d plProj ;
+ // Point3d ptCen ;
+ // if ( ! pCrvCompo->GetCentroid( ptCen)) // punto
+ // if ( ! pCrvCompo->GetStartPoint( ptCen))
+ // return false ;
+ // Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale
+ // if ( vtNorm.IsSmall())
+ // return false ;
+ // plProj.Set( ptCen + vtTrasl, -vtNorm) ; // così taglio tutto cià che sta nel semipiano negativo dello step attuale
+ // if ( ! plProj.IsValid())
+ // return false ;
+ //// 2) TAGLIO DEL GREZZO
+ // PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ;
+ // if ( IsNull( pSrfRaw_clone))
+ // return false ;
+ // if ( ! pSrfRaw_clone->Cut( plProj, true))
+ // return false ;
+ // if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0)
+ // return true ;
+ //// -------------------------------------------------------------------------------------------
+
+ // // ------- PROIEZIONE DELLE CURVE DI OGNI FACCIA DEL GREZZO RICAVATO SUL PIANO DELLA SVUOTATURA --------------
+ //// Proietto ora le curve, delle facce della superificie ottenuta, sul piano della svuotatura
+ // ICRVCOMPOPOVECTOR vCrvExtProj ;
+ // PtrOwner pCrvCompo_Clone_Trasl( CloneCurveComposite( pCrvCompo)) ;
+ // if ( IsNull( pCrvCompo_Clone_Trasl) || ! pCrvCompo_Clone_Trasl->IsValid())
+ // return false ;
+ // pCrvCompo_Clone_Trasl->Translate( vtTrasl) ;
+ // vCrvExtProj.emplace_back( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; // come indice 0
+
+ // for ( int f = 0 ; f < pSrfRaw_clone->GetFacetCount() ; ++ f) {
+ // // controllo se la faccia è quasi perpendicolare, nel caso la salto
+ // Vector3d vtN_check ; pSrfRaw_clone->GetFacetNormal( f, vtN_check) ;
+ // if ( abs( vtN_check * vtNorm) < EPS_ZERO)
+ // continue ;
+ // POLYLINEVECTOR vPL ;
+ // pSrfRaw_clone->GetFacetLoops( f, vPL) ;
+ // // per ogni Loop l della faccia f
+ // for ( int l = 0 ; l < ( int) vPL.size() ; ++ l) {
+ // PtrOwner pCrvBorder( CreateCurveComposite()) ;
+ // if ( IsNull( pCrvBorder) || ! pCrvBorder->FromPolyLine( vPL[l]))
+ // return false ;
+ // PtrOwner pCrvProjFacef( ProjectCurveOnPlane( *pCrvBorder, plProj)) ;
+ // if ( IsNull( pCrvProjFacef) || ! pCrvProjFacef->IsValid())
+ // return false ;
+ // // controllo validità della curva ( che sia chiusa e non degenere)
+ // double dArea = EPS_SMALL ;
+ // Plane3d plCheck ;
+ // if ( ! pCrvProjFacef->IsClosed() || ! pCrvProjFacef->GetArea( plCheck, dArea) || dArea <= EPS_SMALL)
+ // continue ;
+ // // creo la curva composita associata
+ // PtrOwner pCrvBorderProj_f( CreateCurveComposite()) ;
+ // pCrvBorderProj_f->AddCurve( Release( pCrvProjFacef)) ;
+ // vCrvExtProj.emplace_back( Release( pCrvBorderProj_f)) ;
+ // }
+ // }
+ ////-------------------------------------------------------------------------------------------------------------
+
+ //// ---------------- CREAZIONE DELLA VERA A PROPRIA REGIONE DI INCIDENZA, COME SOMMA DELLE
+ //// ----------------------------- SINGOLE FLATREGIONS DI PROIEZIONE -----------------------------
+ // PtrOwner pSrf_Proj_Ext( CreateSurfFlatRegion()) ;
+ // if ( IsNull( pSrf_Proj_Ext))
+ // return false ;
+
+ // for ( int i = 1 ; i < ( int)vCrvExtProj.size() ; ++ i) {
+ // PtrOwner pSrf_H( CreateSurfFlatRegion()) ;
+ // if ( IsNull( pSrf_H))
+ // return false ;
+ // pSrf_H->AddExtLoop( vCrvExtProj[i]->Clone()) ;
+ // // inverto se le normali risultano opposte
+ // if ( pSrf_H->IsValid()) {
+ // if ( AreOppositeVectorApprox( pSrf_H->GetNormVersor() , pSfrOrig->GetNormVersor()))
+ // pSrf_H->Invert() ;
+ // }
+ // if ( pSrf_Proj_Ext->GetChunkCount() == 0)
+ // pSrf_Proj_Ext.Set( Release( pSrf_H)) ;
+ // else
+ // pSrf_Proj_Ext->Add( *pSrf_H) ;
+ // }
+
+ //// creo la vera e propria regione di proiezione, sommando la proiezione esterna con la superifcie originale da svuotare
+ // PtrOwner pSrf_Proj( CloneSurfFlatRegion( pSrf_Proj_Ext)) ;
+ // PtrOwner pSrf_ind0( CreateSurfFlatRegion()) ;
+ // if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid() || IsNull( pSrf_ind0))
+ // return false ;
+ // pSrf_ind0->AddExtLoop( vCrvExtProj[0]->Clone()) ;
+ // if ( AreOppositeVectorApprox( pSrf_ind0->GetNormVersor(), pSfrOrig->GetNormVersor()))
+ // pSrf_ind0->Invert() ;
+ // pSrf_Proj->Add( *pSrf_ind0) ;
+
+ // if ( ! bFromProj) {
+ // //int ooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_Proj->Clone()) ;
+ // //m_pGeomDB->SetMaterial( ooo, Color( 0.0, 1.0, 0.0, 0.3)) ;
+ // }
+
+ //// ===============================================================================================================
+
+ //// Clono la superificie originaria, portandola allo step corrente
+ // PtrOwner pSrfOrig_clone( CloneSurfFlatRegion( pSfrOrig)) ;
+ // if ( IsNull( pSrfOrig_clone) || ! pSrfOrig_clone->IsValid())
+ // return false ;
+ // pSrfOrig_clone->Translate( vtTrasl) ;
+ // if ( ! bFromProj) {
+ // //int oooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfOrig_clone->Clone()) ;
+ // //m_pGeomDB->SetMaterial( oooo, Color( 0.0, 0.0, 0.0, 0.3)) ;
+ // }
+
+
+ // bool bLoopL_isChanged = false ; // flag di indetificazione di un Fake Open Edge
+ // const int MAX_TRY = 10 ; // numero di raffinamenti massimi
+ // int nCont = -1 ; // contatore dei raffinamenti
+ //// OGNI VOLTA CHE INDIVIDUO UN LATO APERTO CHE IN REALTA' DEVE ESSERE CHIUSO, QUEST'ULTIMO VIENE IMPOSTATO COME
+ //// CHIUSO ( FACENDO COSI', PERO', NON GARANTISCO CHE I LATI APERTI CORRETTI IN PRECEDENZA SIANO ANCORA
+ //// LATI APERTI CORRETTI, DEVO RIPETERE L'ALGORITMO....)
+
+ //// calcolo la regione critica
+ // PtrOwner pSrf_critica( CloneSurfFlatRegion( pSrf_Proj)) ;
+ // pSrf_critica->Subtract( *pSrfOrig_clone) ;
+
+ // do {
+ // ++nCont ;
+ // bLoopL_isChanged = false ;
+ // // creo i tratti di curva omogonei ( tratti uniformi chiusi o aperti)
+ // ICURVEPOVECTOR vCrvOpen ; ICURVEPOVECTOR vCrvClose ;
+ // if ( ! GetHomogeneousParts( pCrvCompo_Clone_Trasl, vCrvOpen, vCrvClose, true))
+ // return false ;
+
+ // // scorro tutti i tratti aperti
+ // for ( int t = 0 ; t < ( int)vCrvOpen.size() && !bLoopL_isChanged ; ++ t) {
+ // // 1) ricavo il tratto aperto t-esimo
+ // PtrOwner pCrvCompo_t_Open( CreateCurveComposite()) ;
+ // if ( IsNull( pCrvCompo_t_Open))
+ // return false ;
+ // pCrvCompo_t_Open->AddCurve( vCrvOpen[t]->Clone()) ;
+
+ // // 2) Ricavo il paramtro iniziale e finale sulla curva originale
+ // Point3d ptS ;
+ // double dU_jump ;
+ // pCrvCompo_t_Open->GetStartPoint( ptS) ;
+ // pCrvCompo_Clone_Trasl->GetParamAtPoint( ptS, dU_jump) ;
+
+ // // 3) effettuo l'Offset
+ // pCrvCompo_t_Open->SetExtrusion( vtExtr) ;
+ // OffsetCurve OffsCrv ;
+ // if ( ! OffsCrv.Make( pCrvCompo_t_Open, m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec + m_dOffsetR_Prec :
+ // 0.5 * m_TParams.m_dDiam + GetOffsR(), ICurve::OFF_FILLET))
+ // return false ;
+ // // -> se Offset non preduce nessuna curva, allora passo al tratto successivo
+ // int nCrv_offs = OffsCrv.GetCurveCount() ;
+ // if ( nCrv_offs == 0)
+ // continue ;
+ // PtrOwner pCrvlonger( OffsCrv.GetLongerCurve()) ;
+ // // -> per ogni curva di Offset
+ // while ( ! IsNull( pCrvlonger) && ! bLoopL_isChanged) {
+ // if ( ! pCrvlonger->IsClosed() || nCrv_offs == 1) { // salto le curve "chiuse" ( a meno che non sia l'unica)
+ // // 4) classifico la curva di offset ricavata con la supericie originale
+ // // NB. Tutti tratti di curva che sono esterni alla superificie originale e che si trovano all'interno della
+ // // superificie di proeizione del grezzo lo rovineranno al di fuori della superficie originale, quindi
+ // // vanno impostati come chiusi
+ // PtrOwner pCrv_tOpen_Offs( CloneCurveComposite( pCrvlonger)) ;
+ // if ( IsNull( pCrv_tOpen_Offs) || ! pCrv_tOpen_Offs->IsValid())
+ // return false ;
+ // if ( ! bFromProj) {
+ // //int YE = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_tOpen_Offs->Clone()) ;
+ // //m_pGeomDB->SetMaterial( YE, YELLOW) ;
+ // }
+ // CRVCVECTOR ccClass ;
+ // if ( pSrf_critica->GetCurveClassification( *pCrv_tOpen_Offs, 10 * EPS_SMALL, ccClass)) {
+ // for ( int j = 0 ; j < ( int)ccClass.size() && ! bLoopL_isChanged ; ++ j) {
+ // if ( ccClass[j].nClass == CRVC_IN) {
+ // // 7) se trovo una parte interna alla proeizione, allora devo ricavare la parte di curva
+ // // originaria ( della pCrvCompo_t_Open) relativa a questo tratto e impostarla come aperta
+ // // ... ricavo il tratto di curva
+ // int nRealDUS = ( int)floor( ccClass[j].dParS) ;
+ // int nRealDUE = ( int)floor( ccClass[j].dParE) ;
+ // if ( ceil( ccClass[j].dParS) - ccClass[j].dParS < 50 * EPS_SMALL)
+ // nRealDUS = ( int)ceil( ccClass[j].dParS) ;
+ // if ( abs( ccClass[j].dParE - ceil( ccClass[j].dParE)) < 50 * EPS_SMALL)
+ // nRealDUE = ( int)ceil( ccClass[j].dParE) ;
+
+ // // modifico il range per evitare indici errati
+ // nRealDUS = Clamp( nRealDUS, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ;
+ // nRealDUE = Clamp( nRealDUE, 0, pCrv_tOpen_Offs->GetCurveCount() - 1) ;
+
+ // // recupero la TempProp 0 della curva ( mi indica l'offset da chi deriva)
+ // int nCrvStart ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUS, nCrvStart, 0) ;
+ // -- nCrvStart ;
+ // int nCrvEnd ; pCrv_tOpen_Offs->GetCurveTempProp( nRealDUE, nCrvEnd, 0) ;
+ // -- nCrvEnd ;
+
+ // double dUStart ; // parametro relativo iniziale
+ // double dUEnd ; // parametro relativo finale
+
+ // PtrOwner CIAO( pCrv_tOpen_Offs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
+ // if ( ! bFromProj) {
+ // //int YEs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, CIAO->Clone()) ;
+ // //m_pGeomDB->SetMaterial( YEs, Color( 0.95, 0.0, 0.63, 1.0)) ;
+ // }
+
+ // // ------------------------------ PARAMETRO FINALE -----------------------------------
+ // // se non sono su un raccordo ...
+ // if ( nCrvEnd != -1) {
+ // dUEnd = max( 0., min( nCrvEnd + ( ccClass[j].dParE - ( int)ccClass[j].dParE),
+ // 1. * pCrv_tOpen_Offs->GetCurveCount())) ;
+ // if ( abs(( ccClass[j].dParE) - pCrv_tOpen_Offs->GetCurveCount()) < 50 * EPS_SMALL)
+ // ++ dUEnd ;
+ // }
+ // // se sono su un raccordo ...
+ // else {
+ // // cerco la prima tra le curve successive che non sia un raccordo
+ // int nCrvToAsk = ( int)( min( ccClass[j].dParE + 1, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ;
+ // int nCrvEndReal ;
+ // do {
+ // pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvEndReal, 0) ;
+ // ++ nCrvToAsk ;
+ // nCrvEndReal = min( nCrvEndReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ;
+ // } while ( nCrvEndReal == -1 && nCrvToAsk < pCrv_tOpen_Offs->GetCurveCount()) ;
+ // if ( nCrvEndReal == -1) // se non trovo -> tratto finale in proporzione
+ // dUEnd = pCrv_tOpen_Offs->GetCurveCount() - 1 + ( ccClass[j].dParE - ( int)ccClass[j].dParE) ;
+ // else { // seleziono il pezzo iniziale del primo tratto trovato ...
+ // const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvEndReal) ;
+ // double dLen = EPS_SMALL ;
+ // double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ;
+ // double dParShift = 1. ;
+ // if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin)
+ // dParShift = dLenMin / dLen ;
+ // dUEnd = max( 0.0 , min( nCrvEndReal + 0 + dParShift, 1. * ( pCrv_tOpen_Offs->GetCurveCount() - 1))) ;
+ // }
+ // }
+ // // ------------------------------ PARAMETRO INZIALE -----------------------------------
+ // // se non sono su un raccordo ...
+ // if ( nCrvStart != -1)
+ // dUStart = max( 0., min( nCrvStart + ( ccClass[j].dParS - ( int)ccClass[j].dParS),
+ // 1. * ( pCrv_tOpen_Offs->GetCurveCount()))) ;
+ // // se sono su un raccordo ...
+ // else {
+ // int nCrvToAsk = ( int)( max( 0., ccClass[j].dParS - 1)) ;
+ // int nCrvStartReal ;
+ // do {
+ // pCrv_tOpen_Offs->GetCurveTempProp( nCrvToAsk, nCrvStartReal, 0) ;
+ // --nCrvToAsk ;
+ // nCrvStartReal = min( nCrvStartReal, pCrv_tOpen_Offs->GetCurveCount()) - 1 ;
+ // } while ( nCrvStartReal == -1 && nCrvStartReal > 0) ;
+ // if ( nCrvStartReal == -1) // se non trovo -> tratto iniziale in proporzione
+ // nCrvStartReal = ccClass[j].dParS - ( int)ccClass[j].dParS ;
+ // else { // seleziono il pezzo finale del primo tratto trovato ...
+ // const ICurve* pCrv_forLen = pCrv_tOpen_Offs->GetCurve( nCrvStartReal) ;
+ // double dLen = EPS_SMALL ;
+ // double dLenMin = 0.05 * ( m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec : 0.5 * m_TParams.m_dDiam) ;
+ // double dParShift = 1. ;
+ // if ( pCrv_forLen != nullptr && pCrv_forLen->GetLength( dLen) && dLen > dLenMin)
+ // dParShift = dLenMin / dLen ;
+ // dUStart = max( 0., min( nCrvStartReal + 1 - dParShift, 1. * pCrv_tOpen_Offs->GetCurveCount())) ;
+ // }
+ // }
+
+ // // controllo...
+ // if ( dUStart > dUEnd)
+ // swap( dUStart, dUEnd) ;
+
+ // // tratto precente
+ // PtrOwner pCrv_Bef( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ;
+ // // tratto successivo
+ // PtrOwner pCrv_Aft( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ;
+ // // tratto corrente da mettere come chiuso
+ // PtrOwner pCrv_curr_Close( CreateCurveComposite()) ;
+ // // nuova curva...
+ // PtrOwner pCrv_New( CreateCurveComposite()) ;
+
+ // if ( IsNull( pCrv_Bef) || ! pCrv_Bef->IsValid() ||
+ // IsNull( pCrv_Aft) || ! pCrv_Aft->IsValid() ||
+ // IsNull( pCrv_curr_Close) ||
+ // IsNull( pCrv_New))
+ // return false ;
+
+ // // ricomposizione con tagli per non perdere le proprietà appena impostate
+ // dUStart += dU_jump ;
+ // dUEnd += dU_jump ;
+ // if ( ! pCrv_Bef->TrimEndAtParam( dUStart))
+ // pCrv_Bef->Clear() ;
+ // if ( ! pCrv_Aft->TrimStartAtParam( dUEnd))
+ // pCrv_Aft->Clear() ;
+ // if ( ! IsNull( pCrv_Bef) && pCrv_Bef->IsValid())
+ // pCrv_New->AddCurve( Release( pCrv_Bef)) ;
+ // pCrv_curr_Close->AddCurve( pCrvCompo_Clone_Trasl->CopyParamRange( dUStart, dUEnd)) ;
+
+ // for ( int uu = 0 ; uu < pCrv_curr_Close->GetCurveCount() ; ++ uu) {
+ // pCrv_curr_Close->SetCurveTempProp( uu, 0, 0) ; // chiusa
+ // pCrv_curr_Close->SetCurveTempProp( uu, -99, 1) ; // chiusa
+ // }
+
+ // if ( ! IsNull( pCrv_curr_Close) && pCrv_curr_Close->IsValid())
+ // pCrv_New->AddCurve( Release( pCrv_curr_Close)) ;
+ // else
+ // // se la nuova curva chiusa è piccola, la ignoro...
+ // continue ;
+
+ // if ( ! IsNull( pCrv_Aft) && pCrv_Aft->IsValid())
+ // pCrv_New->AddCurve( Release( pCrv_Aft)) ;
+ // // controllo validità della curva, altrimenti non modifico nulla ed esco ( Avrò un chiuso)
+ // if ( ! IsNull( pCrv_New) && pCrv_New->IsValid() && pCrv_New->IsClosed()) {
+ // pCrvCompo_Clone_Trasl.Set( Release( pCrv_New)) ;
+ // bLoopL_isChanged = true ;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // pCrvlonger.Set( OffsCrv.GetLongerCurve()) ;
+ // }
+ // }
+ // } while ( bLoopL_isChanged && nCont < MAX_TRY) ;
+
+ //// sotituisco la curva originale, traslo e miglioro...
+ // if ( ! IsNull( pCrvCompo_Clone_Trasl) && pCrvCompo_Clone_Trasl->IsValid() && pCrvCompo_Clone_Trasl->IsClosed()) {
+ // pCrvCompo_Clone_Trasl->Translate( - vtTrasl) ;
+ // pCrvCompo_Clone_Trasl->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
+ // pCrvCompo->Clear() ;
+ // pCrvCompo->CopyFrom( pCrvCompo_Clone_Trasl) ;
+ // pCrvCompo->SetExtrusion( vtExtr) ;
+ // pCrvCompo->SetThickness( dThick) ;
+ // pCrvCompo->SetTempProp( nTmpProp0, 0) ;
+ // pCrvCompo->SetTempProp( nTmpProp1, 1) ;
+ // }
+
+ // return pCrvCompo != nullptr && pCrvCompo->IsValid() && pCrvCompo->GetCurveCount() > 0 ;
return true ;
-
- // controllo dei parametri
- if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0)
- return false ;
- if ( pStmRaw == nullptr) // se non c'è grezzo...
- return true ;
-
- // recupero le tmpProp, vettore estrusione e spessore
- int nTmpProp0 = pCrvCompo->GetTempProp() ;
- int nTmpProp1 = pCrvCompo->GetTempProp( 1) ;
- Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ;
- double dThick ; pCrvCompo->GetThickness( dThick) ;
-
- // -------------------- TAGLIO IL GREZZO CON IL PIANO DEFINITO ALLO STEP ATTUALE -------------
- // 1) CREAZIONE DEL PIANO
- Plane3d plProj ;
- Point3d ptCen ;
- if ( ! pCrvCompo->GetCentroid( ptCen)) // punto
- if ( ! pCrvCompo->GetStartPoint( ptCen))
- return false ;
- Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale
- if ( vtNorm.IsSmall())
- return false ;
- plProj.Set( ptCen + vtTrasl, -vtNorm) ; // così taglio tutto cià che sta nel semipiano negativo dello step attuale
- if ( ! plProj.IsValid())
- return false ;
- // 2) TAGLIO DEL GREZZO
- PtrOwner pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ;
- if ( IsNull( pSrfRaw_clone))
- return false ;
- if ( ! pSrfRaw_clone->Cut( plProj, true))
- return false ;
- if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0)
- return true ;
- // -------------------------------------------------------------------------------------------
-
- // ------- PROIEZIONE DELLE CURVE DI OGNI FACCIA DEL GREZZO RICAVATO SUL PIANO DELLA SVUOTATURA --------------
- // Proietto ora le curve, delle facce della superificie ottenuta, sul piano della svuotatura
- ICRVCOMPOPOVECTOR vCrvExtProj ;
- PtrOwner pCrvCompo_Clone_Trasl( CloneCurveComposite( pCrvCompo)) ;
- if ( IsNull( pCrvCompo_Clone_Trasl) || ! pCrvCompo_Clone_Trasl->IsValid())
- return false ;
- pCrvCompo_Clone_Trasl->Translate( vtTrasl) ;
- vCrvExtProj.emplace_back( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; // come indice 0
-
- for ( int f = 0 ; f < pSrfRaw_clone->GetFacetCount() ; ++ f) {
- // controllo se la faccia è quasi perpendicolare, nel caso la salto
- Vector3d vtN_check ; pSrfRaw_clone->GetFacetNormal( f, vtN_check) ;
- if ( abs( vtN_check * vtNorm) < EPS_ZERO)
- continue ;
- POLYLINEVECTOR vPL ;
- pSrfRaw_clone->GetFacetLoops( f, vPL) ;
- // per ogni Loop l della faccia f
- for ( int l = 0 ; l < ( int) vPL.size() ; ++ l) {
- PtrOwner pCrvBorder( CreateCurveComposite()) ;
- if ( IsNull( pCrvBorder) || ! pCrvBorder->FromPolyLine( vPL[l]))
- return false ;
- PtrOwner pCrvProjFacef( ProjectCurveOnPlane( *pCrvBorder, plProj)) ;
- if ( IsNull( pCrvProjFacef) || ! pCrvProjFacef->IsValid())
- return false ;
- // controllo validità della curva ( che sia chiusa e non degenere)
- double dArea = EPS_SMALL ;
- Plane3d plCheck ;
- if ( ! pCrvProjFacef->IsClosed() || ! pCrvProjFacef->GetArea( plCheck, dArea) || dArea <= EPS_SMALL)
- continue ;
- // creo la curva composita associata
- PtrOwner