Compare commits

...

17 Commits

Author SHA1 Message Date
Riccardo Elitropi 72c71b817e EgtMachKernel :
- aggiunto orientalmento utensile per Finiture di superfici.
2026-06-10 12:20:35 +02:00
Riccardo Elitropi ad8a69b7e5 Merge branch 'master' of https://gitlab.steamware.net/egaltech/EgtMachKernel 2026-06-09 15:18:42 +02:00
Riccardo Elitropi 1395ba2c04 EgtMachKernel :
- in PocketingNT aggiunto Warning nel caso di svuotatura senza percorsi
- in PocketingNT migliorata la gestione della superficie limite per isole aperte.
2026-06-09 15:18:37 +02:00
Daniele Bariletti 1a4faa645c EgtMachKernel 3.1f2 :
- aggiunta funzione per la correzione di percorsi tool su angoli interni per lavorazioni a 5 assi.
- cambio versione.
2026-06-09 12:34:41 +02:00
Daniele Bariletti 69d128dbe9 Merge branch '5AxTrimming' 2026-06-09 12:32:40 +02:00
Daniele Bariletti d949864643 Merge branch 'master' into 5AxTrimming 2026-06-09 12:32:25 +02:00
Daniele Bariletti 94cf212333 EgtMachKernel :
- spostata funzione per il calcolo IntersLineCyl
- rimosso codice di debug.
2026-06-09 12:31:59 +02:00
Riccardo Elitropi bcfa3326b8 EgtMachKernel 3.1f1 :
- piccola correzione messaggio di errore in PocketingNT.
2026-06-09 10:20:54 +02:00
Riccardo Elitropi 38ceb12df8 EgtMachKernel 3.1e7 :
- in PocketingNT aggiunto controllo aggiuntivo per Silhouette del grezzo
- in PocketingNT aggiunto parametro da note utenti StartPoint.
2026-06-09 09:50:08 +02:00
Daniele Bariletti 8b8ad9af44 EgtMachKernel :
- aggiunta gestione per angoli interni smooth.
2026-06-05 12:07:38 +02:00
Riccardo Elitropi 1874f6b1f8 EgtMachKernel :
- in finiture migliorati i controlli per tipologia Optimal.
2026-05-29 16:49:28 +02:00
Riccardo Elitropi 981563b682 EgtMachKernel :
- in PocketingNT aggiunto LeadOut a scivolo per percorsi in ToolCompensation
- in PocketingNT aggiunto piccolo arco di raccordo per ingressi ai percorsi in ToolCompensation
- in PocketingNT correzioni varie.
2026-05-29 13:28:02 +02:00
Dario Sassi c848b82235 EgtMachKereel :
- ulteriori migliorie per correzione raggio fresa in macchina/CNC.
2026-05-28 22:52:57 +02:00
Dario Sassi b3366241a2 EgtMachKernel :
- messa a punto offset di Milling per correzione raggio fresa in macchina.
2026-05-27 19:28:59 +02:00
Riccardo Elitropi 31a701a0e3 EgtMachKernel :
- in Finitura di superficie rimozione parametro Offset radiale per considerazione sulla curva di bordo.
2026-05-27 17:31:06 +02:00
Riccardo Elitropi 040be553ad EgtMachKernel :
- aggiunta gestione Spiral  in Correzione utensile per Milling
- aggiunta gestione Tab e Oscillation in correzione utensile per Milling.
2026-05-27 13:37:34 +02:00
Riccardo Elitropi a747e7ecfb Merge commit 'dfa0069a0b402c0a45ddcc56b75056e8f0050962' 2026-05-26 17:01:04 +02:00
11 changed files with 2114 additions and 643 deletions
BIN
View File
Binary file not shown.
+1
View File
@@ -385,6 +385,7 @@ class Machine
static int LuaEmtRemoveClimb( lua_State* L) ;
static int LuaEmtAddRise( lua_State* L) ;
static int LuaEmtRemoveRise( lua_State* L) ;
static int LuaEmtAdjustConcavePartsInPath( lua_State* L) ;
static int LuaEmtGetMoveType( lua_State* L) ;
static int LuaEmtGetAxesPos( lua_State* L) ;
static int LuaEmtGetBackAuxDir( lua_State* L) ;
+1
View File
@@ -128,6 +128,7 @@ Machine::LuaInit( const string& sMachineName)
m_LuaMgr.RegisterFunction( "EmtGetInitialAxesPos", Machine::LuaEmtGetInitialAxesPos) ;
m_LuaMgr.RegisterFunction( "EmtGetFinalAxesPos", Machine::LuaEmtGetFinalAxesPos) ;
m_LuaMgr.RegisterFunction( "EmtGetCurrAxesHomePos", Machine::LuaEmtGetCurrAxesHomePos) ;
m_LuaMgr.RegisterFunction( "EmtAdjustConcavePartsInPath", Machine::LuaEmtAdjustConcavePartsInPath) ;
// registro le funzioni di lettura entità CL per lua
m_LuaMgr.RegisterFunction( "EmtGetMoveType", Machine::LuaEmtGetMoveType) ;
m_LuaMgr.RegisterFunction( "EmtGetAxesPos", Machine::LuaEmtGetAxesPos) ;
+259 -25
View File
@@ -19,12 +19,16 @@
#include "Operation.h"
#include "/EgtDev/Include/EXeExecutor.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkIntersLineCylinder.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkLuaAux.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/ENkPolynomialRoots.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
@@ -153,6 +157,41 @@ Machine::LuaEmtAddRapidMove( lua_State* L)
return 1 ;
}
//----------------------------------------------------------------------------
int
AddLinearMove( const Point3d& ptIni, const Point3d& ptFin, IGeomDB* pGeomDB , int nPathId, const Vector3d& vtTool,
const Vector3d& vtCorr, const Vector3d& vtAux, double dFeed, int nFlag, int nFlag2, bool bToolShow, int nRefId = GDB_ID_NULL)
{
// creo oggetto linea per DB geometrico
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
bool bOk = ! IsNull( pLine) ;
// assegno gli estremi della linea
bOk = bOk && pLine->Set( ptIni, ptFin) ;
// inserisco l'oggetto nel DB geometrico
int nId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pLine)) : GDB_ID_NULL) ;
bOk = bOk && ( nId != GDB_ID_NULL) ;
if ( bOk && nRefId != GDB_ID_NULL)
pGeomDB->RelocateGlob( nId, nRefId, GDB_AFTER) ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
bOk = bOk && ! IsNull( pCam) ;
if ( bOk) {
// assegno valori
pCam->SetMoveType( 1) ;
pCam->SetToolDir( vtTool) ;
pCam->SetCorrDir( vtCorr) ;
pCam->SetAuxDir( vtAux) ;
pCam->SetEndPoint( ptFin) ;
pCam->SetFeed( dFeed) ;
pCam->SetFlag( nFlag) ;
pCam->SetFlag2( nFlag2) ;
pCam->SetToolShow( bToolShow) ;
// associo questo oggetto a quello geometrico
pGeomDB->SetUserObj( nId, Release( pCam)) ;
}
return nId ;
}
//----------------------------------------------------------------------------
int
Machine::LuaEmtAddLinearMove( lua_State* L)
@@ -185,31 +224,8 @@ Machine::LuaEmtAddLinearMove( lua_State* L)
if ( m_pMchLua == nullptr ||
m_pMchLua->m_pMchMgr == nullptr || m_pMchLua->m_pGeomDB == nullptr)
return luaL_error( L, " Unknown Machine") ;
// creo oggetto linea per DB geometrico
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
bool bOk = ! IsNull( pLine) ;
// assegno gli estremi della linea
bOk = bOk && pLine->Set( ptIni, ptFin) ;
// inserisco l'oggetto nel DB geometrico
int nId = ( bOk ? m_pMchLua->m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pLine)) : GDB_ID_NULL) ;
bOk = bOk && ( nId != GDB_ID_NULL) ;
// creo oggetto dati Cam
PtrOwner<CamData> pCam( new( nothrow) CamData) ;
bOk = bOk && ! IsNull( pCam) ;
if ( bOk) {
// assegno valori
pCam->SetMoveType( 1) ;
pCam->SetToolDir( vtTool) ;
pCam->SetCorrDir( vtCorr) ;
pCam->SetAuxDir( vtAux) ;
pCam->SetEndPoint( ptFin) ;
pCam->SetFeed( dFeed) ;
pCam->SetFlag( nFlag) ;
pCam->SetFlag2( nFlag2) ;
pCam->SetToolShow( bToolShow) ;
// associo questo oggetto a quello geometrico
m_pMchLua->m_pGeomDB->SetUserObj( nId, Release( pCam)) ;
}
int nId = AddLinearMove( ptIni, ptFin, m_pMchLua->m_pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow) ;
bool bOk = nId != GDB_ID_NULL ;
// assegno risultato
if ( bOk)
LuaSetParam( L, nId) ;
@@ -581,3 +597,221 @@ Machine::LuaEmtGetBackAuxDir( lua_State* L)
return 1 ;
}
struct Cyl {
Cyl( void): frCyl( GLOB_FRM), dH( 0.), dRad( 0.) {;} ;
Cyl( const Frame3d& _frCyl, double _dH, double _dRad, double _dLinTol) :
frCyl( _frCyl), dH( _dH), dRad( _dRad) { ;}
Cyl( const Point3d& _ptBase, const Vector3d& vtZ, double _dH, double _dRad, double _dLinTol) :
dH( _dH), dRad( _dRad){
frCyl.Set( _ptBase, vtZ); }
public :
Frame3d frCyl ;
public:
double dH ;
double dRad ;
};
typedef vector<Cyl> OFFSETCYLVECT ;
//----------------------------------------------------------------------------
bool
IsPointInsideCylinder( const Point3d& ptTest, const Cyl& offCyl)
{
Point3d ptTestLoc = ptTest ; ptTestLoc.ToLoc( offCyl.frCyl) ;
if ( ptTestLoc.z > offCyl.dH || ptTestLoc.z < 0)
return false ;
double dDist = ptTestLoc.x * ptTestLoc.x + ptTestLoc.y * ptTestLoc.y ;
double dRadSq = offCyl.dRad * offCyl.dRad ;
if ( dDist > dRadSq)
return false ;
return true ;
}
//----------------------------------------------------------------------------
int
Machine::LuaEmtAdjustConcavePartsInPath( lua_State* L)
{
bool bOk = true ;
// 3 parametri : nPathId, nAuxPathId, dRad
int nPathId ;
LuaCheckParam( L, 1, nPathId)
int nAuxPathId ;
LuaCheckParam( L, 2, nAuxPathId)
double dRad ;
LuaCheckParam( L, 3, dRad)
LuaClearStack( L) ;
IGeomDB* pGeomDB = m_pMchLua->m_pGeomDB ;
int nId = pGeomDB->GetFirstInGroup( nPathId) ;
int nIdCrvAux = pGeomDB->GetFirstInGroup( nAuxPathId) ;
const ICurve* pCrvAux = GetCurve( pGeomDB->GetGeoObj(nIdCrvAux)) ;
const double dLinTol = 5 * EPS_SMALL ;
while ( nId != GDB_ID_NULL) {
if ( pGeomDB->GetGeoType( nId) == CRV_LINE) {
int nFlag = 0 ; pGeomDB->GetInfo( nId, "Flg2", nFlag) ;
if ( nFlag == 1) {
// scorro i prossimi finchè trovo la fine della zona concava
INTINTVECTOR vLines ;
while ( nFlag == 1 && nId != GDB_ID_NULL) {
nId = pGeomDB->GetNext( nId) ;
if ( nId != GDB_ID_NULL && pGeomDB->GetGeoType( nId) == CRV_LINE) {
int nDerivedFromId = GDB_ID_NULL ;
if ( pGeomDB->GetInfo( nId, "DerivFrom", nDerivedFromId)) {
pGeomDB->GetInfo( nId, "Flg2", nFlag) ;
vLines.emplace_back( nId, nDerivedFromId) ;
}
}
}
OFFSETCYLVECT vCyl ;
// creo un cilindro della dimensione del raggio
for ( int i = 0 ; i < ssize( vLines) ; ++i) {
const IGeoVector3d* pGV = GetGeoVector3d( pGeomDB->GetGeoObj( vLines[i].second)) ;
if ( pGV == nullptr)
return false ;
Point3d ptBase = pGV->GetBase() ;
double dPar = 0 ;
if ( ! pCrvAux->GetParamAtPoint( ptBase, dPar))
return false ;
dPar = round( dPar) ;
if ( dPar > 0) {
Point3d ptStart, ptEnd ;
Vector3d vtHeight ;
pCrvAux->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptEnd, &vtHeight) ;
pCrvAux->GetPointD1D2( dPar - 1, ICurve::FROM_MINUS, ptStart) ;
vtHeight = ptEnd - ptStart ;
double dHeight = vtHeight.Len() ;
// questa altezza dovrebbe coincidere con quella precedentemente calcolata come direzione della linea
vtHeight.Normalize() ;
vCyl.emplace_back( ptStart, vtHeight, dHeight, dRad, dLinTol) ;
}
}
// controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti
// controllo tutto i punti
bool bErasedSomePart = false ;
bool bErasedPrev = false ;
INTINTVECTOR vInters ;
for ( int i = 0 ; i < ssize( vLines) ; ++i) {
Point3d ptStart, ptEnd ;
const ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vLines[i].first)) ;
if ( pCL == nullptr)
return false ;
pCL->GetEndPoint( ptEnd) ;
pCL->GetStartPoint( ptStart) ;
// se stanno in uno dei cilindri degli altri tratti della zona concava
for ( int j = 0 ; j < ssize( vLines) ; ++j) {
if ( i == j)
continue ;
bool bToErase = IsPointInsideCylinder( ptEnd, vCyl[j]) ;
if ( bErasedPrev && ! bToErase)
bToErase = bToErase || IsPointInsideCylinder( ptStart, vCyl[j]) ;
if ( bToErase) {
bErasedSomePart = true ;
bErasedPrev = true ;
vInters.emplace_back(vLines[i].first,i) ;
vInters.emplace_back(vLines[i+1].first,i+1) ;
++i ;
break ;
}
else
bErasedPrev = false ;
}
}
if ( bErasedSomePart) {
// calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati
// controllo che effettivamente tutti i tratti cancellati siano consecutivi
for ( int i = 1 ; i < ssize( vInters) ; ++i) {
if ( vInters[i].first != vInters[i-1].first + 1)
return false ;
}
for ( int i = 0 ; i < ssize( vInters) ; ++i) {
// cancello i tratti intermedi
if ( i > 0 && i < ssize( vInters) - 1) {
pGeomDB->Erase( vInters[i].first) ;
continue ;
}
// per il primo e ultimo controllo le intersezioni con tutti i cilindri
ICurveLine* pCL = GetCurveLine( pGeomDB->GetGeoObj( vInters[i].first)) ;
Point3d ptStart = pCL->GetStart() ;
Vector3d vtStart ; pCL->GetStartDir( vtStart) ;
double dLen ; pCL->GetLength( dLen) ;
double dUTrim = ( i == 0 ? INFINITO : 0) ;
Point3d ptTrim = P_INVALID ;
for ( int j = 0 ; j < ssize( vCyl) ; ++j) {
if ( vInters[i].second == j)
continue ;
Point3d ptInt1 = P_INVALID, ptInt2 = P_INVALID ;
double dU1, dU2 ;
Vector3d vtN1, vtN2 ;
if ( IntersLineCyl( ptStart, vtStart * dLen, vCyl[j].frCyl, vCyl[j].dH, vCyl[j].dRad, dU1, ptInt1, vtN1, dU2, ptInt2, vtN2)) {
bool bUpdate = ( i == 0 ? dU1 < dUTrim : dU1 > dUTrim) ;
bUpdate = bUpdate && ptInt1.IsValid() && dU1 > 0 && dU1 < 1 ;
bUpdate = bUpdate && vtN1 * vtStart < 0 ;
if ( bUpdate) {
dUTrim = dU1 ;
ptTrim = ptInt1 ;
}
bUpdate = ( i == 0 ? dU2 < dUTrim : dU2 > dUTrim) ;
bUpdate = bUpdate && ptInt2.IsValid() && dU2 > 0 && dU2 < 1 ;
bUpdate = bUpdate && vtN2 * vtStart > 0 ;
if ( bUpdate) {
dUTrim = dU2 ;
ptTrim = ptInt2 ;
}
}
}
if ( ptTrim.IsValid()) {
if ( i == 0) {
pCL->ModifyEnd( ptTrim) ;
double dNewLen ; pCL->GetLength( dNewLen) ;
if ( dNewLen < 0.1) {
int nPrev = pGeomDB->GetPrev( vInters[0].first) ;
pGeomDB->Erase( vInters[0].first) ;
vInters[0].first = nPrev ;
ICurveLine* pCLPrev = GetCurveLine( pGeomDB->GetGeoObj( nPrev)) ;
pCLPrev->ModifyEnd( ptTrim) ;
}
CamData* camData = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ;
camData->SetEndPoint( ptTrim) ;
}
else {
pCL->ModifyStart( ptTrim) ;
double dNewLen ; pCL->GetLength( dNewLen) ;
if ( dNewLen < 0.1) {
int nNext = pGeomDB->GetNext( vInters[i].first) ;
pGeomDB->Erase( vInters[i].first) ;
vInters[i].first = nNext ;
ICurveLine* pCLNext = GetCurveLine( pGeomDB->GetGeoObj( nNext)) ;
pCLNext->ModifyStart( ptTrim) ;
}
}
}
}
// giunto questi due punti
ICurveLine* pCLprev = GetCurveLine( pGeomDB->GetGeoObj( vInters[0].first)) ;
Point3d ptIni = pCLprev->GetEnd() ;
ICurveLine* pCLnext = GetCurveLine( pGeomDB->GetGeoObj( vInters.back().first)) ;
Point3d ptFin = pCLnext->GetStart() ;
const CamData* camDataPrev = GetCamData( pGeomDB->GetUserObj( vInters[0].first)) ;
const CamData* camDataNext = GetCamData( pGeomDB->GetUserObj( vInters.back().first)) ;
Vector3d vtTool = Media( camDataPrev->GetToolDir(), camDataNext->GetToolDir()) ;
Vector3d vtCorr = Media( camDataPrev->GetCorrDir(), camDataNext->GetCorrDir()) ;
Vector3d vtAux = Media( camDataPrev->GetAuxDir(), camDataNext->GetAuxDir()) ;
double dFeed = camDataPrev->GetFeed() ;
int nFlag = camDataPrev->GetFlag() ;
int nFlag2 = camDataPrev->GetFlag2() ;
bool bToolShow = camDataPrev->GetToolShow() ;
AddLinearMove( ptIni, ptFin, pGeomDB, nPathId, vtTool, vtCorr, vtAux, dFeed, nFlag, nFlag2, bToolShow, vInters[0].first) ;
}
nId = vLines.back().first ;
}
}
nId = m_pMchLua->m_pGeomDB->GetNext( nId) ;
}
LuaSetParam( L, bOk) ;
return 1 ;
}
+682 -221
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -137,7 +137,9 @@ class Milling : public Machining
bool GetPointBelowRaw( const Point3d& ptP, const Vector3d& vtTool) const ;
bool CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU, bool bInvertSide = false, bool bSawSpecial = false) ;
Vector3d CalcCorrDir( const ICurveComposite* pCompo, double dU, bool bInvertSide = false, bool bSawSpecial = false) const ;
bool CalcOffset( ICurveComposite* pCompo, double dSignOffs) const ;
bool CalcAndSetCorrAuxDir( const Vector3d& vtCorr) ;
bool AdjustAllCorrAuxDirToSide( int nId, bool bCcwRot) ;
bool CalcOffset( ICurveComposite* pCompo, double dSignOffs, double dExtraOffs = 0) const ;
bool TrimExtendCurveToClosedStm( ICurveComposite* pCompo, int nCstmId, bool bInvert) ;
int GetCorrType( int nToolCompEntity, bool bInvert) const ;
@@ -201,6 +203,8 @@ class Milling : public Machining
double m_dCurrOscillLen ; // lunghezza corrente lungo il percorso per l'oscillazione
double m_dCurrTabsLen ; // lunghezza corrente lungo il percorso per tabs
bool m_bToolComp ; // correzione raggio utensile abilitata dai dati
Vector3d m_vtLieCorr ; // versore correzione da applicare a fine attacco
Vector3d m_vtLieAux ; // versore ausiliario da applicare a fine attacco
bool m_bStartOutRaw ; // flag forzatura inizio fuori dal grezzo
bool m_bEndOutRaw ; // flag forzatura fine fuori dal grezzo
Vector3d m_vtStartDir ; // direzione iniziale del percorso in elaborazione
+2
View File
@@ -54,6 +54,7 @@ static const std::string UN_PROJEXT = "ExtProj" ;
static const std::string UN_ADJUSTFEED = "AdjustFeed" ;
static const std::string UN_MINFEED = "MinFeed" ;
static const std::string UN_TOOL_COMPENSATION = "ToolCompensation" ;
static const std::string UN_START_PNT = "StartPoint" ;
// Solo per Sawing
static const std::string UN_DOWNSE = "DownSE" ;
@@ -70,6 +71,7 @@ static const std::string UN_STEPNUMBER = "StepNumber" ;
static const std::string UN_BITANGANG = "BiTangAng" ;
static const std::string UN_OPTIMALTYPE = "OptimalType" ;
static const std::string UN_ANGLETOL = "AngleTol" ;
static const std::string UN_TILT_ANGS = "Tilt" ;
// Solo per SurfRoughing
static const std::string UN_PLANEZ = "PlaneZ" ;
+507 -83
View File
@@ -60,6 +60,7 @@ static double EXTRA_ELEV = 5. ;
static double EXTRA_DEPTH = 5. ;
static double SAFETY_LINK_COS = cos( - ( 175 * DEGTORAD)) ;
static double TOOL_RAD_PTSTART = 20. ;
static double FEED_MAX_COEFF = 1000. ;
//------------------------------ Errori/Warnings --------------------------------------
// 2401 = "Error in PocketingNT : UpdateToolData failed"
@@ -105,6 +106,7 @@ static double TOOL_RAD_PTSTART = 20. ;
// 2442 = "Error in PocketingNT : Error in CalcPocketing"
// 2443 = "Error in PocketingNT : Calc Limit Region failed"
// 2444 = "Error in PocketingNT : Slicing Raw failed"
// 2445 = "Error in PocketingNT : Error in Connecting Start Point"
// 2451 = "Warning in PocketingNT : Skipped entity (xx)"
// 2452 = "Warning in PocketingNT : No pocket"
// 2453 = "Warning in PocketingNT : Tool name changed (xx)"
@@ -114,6 +116,7 @@ static double TOOL_RAD_PTSTART = 20. ;
// 2457 = "Warning in PocketingNT : machining step (xxx) bigger than MaxMaterial (yyy)"
// 2458 = "Warning in PocketingNT : machining depth (xxx) bigger than MaxMaterial (yyy)"
// 2459 = "Warning in PocketingNT : No compensation in tool, so no compensation in machine"
// 2460 = "Warning in PocketingNT : Machining toolpath empty"
//----------------------------------------------------------------------------
// Debug
@@ -133,10 +136,12 @@ static double TOOL_RAD_PTSTART = 20. ;
#define DEBUG_ZIGZAG_LEADIN 0 // Debug per ZigZag LeadIn
#define DEBUG_DOUBLE_PARALLEL 0 // Debug per Pocketing in Doppio con Parallelo
#define DEBUG_TOOL_COMPENSATION 0 // Debug per Tool Compensation
#define DEBUG_SILHOUETTE 0 // Debug Silhouette
#define DEBUG_USER_PTSTART 0 // Debug punto iniziale stabilito dall'utente
#define DEBUG 0 // Debug
#if DEBUG_STM_TOPOLOGY || DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_SFR_STEPS || DEBUG_SFR_RAW || DEBUG_SFR_GEO_EXT || \
DEBUG_GLIDE || DEBUG_SAFETY_LINK || DEBUG_FEED || DEBUG_START_POINT || DEBUG_PATH_CL || DEBUG_ZIGZAG_LEADIN || DEBUG_DOUBLE_PARALLEL || \
DEBUG
DEBUG_SILHOUETTE || DEBUG
#include "EgtDev/Include/EGkGeoPoint3d.h"
#include "EgtDev/Include/EGkGeoVector3d.h"
#include "EgtDev/Include/EGkFrame3d.h"
@@ -1732,6 +1737,7 @@ PocketingNT::SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve,
*pbSomeOpen = false ;
// reset proprietà temporanee
ResetCurveAllTempProp( pCurve) ;
// se svuotatura tutta chiusa, allora esco
if ( m_bAllClose)
return true ;
// se forzato chiuso o non presenti info per lati aperti, esco
@@ -1740,6 +1746,11 @@ PocketingNT::SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve,
// recupero info sui lati aperti
INTVECTOR vOpen ;
m_pGeomDB->GetInfo( nCrvId, KEY_OPEN, vOpen) ;
// se curva da considerare come tutta aperta
if ( ! bForcedClose && ssize( vOpen) == 1 && vOpen[0] == -1) {
ResetCurveAllTempProp( pCurve, false) ;
return true ;
}
// se curva composita
ICurveComposite* pCC = GetCurveComposite( pCurve) ;
if ( pCC != nullptr) {
@@ -1791,7 +1802,7 @@ PocketingNT::SetSfrLoopsAllTempProp( int nSfrId, ISurfFlatRegion* pSfr)
//----------------------------------------------------------------------------
bool
PocketingNT::ResetCurveAllTempProp( ICurve* pCurve)
PocketingNT::ResetCurveAllTempProp( ICurve* pCurve, bool bClose)
{
if ( pCurve == nullptr)
return false ;
@@ -1799,7 +1810,7 @@ PocketingNT::ResetCurveAllTempProp( ICurve* pCurve)
ICurveComposite* pCC = GetCurveComposite( pCurve) ;
if ( pCC != nullptr) {
for ( int i = 0 ; i < pCC->GetCurveCount() ; ++ i)
pCC->SetCurveTempProp( i, TEMP_PROP_CLOSE_EDGE) ;
pCC->SetCurveTempProp( i, bClose ? TEMP_PROP_CLOSE_EDGE : TEMP_PROP_OPEN_EDGE) ;
}
return true ;
}
@@ -2141,11 +2152,7 @@ PocketingNT::GetExtrusionStm( const ISurfFlatRegion* pSfr, const Vector3d& vtExt
if ( pSfr == nullptr || ! pSfr->IsValid())
return nullptr ;
/*
pSfr -> superficie da cui estrudere i lati chiusi
vtExtrs -> vettore estrusione dei lati chiusi di pSfr
*/
// inizializzo la superficie di estrusione
PtrOwner<ISurfFlatRegion> pMySfr( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pMySfr) || ! pMySfr->IsValid())
return nullptr ;
@@ -2167,16 +2174,14 @@ PocketingNT::GetExtrusionStm( const ISurfFlatRegion* pSfr, const Vector3d& vtExt
if ( ! GetHomogeneousParts( pCompoLoop, vpCrvs))
return nullptr ;
// scorro i tratti omogenei chiusi
for ( int nP = 0 ; nP < int( vpCrvs.size()) ; ++ nP) {
for ( int nP = 0 ; nP < ssize( vpCrvs) ; ++ nP) {
if ( vpCrvs[nP]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) {
// approssimo la curva ad una PolyLine
PolyLine PL ;
vpCrvs[nP]->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ;
vpCrvs[nP]->ApproxWithLines( 10. * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
// estrusione del tratto chiuso
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) ||
! pStm->AdjustTopology() ||
! pStm->CreateByExtrusion( PL, vtExtr))
if ( IsNull( pStm) || ! pStm->AdjustTopology() || ! pStm->CreateByExtrusion( PL, vtExtr))
return nullptr ;
// aggiungo i triangoli ricavati alla zuppa
if ( ! IsNull( pStm) && pStm->IsValid()) {
@@ -2288,12 +2293,11 @@ PocketingNT::GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, doubl
//----------------------------------------------------------------------------
ISurfFlatRegion*
PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr,
const Vector3d& vtTool)
PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr, const Vector3d& vtTool,
const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil)
{
// controllo dei parametri
if ( pStmRaw == nullptr || ! pStmRaw->IsValid() ||
pSfr == nullptr || ! pSfr->IsValid())
if ( pStmRaw == nullptr || ! pStmRaw->IsValid() || pSfr == nullptr || ! pSfr->IsValid())
return nullptr ;
// recupero il piano di taglio dalla regione piana
@@ -2302,10 +2306,48 @@ PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRe
if ( ! plProj.Set( ptCen, vtTool))
return nullptr ;
// recupero la Silhouette al piano trovato
#if DEBUG_SILHOUETTE
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "Silhouette") ;
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
int nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pStmRaw->Clone()) ;
m_pGeomDB->SetMaterial( nSfr, Color( 0., 0., 0., .5)) ;
PtrOwner<IGeoFrame3d> frPock( CreateGeoFrame3d()) ; frPock->Set( frAtTop) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, Release( frPock)) ;
PtrOwner<IGeoPoint3d> ptDepth( CreateGeoPoint3d()) ;
double dLevel = abs( ( frAtTop.Orig() - plProj.GetPoint()) * vtTool) ;
ptDepth->Set( frAtTop.Orig() - frAtTop.VersZ() * dLevel) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, Release( ptDepth)) ;
#endif
// verifico con quale metodo calcolare la Silhouette in base al numero di triangoli
const double TRIA_NUM = 500 ;
int nTriaCnt = pStmRaw->GetTriangleCount() ;
bool bSimpleSil = ( nTriaCnt <= TRIA_NUM) ;
POLYLINEVECTOR vPL ;
if ( ! pStmRaw->GetSilhouette( plProj, EPS_SMALL, vPL))
return nullptr ;
if ( bSimpleSil) {
// calcolo la Silhouette base mediante proiezione dei triangoli
bSimpleSil = ( pStmRaw->GetSilhouette( plProj, EPS_SMALL, vPL)) ;
}
if ( ! bSimpleSil) {
// calcolo la Silhouette mediante CAv
vPL.clear() ; // per sicurezza
// --- se non ho già istanziato un classe di Cav, la inizializzo, altrimenti utilizzo quella presente
if ( *ppCavParSil == nullptr) {
*ppCavParSil = CreateCAvParSilhouettesSurfTm() ;
if ( *ppCavParSil == nullptr)
return nullptr ;
}
if ( ! frAtTop.IsValid())
return nullptr ;
double dLevel = abs( ( frAtTop.Orig() - plProj.GetPoint()) * vtTool) ;
const double SIL_TOL = 1.0 ;
if ( ! ( *ppCavParSil)->SetData( CISURFTMPVECTOR{ pStmRaw}, frAtTop, SIL_TOL) ||
! ( *ppCavParSil)->GetSilhouette( - dLevel - 10. * EPS_SMALL, vPL)) // evito di essere a filo del grezzo
return nullptr ;
}
// se non trovo nessun contorno sono fuori dal grezzo, la superficie è vuota
if ( vPL.empty())
return ( CreateSurfFlatRegion()) ;
@@ -2316,6 +2358,10 @@ PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRe
PtrOwner<ICurveComposite> pCrvLoop( CreateCurveComposite()) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->FromPolyLine( PL))
return nullptr ;
#if DEBUG_SILHOUETTE
int nCvrId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCrvLoop->Clone()) ;
m_pGeomDB->SetMaterial( nCvrId, RED) ;
#endif
SfrByC.AddCurve( Release( pCrvLoop)) ;
}
PtrOwner<ISurfFlatRegion> pSfrRaw( SfrByC.GetSurf()) ;
@@ -2326,6 +2372,46 @@ PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRe
return Release( pSfrRaw) ;
}
//----------------------------------------------------------------------------
Point3d
PocketingNT::GetStartPointByUser( const ISurfFlatRegion* pSfr) const
{
// se dalle note utente non ho un punto scelto, non faccio nulla
Point3d ptStartRef = P_INVALID ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_START_PNT, ptStartRef) || ! ptStartRef.IsValid())
return P_INVALID ;
// se il tipo di svuotatura è di categoria ZigZag/OneWay, non considero tale parametro
if ( m_Params.m_nSubType == POCKET_SUB_ZIGZAG || m_Params.m_nSubType == POCKET_SUB_ONEWAY ||
m_Params.m_nSubType == POCKET_SUB_CONFORMAL_ZIGZAG || m_Params.m_nSubType == POCKET_SUB_CONFORMAL_ONEWAY)
return P_INVALID ;
// se lavorazione in SpiralIn il punto serve per determinare su quale aperto entrare, quindi restituisco automaticamente il punto
// (il calcolo dei percorsi di svuotatura cerca automaticamente l'aperto migliore in base al punto su sui effettuare l'entrata)
if ( m_Params.m_nSubType == POCKET_SUB_SPIRALIN)
return ptStartRef ;
// se la lavorazione e in SpiralOut, allora il punto serve per effettuare l'entrata e poi per collegarsi al punto iniziale della
// svuotatura
if ( m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) {
if ( pSfr != nullptr && pSfr->IsValid()) {
// recupero il piano della regione
Point3d ptCentroid ; pSfr->GetCentroid( ptCentroid) ;
Plane3d plSfr ;
if ( ! plSfr.Set( ptCentroid, pSfr->GetNormVersor()))
return P_INVALID ;
// proietto il punto trovato su tale piano
Point3d ptProj = ProjectPointOnPlane( ptStartRef, plSfr) ;
// verifico che sia al suo interno
bool bIsInside = false ;
if ( IsPointInsideSurfFr( ptProj, pSfr, m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, bIsInside) && bIsInside)
return ptProj ;
}
}
return P_INVALID ;
}
//----------------------------------------------------------------------------
Point3d
PocketingNT::GetStartPointsByHead( const STEPINFOPOVECTOR& vStepInfo) const
@@ -2504,7 +2590,7 @@ PocketingNT::GetStartPointsByHead( const STEPINFOPOVECTOR& vStepInfo) const
//----------------------------------------------------------------------------
Point3d
PocketingNT::GetStartPointsFromSteps( const STEPINFOPOVECTOR& vStepInfo, int nCrvType) const
PocketingNT::GetStartPointsBySteps( const STEPINFOPOVECTOR& vStepInfo, int nCrvType) const
{
// se non ho step, allora non ho un punto di riferimento
if ( vStepInfo.empty())
@@ -2871,24 +2957,25 @@ PocketingNT::ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
bool
PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion)
{
// controllo parametri :
if ( pSfr == nullptr || ! pSfr->IsValid() ||
pStmExtrusion == nullptr)
if ( pSfr == nullptr || ! pSfr->IsValid() || pStmExtrusion == nullptr)
return false ;
// se non ho una superificie di estrusione, allora è tutto aperto
if ( ! pStmExtrusion->IsValid() || pStmExtrusion->GetTriangleCount() == 0) {
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC)
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL)
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) {
for ( int nU = 0 ; nU < pSfr->GetLoopCurveCount( nC, nL) ; ++ nU)
pSfr->SetCurveTempProp( nC, nL, nU, TEMP_PROP_OPEN_EDGE, 0) ;
}
}
return true ;
}
// per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti.
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO A CONTATTO CON pStmExtrusion "
const int NUM_POINTS = 4 ;
const double DIST_TOL = 250. * EPS_SMALL ;
// scorro tutti i loop
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) {
@@ -2898,7 +2985,7 @@ PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* p
return false ;
// scorro ogni sua sottocurva
for ( int nU = 0 ; nU < pCrvCompoLoop->GetCurveCount() ; ++ nU) {
// la sottocurva viene messa chiusa ( condizione base)
// la sottocurva viene messa aperta ( condizione base)
pSfr->SetCurveTempProp( nC, nL, nU, TEMP_PROP_OPEN_EDGE, 0) ;
// recupero la sottocurva
const ICurve* pCrv = pCrvCompoLoop->GetCurve( nU) ;
@@ -2915,7 +3002,7 @@ PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* p
DistPointSurfTm distCalculator( ptPar, *pStmExtrusion) ;
double dDist = 0. ;
distCalculator.GetDist( dDist) ;
bIsOnStm = ( dDist < 25 * EPS_SMALL) ;
bIsOnStm = ( dDist < DIST_TOL) ;
}
if ( bIsOnStm)
pSfr->SetCurveTempProp( nC, nL, nU, TEMP_PROP_CLOSE_EDGE, 0) ;
@@ -2924,7 +3011,6 @@ PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* p
}
return true ;
}
//----------------------------------------------------------------------------
@@ -2942,12 +3028,52 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe
if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid())
return false ;
// piccolo Offset di correzione
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfrPock->CreateOffsetSurf( 10 * EPS_SMALL, ICurve::OFF_FILLET)) ;
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfrPock->CreateOffsetSurf( 10. * EPS_SMALL, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid())
return false ;
// sottrazione
pSfrLimit->Subtract( *pSfrOffs) ;
// se la superficie corrente ha delle isole aperte interne al grezzo, la prevalenza va sulle isole aperte
// [NB. Queste isole potrebbero essere definite sul bordo del grezzo, seza che vengano riconosciute come lati aperti interni al grezzo,
// per estrerema sicurezza semplifico la regione Limite]
if ( pSfrLimit->IsValid()) {
for ( int nC = 0 ; nC < pSfrPock->GetChunkCount() && pSfrLimit->IsValid() ; ++ nC) {
int nLoopCnt = ( pSfrPock->GetLoopCount( nC)) ;
if ( nLoopCnt > 1) {
// raggio di riferimento per offset
double dOutEdge = 0.5 * m_TParams.m_dDiam ;
if ( m_Params.m_nSubType == POCKET_SPIRALIN || m_Params.m_nSubType == POCKET_ZIGZAG)
dOutEdge = max( dOutEdge, m_TParams.m_dDiam - m_Params.m_dSideStep) ;
double dExtension = dOutEdge + GetOffsR() + 100. * EPS_SMALL ;
for ( int nL = 1 ; nL < nLoopCnt && pSfrLimit->IsValid() ; ++ nL) {
PtrOwner<ICurveComposite> pInternalLoop( ConvertCurveToComposite( pSfrPock->GetLoop( nC, nL))) ;
if ( IsNull( pInternalLoop) || ! pInternalLoop->IsValid())
return false ;
ICRVCOMPOPOVECTOR vCrv ;
GetHomogeneousParts( pInternalLoop, vCrv) ;
if ( ssize( vCrv) == 1 && vCrv[0]->GetTempProp() == TEMP_PROP_OPEN_EDGE) {
// considero la curva come chiusa, le isole non sono definite
OffsetCurve OffsCrv ;
OffsCrv.Make( pInternalLoop, dExtension, ICurve::OFF_FILLET) ;
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid()) {
SurfFlatRegionByContours SfrByC ;
SfrByC.AddCurve( Release( pCrvOffs)) ;
SfrByC.AddCurve( CloneCurveComposite( pInternalLoop)) ;
PtrOwner<ISurfFlatRegion> pSfrSub( SfrByC.GetSurf()) ;
if ( ! IsNull( pSfrSub) && pSfrSub->IsValid()) {
if ( AreOppositeVectorApprox( pSfrSub->GetNormVersor(), pSfrLimit->GetNormVersor()))
pSfrSub->Invert() ;
pSfrLimit->Subtract( *pSfrSub) ;
}
}
}
}
}
}
}
// se richiesto non controllo dei lati aperti
if ( m_bOpenOutRaw && pSfrLimit->IsValid()) {
double dExtension = 4. * m_TParams.m_dDiam + max( 0., m_dOpenMinSafe) + EPS_SMALL ;
@@ -3520,13 +3646,19 @@ PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d&
if ( vGeoSel.empty())
return true ;
// porto la regione di svuotatura nel più basso
// porto la regione di svuotatura nel punto più basso
PtrOwner<ISurfFlatRegion> pSfr( CloneSurfFlatRegion( pSfrPock)) ;
if ( IsNull( pSfr) || ! pSfr->IsValid())
return false ;
pSfr->Translate( - vtTool * dDepth) ;
// sempre in questo piano calcolo la silhouette del Grezzo
PtrOwner<ISurfFlatRegion> pSfrRaw( GetSfrRawProjection( pStmRaw, pSfr, vtTool)) ;
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSil( nullptr) ;
ICAvParSilhouettesSurfTm* ppCavParSil = Get( pCavParSil) ;
Point3d ptAtTop ; pSfr->GetCentroid( ptAtTop) ;
Frame3d frAtTop ;
if ( ! frAtTop.Set( ptAtTop, pSfr->GetNormVersor()))
return false ;
PtrOwner<ISurfFlatRegion> pSfrRaw( GetSfrRawProjection( pStmRaw, pSfr, vtTool, frAtTop, &ppCavParSil)) ;
// verifico se l'entità selezionata è una superficie TriMesh ( quindi un SoloId)
for ( const SelData& Id : vGeoSel) {
@@ -3828,6 +3960,13 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
}
#endif
// definisco la classe di calcolo della Silhoette del grezzo nel caso mi servisse
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSil( nullptr) ;
Point3d ptAtTop ; pSfr->GetCentroid( ptAtTop) ;
Frame3d frAtTop ;
if ( ! frAtTop.Set( ptAtTop, pSfr->GetNormVersor()))
return false ;
// se necessario modifico la geometria in caso di selezione originaria di TriMesh
// ( Gestione dei lati chiusi di una TriMesh tagliati su più facce del grezzo)
ISURFFRPOVECTOR vSurfFrGeoExt ;
@@ -3951,6 +4090,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
}
// se richiesta lavorazione
bool bEmptyPocket = false ;
if ( nClId != GDB_ID_NULL) {
// creo gruppo per geometria di lavorazione del percorso
int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
@@ -4016,7 +4156,9 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
return false ;
// adatto la regione piana alla geometria del grezzo
PtrOwner<ISurfFlatRegion> pSfrTrim( GetSfrRawProjection( ( pStmTrim == nullptr ? pStmRaw : pStmTrim), pSfrPock, vtTool)) ;
ICAvParSilhouettesSurfTm* pCavParSilTmp = Get( pCavParSil) ;
PtrOwner<ISurfFlatRegion> pSfrTrim( GetSfrRawProjection( ( pStmTrim == nullptr ? pStmRaw : pStmTrim), pSfrPock, vtTool, frAtTop,
&pCavParSilTmp)) ;
if ( IsNull( pSfrTrim)) {
m_pMchMgr->SetLastError( 3027, "Error in PocketingNT : Slicing Raw failed") ;
return false ;
@@ -4089,7 +4231,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
// calcolo le lavorazioni
Point3d ptPockStart ; pSfr->GetCentroid( ptPockStart) ;
Point3d ptPockEnd = ptPockStart ;
if ( ! AddPocket( vStepInfo, vtTool, dStep, bSplitArcs, ptPockStart, ptPockEnd))
if ( ! AddPocket( vStepInfo, vtTool, dStep, bSplitArcs, ptPockStart, ptPockEnd, bEmptyPocket))
return false ;
// assegno il vettore estrazione al gruppo del percorso
@@ -4116,7 +4258,8 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
}
// incremento numero di svuotature
++ m_nPockets ;
if ( ! bEmptyPocket)
++ m_nPockets ;
return true ;
}
@@ -4601,21 +4744,40 @@ PocketingNT::CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, con
//----------------------------------------------------------------------------
bool
PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty)
{
// se non ho Step, non faccio nulla
if ( vStepInfo.empty())
return true ;
bEmpty = false ;
// punto finale di riferimento per il percorso attuale ( serve per trovare il punto iniziale
// del percorso successivo). Parto analizzando la testa ( da sopra/da sotto)
Point3d ptStartRef = GetStartPointsByHead( vStepInfo) ;
// --- se punto invalido e raggio utensile grande
if ( ! ptStartRef.IsValid() && m_TParams.m_dDiam / 2. > TOOL_RAD_PTSTART - EPS_ZERO) {
// cerco l'ingresso in base alla geometria iniziale della tasca
ptStartRef = GetStartPointsFromSteps( vStepInfo, TEMP_PROP_OPEN_EDGE) ;
if ( ! ptStartRef.IsValid())
ptStartRef = GetStartPointsFromSteps( vStepInfo, TEMP_PROP_CLOSE_EDGE) ;
// definisco il tipo di punto iniziale
enum START_PT { DEFAULT = 0, BY_USER = 1, BY_HEAD = 2, BY_OPEN_GEO = 3, BY_CLOSE_GEO = 4} ;
int nStartPtType = START_PT::DEFAULT ;
Point3d ptLinkStart = P_INVALID ;
// recupero eventuale punto iniziale per la svuotatura definito dall'utente
Point3d ptStartRef = GetStartPointByUser( vStepInfo.front().pSfrPock) ;
if ( ! ptStartRef.IsValid()) {
// se l'utente non ha definito un punto iniziale, allora eseguo analisi della testa (da sopra/da sotto)
ptStartRef = GetStartPointsByHead( vStepInfo) ;
if ( ! ptStartRef.IsValid() && m_TParams.m_dDiam / 2. > TOOL_RAD_PTSTART - EPS_ZERO) {
// se punto non valido ed utensile grane, cerco l'ingresso in base alla geometria dei lati aperti della tasca
ptStartRef = GetStartPointsBySteps( vStepInfo, TEMP_PROP_OPEN_EDGE) ;
if ( ! ptStartRef.IsValid()) {
// se punto non valido, cerco l'ingresso in base alla geometria dei lati chiusi della tasca
ptStartRef = GetStartPointsBySteps( vStepInfo, TEMP_PROP_CLOSE_EDGE) ;
if ( ptStartRef.IsValid())
nStartPtType = START_PT::BY_CLOSE_GEO ;
}
else
nStartPtType = START_PT::BY_OPEN_GEO ;
}
else
nStartPtType = START_PT::BY_HEAD ;
}
else {
nStartPtType = START_PT::BY_USER ;
ptLinkStart = ptStartRef ;
}
// recupero flag per casi ottimizzati
@@ -4665,6 +4827,10 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
bool bConventionalMilling = ( m_Params.m_nSubType == POCKET_SPIRALIN || m_Params.m_nSubType == POCKET_SPIRALOUT ||
m_Params.m_nSubType == POCKET_ONEWAY || m_Params.m_nSubType == POCKET_CONFORMAL_ONEWAY) ;
// flag per svuotatura in SpiralOut con punto iniziale
bool bPtStartLink = ( nStartPtType == START_PT::BY_USER && m_Params.m_nSubType == POCKET_SUB_SPIRALOUT) ;
// scorro gli indici delle superfici
for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) {
// calcolo i percorsi di Pocketing ( o di lucidatura se richiesto)
@@ -4678,8 +4844,11 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
return false ;
}
// se non ho ottenuto percorsi, errore
if ( vCrvPaths.empty())
return false ;
if ( vCrvPaths.empty()) {
m_pMchMgr->SetWarning( 2460, "Warning in PocketingNT : Machining toolpath empty") ;
bEmpty = true ;
return true ;
}
// sistemo gli archi per massimo angolo al centro
for ( int j = 0 ; j < ssize( vCrvPaths) ; ++ j)
VerifyArcs( vCrvPaths[j]) ;
@@ -4735,27 +4904,43 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
if ( ! vStepInfo[i].vPaths[j].pCrvPath.Set( vCrvPaths[j]))
return false ;
}
// definisco il nuovo punto di riferimento per il percorso successivo
// --------------------- Se caso ottimizzato a spirale ---------------------
if ( ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle) {
// Se entrata da fuori, ricomincio dall'esterno
if ( vStepInfo[i].vPaths[0].bOutStart)
vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptStartRef) ;
// altrimenti
else {
if ( m_Params.m_nSubType == POCKET_SPIRALOUT)
vStepInfo[i].vPaths[0].pCrvPath->GetEndPoint( ptStartRef) ; // è invertito
else
vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptStartRef) ;
// se lavorazione in SpiralOut e punto d'inizio definito dall'utente, aggiungo un tratto di collegamento
if ( bPtStartLink) {
Point3d ptStartPath ; vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartPath) ;
PtrOwner<ICurveComposite> pCompoLink( CreateCurveComposite()) ;
if ( IsNull( pCompoLink))
return false ;
if ( CalcLinkByStartUserPoint( vStepInfo[i].pSfrPock, vStepInfo[i].pSfrLimit, ptLinkStart, ptStartPath, pCompoLink)) {
if ( ! vStepInfo[i].vPaths.front().pCrvPath->AddCurve( Release( pCompoLink), false, 10. * EPS_SMALL)) {
m_pMchMgr->SetLastError( 2445, "Error in PocketingNT : Error in Connecting Start Point") ;
return false ;
}
}
}
// altrimenti rimane fisso al punto iniziale del percorso precedente
else {
// se percorso di correzione, e caso precedente a spirale, non aggiorno il percorso
if ( bToolComp && ssize( vStepInfo[i].vPaths) == 2 && vStepInfo[i].vPaths[0].bOptCirle)
; // lascio invariato
else
vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartRef) ;
// definisco il nuovo punto di riferimento per il percorso successivo
// --------------------- Se caso ottimizzato a spirale ---------------------
if ( ! ( bPtStartLink && i == 0) && ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle) {
// Se entrata da fuori, ricomincio dall'esterno
if ( vStepInfo[i].vPaths[0].bOutStart)
vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptStartRef) ;
// altrimenti
else {
if ( m_Params.m_nSubType == POCKET_SPIRALOUT)
vStepInfo[i].vPaths[0].pCrvPath->GetEndPoint( ptStartRef) ; // è invertito
else
vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptStartRef) ;
}
}
// altrimenti rimane fisso al punto iniziale del percorso precedente
else {
// se percorso di correzione, e caso precedente a spirale, non aggiorno il percorso
if ( bToolComp && ssize( vStepInfo[i].vPaths) == 2 && vStepInfo[i].vPaths[0].bOptCirle)
; // lascio invariato
else
vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartRef) ;
}
}
// aggiorno la progressBar
ExeProcessEvents( 50 + i * 50 / ssize( vStepInfo), 0) ;
@@ -4787,7 +4972,10 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
for ( int j = 0 ; j < ssize( vStepInfo[i].vPaths) ; ++ j) {
if ( vStepInfo[i].vPaths[j].bToolCompensation &&
! IsNull( vStepInfo[i].vPaths[j].pCrvPath) && vStepInfo[i].vPaths[j].pCrvPath->IsValid()) {
if ( ! AddTangentLinesForToolCompensation( vStepInfo[i].vPaths[j].pCrvPath, m_vtTool, vStepInfo[i].pSfrLimit))
// stabilisco se aggiungere il tratto a scivolo alla fine
bool bWithEndGlide = ( GetLeadOutType() == POCKET_LO_GLIDE && ! vStepInfo[i].vPaths[j].bOutEnd &&
! vStepInfo[i].vPaths[j].bOptTrap && i == ssize( vStepInfo) - 1 && j == ssize( vStepInfo[i].vPaths) - 1) ;
if ( ! AddTangentLinesForToolCompensation( vStepInfo[i].vPaths[j].pCrvPath, m_vtTool, vStepInfo[i].pSfrLimit, bWithEndGlide))
return false ;
}
}
@@ -4807,7 +4995,7 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
if ( ! bToolComp || ( bToolComp && bHolePocketing && j == 1)) {
if ( IsNull( pCrvGlideIn) ||
! CalcRetCurve( vStepInfo[i].vPaths[j], vStepInfo[i], vStepInfo[i].vPaths[j].pCrvPath,
vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, ptHoleDest, bToolComp, true, pCrvGlideIn)) {
vStepInfo[i].pSfrPock->GetNormVersor(), ( ! bPtStartLink && bHolePocketing), ptHoleDest, bToolComp, true, pCrvGlideIn)) {
m_pMchMgr->SetLastError( 2415, "Error in PocketingNT : LeadIn not computable") ;
return false ;
}
@@ -4815,7 +5003,6 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
if ( ! IsNull( pCrvGlideIn) && pCrvGlideIn->IsValid()) {
if ( ! vStepInfo[i].vPaths[j].pCrvGlideIn.Set( Release( pCrvGlideIn)))
return false ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vStepInfo[i].vPaths[j].pCrvGlideIn->Clone()) ;
}
}
// se uscita a scivolo
@@ -4823,13 +5010,14 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
PtrOwner<ICurveComposite> pCrvGlideOut( CreateCurveComposite()) ;
if ( IsNull( pCrvGlideOut) ||
! CalcRetCurve( vStepInfo[i].vPaths[j], vStepInfo[i], vStepInfo[i].vPaths[j].pCrvPath,
vStepInfo[i].pSfrPock->GetNormVersor(), bHolePocketing, P_INVALID, false, bToolComp, pCrvGlideOut)) {
vStepInfo[i].pSfrPock->GetNormVersor(), ( ! bToolComp && ! bPtStartLink && bHolePocketing), P_INVALID, bToolComp, false, pCrvGlideOut)) {
m_pMchMgr->SetLastError( 2416, "Error in PocketingNT : LeadOut not computable") ;
return false ;
}
if ( ! IsNull( pCrvGlideOut) && pCrvGlideOut->IsValid())
if ( ! IsNull( pCrvGlideOut) && pCrvGlideOut->IsValid()) {
if ( ! vStepInfo[i].vPaths[j].pCrvGlideOut.Set( Release( pCrvGlideOut)))
return false ;
}
}
}
}
@@ -5185,15 +5373,21 @@ PocketingNT::CalcDoubleParallelPenultimateStep( int nDouble, int nIdDblS, double
//----------------------------------------------------------------------------
bool
PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs,
Point3d& ptPockStart, Point3d& ptPockEnd)
Point3d& ptPockStart, Point3d& ptPockEnd, bool& bEmpty)
{
// se non ho superfici da svuotare, non faccio nulla
if ( vStepInfo.empty())
return true ;
// calcolo i percorsi di svuotatura per ogni Step/SubStep
if ( ! CalcPaths( vStepInfo))
if ( ! CalcPaths( vStepInfo, bEmpty))
return false ;
// se svuotatura vuota, aggiorno la ProgressBar ed esco
if ( bEmpty) {
ExeProcessEvents( 100, 0) ;
return true ;
}
#if DEBUG_FEED
nGrpDebugFeed = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
nLayDebugFeed = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDebugFeed, GLOB_FRM) ;
@@ -5248,7 +5442,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
return false ;
// coefficiente feed ( riduzione di feed per sezione di taglio superiore al previsto )
double dTempParam ; currPath.pCrvPath->GetCurveTempParam( k, dTempParam) ;
double dCoeffFeed = min( 1., ( dTempParam > EPS_SMALL ? dTempParam /= 1000 : 1)) ;
double dCoeffFeed = min( 1., ( dTempParam > EPS_SMALL ? dTempParam /= FEED_MAX_COEFF : 1)) ;
// se prima entità
if ( k == 0) {
@@ -5528,7 +5722,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
}
}
// aggiorno per sicurezza la ProgressBar nel caso di Step vuoti
// aggiorno per sicurezza la ProgressBar
ExeProcessEvents( 100, 0) ;
return true ;
}
@@ -6787,7 +6981,8 @@ PocketingNT::CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const V
//----------------------------------------------------------------------------
bool
PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit) const
PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit,
bool bWithEndGlide) const
{
// Verifico che la curva sia valida
if ( pCompoPath == nullptr || ! pCompoPath->IsValid())
@@ -6801,6 +6996,8 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
PtrOwner<ICurveComposite> pCompoPathLoc( CloneCurveComposite( pCompoPath)) ;
if ( IsNull( pCompoPathLoc) || ! pCompoPathLoc->IsValid() || ! pCompoPathLoc->ToLoc( frLoc))
return false ;
// definisco la regione limite, quella che l'utensile non deve intersecare
PtrOwner<ISurfFlatRegion> pSfrLimitLocUB( nullptr) ; // Upper Bound
if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) {
if ( ! pSfrLimitLocUB.Set( CloneSurfFlatRegion( pSfrLimit)) || ! pSfrLimitLocUB->IsValid() || ! pSfrLimitLocUB->ToLoc( frLoc))
@@ -6810,7 +7007,7 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
return false ;
}
#if DEBUG_TOOL_COMPENSATION
#if DEBUG_TOOL_COMPENSATION
int nGrpLocId = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrpLocId, "LOCAL_COMPENSATION") ;
int nLayId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpLocId, GLOB_FRM) ;
@@ -6823,7 +7020,43 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
}
#endif
// Calcolo tratto lineare Iniziale e Finale
// se la curva è chiusa, aggiungo un piccolo raccordo iniziale
if ( pCompoPathLoc->IsClosed()) {
const double EXTRA_TANG_LEN = 2.0 ;
const double EXTRA_PERP_LEN = 0.5 ;
double dLen ; pCompoPathLoc->GetLength( dLen) ;
if ( dLen > EXTRA_TANG_LEN + EPS_SMALL) {
double dUS, dUE ; pCompoPathLoc->GetDomain( dUS, dUE) ;
double dUCurr ;
Point3d ptCurr ;
Vector3d vtCurr ;
if ( pCompoPathLoc->GetParamAtLength( dLen - EXTRA_TANG_LEN, dUCurr) &&
pCompoPathLoc->GetPointD1D2( dUCurr, ICurve::FROM_MINUS, ptCurr, &vtCurr)) {
double dArea ; pCompoPathLoc->GetAreaXY( dArea) ;
double dAng = ( dArea > 0. ? ANG_RIGHT : - ANG_RIGHT) ;
vtCurr.Normalize() ;
Vector3d vtPerp = vtCurr ; vtPerp.Rotate( Z_AX, dAng) ;
Point3d ptArcStart = ptCurr + EXTRA_PERP_LEN * vtPerp ;
Point3d ptArcEnd ; pCompoPathLoc->GetStartPoint( ptArcEnd) ;
Vector3d vtArcEnd ; pCompoPathLoc->GetStartDir( vtArcEnd) ;
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
if ( ! IsNull( pCrvArc) && pCrvArc->Set2PVN( ptArcEnd, ptArcStart, -vtArcEnd, Z_AX) && pCrvArc->Invert()) {
#if DEBUG_TOOL_COMPENSATION
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCrvArc->Clone()) ;
m_pGeomDB->SetMaterial( nId, LIME) ;
#endif
if ( ! IsNull( pSfrLimitLocUB) && pSfrLimitLocUB->IsValid()) {
CRVCVECTOR ccClass ;
if ( pSfrLimitLocUB->GetCurveClassification( *pCrvArc, EPS_SMALL, ccClass) &&
( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT))
pCompoPathLoc->AddCurve( Release( pCrvArc), false) ;
}
}
}
}
}
// Calcolo tratto lineare Iniziale e ( se richiesto ) Finale
const double EXTRA_LEN = 2. ;
const double LEN_LINE = EXTRA_LEN ;
@@ -6838,6 +7071,7 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
else
dRotAngle = ( m_Params.m_bInvert ? - ANG_RIGHT : ANG_RIGHT) ;
// aggiungo il tratto inziale
pCompoPathLoc->GetStartPoint( ptStart) ;
Vector3d vtStart ; pCompoPathLoc->GetStartDir( vtStart) ;
Vector3d vtOut = vtStart ; vtOut.Rotate( Z_AX, dRotAngle) ;
@@ -6857,6 +7091,46 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
}
}
// se necessario calcolo il tratto a scivolo (precedentemente all'uscita finale)
// (calcolato solo per i bordi chiusi)
if ( bWithEndGlide && pCompoPath->IsClosed()) {
// inizializzo e recupero il percorso :
PtrOwner<ICurveComposite> pCrvGlideOut( CreateCurveComposite()) ;
if ( IsNull( pCrvGlideOut))
return false ;
// controllo che la lunghezza del percorso sia compatibile
double dLen = 0. ;
if ( pCompoPath->GetLength( dLen) && dLen > m_Params.m_dLoTang + 10. * EPS_SMALL) {
// recupero il tratto di curva alla fine
double dU = 0. ;
if ( ! pCompoPath->GetParamAtLength( m_Params.m_dLoTang, dU))
return false ;
pCrvGlideOut->AddCurve( pCompoPath->CopyParamRange( 0., dU)) ;
}
// se non sufficientemente lunga, la guida diventa la curva stessa
else
pCrvGlideOut->AddCurve( Release( pCrvGlideOut)) ;
// se curva a scivolo valida
if ( pCrvGlideOut->IsValid()) {
// porto la curva in locale al riferimento corrente
pCrvGlideOut->ToLoc( frLoc) ;
pCrvGlideOut->SetExtrusion( Z_AX) ;
// recupero le quote della curva
Point3d ptIni ; pCrvGlideOut->GetStartPoint( ptIni) ;
Point3d ptFin ; pCrvGlideOut->GetEndPoint( ptFin) ;
double dExtraElev = 1.0 ;
if ( m_TParams.m_nType == TT_MILL_POLISHING) // ???
dExtraElev = max( m_Params.m_dLiElev, 1.0) ;
ptFin += Z_AX * dExtraElev ;
double dNini = ( ptIni - ORIG) * Z_AX ;
double dNfin = ( ptFin - ORIG) * Z_AX ;
AdjustCurveSlope( pCrvGlideOut, dNini, dNfin) ;
pCompoPathLoc->AddCurve( Release( pCrvGlideOut)) ;
}
}
// aggiungo il tratto alla fine
Point3d ptEnd ; pCompoPathLoc->GetEndPoint( ptEnd) ;
Vector3d vtEnd ; pCompoPathLoc->GetEndDir( vtEnd) ;
vtOut = vtEnd ; vtOut.Rotate( Z_AX, dRotAngle) ;
@@ -6864,8 +7138,8 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
if ( IsNull( pLineE) || ! pLineE->Set( ptEnd, ptEnd + vtOut * LEN_LINE))
return false ;
#if DEBUG_TOOL_COMPENSATION
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLineE->Clone()) ;
m_pGeomDB->SetMaterial( nId, AQUA) ;
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLineE->Clone()) ;
m_pGeomDB->SetMaterial( nId, AQUA) ;
#endif
if ( ! IsNull( pSfrLimitLocUB) && pSfrLimitLocUB->IsValid()) {
CRVCVECTOR ccClass ;
@@ -6876,13 +7150,13 @@ PocketingNT::AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, co
}
}
// Aggiungo il tratto lineare all'inizio e alla fine
// restituisco in globale i risultati ottenuti
Point3d ptSLoc ; pLineS->GetStartPoint( ptSLoc) ;
Point3d ptELoc ; pLineE->GetEndPoint( ptELoc) ;
Point3d ptSGlob = GetToGlob( ptSLoc, frLoc) ;
Point3d ptEGlob = GetToGlob( ptELoc, frLoc) ;
if ( ! pCompoPath->AddLine( ptSGlob, false) || ! pCompoPath->AddLine( ptEGlob, true))
if ( ! pCompoPathLoc->AddLine( ptSLoc, false) || ! pCompoPathLoc->AddLine( ptELoc, true))
return false ;
pCompoPathLoc->ToGlob( frLoc) ;
pCompoPath->CopyFrom( pCompoPathLoc) ;
return true ;
}
@@ -6952,6 +7226,156 @@ PocketingNT::AssignPropsToCamDataForToolCompensation( int nId, bool bLineIn, boo
return true ;
}
//----------------------------------------------------------------------------
bool
PocketingNT::CalcLinkByStartUserPoint( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrLimit, const Point3d& ptStart,
const Point3d& ptEnd, ICurveComposite* pCompoLink) const
{
// se la regione di svuotarua non è valida, errore
if ( pSfrPock == nullptr || ! pSfrPock->IsValid())
return false ;
// calcolo un collegamento lineare tra inizio e fine
if ( pCompoLink == nullptr)
return false ;
pCompoLink->Clear() ;
Point3d ptC ; pSfrPock->GetCentroid( ptC) ;
Plane3d plProj ;
if ( ! plProj.Set( ptC, pSfrPock->GetNormVersor()))
return false ;
Point3d ptStartProj = ProjectPointOnPlane( ptStart, plProj) ;
Point3d ptEndProj = ProjectPointOnPlane( ptEnd, plProj) ;
if ( ! pCompoLink->AddPoint( ptStartProj) || ! pCompoLink->AddLine( ptEndProj))
return false ;
#if DEBUG_USER_PTSTART
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ;
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, Frame3d()) ;
m_pGeomDB->SetName( nGrp, "User_Pt_Start") ;
m_pGeomDB->SetName( nLay, "user_Pt_Start_Glob") ;
int nCrv = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pCompoLink->Clone()) ;
m_pGeomDB->SetMaterial( nCrv, BLUE) ;
#endif
// se non ho una regione limite, allora il collegamento l'ho già calcolato
if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid()) {
for ( int nCrv = 0 ; nCrv < pCompoLink->GetCurveCount() ; ++ nCrv)
pCompoLink->SetTempParam( FEED_MAX_COEFF) ;
return true ;
}
else {
#if DEBUG_USER_PTSTART
int nSfrLimit = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrLimit->Clone()) ;
m_pGeomDB->SetMaterial( nSfrLimit, Color( .0, .0, .0, .9)) ;
#endif
// effettuo un Offset della regione del raggio utensile a cui sommo eventuale sovramateriale
double dOffs = m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrSafe( pSfrPock->CreateOffsetSurf( - dOffs, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrSafe) || ! pSfrSafe->IsValid())
return false ;
// verifico se il collegamento lineare passa nella regione limite
CRVCVECTOR ccClass ;
if ( ! pSfrSafe->GetCurveClassification( *pCompoLink, EPS_SMALL, ccClass))
return false ;
if ( ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT) {
for ( int nCrv = 0 ; nCrv < pCompoLink->GetCurveCount() ; ++ nCrv)
pCompoLink->SetCurveTempParam( nCrv, FEED_MAX_COEFF) ;
return true ;
}
// eseguo un percorso di raccordo mediante smussamento sulla regione
else {
// porto tutto in un piano locale XY
Point3d ptC ; pSfrPock->GetCentroid( ptC) ;
Frame3d frXY ;
if ( ! frXY.Set( ptC, pSfrPock->GetNormVersor()))
return false ;
pCompoLink->ToLoc( frXY) ;
pCompoLink->SetExtrusion( Z_AX) ;
pSfrSafe->ToLoc( frXY) ;
// recupero il vettore delle curve della regione
ICURVEPOVECTOR vSfrOffsLoops ;
for ( int nC = 0 ; nC < pSfrSafe->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrSafe->GetLoopCount( nC) ; ++ nL) {
PtrOwner<ICurve> pCrvLoop( pSfrSafe->GetLoop( nC, nL)) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid() ||
! vSfrOffsLoops.emplace_back( Release( pCrvLoop)) || ! vSfrOffsLoops.back()->IsValid())
return false ;
}
}
if ( vSfrOffsLoops.empty())
return false ;
#if DEBUG_USER_PTSTART
int nLay1 = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, Frame3d()) ;
int nCrv = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, pCompoLink->Clone()) ;
m_pGeomDB->SetMaterial( nCrv, BLUE) ;
int nSfrLimit = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, pSfrSafe->Clone()) ;
m_pGeomDB->SetMaterial( nSfrLimit, Color( .0, .0, .0, .9)) ;
for ( int i = 0 ; i < ssize( vSfrOffsLoops) ; ++ i) {
int nLoopId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, vSfrOffsLoops[i]->Clone()) ;
m_pGeomDB->SetMaterial( nLoopId, RED) ;
}
#endif
// definisco le curve di calcolo e di verifica
PtrOwner<ICurveComposite> pCompo( pCompoLink->Clone()) ;
PtrOwner<ICurveComposite> pCompoHelp( pCompoLink->Clone()) ;
if ( IsNull( pCompo) || ! pCompo->IsValid() || IsNull( pCompoHelp) || ! pCompoHelp->IsValid())
return false ;
// scorro il vettore delle curve di bordo
for ( int i = 0 ; i < ssize( vSfrOffsLoops) ; ++ i) {
CRVCVECTOR ccClass ;
IntersCurveCurve intCC( *pCompo, *vSfrOffsLoops[i]) ;
intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ;
if ( ! pCompoHelp->Clear())
return false ;
// per ogni intersezione con l'offset dell'isola, recupero le parti esterne e raccordo esternamente le parti interne
for ( int j = 0 ; j < ssize( ccClass) ; ++ j) {
// se ho intersezione spezzo il segmento
if ( ccClass[j].nClass == CRVC_OUT) {
Point3d ptS ; pCompo->GetPointD1D2( ccClass[j].dParS, ICurve::FROM_PLUS, ptS) ;
double dOffS ; vSfrOffsLoops[i]->GetParamAtPoint( ptS, dOffS) ;
Point3d ptE ; pCompo->GetPointD1D2( ccClass[j].dParE, ICurve::FROM_MINUS, ptE) ;
double dOffE ; vSfrOffsLoops[i]->GetParamAtPoint( ptE, dOffE) ;
// recupero i due possibili percorsi e uso il più corto
PtrOwner<ICurve> pCrvA( vSfrOffsLoops[i]->CopyParamRange( dOffS, dOffE)) ;
PtrOwner<ICurve> pCrvB( vSfrOffsLoops[i]->CopyParamRange( dOffE, dOffS)) ;
if ( IsNull( pCrvA) || IsNull( pCrvB))
return false ;
double dLenA ; pCrvA->GetLength( dLenA) ;
double dLenB ; pCrvB->GetLength( dLenB) ;
if ( dLenA < dLenB)
pCompoHelp->AddCurve( Release( pCrvA)) ;
else {
pCrvB->Invert() ;
pCompoHelp->AddCurve( Release( pCrvB)) ;
}
}
// se non interseco
else
pCompoHelp->AddCurve( pCompo->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
}
pCompo->Clear() ;
pCompo->AddCurve( pCompoHelp->Clone()) ;
}
if ( pCompo->IsValid()) {
pCompoLink->Clear() ;
pCompoLink->AddCurve( Release( pCompo)) ;
for ( int nCrv = 0 ; nCrv < pCompoLink->GetCurveCount() ; ++ nCrv)
pCompoLink->SetCurveTempParam( nCrv, FEED_MAX_COEFF) ;
pCompoLink->ToGlob( frXY) ;
return true ;
}
}
}
return false ;
}
// debug functions
//----------------------------------------------------------------------------
void
+14 -6
View File
@@ -21,6 +21,7 @@
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
// struttura informazioni sui singoli percorsi
struct PathInfoPO {
@@ -109,15 +110,17 @@ class PocketingNT : public Machining
bool GetCurves( const SelData& Id, const ISurfTriMesh* pStmRaw, const ISurfTriMesh* pStmTrim, ICURVEPLIST& lstPC) ;
bool SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve, bool* pbSomeOpen = nullptr) ;
bool SetSfrLoopsAllTempProp( int nSfrId, ISurfFlatRegion* pSfr) ;
bool ResetCurveAllTempProp( ICurve* pCurve) ;
bool ResetCurveAllTempProp( ICurve* pCurve, bool bClose = true) ;
bool Chain( int nGrpDestId) ;
ISurfTriMesh* GetRaw( void) ;
ISurfTriMesh* GetStmTrim( void) ;
ISurfTriMesh* GetExtrusionStm( const ISurfFlatRegion* pSfr, const Vector3d& vtExtr) ;
ISurfFlatRegion* GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, double dDist, double dSmallOffs = 0) ;
ISurfFlatRegion* GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr, const Vector3d& vtTool) ;
ISurfFlatRegion* GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr, const Vector3d& vtTool,
const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil = nullptr) ;
Point3d GetStartPointByUser( const ISurfFlatRegion* pSfr) const ;
Point3d GetStartPointsByHead( const STEPINFOPOVECTOR& vStepInfo) const ;
Point3d GetStartPointsFromSteps( const STEPINFOPOVECTOR& vStepInfo, int nCrvType) const ;
Point3d GetStartPointsBySteps( const STEPINFOPOVECTOR& vStepInfo, int nCrvType) const ;
bool ChooseRawPart( const ISurfFlatRegion* pSfrChunk, ISurfTriMesh* pStm) const ;
bool ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmPart) ;
bool GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const ;
@@ -134,10 +137,11 @@ class PocketingNT : public Machining
bool CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, const ISurfTriMesh* pStmRaw,
const SELVECTOR& vGeoSel, ISURFFRPOVECTOR& vSfrGeoExt) ;
bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ;
bool CalcPaths( STEPINFOPOVECTOR& vStepInfo) ;
bool CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty) ;
bool CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath,
const Vector3d& vtTool, bool bHolePocketing, const Point3d& ptHoleDest, bool bToolComp, bool bInVsOut, ICurveComposite* pCrvGlide) ;
bool AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, Point3d& ptPockStart, Point3d& ptPockEnd) ;
bool AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, Point3d& ptPockStart, Point3d& ptPockEnd,
bool& bEmpty) ;
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
double GetRightStartFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
bool CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) ;
@@ -183,8 +187,12 @@ class PocketingNT : public Machining
const INTVECTOR& vLeadOutId, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool,
bool bSplitArcs, double dMinFeed) ;
double GetDoubleLastStep( void) ;
bool AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit) const ;
bool AddTangentLinesForToolCompensation( ICurveComposite* pCompoPath, const Vector3d& vtTool, const ISurfFlatRegion* pSfrLimit,
bool bWithEndGuide) const ;
bool AssignPropsToCamDataForToolCompensation( int nId, bool bLineIn, bool bLineOut, bool bToolAtLeft) ;
bool CalcLinkByStartUserPoint( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrLimit, const Point3d& ptStart,
const Point3d& ptEnd, ICurveComposite* pCompoLink) const ;
// debug
void DebugDrawSfr( const ISurfFlatRegion* pSfr, bool bUniform, int nlayer = GDB_ID_ROOT) ;
void DebugDrawLoop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ;
+613 -289
View File
File diff suppressed because it is too large Load Diff
+30 -18
View File
@@ -100,21 +100,25 @@ class SurfFinishing : public Machining
public :
SurfFinishing( void) ;
Frame3d GetFrame() const { return m_Frame ; } ; // spostare in Machining se tutto ok
Frame3d& GetFrame() { return m_Frame ; } ; // spostare in Machining se tutto ok
void SetFrame( const Frame3d& frFinishing) { m_Frame = frFinishing ; } ; // spostare in Machining se tutto ok
private :
bool MyApply( bool bRecalc, bool bPostApply) ;
bool VerifyGeometry( SelData Id, int& nSubs) ;
bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ;
bool Chain( int nGrpDestId) ;
bool UpdateFrameAndToolDir( int nAuxId, bool& bRecalc) ;
bool GetSurfacesByIds( SURFLOCALVECTOR& vSrfLoc, SURFLOCALVECTOR& vSrfSuppLoc, Frame3d& frSurf) ;
bool CalcRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dRad, double dLen, double& dElev) const ; ;
bool CalcRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dRad, double dLen, double& dElev) const ;
bool SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFlatRegion* pSfrCnt, double dDepth,
double dToolLen, double dToolDiam, double dToolCornRad,
double dToolSideAng, double dToolMaxMat, double dMachOffsR,
const SURFLOCALVECTOR& vSurfLoc, const SURFLOCALVECTOR& vSurfSuppLoc) ;
bool EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtTool,
bool EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtMove,
double dDepth, ISurfFlatRegion* pSfrCnt) ;
bool ProcessCrvCompo( int nPathId, int nPvId, int nClId) ;
bool ProcessCrv( int nPathId, int nPvId, int nClId) ;
bool ProcessSfr( int nPathId, int nPvId, int nClId) ;
bool SimplifyCurve( ICurveComposite* pCompo, const Frame3d& frLocXY,
double dMergeLinTol = 200. * EPS_SMALL, double dMergeAndTolDeg = 200. * EPS_ANG_SMALL,
@@ -126,26 +130,26 @@ class SurfFinishing : public Machining
ICurveComposite* pCrv) const ;
// lavorazioni per superfici
bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrCnt,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
const Vector3d& vtTool, const Vector3d& vtMove, double dDepth, double dElev, bool bSplitArcs) ;
bool AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrCnt,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
const Vector3d& vtTool, const Vector3d& vtMove, double dDepth, double dElev, bool bSplitArcs) ;
bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrCnt,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ;
const Vector3d& vtTool, const Vector3d& vtMove, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ;
bool AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfrCnt, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
bool AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfrCntZigZag, const ISurfFlatRegion* pSfrCntZConst, const Vector3d& vtTool,
double dDepth, double dElev, bool bSplitArcs) ;
const Vector3d& vtMove, double dDepth, double dElev, bool bSplitArcs) ;
bool AddPencil( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfrCnt, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
// lavorazioni per curve
bool AddProjection( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ICurveComposite* pCompo,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
const Vector3d& vtTool, const Vector3d& vtMove, double dDepth, double dElev, bool bSplitArcs) ;
// creazione del percorso finale di lavorazione
bool AddFinishing( const ISurfFlatRegion* pSfrCnt, ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ICRVCOMPOPOVECTOR& vCrvCompo,
const Vector3d& vtTool, double dElev, double dDepth, bool bSplitArcs) ;
const Vector3d& vtTool, const Vector3d& vtMove, double dElev, double dDepth, bool bSplitArcs) ;
// collisione con i percorsi di lavorazione
bool CorrectPathByCollision( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Vector3d& vtTool,
bool CorrectPathByCollision( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Vector3d& vtTool, const Vector3d& vtMove,
double dDepth, ICRVCOMPOPOVECTOR& vpCrvs) ;
bool WorkPencilCurves( const ICRVCOMPOPOVECTOR& vCrvCompo, const ISurfFlatRegion* pSfrCnt, int nPencilType, double dOffs, int nOffs,
@@ -178,7 +182,10 @@ class SurfFinishing : public Machining
double dFrontTriaTolerAng, double& dMaxFrontTriaRad) const ;
bool CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc,
const Frame3d& frSurf, const Vector3d& vtTool, double dAngDegSplit,
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths,
ISurfFlatRegion* pSfrToolColl) const ;
bool CalcOptimalZigZagSfrByZConstCrv( const ISurfFlatRegion* pSfrLoc, const CISURFTMPVECTOR& vpStm, const Vector3d& vtToolLoc,
double dExtraCollOffs, ICurveComposite* pCompoSil, ISurfFlatRegion* pSfrZigZag) const ;
bool CalcOptimalZigZagCurves( ISURFFRPOVECTOR& vSfrZigZagProj, const Frame3d& frSurf,
const Vector3d& vtTool, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
bool GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfrLoc, const Vector3d& vtTool,
@@ -195,13 +202,12 @@ class SurfFinishing : public Machining
bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtTool, bool bSplitArcs) ;
bool CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool, const Vector3d& vtNorm, Point3d& ptP1) const ;
bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Point3d& ptP1, const Vector3d& vtTool, bool bSplitArcs) ;
bool GetLastGoodPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Point3d& ptStart,
const Point3d& ptEnd, const Vector3d& vtInit, const Vector3d& vtTool,
bool bLeadInVsOut, Point3d& ptP1) const ;
bool GetLinkFromPaths( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtTool, const ISurfFlatRegion* pSfrCnt,
bool GetLastGoodPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Point3d& ptStart, const Point3d& ptEnd,
const Vector3d& vtInit, const Vector3d& vtTool, const Vector3d& vtMove, bool bLeadInVsOut, Point3d& ptP1) const ;
bool GetLinkFromPaths( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtTool, const Vector3d& vtMove, const ISurfFlatRegion* pSfrCnt,
double dDepth, double dSafeZ, ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, ICurveComposite* pCrvLink) const ;
bool GetSurfaceNormalAtPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const Point3d& ptTool, const Vector3d& vtTool, Vector3d& vtNorm) const ;
const Point3d& ptTool, const Vector3d& vtTool, const Vector3d& vtMove, Vector3d& vtNorm) const ;
bool GetActiveSurfaces( INTVECTOR& vSurfId, INTVECTOR& vSurfSuppId) const ;
int ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQpt1, double dQpt2, double dQpt3,
int& nI1s, int& nI1e, int& nI2s, int& nI2e) const ;
@@ -215,10 +221,12 @@ class SurfFinishing : public Machining
double dLimInfClippingAng, double dLimSupClippingAng, const Vector3d& vtAxL, const Vector3d& vtMoveL, ICAvToolSurfTm* pCAvTlStm,
ICRVCOMPOPOVECTOR& vCrvCompo) const ;
bool AreSameSfrChunkEpsilon( const ISurfFlatRegion* pSfrChunkA, const ISurfFlatRegion* pSfrChunkB, double dMaxDist) const ;
bool CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const Vector3d& vtTool, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const ;
bool CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const ISurfFlatRegion* pSfrZLevelColl, const SURFLOCALVECTOR& vSrfLoc,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const ;
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
double GetRadiusForStartEndElevation( void) const ;
double GetLocalSideAngle() const ;
bool GetLocalToolDir( Vector3d& vtToolLoc) const ;
private :
double GetSpeed() const
@@ -235,6 +243,7 @@ class SurfFinishing : public Machining
{ return ( IsUnknownValue( m_Params.m_dOffsR) ? m_TParams.m_dOffsR : m_Params.m_dOffsR) ; }
double GetSideStep( void) const
{ return Clamp( m_Params.m_dSideStep, 0.1, m_TParams.m_dTDiam) ; }
int GetLeadInType( void) const ;
int GetLeadOutType( void) const ;
@@ -242,6 +251,9 @@ class SurfFinishing : public Machining
SELVECTOR m_vId ; // identificativi entità geometriche da lavorare
SurfFinishingData m_Params ; // parametri lavorazione
ToolData m_TParams ; // parametri utensile
Frame3d m_Frame ; // terna per orientamento finitura ZigZag/OneWay
double m_dTheta ; // orientamento verticale utensile rispetto a m_Frame
double m_dPhi ; // orientamento orizzontale utesnile rispetto a m_Frame
double m_dTHoldBase ; // posizione base del porta-utensile
double m_dTHoldLen ; // lunghezza del porta-utensile
double m_dTHoldDiam ; // diametro del porta-utensile