EgtMachKernel :

- Aggiunta gestione lati aperti.
This commit is contained in:
Riccardo Elitropi
2024-06-06 14:49:06 +02:00
parent 60ce762793
commit 4ac0de990e
2 changed files with 287 additions and 1 deletions
+280 -1
View File
@@ -36,6 +36,8 @@
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkCurveAux.h"
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
// per far dimenticare macro di WinUser.h
#undef GetClassName
@@ -66,6 +68,9 @@ using namespace std ;
// 3022 = "Error in SurfRoughing : aggregate from bottom not allowed"
// 3023 = "Error in SurfRoughing : missing surfaces"
// 3024 = "Error in SurfRoughing : region not computable"
// 3025 = "Error in SurfRoughing : RawPart not computable"
// 3026 = "Error in SurfRoughing : Detecting open edges failed"
// 3027 = "Error in SurfRoughing : Slicing Raw failed"
// 3051 = "Warning in SurfRoughing : Skipped entity (xx)"
// 3052 = "Warning in SurfRoughing : No machinable path"
// 3053 = "Warning in SurfRoughing : Tool name changed (xx)"
@@ -1151,6 +1156,11 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
if ( plPlane.GetVersN() * vtExtr < 0)
plPlane.Invert() ;
// creo un frame centrato sulla curva
Frame3d fr_pCompo ;
if ( ! fr_pCompo.Set( plPlane.GetPoint(), plPlane.GetVersN()))
return false ;
// unisco le parti allineate
if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true))
return false ;
@@ -1203,12 +1213,25 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
return false ;
}
// recupero il grezzo
PtrOwner<ISurfTriMesh> pStmRaw( CreateSurfTriMesh()) ;
if ( IsNull( pStmRaw) ||
! GetRaw( pStmRaw)) {
m_pMchMgr->SetLastError( 3025, "Error in SurfRoughing : RawPart not computable") ;
return false ;
}
// inizializzo la classe di intersezione tra il piano e il grezzo ( serve per limitare le
// FlatRegions per il calcolo delle svuotature )
IntersParPlanesSurfTm IPPStm( fr_pCompo, *pStmRaw) ;
// calcolo le regioni di svuotatura alle varie quote come differenza tra regioni da lavorare e regioni di silhouette
INTVECTOR vPocket ;
const double SILH_TOL = max( GetOffsR(), 1.) ;
int nStep = max( 1, static_cast<int>( ceil( dDepth / dOkStep))) ;
double dStep = dDepth / nStep ;
for ( int i = 1 ; i <= nStep ; ++ i) {
// regione di lavoro allo step corrente
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( *pCompo)) {
@@ -1216,14 +1239,28 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
return false ;
}
pSfr->Translate( -i * dStep * vtTool) ;
// piano di taglio per silhouette (compreso di offset longitudinale)
Plane3d plCut = plPlane ;
plCut.Translate( - ( i * dStep + GetOffsL()) * vtTool) ;
// questa regione bisogna ridurla basandosi sulla geometria del grezzo, in modo da non lavorare
// parti in eccesso ; taglio il grezzo sul piano corrente
PtrOwner<ISurfFlatRegion> pSfrInt( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrInt) ||
! GetSfrByRawIntersection( pSfrInt, IPPStm, -i * dStep)) {
m_pMchMgr->SetLastError( 3027, "Error in SurfRoughing : Slicing Raw failed") ;
return false ;
}
pSfr->Intersect( *pSfrInt) ;
// per ogni superficie
for ( int nSurfId : vSurfId) {
const ISurfTriMesh* pSurf = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ;
Frame3d frSurf ; m_pGeomDB->GetGlobFrame( nSurfId, frSurf) ;
Plane3d plCutL = plCut ; plCutL.ToLoc( frSurf) ;
// determino le regioni da non lavorare e le sottraggo
POLYLINEVECTOR vPL ;
if ( pSurf == nullptr || ! pSurf->GetSilhouette( plCutL, SILH_TOL, vPL)) {
@@ -1244,10 +1281,21 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
return false ;
}
pSfrSil->ToGlob( frSurf) ;
// sottraggo le parti da non lavorare
pSfr->Subtract( *pSfrSil) ;
}
// se regione risultante non vuota, la salvo nel gruppo temporaneo
// se regione risultante non vuota
if ( pSfr->IsValid()) {
// determino i lati aperti
if ( ! ChooseCloseOrOpenEdge( pSfr, pStmRaw, false)) {
m_pMchMgr->SetLastError( 3026, "Error in SurfRoughing : Detecting open edges failed") ;
return false ;
}
// la salvo nel gruppo temporaneo
int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ;
if ( nNewId == GDB_ID_NULL) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
@@ -1276,6 +1324,132 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::GetRaw( ISurfTriMesh* pStmRaw) const
{
// controllo parametri, MachManager e database geometrico
if ( pStmRaw == nullptr || m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
pStmRaw->AdjustTopology() ;
// Id prima RawPart
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 l'oggetto dal database con tale Id
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( nRawSolidId) ;
// recupero il frame in cui si trova
Frame3d frRaw ;
m_pGeomDB->GetGlobFrame( nRawSolidId, frRaw) ;
if ( pGObj == nullptr)
return false ;
// controllo che sia una Trimesh
if ( pGObj->GetType() == SRF_TRIMESH) {
// Trimesh della parte p-esima
PtrOwner<ISurfTriMesh> pStmRawPart( CloneSurfTriMesh( pGObj)) ;
if ( IsNull( pStmRawPart))
return false ;
// porto la trimesh in globale
pStmRawPart->LocToLoc( frRaw, GLOB_FRM) ;
// lo aggiungo alla Trimesh complessiva
pStmRaw->Add( *pStmRawPart) ;
}
}
// passo al grezzo successivo
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
return pStmRaw->IsValid() && pStmRaw->GetTriangleCount() > 0 ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::GetSfrByRawIntersection( ISurfFlatRegion* pSfrInt, IntersParPlanesSurfTm IPPStm, double dDist) const
{
// controllo dei parametri
if ( pSfrInt == nullptr)
return false ;
pSfrInt->Clear() ;
// interseco la superficie alla quota corrente
PNTVECTOR vPnt ;
BIPNTVECTOR vBpt ;
TRIA3DVECTOR vTria ;
if ( ! IPPStm.GetInters( dDist, vPnt, vBpt, vTria))
return false ;
// definisco la tolleranza per i concatenamenti
double dToler = EPS_SMALL ;
// costruisco la FlatRegion da ritornare
SurfFlatRegionByContours SfrByC ;
// Considero l'intersezione solo con Curve ( escludo punti e superfici)
ChainCurves chainC ;
chainC.Init( false, dToler, int( vBpt.size())) ;
for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) {
Vector3d vtDir = vBpt[i].second - vBpt[i].first ;
vtDir.Normalize() ;
if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir))
return false ;
}
// recupero i percorsi concatenati
Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ;
INTVECTOR vId ;
while ( chainC.GetChainFromNear( ptNear, false, vId)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita
bool bAdded = true ;
for ( int i = 0 ; i < int( vId.size()) ; ++ i) {
// creo un segmento di retta
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
// recupero gli estremi ( non vanno mai invertiti per opzione di concatenamento)
int nInd = abs( vId[i]) - 1 ;
Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ;
Point3d ptEnd = vBpt[nInd].second ;
// provo ad accodarlo alla composita
bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 &&
pLine->Set( ptStart, ptEnd) &&
pCrvCompo->AddCurve( Release( pLine), true, dToler)) ;
ptNear = ( bAdded ? ptEnd : ptStart) ;
}
// se lunghezza curva inferiore a 5 volte la tolleranza, la ignoro
double dCrvLen ;
if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler)
continue ;
// se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene
Point3d ptStart, ptEnd ;
if ( pCrvCompo->GetStartPoint( ptStart) &&
pCrvCompo->GetEndPoint( ptEnd) &&
AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) &&
! AreSamePointApprox( ptStart, ptEnd)) {
// porto il punto finale a coincidere esattamente con l'inizio
pCrvCompo->ModifyEnd( ptStart) ;
}
// unisco segmenti allineati
pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ;
// inserisco la curva nella FlatRegion
SfrByC.AddCurve( Release( pCrvCompo)) ;
}
// recupero la regione da restituire
PtrOwner<ISurfFlatRegion> pSfrFromCrvs( SfrByC.GetSurf()) ;
if ( IsNull( pSfrFromCrvs) || ! pSfrFromCrvs->IsValid())
return false ;
return ( pSfrInt->CopyFrom( pSfrFromCrvs)) ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::GetActiveSurfaces( INTVECTOR& vSurfId) const
@@ -1425,6 +1599,8 @@ SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const
// prendo il punto finale della prima curva, così sono interno alla regione
Point3d ptEnd ;
pCurve->GetEndPoint( ptEnd) ;
if ( bOutStart)
ptEnd.Translate( ( 0.5 * m_TParams.m_dDiam) * vtStart) ;
if ( IsPointInsidePolyLine( ptEnd, vPLExtLoops[nInd], 500 * EPS_SMALL))
break ;
}
@@ -1832,6 +2008,109 @@ SurfRoughing::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) cons
return min( GetFeed(), GetTipFeed() / abs( dCosMove)) ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::ResetCurveAllTempProp( ICurve* pCurve) const
{
// controllo validità della curva
if ( pCurve == nullptr)
return false ;
// metto a 0 le tmpProps della curva
pCurve->SetTempProp( 0, 0) ;
pCurve->SetTempProp( 0, 1) ;
// ricavo la composita associata
ICurveComposite* pCC = GetCurveComposite( pCurve) ;
if ( pCC != nullptr)
for ( int i = 0 ; i < pCC->GetCurveCount() ; ++ i) {
// per ogni sottcurva metto a 0 le temProps
pCC->SetCurveTempProp( i, 0, 0) ;
pCC->SetCurveTempProp( i, 0, 1) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm, const bool bOnIsClosed) const
{
// controllo parametri :
if ( pSfr == nullptr || ! pSfr->IsValid())
return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati
if ( pStm == nullptr || ! pStm->IsValid())
return false ;
bool bStmClosed = pStm->IsClosed() ;
// per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti.
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO DENTRO AL GREZZO " ( bOnIsClosed = T)
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO DISTANO MENO DI 50 * EPS_SMALL DALLE FACCE ( bOnIsClosed = F)
const int NUM_POINTS = 4 ;
PtrOwner<ISurfFlatRegion> pSfrWithTmpProps( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrWithTmpProps))
return false ;
// scorro tutti i loop
for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++ l) {
// recupero la curva composita del Loop
PtrOwner<ICurveComposite> pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ;
if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid())
return false ;
// miglioro
pCrvCompoLoop->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
// resetto tutte le temp Prop
ResetCurveAllTempProp( pCrvCompoLoop) ; // -> tutto chiuso ( 0)
// scorro ogni sua sottocurva
for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) {
// recupero la sottocurva
const ICurve* pCrv = pCrvCompoLoop->GetCurve( u) ;
if ( pCrv == nullptr)
return false ;
// recupero i NUM_POINTS punti
bool bIsOn = true ;
for ( int p = 0 ; p < NUM_POINTS + 1 && bIsOn ; ++ p) {
double dPar = ( 1. / ( 1. * NUM_POINTS)) * p ;
Point3d ptPar ;
if ( ! pCrv->GetPointD1D2( dPar, ICurve::FROM_PLUS, ptPar))
return false ;
// calcolo la distanza tra tale punto e la TriMesh
DistPointSurfTm distPtStm( ptPar, *pStm) ;
if ( bStmClosed)
bIsOn = ! distPtStm.IsPointInside() ;
else {
double dDist = 0. ;
bIsOn = distPtStm.GetDist( dDist) && dDist < 50 * EPS_SMALL ;
}
}
if (( bIsOn && ! bOnIsClosed) || ( ! bIsOn && bOnIsClosed))
pCrvCompoLoop->SetCurveTempProp( u, 1, 0) ;
}
// aggiungo il Loop con Flag di lato Aperto/Chiuso alla superficie
if ( l == 0) {
if ( ! pSfrWithTmpProps->AddExtLoop( *pCrvCompoLoop))
return false ;
}
else
if ( ! pSfrWithTmpProps->AddIntLoop( *pCrvCompoLoop))
return false ;
}
}
// sostituisco la superficie da restituire
if ( ! pSfrWithTmpProps->IsValid() ||
! pSfr->Clear() ||
! pSfr->CopyFrom( pSfrWithTmpProps))
return false ;
return pSfr->IsValid() && pSfr->GetChunkCount() != 0 ;
}
//----------------------------------------------------------------------------
double
SurfRoughing::GetRadiusForStartEndElevation( void) const
+7
View File
@@ -19,6 +19,9 @@
#include "MachiningConst.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
class ICAvToolSurfTm ;
@@ -86,9 +89,13 @@ class SurfRoughing : public Machining
bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN,
const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced,
Point3d& ptP1, double& dElev) ;
bool GetRaw( ISurfTriMesh* pStmRaw) const ;
bool GetSfrByRawIntersection( ISurfFlatRegion* pSfrInt, IntersParPlanesSurfTm IPPStm, double dDist) const ;
bool GetActiveSurfaces( INTVECTOR& vSurfId) const ;
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
double GetRadiusForStartEndElevation( void) const ;
bool ResetCurveAllTempProp( ICurve* pCurve) const ;
bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, bool bOnIsClosed) const ;
bool CalcRetCrv( const ICurveComposite* pCompo, const Point3d& ptRef, bool bOutStart,
ICurveComposite* pRCrv) const ;
bool VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const ;