Merge commit 'b5ef9ae6dc7564e172af1a7558348e60b5da6a0f' into svuotature

This commit is contained in:
Riccardo Elitropi
2024-01-03 09:32:55 +01:00
12 changed files with 990 additions and 369 deletions
+573 -22
View File
@@ -1,13 +1,14 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
// EgalTech 2015-2023
//----------------------------------------------------------------------------
// File : Drilling.cpp Data : 21.05.15 Versione : 1.6e7
// File : Drilling.cpp Data : 20.12.23 Versione : 2.5l47
// Contenuto : Implementazione gestione forature.
//
// Note : Questa lavorazione è sempre espressa nel riferimento globale.
//
// Modifiche : 21.05.15 DS Creazione modulo.
//
// 20.12.23 RE Forature multiple con aggregati.
//
//
//----------------------------------------------------------------------------
@@ -19,6 +20,7 @@
#include "OperationConst.h"
#include "/EgtDev/Include/EXeCmdLogOff.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
@@ -27,6 +29,7 @@
#include "/EgtDev/Include/EGkUserObjFactory.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkGeoFrame3d.h"
using namespace std ;
@@ -46,6 +49,8 @@ using namespace std ;
// 2113 = "Error in Drilling : post apply not calculable"
// 2114 = "Error in Drilling : blind hole not reversible"
// 2115 = "Error in Drilling : Mirror for Double calculation failed"
// 2116 = "Error in Drilling : multi drilling head without valid tools"
// 2117 = "Error in Drilling : incorrect multi drilling head"
// 2151 = "Warning in Drilling : Skipped entity (xx)"
// 2152 = "Warning in Drilling : No machinable path"
// 2153 = "Warning in Drilling : Tool name changed (xx)"
@@ -69,6 +74,39 @@ struct Hole
: nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dThick( 0), dLen( 0), bBlind( true) {}
} ;
struct MHDrill {
int nInd_id_hole ; // indice foro
Vector3d vtAux ; // vettore ausiliario per tale foratura
} ;
struct HoleInfo {
Hole hole ; // foro
bool bDrill = false ; // se alla fine verrà lavorato
bool bTempDrill = false ; // per test maschera (se durante un test viene lavorato o no)
int nTempTool = -1 ; // per test maschera ( indice utensile che lo lavora durante un test)
bool bSkipToAngle = false ; // nel caso di più assi rotanti, se foro già lavorato con testa orientata
bool bForToolM = false ; // se tool main lavorerà questo foro
int nIndHoleToolM = -1 ; // indice del foro che lo svuoterà inserendo il primo tool in esso
INTVECTOR vToolHole ; // vettore di indici dei fori ai quali inserire l'ultim punta per lavorare il foro corrente
INTVECTOR vIndTools ; // vettore dei tool associati ad ogni lavorazione in vToolHole (ordinati)
VCT3DVECTOR vVtAux ; // vettore dei vtAux ausiliari del tool principale per lavorare questo foro (ordinati)
int nIndTool = -1 ; // indice del tool che alla fine lavorerà il foro
Vector3d vtAux ; // vettore ausiliario del tool principale che permette al tool principale di lavorare questo foro
Point3d ptBtn ; // punto interno alla base del foro
int nIndInSelVector = 0 ; // indice nel vettore m_vId (id fori selezionati)
} ;
struct ToolInfo
{
const ToolData* pTool ; // puntatore per utensile (nullo se utensile non presente)
Point3d ptToolTip ; // punto finale del tool (per ptBtn del foro)
ToolInfo( void)
: pTool( nullptr) {}
ToolInfo( const ToolData* pT)
: pTool( pT) {}
} ;
//----------------------------------------------------------------------------
USEROBJ_REGISTER( GetOperationClass( OPER_DRILLING), Drilling) ;
@@ -452,16 +490,16 @@ Drilling::SetGeometry( const SELVECTOR& vIds)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD) {
// recupero il valore di tolleranza sul diametro
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
//double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
// verifico che gli identificativi rappresentino dei fori con il corretto diametro
for ( int i = 0 ; i < int( vIds.size()) ; ++ i) {
// recupero i dati del foro
Hole hole ;
if ( ! GetHoleData( vIds[i], hole) || ! VerifyDiameter( hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
m_pMchMgr->SetWarning( 2151, sInfo) ;
continue ;
}
//Hole hole ;
//if ( ! GetHoleData( vIds[i], hole) || !VerifyDiameter(hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
// string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
// m_pMchMgr->SetWarning( 2151, sInfo) ;
// continue ;
//}
// posso aggiungere alla lista
m_vId.push_back( vIds[i]) ;
}
@@ -515,7 +553,7 @@ Drilling::Preview( bool bRecalc)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD)
return StdandardProcess( bRecalc, nPvId, GDB_ID_NULL) ;
return StandardProcess( bRecalc, nPvId, GDB_ID_NULL) ;
// se altrimenti lavorazione lungo curve
else if ( m_Params.m_nSubType == DRI_SUB_ALONG_CURVE)
return AlongCurveProcess( bRecalc, nPvId, GDB_ID_NULL) ;
@@ -580,7 +618,7 @@ Drilling::Apply( bool bRecalc, bool bPostApply)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD) {
if ( ! StdandardProcess( bRecalc, GDB_ID_NULL, nClId))
if ( ! StandardProcess( bRecalc, GDB_ID_NULL, nClId))
return false ;
}
// se altrimenti lavorazione lungo curve
@@ -676,10 +714,42 @@ Drilling::Update( bool bPostApply)
//----------------------------------------------------------------------------
bool
Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId)
Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId)
{
// elaboro i singoli fori
// controllo se ho più uscite
string sCurrHead ;
if ( ! m_pMchMgr->GetCurrMachine()->GetCurrHead( sCurrHead))
return false ;
int nExitCnt = m_pMchMgr->GetCurrMachine()->GetHeadExitCount( sCurrHead) ;
TABMHDRILL tabDrills ;
double dMHOff = 0 ;
// se ho più uscite...
if ( nExitCnt > 1) {
if ( ! MultiHeadDrilling( nExitCnt, m_vId, nClId, tabDrills, dMHOff))
return false ;
if( tabDrills.size() == 0)
return true ;
int j = 0 ;
for ( int i = 0 ; i < ( int)tabDrills.size() ; ++i) {
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( j, m_vId[tabDrills[i][0].nInd_id_hole], MCH_PATH, nClId))
return false ;
// creo la regione di ingombro del foro
int nDriId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetLastGroupInGroup( nPvId)) ;
GenerateHoleRegionPv( nDriId, 1, nPvId) ;
}
// se richiesta lavorazione
if ( nClId != GDB_ID_NULL) {
if ( ! GenerateHoleCl( j, m_vId[tabDrills[i][0].nInd_id_hole], MCH_PATH, nClId, dMHOff, tabDrills[i][0].vtAux))
return false ;
}
// incremento indice
++j ;
}
return true ;
}
// ... altrimenti elaboro i singoli fori
int i = 0 ;
for ( const auto& vId : m_vId) {
// se richiesto preview
@@ -696,12 +766,491 @@ Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId)
return false ;
}
// incremento indice
++ i ;
++i ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::MultiHeadDrilling( int nExitCnt, const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff, bool bOrd)
{
// controllo parametri
tabDrills.clear() ;
if ( vId.empty())
return true ;
// recupero il nome della testa
string sHead ;
m_pMchMgr->GetCurrMachine()->GetCurrHead( sHead) ;
// gestore degli utensili
ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ;
if ( pTMgr == nullptr)
return false ;
// Recupero i dati degli utensili montati sulla testa
int nMainToolInd = -1 ;
VECTORTOOL vTools ; vTools.reserve( nExitCnt) ;
// ricavo gli utensili presenti sulle uscite
for ( int nT = 0 ; nT < nExitCnt ; ++ nT) {
string sToolName ;
ToolInfo TInf ;
if ( ! m_pMchMgr->GetLoadedTool( sHead, nT + 1, sToolName) || sToolName.empty()) {
// non c'è utensile
vTools.emplace_back( nullptr) ;
continue ;
}
// se presente e valido
const ToolData* pTdata = pTMgr->GetTool( sToolName) ;
vTools.emplace_back( pTdata) ;
// imposto il tool di riferimento come il tool m_TParams
if ( pTdata->m_Uuid == m_TParams.m_Uuid)
nMainToolInd = nT ;
}
// se non ho utensili attivi o validi, errore
if ( nMainToolInd == -1 || vTools.empty()) {
m_pMchMgr->SetLastError( 2116, "Error in Drilling : multi drilling head without valid tools") ;
return false ;
}
// carico i dati della testa con le sue uscite
Vector3d vtTool, vtAux ;
for ( int nT = 0 ; nT < nExitCnt ; ++ nT) {
// se non attrezzato, salto al successivo
if ( vTools[nT].pTool == nullptr)
continue ;
// recupero i dati dell'uscita
Point3d ptExit ;
Vector3d vtCurrDir, vtCurrAux ;
m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux( sHead, nT + 1, ptExit, vtCurrDir, vtCurrAux) ;
// se utensile successivo
if ( ! vtTool.IsSmall()) {
// controllo abbia la stessa direzione dei precedenti, altrimenti errore
if ( ! AreSameVectorApprox( vtCurrDir, vtTool)) {
vtTool = V_NULL ;
break ;
}
}
// altrimenti primo utensile
else {
vtTool = vtCurrDir ;
vtAux = vtCurrAux ;
}
// assegno tip utensile
vTools[nT].ptToolTip = ptExit - vtCurrDir * vTools[nT].pTool->m_dLen ;
}
if ( vtTool.IsSmall() || vtAux.IsSmall()) {
m_pMchMgr->SetLastError( 2117, "Error in Drilling : incorrect multi drilling head") ;
return false ;
}
// Recupero le geometrie dei fori
bool bSomeHoleOk = false ;
VECTORHOLE vHoles( vId.size()) ;
for ( int h = 0 ; h < ( int)vId.size() ; ++ h) {
Hole hole ;
if ( ! GetHoleData( m_vId[h], hole)) {
string sInfo = "Warning in Drilling : Skipped entity " + ToString( m_vId[h]) ;
m_pMchMgr->SetWarning( 2151, sInfo) ;
continue ;
}
// se richiesta inversione e foro passante, provvedo
if ( m_Params.m_bInvert) {
if ( hole.bBlind) {
m_pMchMgr->SetLastError( 2114, "Error in Drilling : blind hole not reversible") ;
return false ;
}
else {
hole.ptIni -= hole.vtDir * hole.dThick ;
hole.vtDir.Invert() ;
}
}
// se lavorazione del foro non arriva al suo fondo, lo considero cieco
if ( hole.dLen < hole.dThick - 10 * EPS_SMALL)
hole.bBlind = true ;
vHoles[h].hole = hole ;
vHoles[h].nIndInSelVector = h ;
bSomeHoleOk = true ;
}
if ( ! bSomeHoleOk)
return true ;
// calcolo la corrispondenza tra utensili e fori
if ( ! CalcMask( vHoles, vTools, nMainToolInd, vtTool, vtAux))
return false ;
// i fori con dimensione 0 del vettore vToolHole non possono essere lavorati
int nNoDrillHoles = 0 ;
for ( int i = 0 ; i < ( int)vHoles.size() ; ++ i) {
if ( vHoles[i].vToolHole.size() == 0)
++ nNoDrillHoles ;
}
// resetto le variabili di controllo di lavorazione temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k)
vHoles[k].bTempDrill = false ;
// numero di fori lavorati
int nOkHole = 0 ;
// decido in quali fori inserire il tool principale
for ( int nCheck = 1 ; nCheck < ( int)vHoles.size() && nOkHole < ( int)vHoles.size() - nNoDrillHoles ; ++ nCheck) {
for ( int i = 0 ; i < ( int)vHoles.size() ; ++i) {
if ( vHoles[i].vToolHole.size() == nCheck && ! vHoles[i].bDrill) { // prendo tutti i fori con vToolHope di lunghezza nCheck non già svuotati
vHoles[vHoles[i].vToolHole[0]].bForToolM = true ;
vHoles[vHoles[i].vToolHole[0]].nIndTool = nMainToolInd ;
vHoles[vHoles[i].vToolHole[0]].nIndHoleToolM = vHoles[i].vToolHole[0] ;
vHoles[vHoles[i].vToolHole[0]].vtAux = vHoles[i].vVtAux[0] ;
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k) {
for ( int l = 0 ; l < ( int)vHoles[k].vToolHole.size() ; ++l) {
if ( vHoles[k].vToolHole[l] == vHoles[i].vToolHole[0] && ! vHoles[k].bDrill) {
vHoles[k].bDrill = true ;
vHoles[k].nIndTool = vHoles[k].vIndTools[0] ;
vHoles[k].nIndHoleToolM = vHoles[vHoles[i].vToolHole[0]].nIndHoleToolM ;
vHoles[k].vtAux = vHoles[k].vVtAux[l] ;
++ nOkHole ;
break ;
}
}
}
}
}
}
// calcolo la massima differenza di lunghezza tra il primo tool e gli altri ( così l'elevazione finale rimane compatibile)
double dRefLen = vTools[nMainToolInd].pTool->m_dTLen ;
double dOffMax = 0 ;
for ( int nT = 0 ; nT < ( int)vTools.size() && nNoDrillHoles != (int)vHoles.size() ; ++ nT) {
if ( vTools[nT].pTool == nullptr || nT == nMainToolInd)
continue ;
if ( vTools[nT].pTool->m_dTLen > dRefLen + dOffMax) {
dOffMax = vTools[nT].pTool->m_dTLen - dRefLen ;
}
}
dMHOff = dOffMax ;
// riempio la maschera
VCT3DVECTOR vVtA ;
for ( int i = 0 ; i < ( int)vHoles.size() && nNoDrillHoles != ( int)vHoles.size() ; ++ i) {
if ( ! vHoles[i].bForToolM)
continue ;
// per tutti i fori che vengono svuotati da un tool t-esimo conto quanti versori A diversi tra loro trovo
for ( int j = 0 ; j < ( int)vHoles.size() ; ++j) {
if ( vHoles[j].nIndHoleToolM != i)
continue ;
if ( vVtA.empty())
vVtA.push_back( vHoles[j].vtAux) ;
else {
bool bPush = true ;
for ( int v = 0 ; v < ( int)vVtA.size() ; ++ v) {
if ( AreSameVectorApprox( vHoles[j].vtAux, vVtA[v])) {
bPush = false ;
break ;
}
}
if ( bPush)
vVtA.push_back( vHoles[j].vtAux) ;
}
}
for ( int v = 0 ; v < ( int)vVtA.size() ; ++ v) {
vector<MHDrill> vRowDrill ;
MHDrill FirstMHDrill ;
FirstMHDrill.nInd_id_hole = i ;
FirstMHDrill.vtAux = vVtA[v] ;
vRowDrill.push_back( FirstMHDrill) ;
tabDrills.push_back( vRowDrill) ;
}
vVtA.clear() ;
}
// se non trovo corrispondenze ...
if ( tabDrills.empty())
return true ;
// se devo riordinare
if ( bOrd) {
struct Order {
int nInd_id_hole ;
Point3d ptIni ;
} ;
vector<Order> vOrder ;
for ( int i = 0 ; i < ( int)tabDrills.size() ; ++ i) {
Order newOrder ;
newOrder.nInd_id_hole = tabDrills[i][0].nInd_id_hole ;
newOrder.ptIni = vHoles[tabDrills[i][0].nInd_id_hole].hole.ptIni ;
vOrder.push_back( newOrder) ;
}
// prendo come riferimento il punto del primo foro selezionato dall'utente
Point3d ptRef = vOrder[0].ptIni ;
double dMinDist = INFINITO ;
int nIndexSwitch = -1 ;
for ( int i = 0 ; i < ( int)vOrder.size() - 1 ; ++ i) {
for ( int j = i + 1 ; j < ( int)vOrder.size() ; ++ j) {
Point3d ptS = vOrder[j].ptIni ;
if ( Dist( ptS, ptRef) < dMinDist) {
dMinDist = Dist( ptS, ptRef) ;
nIndexSwitch = j ;
}
}
if ( nIndexSwitch != i + 1) {
vector<MHDrill> VHelp = tabDrills[nIndexSwitch] ;
tabDrills[nIndexSwitch] = tabDrills[i + 1] ;
tabDrills[i + 1] = VHelp ;
}
ptRef = vOrder[i + 1].ptIni ;
dMinDist = INFINITO ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux)
{
// controllo dei parametri
if ( vHoles.empty() || vTools.empty())
return false ;
// recupero il valore di tolleranza sul diametro
double dDiamToler = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
int nExitCnt = ( int)vTools.size() ;
int nNullTools = 0 ;
for ( int i = 0 ; i < ( int)vTools.size() ; ++ i) {
if ( vTools[i].pTool == nullptr)
++ nNullTools ;
}
// in ogni foro i-esimo inserisco il Tool principale
for ( int i = 0 ; i < ( int)vHoles.size() ; ++ i) {
// resetto le veriabili di controllo di svuotatura temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++ k) {
vHoles[k].bTempDrill = false ;
vHoles[k].nTempTool = -1 ;
}
// verifica validità del foro i-esimo per il Tool principale
Hole Hole_i = vHoles[i].hole ;
if ( ! MultiHeadVerifyHole( Hole_i, vTools[nIndMT].pTool, dDiamToler, m_vId[vHoles[i].nIndInSelVector]))
continue ;
int nStat ;
DBLVECTOR vAng1, vAng2 ;
// angoli per allineare T del tool principale con vtDir del foro i-esimo
if ( ! m_pMchMgr->GetCalcAngles( Hole_i.vtDir, V_NULL, nStat, vAng1, vAng2))
continue ;
Vector3d vtTnew ;
// check che T sia allineato con vtDir
if ( ! m_pMchMgr->GetCalcToolDirFromAngles( vAng1, vtTnew) || ! AreSameVectorApprox( vtTnew, Hole_i.vtDir))
continue ;
Vector3d vtAnew ;
// nuova configurazione del versore A ottenuta
if ( ! m_pMchMgr->GetCalcAuxDirFromAngles( vAng1, vtAnew))
continue ;
// creo un nuovo sistema di riferimento centrato nel Tool principale
Frame3d frMT ;
frMT.Set( vTools[nIndMT].ptToolTip, vtTool, vtAux) ;
if ( ! frMT.IsValid())
return false ;
// creo un frame nel foro i-esimo orientato come il frame sul tool principale ( origine nella base interna del foro)
Frame3d frHMT ;
frHMT.Set( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen, vtTnew, vtAnew) ;
if ( ! frHMT.IsValid())
return false ;
// numero di svuotature inserendo il Tool principale nel foro i-esimo
int nDrills = 1 ;
// setto le variabili temporanee per il foro i-esimo
vHoles[i].bTempDrill = true ;
vHoles[i].nTempTool = nIndMT ;
// controllo la compatibilità tra le geometrie dei Tool e dei fori
CheckOtherHolesWithTools( vHoles, vTools, nIndMT, i, Hole_i, frMT, frHMT, dDiamToler, nDrills) ;
// controllo quanti fori sono riuscito a svuotare e setto i loro parametri di foratura
if ( nDrills == nExitCnt - nNullTools) { // se ho svuotato il numero corretto di fori ...
for ( int d = 0 ; d < ( int)vHoles.size() ; ++ d) {
if ( vHoles[d].bTempDrill) {
vHoles[d].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[d].vIndTools.push_back( vHoles[d].nTempTool) ; // indice del tool che svuota questo foro
vHoles[d].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario A del tool principale
}
}
}
else {
for ( int d = 0 ; d < ( int)vHoles.size() ; ++ d)
if ( vHoles[d].bTempDrill)
vHoles[d].bTempDrill = false ;
}
// se la testa può ruotare
if ( nStat < 0) {
// inizio a scorrere tutti i tools
for ( int t = 0 ; t < ( int)vTools.size() ; ++ t) {
if ( vTools[t].pTool == nullptr || t == nIndMT)
continue ;
// cerco se ho un foro j-esimo adatto per quella punta
for ( int j = 0 ; j < ( int)vHoles.size() ; ++ j) {
Hole Hole_j = vHoles[j].hole ;
if ( i == j ||
vHoles[j].bSkipToAngle ||
! AreSameVectorApprox( Hole_j.vtDir, Hole_i.vtDir) ||
! MultiHeadVerifyHole( Hole_j, vTools[t].pTool, dDiamToler, m_vId[vHoles[j].nIndInSelVector]))
continue ;
// resetto le veriabili di controllo di svuotatura temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++ k) {
vHoles[k].bTempDrill = false ;
vHoles[k].nTempTool = -1 ;
}
Vector3d vtRefT = vTools[t].ptToolTip - vTools[nIndMT].ptToolTip ;
Vector3d vtRefH = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen -
( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen) ;
// se le distanze sono compatibili
if ( abs( vtRefH.Len() - vtRefT.Len()) < EPS_SMALL) {
// rioriento il frame sul foro i-esimo
Point3d ptHj = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen ;
ptHj.ToLoc( frHMT) ;
Vector3d vtProjB( ptHj.x, ptHj.y, 0) ;
Point3d ptTt = vTools[t].ptToolTip ;
ptTt.ToLoc( frMT) ;
Vector3d vtProjA( ptTt.x, ptTt.y, 0) ;
double dAngle ; vtProjA.GetAngle( vtProjB, dAngle) ;
frHMT.Rotate( frHMT.Orig(), frHMT.VersZ(), dAngle) ;
nDrills = 1 ; // foratura nel foro i-esimo e j-esimo
CheckOtherHolesWithTools( vHoles, vTools, nIndMT, i, Hole_i, frMT, frHMT, dDiamToler, nDrills) ;
// setto le variabili temporanee per il foro i-esimo
vHoles[i].bTempDrill = true ;
vHoles[i].nTempTool = nIndMT ;
// controllo quanti fori sono riuscito a svuotare in questo nuovo sistema di riferimento
if ( nDrills == nExitCnt - nNullTools) {
for ( int d = 0 ; d < ( int)vHoles.size() ; ++ d) {
if ( vHoles[d].bTempDrill) {
vHoles[d].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[d].vIndTools.push_back( vHoles[d].nTempTool) ; // indice del tool che svuota questo foro
vHoles[d].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario del tool principale
vHoles[d].bSkipToAngle = true ;
}
}
}
else {
for ( int d = 0 ; d < ( int)vHoles.size() ; ++ d)
if ( vHoles[d].bTempDrill)
vHoles[d].bTempDrill = false ;
}
}
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP,
const Frame3d& frMT, const Frame3d& frHMT, double dDiamToler, int& nDrills)
{
// controllo parametri
if ( vHoles.empty() || vTools.empty())
return true ;
if ( nIndTM < 0 || nIndTM >= ( int)vTools.size() ||
nIndHTM < 0 || nIndHTM >= ( int)vHoles.size() ||
! frMT.IsValid() || ! frHMT.IsValid() ||
nDrills < 0 || nDrills > max( ( int)vHoles.size(), ( int)vTools.size()))
return false ;
// definisco il punto dove cade il tool principale
Hole holeTM = holeICP ; // copia del foro i-esimo
// ciclo su tutti i tools
for ( int t = 0 ; t < ( int)vTools.size() ; ++ t) {
if ( vTools[t].pTool == nullptr || t == nIndTM)
continue ;
// esprimo il punto finale del tool t-esimo nel sistema di riferimento del Tool principale
Point3d ptETt = vTools[t].ptToolTip ;
ptETt.ToLoc( frMT) ;
// cerco se ho un foro j-esimo adatto per quella punta
for ( int j = 0 ; j < ( int)vHoles.size() ; ++ j) {
Hole Hole_j = vHoles[j].hole ; // copia del foro j-esimo
// controllo che il foro j-esimo non sia l'i-esimo, che non sia stato già precedentemente svuotato da un altro tool t'-esimo ...
// ... che vtDir del foro i-esimo coincida con vtDir del foro j-esimo e che il tool t-esimo sia compatibile con il foro j-esimo
if ( nIndHTM == j ||
vHoles[j].bTempDrill ||
! AreSameVectorApprox( Hole_j.vtDir, holeTM.vtDir) ||
! MultiHeadVerifyHole( Hole_j, vTools[t].pTool, dDiamToler, m_vId[vHoles[j].nIndInSelVector]))
continue ;
// esprimo il foro j-esimo nel sistema di riferimento del Tool principale centrato nel foro i-esimo
Point3d ptHj = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen ;
ptHj.ToLoc( frHMT) ;
// controllo la compatibilità
if ( AreSamePointApprox( ptHj, ptETt)) {
// un foro in più lavorato
++ nDrills ;
// aggiorno le variabili temporanee
vHoles[j].bTempDrill = true ;
vHoles[j].nTempTool = t ;
// non controllo gli altri vertici per la punta t-esima
break ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id)
{
// verifico che il diamtro del tool sia compatibile con quello del foro
if ( ! VerifyDiameter( hole.dDiam, Tool->m_dDiam, dDiamToler))
return false ;
// imposto elevazione da lunghezza foro con possibilità di sovrascrittura da info
double dElev = hole.dLen ;
double dMaxElev ;
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) {
dElev = dMaxElev ;
hole.ptIni += hole.vtDir * ( dElev - hole.dLen) ;
hole.dLen = dElev ;
}
// limito lunghezza foro a massima lavorazione della punta
double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ;
if ( ( dElev + dAddLen) > Tool->m_dMaxMat + EPS_SMALL) {
hole.dLen = Tool->m_dMaxMat + max( hole.dLen - dElev, 0.) ;
hole.bBlind = true ;
}
if ( ! VerifyHoleFromBottom( hole, Id))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::AlongCurveProcess( bool bRecalc, int nPvId, int nClId)
@@ -994,12 +1543,12 @@ Drilling::GenerateHolePv( int nInd, const SelData& nCircId, const string& sPName
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
if ( IsNull( pCrvArc) || ! pCrvArc->Set( hole.ptIni, hole.vtDir, 0.5 * m_TParams.m_dDiam))
return false ;
// assegno il versore estrusione e lo spessore
// assegno il versore estrusione e lo spessore
pCrvArc->SetExtrusion( hole.vtDir) ;
pCrvArc->SetThickness( - hole.dLen) ;
// inserisco nel DB
int nDriId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrvArc)) ;
// assegno nome e colore
// assegno nome e colore
m_pGeomDB->SetName( nDriId, MCH_PV_CUT) ;
m_pGeomDB->SetMaterial( nDriId, LIME) ;
// aggiorno numero forature
@@ -1009,7 +1558,7 @@ Drilling::GenerateHolePv( int nInd, const SelData& nCircId, const string& sPName
//----------------------------------------------------------------------------
bool
Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName, int nClId)
Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName, int nClId, double dMHOff, Vector3d vtA)
{
// creo gruppo per geometria di lavorazione del foro
int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
@@ -1077,7 +1626,7 @@ Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName
// foro normale
if ( m_Params.m_dStep < EPS_SMALL ||
m_Params.m_dStep > hole.dLen - EPS_SMALL) {
if ( DoStandardDrilling( hole, nCircId, nPathId)) {
if ( DoStandardDrilling( hole, nCircId, nPathId, dMHOff, vtA)) {
// aggiorno numero forature
++ m_nDrillings ;
}
@@ -1495,7 +2044,7 @@ Drilling::VerifyHoleFromBottom( const Hole& hole, SelData Id)
//----------------------------------------------------------------------------
bool
Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId, double dMHOff, Vector3d vtA)
{
// aggiusto alcuni parametri del ciclo di foratura
double dStartSlowLen = abs( m_Params.m_dStartSlowLen) ;
@@ -1525,7 +2074,7 @@ Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
double dAppr = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ;
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen) ;
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen + dMHOff) ;
if ( m_bAggrBottom) {
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
@@ -1552,6 +2101,8 @@ Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
return false ;
}
else {
if( ! vtA.IsSmall())
SetAuxDir( vtA) ;
if ( AddRapidStart( ptP1) == GDB_ID_NULL)
return false ;
}
+14 -3
View File
@@ -19,7 +19,13 @@
#include "MachiningConst.h"
struct Hole ;
struct MHDrill ;
struct HoleInfo ;
struct ToolInfo ;
class ICurve ;
typedef std::vector<std::vector<MHDrill>> TABMHDRILL ;
typedef std::vector<HoleInfo> VECTORHOLE ;
typedef std::vector<ToolInfo> VECTORTOOL ;
//----------------------------------------------------------------------------
class Drilling : public Machining
@@ -68,18 +74,23 @@ class Drilling : public Machining
private :
bool GetHoleData( SelData Id, Hole& hole) ;
bool StdandardProcess( bool bRecalc, int nPvId, int nClId) ;
bool StandardProcess( bool bRecalc, int nPvId, int nClId) ;
bool AlongCurveProcess( bool bRecalc, int nPvId, int nClId) ;
bool Chain( int nGrpDestId) ;
ICurve* GetCurve( SelData Id) ;
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
bool GenerateHolePv( int nInd, const SelData& nCircId, const std::string& sPName, int nPvId) ;
bool GenerateHoleCl( int nInd, const SelData& nCircId, const std::string& sPName, int nClId) ;
bool GenerateHoleCl( int nInd, const SelData& nCircId, const std::string& sPName, int nClId, double dMHOff = .0, Vector3d vtAux = V_NULL) ;
bool GenerateHoleRegionPv( int nFirstId, int nCount, int nPvId) ;
bool VerifyDiameter( double dHdiam, double dTdiam, double ddiamTol) ;
bool VerifyHoleFromBottom( const Hole& hole, SelData Id) ;
bool DoStandardDrilling( const Hole& hole, SelData Id, int nPathId) ;
bool DoStandardDrilling( const Hole& hole, SelData Id, int nPathId, double nMHOff, Vector3d vtA) ;
bool DoPeckDrilling( const Hole& hole, SelData Id, int nPathId) ;
bool MultiHeadDrilling( int nExitCnt, const SELVECTOR& vId, int nClId, TABMHDRILL& vDrills, double& dMHOff, bool bOrd = true) ;
bool CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux) ;
bool CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP,
const Frame3d& frHTM, const Frame3d& frHMTOP, double dDiamToler, int& nDrills) ;
bool MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id) ;
private :
double GetSpeed() const
BIN
View File
Binary file not shown.
+1
View File
@@ -19,6 +19,7 @@
//----------- Costanti per approssimazioni con polilinee o poliarchi --------
const double LIN_TOL_STD = 0.1 ;
const double LIN_TOL_MID = 0.05 ;
const double LIN_TOL_RAW = 0.5 ;
const double ANG_TOL_MAX_DEG = 90 ;
const double ANG_TOL_STD_DEG = 15 ;
const double LIN_FEA_STD = 20 ;
+302 -237
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -106,13 +106,13 @@ class Milling : public Machining
bool AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, const Vector3d& vtTool,
double dSafeZ, double dSawEndElev, double dEndElev, double dAppr) ;
bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtTool,
double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ;
double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1, Vector3d& vtDir1) const ;
bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart,
const Vector3d& vtTool, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) ;
const Vector3d& vtTool, double dStElev, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) ;
bool CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool,
double dEndElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ;
bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool, double dEndElev,
bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1) ;
bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1, Vector3d& vtDir1) ;
bool AdjustOscillParams( const ICurve* pCrv, bool& bPathOscEnable, double& dRampLen, double& dFlatLen) ;
bool AddOscillLine( const ICurveLine* pLine, const Vector3d& vtTool, double dRampLen, double dFlatLen) ;
bool AddOscillArc( const ICurveArc* pArc, const Vector3d& vtTool, double dRampLen, double dFlatLen) ;
+44 -97
View File
@@ -317,7 +317,7 @@ Operation::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2,
double dElevS = 0 ;
// faccio test con un insieme di punti ( !!! sostituire con intersezione tra rettangolo e trimesh !!!)
const double STEP = 50 ;
int nStep = max( (int) ceil( ApproxDist( ptP1L, ptP2L) / STEP), 3) ;
int nStep = max( (int) ceil( ApproxDist( ptP1L, ptP2L) / STEP), 2) ;
for ( int i = 0 ; i <= nStep ; ++ i) {
// calcolo punto di test
double dFraz = i / (double) nStep ;
@@ -380,90 +380,6 @@ Operation::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, c
return true ;
}
#if 1
//----------------------------------------------------------------------------
bool
Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad,
const Vector3d& vtDir, double& dElev) const
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// vettore grezzi interessati
INTVECTOR vRawStmId ;
// considero il punto centrale
if ( ! GetElevation( nPhase, ptP, vtDir, dElev, vRawStmId))
return false ;
// considero più posizioni sulla circonferenza
const int MIN_STEP = 9 ;
const int MAX_STEP = 127 ;
const double LEN_STEP = 12.5 ;
int nStep = Clamp( 2 * int( ( PIGRECO * dRad) / LEN_STEP) + 1, MIN_STEP, MAX_STEP) ;
Vector3d vtRad = FromUprightOrtho( vtTool) * dRad ;
for ( int i = 0 ; i < nStep ; ++ i) {
double dElevT = 0 ;
if ( ! GetElevation( nPhase, ptP + vtRad, vtDir, dElevT, vRawStmId))
return false ;
dElev = max( dElev, dElevT) ;
// passo alla direzione successiva
vtRad.Rotate( vtTool, ANG_FULL / nStep) ;
}
// considero i vertici che cadono entro il cilindro positivo spazzato dal fondo utensile
for ( auto nRawStmId : vRawStmId) {
// recupero la superficie
const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawStmId)) ;
if ( pStm != nullptr) {
// recupero il riferimento della trimesh
Frame3d frStm ;
m_pGeomDB->GetGlobFrame( nRawStmId, frStm) ;
// ciclo sui vertici
Point3d ptV ;
int nV = pStm->GetFirstVertex( ptV) ;
while ( nV != SVT_NULL) {
ptV.ToGlob( frStm) ;
double dDist = ( ptV - ptP) * vtDir ;
if ( dDist > EPS_ZERO) {
if ( AreSameOrOppositeVectorApprox( vtTool, vtDir)) {
Vector3d vtOrtho = OrthoCompo( ptV - ptP, vtDir) ;
if ( vtOrtho.SqLen() < dRad * dRad + EPS_ZERO)
dElev = max( dElev, dDist) ;
}
else {
Vector3d vtOrtho = OrthoCompo( ptV - ptP, vtDir) ;
Vector3d vtMajAx = vtTool ^ vtDir ; vtMajAx.Normalize( EPS_ZERO) ;
Vector3d vtMajOrt = ParallCompo( vtOrtho, vtMajAx) ;
Vector3d vtMinOrt = ( vtOrtho - vtMajOrt) / abs( vtTool * vtDir) ;
if ( vtMajOrt.SqLen() + vtMinOrt.SqLen() < dRad * dRad + EPS_ZERO)
dElev = max( dElev, dDist) ;
}
}
nV = pStm->GetNextVertex( nV, ptV) ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, double dLen,
const Vector3d& vtDir, double& dElev) const
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// sopra e sotto
double dElev1, dElev2 ;
if ( ! GetElevation( nPhase, ptP, vtTool, dRad, vtDir, dElev1))
return false ;
if ( ! GetElevation( nPhase, ptP + dLen * vtTool, vtTool, dRad, vtDir, dElev2))
return false ;
dElev = max( dElev1, dElev2) ;
return true ;
}
#else
//----------------------------------------------------------------------------
bool
Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad,
@@ -508,10 +424,18 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool,
pCAvTlStm->SetStdTool( dLen, dRad, 0) ;
pCAvTlStm->SetSurfTm( *pStm) ;
double dDist = 0 ;
// per Collision Avoid il punto di riferimento non è il tip dell'utensile ma il naso mandrino
if ( ! pCAvTlStm->TestPosition( ptPL + dLen * vtToolL, vtToolL, vtDirL, dDist))
return false ;
if ( dDist > 0)
// non è ammesso un angolo oltre 90deg tra direzione utensile e vettore movimento
if ( vtToolL * vtDirL < 0) {
// il tip utensile è qui il naso mandrino per Collision Avoid
if ( ! pCAvTlStm->TestPosition( ptPL, -vtToolL, vtDirL, dDist))
return false ;
}
else {
// per Collision Avoid il punto di riferimento non è il tip dell'utensile ma il naso mandrino
if ( ! pCAvTlStm->TestPosition( ptPL + dLen * vtToolL, vtToolL, vtDirL, dDist))
return false ;
}
if ( dDist > EPS_SMALL)
vRawElev.emplace_back( nStmId, dDist) ;
}
}
@@ -541,7 +465,7 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool,
}
b3Tool.Expand( MAX_DIST_RAW) ;
// verifico la reale interferenza dell'utensile con i diversi grezzi
for ( int i = 0 ; i < vRawElev.size() ; ++ i) {
for ( int i = 0 ; i < int( vRawElev.size()) ; ++ i) {
// box del grezzo
BBox3d b3Raw ;
m_pGeomDB->GetGlobalBBox( vRawElev[i].first, b3Raw) ;
@@ -556,7 +480,30 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool,
return true ;
}
#endif
//----------------------------------------------------------------------------
bool
Operation::GetElevation( int nPhase, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtTool, double dRad, double dLen,
const Vector3d& vtDir, double& dElev) const
{
// risultato di default
bool bOk = false ;
dElev = 0 ;
// faccio test sui punti dall'inizio alla fine
const double STEP = 50 ;
int nStep = max( (int) ceil( ApproxDist( ptS, ptE) / STEP), 2) ;
for ( int i = 0 ; i <= nStep ; ++ i) {
// calcolo punto di test
double dFraz = i / (double) nStep ;
Point3d ptP = Media( ptS, ptE, dFraz) ;
// eseguo il calcolo
double dCurrElev ;
if ( GetElevation( nPhase, ptP, vtTool, dRad, dLen, vtDir, dCurrElev)) {
bOk = true ;
dElev = max( dElev, dCurrElev) ;
}
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
@@ -597,17 +544,17 @@ Operation::GetAhPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, doubl
// determino elevazione del punto rispetto al grezzo a metà altezza
Point3d ptTest( ptP.x, ptP.y, dRawCentZ) ;
double dNewElev ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
// se direzione di fuga quasi orizzontale (max 30 deg) e ingombro utensile rilevante rispetto ad altezza grezzo
if ( vtMyDir.z < 0.5 && dToolDimZ > dRawDimZ / 2) {
// determino elevazione del punto rispetto al grezzo a metà altezza più metà ingombro utensile
ptTest = Point3d( ptP.x, ptP.y, dRawCentZ + dToolDimZ / 2) ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
// determino elevazione del punto rispetto al grezzo a metà altezza meno metà ingombro utensile
ptTest = Point3d( ptP.x, ptP.y, dRawCentZ - dToolDimZ / 2) ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
}
return true ;
@@ -920,17 +867,17 @@ Operation::GetUhPointAboveRaw( const Point3d& ptP, const Vector3d& vtTool, doubl
// determino elevazione del punto rispetto al grezzo a metà altezza
Point3d ptTest( ptP.x, ptP.y, dRawCentZ) ;
double dNewElev ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
// se direzione di fuga quasi orizzontale (max 30 deg) e ingombro utensile rilevante rispetto ad altezza grezzo
if ( vtMyDir.z > -0.5 && dToolDimZ > dRawDimZ / 2) {
// determino elevazione del punto rispetto al grezzo a metà altezza più metà ingombro utensile
ptTest = Point3d( ptP.x, ptP.y, dRawCentZ + dToolDimZ / 2) ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
// determino elevazione del punto rispetto al grezzo a metà altezza meno metà ingombro utensile
ptTest = Point3d( ptP.x, ptP.y, dRawCentZ - dToolDimZ / 2) ;
if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev))
if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev))
dElev = max( dElev, dNewElev) ;
}
return true ;
+2
View File
@@ -84,6 +84,8 @@ class Operation : public IUserObj
const Vector3d& vtDir, double& dElev) const ;
bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, double dLen,
const Vector3d& vtDir, double& dElev) const ;
bool GetElevation( int nPhase, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtTool, double dRad, double dLen,
const Vector3d& vtDir, double& dElev) const ;
bool GetAhPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev,
double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const ;
bool GetUhPointAboveRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev,
+36 -2
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// EgalTech 2017-2022
//----------------------------------------------------------------------------
// File : Pocketing.cpp Data : 24.08.22 Versione : 2.4h2
// File : Pocketing.cpp Data : 17.12.23 Versione : 2.5l3
// Contenuto : Implementazione gestione svuotature.
//
//
@@ -32,6 +32,7 @@
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkCurveLocal.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkPolygonElevation.h"
#include "/EgtDev/Include/EGkUserObjFactory.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
@@ -2585,6 +2586,39 @@ Pocketing::GetNewSfrByAnotherPocketing( ISurfFlatRegion* pSfrPock, const ISurfFl
if ( IsNull( pSfrToolPath)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
Polygon3d pgFacet ;
if ( ! pgFacet.FromPolyLine( PL))
return false ;
// aggiungo l'affondamento
pgFacet.Translate( -dDepth * vtTool) ;
// inizializzo elevazioni per ogni grezzo
INTDBLVECTOR vRawElev ;
// ciclo sui grezzi della fase
int nRawId = m_pMchMgr->GetFirstRawPart() ;
while ( nRawId != GDB_ID_NULL) {
// verifico che il grezzo compaia nella fase
if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) {
// recupero la trimesh del grezzo
int nStmId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nStmId)) ;
if ( pStm != nullptr) {
// recupero il riferimento della trimesh
Frame3d frStm ;
m_pGeomDB->GetGlobFrame( nStmId, frStm) ;
// porto il poligono in questo riferimento
Polygon3d pgFacetL = pgFacet ;
pgFacetL.ToLoc( frStm) ;
// calcolo l'elevazione
double dCurrElev ;
if ( ! PolygonElevationInClosedSurfTm( pgFacetL, *pStm, true, dCurrElev))
return false ;
if ( dCurrElev > EPS_SMALL)
vRawElev.emplace_back( nStmId, dCurrElev) ;
}
}
// passo al grezzo successivo
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
if ( ! pSfrToolPath->IsValid())
return true ;
+1 -1
View File
@@ -76,7 +76,7 @@ class Pocketing : public Machining
bool ResetCurveAllTempProp( ICurve* pCurve) ;
bool Chain( int nGrpDestId) ;
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ;
bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double dLen, double& dElev) const ;
bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ;
bool GeneratePocketingPv( int nPathId, const ISurfTriMesh* pStm_PartVolume) ;
bool CheckSimpleOverlap( const ICurve* pCrv, const ICurveComposite* pCrvOri, int& nStat, double dToll) ;
+6
View File
@@ -84,6 +84,9 @@ Processor::Run( const string& sOutFile, const string& sInfo)
if ( ! VerifySetup())
return false ;
// imposto la fase iniziale come corrente
m_pMchMgr->SetCurrPhase( 1) ;
// evento inizio esecuzione
bool bOk = true ;
if ( ! OnStart()) {
@@ -145,6 +148,9 @@ Processor::Run( const string& sOutFile, const string& sInfo)
LOG_ERROR( GetEMkLogger(), "OnEnd error") ;
}
// imposto la fase iniziale come corrente
m_pMchMgr->SetCurrPhase( 1) ;
return bOk ;
}
+8 -4
View File
@@ -47,10 +47,12 @@ static const double MIN_STEP = 1.0 ;
static const double MAX_STEP = 100.0 ;
static const double MID_STEP = 50.0 ;
static const double COLL_STEP = 10. ;
static const double SQ_COEFF_ROT_MOVE = 100. ;
static const double COEFF_LIM = 0.999 ;
static const double SAFEDIST_STD = 5.0 ;
static const int ERR_OUTSTROKE = 1 ;
static const int ERR_COLLISION = 11 ;
static const int ERR_TOOL_SEL = 21 ;
//----------------------------------------------------------------------------
Simulator::Simulator( void)
@@ -997,7 +999,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove)
double dSqDist = 0 ;
for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) {
// coefficiente moltiplicativo per differenziare assi lineari (primi 3) e rotanti (altri)
double dSqCoeff = (( i < 3) ? 1 : 100) ;
double dSqCoeff = (( i < 3) ? 1 : SQ_COEFF_ROT_MOVE) ;
dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ;
}
// Calcolo distanza di movimento eventuali assi ausiliari
@@ -1006,7 +1008,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove)
if ( m_AuxAxesLink[i] != 0)
continue ;
// coefficiente moltiplicativo per differenziare assi lineari e rotanti
double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : 100) ;
double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
dSqDistAux += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
}
// Considero il massimo delle due distanze
@@ -1188,7 +1190,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove)
double dSqDist = 0 ;
for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) {
// coefficiente moltiplicativo per differenziare assi lineari e rotanti
double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : 100) ;
double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ;
dSqDist += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ;
}
double dPrevCoeff = m_dCoeff ;
@@ -1634,8 +1636,10 @@ Simulator::OnToolSelect( const string& sTool, const string& sHead, int nExit, co
m_AuxAxesLink.emplace_back( 0) ;
}
}
else
else {
bOk = false ;
nErr = ERR_TOOL_SEL ;
}
}
return ( bOk && nErr == 0) ;