EgtMachKernel :

- In finiture primo utilizzo delle funzioni di Offset per superfici di supporto
- in finiture semplicificazione e riorganizzazione del codice.
This commit is contained in:
Riccardo Elitropi
2025-06-17 14:31:12 +02:00
parent 478a23c3fe
commit ba9bf97372
2 changed files with 294 additions and 193 deletions
+287 -191
View File
@@ -41,6 +41,7 @@
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include <thread>
#include <future>
// per far dimenticare macro di WinUser.h
@@ -86,12 +87,15 @@ using namespace std ;
//----------------------------------------------------------------------------
static string KEY_THICK = "THICK" ;
static string SRF_SUPP_LAYER_NAME = "SUPP" ;
const double SILH_SAMPLING = 1. ;
const double SUPP_SURF_RADIAL_OFFS = 5. ;
#define DEBUG_SFR 0
#define ENABLE_ZCONST_DEBUG 0
#define ENABLE_OPTIMAL_DEBUG 0
#define ENABLE_OPTIMAL_SOFT_DEBUG 0
#if ENABLE_ZCONST_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG
#if DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG
#include "EgtDev/Include/EGkGeoPoint3d.h"
#include "EgtDev/Include/EGkGeoVector3d.h"
#include "chrono"
@@ -1267,6 +1271,209 @@ SurfFinishing::Chain( int nGrpDestId)
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::GetSurfacesByIds( SURFLOCALVECTOR& vSrfLoc, SURFLOCALVECTOR& vSrfSuppLoc, Frame3d& frSurf)
{
/* funzione che restituisce le superfici attive, le superfici di supporto e il frame di riferimento */
vSrfLoc.clear() ;
vSrfSuppLoc.clear() ;
// recupero le superfici attive e le superfici nel Layer di supporto
INTVECTOR vSurfId, vSurfSuppId ;
GetActiveSurfaces( vSurfId, vSurfSuppId) ;
// porto tutte le superfici nel riferimento della prima
for ( int& nSurfId : vSurfId) {
if ( vSrfLoc.empty()) {
if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf))
return false ;
}
vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ;
}
if ( ! frSurf.IsValid())
return false ;
for ( int& nSrfSuppId : vSurfSuppId)
vSrfSuppLoc.emplace_back( m_pGeomDB, nSrfSuppId, frSurf) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFlatRegion* pSfrCnt, double dDepth,
SURFLOCALVECTOR& vSurfLoc, SURFLOCALVECTOR& vSurfSuppLoc)
{
// controllo dei parametri
if ( pCAvTlStm == nullptr || vSurfLoc.empty())
return false ;
// definisco l'ambiente di correzione dei percorsi utensili
if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) {
pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(),
m_TParams.m_dDiam / 2. + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
else {
double dDeltaRad ;
double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ;
if ( m_TParams.m_dSideAng > 0) {
if ( m_TParams.m_dCornRad < EPS_SMALL)
dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ;
else
dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) +
( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ;
}
else
dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ;
double dStemRad = m_TParams.m_dDiam / 2. + dDeltaRad ;
double dTipRad = m_TParams.m_dDiam / 2. ;
pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(), dStemRad + GetOffsR(),
m_TParams.m_dMaxMat, dTipRad + GetOffsR(), m_TParams.m_dCornRad + GetOffsR()) ;
}
// aggiungo tutte le superfici di lavoro
pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSurfLoc[0].Get())) ;
for ( int i = 1 ; i < int( vSurfLoc.size()) ; ++ i)
pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSurfLoc[i].Get())) ;
// aggiungo le superfici di supporto
if ( ! vSurfSuppLoc.empty()) {
/* Se considero interamente la superficie di supporto ho diversi svantaggi :
1) Incrementa notevolmente il Box complessivo delle superfici di lavoro
=> Ho molti più punti nelle griglie di campionamento per Silhouette o percorsi di collisione
2) Calcolo l'Offset di TriMesh di parti "lontane" dalla regione corrente di lavoro
=> Più tempo computazionale per Offset
=> Superfici con più triangoli
*/
// definisco una superficie di contenimento ; L'Offset verrà fatto solo sulle aprti di Stm interne ad essa
PtrOwner<ISurfTriMesh> pStmContainment( CreateSurfTriMesh()) ;
if ( IsNull( pStmContainment))
return false ;
if ( pSfrCnt != nullptr && pSfrCnt->IsValid() && abs( dDepth) > 10 * EPS_SMALL) {
// considero la regione complessiva di lavoro dell'utensile all'interno della quale non può uscire
double dOffs = m_TParams.m_dDiam / 2. + m_Params.m_dOverlap + SUPP_SURF_RADIAL_OFFS + 50 * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrFreeMove( pSfrCnt->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrFreeMove) || ! pSfrFreeMove->IsValid())
return false ;
// definisco una TriMesh di estrusione da questa regione
pSfrFreeMove->Translate( - dDepth * pSfrCnt->GetNormVersor()) ;
CICURVEPVECTOR vpCrv ;
for ( int nC = 0 ; nC < pSfrFreeMove->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrFreeMove->GetLoopCount( nC) ; ++ nL)
vpCrv.emplace_back( pSfrFreeMove->GetLoop( nC, nL)) ;
}
pStmContainment.Set( GetSurfTriMeshByRegionExtrusion( vpCrv, ( dDepth + m_TParams.m_dLen) * pSfrCnt->GetNormVersor())) ;
}
// definisco la tolleranza lineare per Offset
double dLinTol = 2. ;
// recupero le superfici singole ( più veloce che calcolare Offset complessivo)
for ( const SurfLocal& SurfSupp : vSurfSuppLoc) {
// le superfici di supporto devono essere ben definite ed avere un volume chiuso
const ISurfTriMesh* pStmSupp = GetSurfTriMesh( SurfSupp.Get()) ;
if ( pStmSupp == nullptr || ! pStmSupp->IsValid() || pStmSupp->GetTriangleCount() == 0 ||
! pStmSupp->IsClosed())
continue ;
// tengo la la tengo la parte di superficie
PtrOwner<ISurfTriMesh> pTruncStm( CloneSurfTriMesh( pStmSupp)) ;
if ( IsNull( pTruncStm) || ! pTruncStm->IsValid())
return false ;
if ( ! IsNull( pStmContainment) && pStmContainment->IsValid() &&
pStmContainment->GetTriangleCount() > 0 && pStmContainment->IsClosed()) {
PtrOwner<ISurfTriMesh> pStmTemp( CloneSurfTriMesh( pTruncStm)) ;
if ( IsNull( pStmTemp) || ! pStmTemp->IsValid())
return false ;
if ( pStmTemp->Intersect( *pStmContainment) && pStmTemp->IsClosed())
pTruncStm.Set( Release( pStmTemp)) ;
}
// calcolo l'Offset
if ( ! IsNull( pTruncStm) && pTruncStm->IsValid()) {
PtrOwner<ISurfTriMesh> pStmSuppOffs( CreateSurfTriMeshOffset( pTruncStm, SUPP_SURF_RADIAL_OFFS, dLinTol)) ;
if ( ! IsNull( pStmSuppOffs) && pStmSuppOffs->IsValid() && pStmSuppOffs->GetTriangleCount() > 0)
pCAvTlStm->AddSurfTm( *Release( pStmSuppOffs)) ;
}
}
}
return true ;
}
//---------------------------------------------------------------------------
bool
SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtTool,
double dDepth, ISurfFlatRegion* pSfrCnt)
{
// controllo dei parametri
if ( vSurfLoc.empty() || pSfrCnt == nullptr || ! pSfrCnt->IsValid())
return true ;
// calcolo silhouette dell'insieme di superfici
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfLoc.size()) ;
for ( int i = 0 ; i < int( vSurfLoc.size()) ; ++ i)
vpStm.emplace_back( GetSurfTriMesh( vSurfLoc[i].Get())) ;
// determino il frame locale delle superfici analizzando la prima
Frame3d frPocket ;
Point3d ptCen ; pSfrCnt->GetCentroid( ptCen) ;
frPocket.Set( ptCen, vtTool) ;
frPocket.ToLoc( frSurf) ;
const double SILH_TOL = 1. ;
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPocket, SILH_TOL))
return false ;
POLYLINEVECTOR vPL ;
if ( ! pCavParSilh->GetSilhouette( - dDepth, vPL))
return false ;
// creazione della regione piana dalle PolyLine ricavate dalla Silhouette
const double SILH_ARC_TOL = SILH_TOL / 10. ;
const double SILH_ARC_FEA_MAX = 100. ;
SurfFlatRegionByContours SfrMaker ;
for ( auto& PL : vPL) {
// recupero la curva dalla silhouette
PtrOwner<ICurveComposite> pSilCrv( CreateCurveComposite()) ;
if ( IsNull( pSilCrv))
return false ;
pSilCrv->FromPolyLine( PL) ;
// approssimo con archi
PolyArc PA ;
if ( pSilCrv->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) {
PtrOwner<ICurveComposite> pTempCrv( CreateCurveComposite()) ;
if ( ! IsNull( pTempCrv) &&
pTempCrv->FromPolyArc( PA) &&
pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2., ANG_TOL_STD_DEG) &&
pTempCrv->MergeCurves( SILH_ARC_TOL / 2., ANG_TOL_STD_DEG))
pSilCrv.Set( pTempCrv) ;
}
// aggiungo per regione
if ( ! SfrMaker.AddCurve( Release( pSilCrv)))
return false ;
}
PtrOwner<ISurfFlatRegion> pSfrSil( SfrMaker.GetSurf()) ;
if ( ! IsNull( pSfrSil)) {
pSfrSil->ToGlob( frSurf) ;
double dPockRadOffs = SILH_ARC_TOL ;
pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ;
// intersezione tra contorno e regione
if ( ! pSfrCnt->Intersect( *pSfrSil)) {
// ricreo la regione originale
PtrOwner<ISurfFlatRegion> pSfrCntCopy( CloneSurfFlatRegion( pSfrCnt)) ;
if ( IsNull( pSfrCntCopy) || ! pSfrCntCopy->IsValid())
return false ;
pSfrCnt->Clear() ;
pSfrCnt->CopyFrom( pSfrCntCopy) ;
}
// azzero le proprietà delle curve semplici dei contorni delle regioni ( se 1 lato aperto)
for ( int nC = 0 ; nC < pSfrCnt->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrCnt->GetLoopCount( nC) ; ++ nL) {
for ( int nCrv = 0 ; ; ++ nCrv) {
if ( ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, TEMP_PROP_CLOSE_EDGE, 0) ||
! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, TEMP_PROP_CLOSE_EDGE, 1))
break ;
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId)
@@ -1317,13 +1524,9 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId)
m_pMchMgr->SetLastError( 3108, "Error in SurfFinishing : Depth not computable") ;
return false ;
}
// recupero il box del grezzo in globale
BBox3d b3Raw ;
if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) {
m_pMchMgr->SetLastError( 3107, "Error in SurfFinishing : Empty RawBox") ;
return false ;
}
// se spessore positivo, lo sottraggo al risultato
if ( dThick > 0)
dDepth -= dThick ;
// verifico che la curva sia piana
Plane3d plPlane ;
@@ -1351,56 +1554,20 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId)
// verifico se archi vanno approssimati con segmenti di retta
bool bSplitArcs = GetSplitArcs( vtTool) ;
// porto tutte le superfici nel riferimento della prima
// recupero le superfici di lavoro e di supporto
SURFLOCALVECTOR vSrfLoc, vSrfLocSupp ;
Frame3d frSurf ;
SURFLOCALVECTOR vSrfLoc ;
INTVECTOR vSurfId ;
GetActiveSurfaces( vSurfId) ;
for ( auto nSurfId : vSurfId) {
if ( vSrfLoc.empty()) {
if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf))
return false ;
}
vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ;
}
if ( ! frSurf.IsValid()) {
if ( ! GetSurfacesByIds( vSrfLoc, vSrfLocSupp, frSurf)) {
m_pMchMgr->SetLastError( 3123, "Error in SurfFinishing : missing surfaces") ;
return false ;
}
// predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi
// predispongo l'ambiente di correzione dei percorsi utensili
PtrOwner<ICAvToolSurfTm> pCAvTlStm( CreateCAvToolSurfTm()) ;
if ( IsNull( pCAvTlStm))
if ( IsNull( pCAvTlStm) || ! SetCAvTlStmForSurfaces( pCAvTlStm, nullptr, dDepth, vSrfLoc, vSrfLocSupp)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) {
pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(),
m_TParams.m_dDiam / 2 + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
else {
double dDeltaRad ;
double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ;
if ( m_TParams.m_dSideAng > 0) {
if ( m_TParams.m_dCornRad < EPS_SMALL)
dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ;
else
dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) +
( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ;
}
else {
dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ;
}
double dStemRad = m_TParams.m_dDiam / 2 + dDeltaRad ;
double dTipRad = m_TParams.m_dDiam / 2 ;
pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(),
dStemRad + GetOffsR(),
m_TParams.m_dMaxMat,
dTipRad + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ;
for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i)
pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ;
// assegno il vettore estrazione al gruppo del percorso
m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ;
@@ -1409,11 +1576,6 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId)
SetPathId( nPxId) ;
SetToolDir( vtTool) ;
// recupero la curva da lavorare
PtrOwner<ICurveComposite> pCrvCompo( pCrvCompoGDB->Clone()) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid())
return false ;
// Eseguo la lavorazione a seconda del tipo
double dElev = dDepth ;
@@ -1485,13 +1647,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
if ( dThick > 0)
dDepth -= dThick ;
// recupero il box del grezzo in globale
BBox3d b3Raw ;
if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) {
m_pMchMgr->SetLastError( 3107, "Error in SurfFinishing : Empty RawBox") ;
return false ;
}
// recupero il Loop esterno della regione da svuotatare
PtrOwner<ICurve> pCrvExt( pSfrGDB->GetLoop( 0, 0)) ;
if ( IsNull( pCrvExt) || ! pCrvExt->IsValid())
@@ -1509,12 +1664,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
}
if ( plPlane.GetVersN() * vtExtr * dArea < 0)
pCrvExt->Invert() ;
if ( plPlane.GetVersN() * vtExtr < 0)
plPlane.Invert() ;
// recupero flag per saltare parti a massimo affondamento
bool bSkipMaxDown = true ;
GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ;
// recupero nome del path
string sPathName ;
@@ -1535,57 +1684,14 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
// verifico se archi vanno approssimati con segmenti di retta
bool bSplitArcs = GetSplitArcs( vtTool) ;
// porto tutte le superfici nel riferimento della prima
// recupero le superfici di lavoro e di supporto
SURFLOCALVECTOR vSrfLoc, vSrfLocSupp ;
Frame3d frSurf ;
SURFLOCALVECTOR vSrfLoc ;
INTVECTOR vSurfId ;
GetActiveSurfaces( vSurfId) ;
for ( auto nSurfId : vSurfId) {
if ( vSrfLoc.empty()) {
if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf))
return false ;
}
vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ;
}
if ( ! frSurf.IsValid()) {
if ( ! GetSurfacesByIds( vSrfLoc, vSrfLocSupp, frSurf)) {
m_pMchMgr->SetLastError( 3123, "Error in SurfFinishing : missing surfaces") ;
return false ;
}
// predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi
PtrOwner<ICAvToolSurfTm> pCAvTlStm( CreateCAvToolSurfTm()) ;
if ( IsNull( pCAvTlStm))
return false ;
if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) {
pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(),
m_TParams.m_dDiam / 2 + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
else {
double dDeltaRad ;
double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ;
if ( m_TParams.m_dSideAng > 0) {
if ( m_TParams.m_dCornRad < EPS_SMALL)
dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ;
else
dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) +
( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ;
}
else {
dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ;
}
double dStemRad = m_TParams.m_dDiam / 2 + dDeltaRad ;
double dTipRad = m_TParams.m_dDiam / 2 ;
pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(),
dStemRad + GetOffsR(),
m_TParams.m_dMaxMat,
dTipRad + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ;
for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i)
pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ;
// determino la regione da lavorare
PtrOwner<ISurfFlatRegion> pSfrCnt( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrCnt) || ! pSfrCnt->AddExtLoop( *pCrvExt)) {
@@ -1596,81 +1702,54 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
// recupero l'isola
PtrOwner<ICurve> pCrvIsl( pSfrGDB->GetLoop( 0, nL)) ;
if ( IsNull( pCrvIsl) || ! pCrvIsl->IsValid() ||
! pSfrCnt->AddIntLoop( Release( pCrvIsl)))
return false ;
}
// se richiesto, elimino le parti al massimo affondamento
if ( bSkipMaxDown) {
// calcolo silhouette dell'insieme di superfici
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfId.size()) ;
for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i)
vpStm.emplace_back( GetSurfTriMesh( vSrfLoc[i].Get())) ;
Frame3d frPocket ;
Point3d ptCen ; pCrvExt->GetCentroid( ptCen) ;
frPocket.Set( ptCen, vtTool) ;
frPocket.ToLoc( frSurf) ;
const double SILH_TOL = 1.0 ;
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPocket, SILH_TOL))
return false ;
POLYLINEVECTOR vPL ;
if ( ! pCavParSilh->GetSilhouette( -dDepth, vPL)) {
! pSfrCnt->AddIntLoop( Release( pCrvIsl))) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// creo la regione piana dalle PolyLine ricavate dalla Silhouette
const double SILH_ARC_TOL = 0.1 * SILH_TOL ;
const double SILH_ARC_FEA_MAX = 100. ;
SurfFlatRegionByContours SfrMaker ;
for ( auto& PL : vPL) {
// recupero la curva dalla silhouette
PtrOwner<ICurveComposite> pSilCrv( CreateCurveComposite()) ;
if ( IsNull( pSilCrv))
return false ;
pSilCrv->FromPolyLine( PL) ;
// approssimo con archi
PolyArc PA ;
if ( pSilCrv->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) {
PtrOwner<ICurveComposite> pTempCrv( CreateCurveComposite()) ;
if ( ! IsNull( pTempCrv) &&
pTempCrv->FromPolyArc( PA) &&
pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) &&
pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG))
pSilCrv.Set( pTempCrv) ;
}
// aggiungo per regione
if ( ! SfrMaker.AddCurve( Release( pSilCrv))) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
}
PtrOwner<ISurfFlatRegion> pSfrSil( SfrMaker.GetSurf()) ;
if ( ! IsNull( pSfrSil)) {
pSfrSil->ToGlob( frSurf) ;
double dPockRadOffs = SILH_ARC_TOL ;
pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ;
// intersezione tra contorno e regione
if ( ! pSfrCnt->Intersect( *pSfrSil)) {
// ricreo la regione originale
pSfrCnt->Clear() ;
pSfrCnt->AddExtLoop( *pCrvExt) ;
}
// azzero le proprietà delle curve semplici dei contorni delle regioni ( se 1 lato aperto)
for ( int nC = 0 ; nC < pSfrCnt->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrCnt->GetLoopCount( nC) ; ++ nL) {
for ( int nCrv = 0 ; ; ++ nCrv) {
if ( ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, 0, 0) ||
! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, 0, 1))
break ;
}
}
}
}
// se regione non valida, non faccio nulla
if ( ! pSfrCnt->IsValid())
return true ;
#if DEBUG_SFR
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "FlatRegions") ;
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLay, "Sfr_by_curves") ;
int nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrCnt->Clone()) ;
m_pGeomDB->SetMaterial( nSfr, Color( 0., 1., 0., .5)) ;
#endif
// predispongo l'ambiente di correzione dei percorsi utensili
PtrOwner<ICAvToolSurfTm> pCAvTlStm( CreateCAvToolSurfTm()) ;
PtrOwner<ISurfFlatRegion> pSfrCntLoc( CloneSurfFlatRegion( pSfrCnt)) ;
if ( IsNull( pCAvTlStm) ||
IsNull( pSfrCntLoc) || ! pSfrCntLoc->IsValid() || ! pSfrCntLoc->ToLoc( frSurf) ||
! SetCAvTlStmForSurfaces( pCAvTlStm, pSfrCntLoc, dDepth, vSrfLoc, vSrfLocSupp)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// se richiesto, elimino le parti al massimo affondamento
bool bSkipMaxDown = true ;
GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ;
PerformanceCounter PC ;
PC.Start() ;
if ( bSkipMaxDown) {
if ( ! EraseMaxDownSurf( vSrfLoc, frSurf, vtTool, dDepth, pSfrCnt)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
}
LOG_INFO( GetEMkLogger(), ( "ToT Time : " + ToString( PC.Stop())).c_str()) ;
// se regione risultante vuota, non devo fare altro
if ( ! pSfrCnt->IsValid())
return true ;
#if DEBUG_SFR
int nLay3 = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLay3, "Sfr_Final") ;
int nSfrF = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay3, pSfrCnt->Clone()) ;
m_pGeomDB->SetMaterial( nSfrF, LIME) ;
#endif
// assegno il vettore estrazione al gruppo del percorso
m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ;
@@ -1679,9 +1758,12 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
SetPathId( nPxId) ;
SetToolDir( vtTool) ;
// inserisco le superfici di supporto tra le superfici locali
for ( SurfLocal& SurfLocSupp : vSrfLocSupp)
vSrfLoc.emplace_back( SurfLocSupp) ;
// Eseguo la lavorazione a seconda del tipo
double dElev = dDepth ;
switch ( m_Params.m_nSubType) {
case SURFFIN_SUB_ZIGZAG :
if ( ! AddZigZag( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs))
@@ -1759,10 +1841,17 @@ SurfFinishing::SimplifyCurve( ICurveComposite* pCompo) const
//----------------------------------------------------------------------------
bool
SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const
SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId, INTVECTOR& vSurfSuppId) const
{
// NB.
// - vSrufInd contiene gli Id delle superfici selezionate ( nel caso non ci siano superfici
// seleionate, allora vengono considerate tutte le superfici presenti nei grezzi attivi della fase
// - vSurfSupp contiene gli Id delle superfici di supporto, quindi quelle superici da cui si vuole
// mantenere una certa distanza con l'utensile ( senza che siano selezionate)
// pulisco vettore superfici
vSurfId.clear() ;
vSurfSuppId.clear() ;
// verifiche
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
@@ -1772,10 +1861,9 @@ SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const
if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH)
vSurfId.emplace_back( nEntId) ;
}
// se trovate superfici, considero solo queste ed esco
if ( ! vSurfId.empty())
return true ;
// altrimenti considero tutte le superfici dei pezzi nei grezzi attivi della fase
// controllo se sono state trovate delle superfici
bool bNoSurfId = ( vSurfId.empty()) ;
// scorro tutte le superfici dei pezzi nei grezzi attivi della fase
int nRawId = m_pMchMgr->GetFirstRawPart() ;
while ( nRawId != GDB_ID_NULL) {
if ( m_pMchMgr->VerifyRawPartPhase(nRawId, m_nPhase)) {
@@ -1791,18 +1879,26 @@ SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const
// se entità superficie e visibile, la aggiungo
int nStat ;
if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH &&
m_pGeomDB->GetCalcStatus( nEntId, nStat) && nStat != GDB_ST_OFF)
vSurfId.emplace_back( nEntId) ;
m_pGeomDB->GetCalcStatus( nEntId, nStat) && nStat != GDB_ST_OFF) {
// se non sono state selezionate superfici precedentemente, memorizzo tale id
if ( bNoSurfId)
vSurfId.emplace_back( nEntId) ;
// verifico se è presente una superficie di controllo
string sLayIdName ;
if ( m_pGeomDB->GetName( nLayId, sLayIdName) && EqualNoCase( sLayIdName, SRF_SUPP_LAYER_NAME))
vSurfSuppId.emplace_back( nEntId) ;
}
// passo alla entità successiva
nEntId = m_pGeomDB->GetNext( nEntId) ;
}
nLayId =m_pGeomDB->GetNextGroup( nLayId) ;
nLayId = m_pGeomDB->GetNextGroup( nLayId) ;
}
nPartId = m_pMchMgr->GetNextPartInRawPart( nPartId) ;
}
}
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
return true ;
}
@@ -5472,7 +5568,7 @@ SurfFinishing::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) con
double
SurfFinishing::GetRadiusForStartEndElevation( void) const
{
const double DELTA_ELEV_RAD = 4.0 ;
const double DELTA_ELEV_RAD = 4.0 ;
double dDeltaRad = min( DELTA_ELEV_RAD, 0.5 * m_TParams.m_dTDiam) ;
return ( 0.5 * m_TParams.m_dTDiam + dDeltaRad) ;
}
+7 -2
View File
@@ -104,8 +104,13 @@ class SurfFinishing : public Machining
bool VerifyGeometry( SelData Id, int& nSubs) ;
bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ;
bool Chain( int nGrpDestId) ;
bool ProcessSfr( int nPathId, int nPvId, int nClId) ;
bool GetSurfacesByIds( SURFLOCALVECTOR& vSrfLoc, SURFLOCALVECTOR& vSrfSuppLoc, Frame3d& frSurf) ;
bool SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFlatRegion* pSfrCnt, double dDepth,
SURFLOCALVECTOR& vSurfLoc, SURFLOCALVECTOR& vSurfSuppLoc) ;
bool EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtTool,
double dDepth, ISurfFlatRegion* pSfrCnt) ;
bool ProcessCrvCompo( int nPathId, int nPvId, int nClId) ;
bool ProcessSfr( int nPathId, int nPvId, int nClId) ;
bool SimplifyCurve( ICurveComposite* pCompo) const ;
bool CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
@@ -158,7 +163,7 @@ class SurfFinishing : public Machining
const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtTool, Point3d& ptP1) const ;
bool GetSurfaceNormalAtPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const Point3d& ptTool, const Vector3d& vtTool, Vector3d& vtNorm) const ;
bool GetActiveSurfaces( INTVECTOR& vSurfId) const ;
bool GetActiveSurfaces( INTVECTOR& vSurfId, INTVECTOR& vSurfSuppId) const ;
int ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQpt1, double dQpt2, double dQpt3,
int& nI1s, int& nI1e, int& nI2s, int& nI2e) const ;
Point3d CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& myInfoEnd, bool bSpiral, const Vector3d& vtAxL,