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:
+287
-191
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user