Merge commit 'b5ef9ae6dc7564e172af1a7558348e60b5da6a0f' into svuotature
This commit is contained in:
+573
-22
@@ -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
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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 ;
|
||||
|
||||
@@ -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
@@ -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
@@ -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) ;
|
||||
|
||||
@@ -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
@@ -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) ;
|
||||
|
||||
Reference in New Issue
Block a user