EgtMachKernel :

- in Pocketing NT aggiunto parametro "LimitTab"
- In Pocketing NT aggiunto parametro "Closed".
This commit is contained in:
Riccardo Elitropi
2026-08-18 10:30:10 +02:00
parent 947164bfcc
commit ff126a8877
3 changed files with 267 additions and 113 deletions
+2
View File
@@ -56,6 +56,8 @@ static const std::string UN_MINFEED = "MinFeed" ;
static const std::string UN_TOOL_COMPENSATION = "ToolCompensation" ;
static const std::string UN_START_PNT = "StartPoint" ;
static const std::string UN_LIMIT_PLANE_ID = "LimitPlaneId" ;
static const std::string UN_LIMIT_TAB_DIST = "LimitTab" ;
static const std::string UN_CLOSED_EDGES = "Closed" ;
// Solo per Sawing
static const std::string UN_DOWNSE = "DownSE" ;
+261 -110
View File
@@ -151,6 +151,9 @@ static double FEED_MAX_COEFF = 1000. ;
int nGrpDebugFeed = GDB_ID_NULL, nLayDebugFeed = GDB_ID_NULL ;
#endif
// Utility
#define USE_PROGRESS_BAR 0
//----------------------------------------------------------------------------
// USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), PocketingNT) ;
@@ -1244,8 +1247,8 @@ PocketingNT::VerifyGeometry( SelData Id, int& nSubs, int& nType)
//----------------------------------------------------------------------------
bool
PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d& frGlob, const ISurfTriMesh* pStmTrim,
ICURVEPLIST& lstPC)
PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, int nFacet, const Frame3d& frGlob, const ISurfTriMesh* pStmTrim,
const INTVECTOR& vIndCloseEdgesByUS, ICURVEPLIST& lstPC) const
{
// controllo dei parametri
if ( pSurf == nullptr || ! pSurf->IsValid())
@@ -1253,23 +1256,22 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
if ( lstPC.empty())
return true ;
// le curve devono essere tutte valide
for ( auto& pCrv : lstPC) {
for ( ICurve*& pCrv : lstPC) {
if ( pCrv == nullptr || ! pCrv->IsValid())
return false ;
}
// trasformo la lista di curve in curve composite
ICRVCOMPOPOVECTOR vCrvCompo ; vCrvCompo.reserve( lstPC.size()) ;
for ( auto& pCrv : lstPC) {
for ( ICurve*& pCrv : lstPC) {
PtrOwner<ICurveComposite> pCrvCompo( ConvertCurveToComposite( pCrv->Clone())) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid() ||
! vCrvCompo.emplace_back( Release( pCrvCompo)))
return false ;
}
// se non ho isole e non esistono lati aperti, non faccio nulla
// Le isole chiuse necessitano di essere estruse
if ( int( vCrvCompo.size()) == 1) {
// se non ho isole e non esistono lati aperti, non faccio nulla, le isole chiuse necessitano di essere estruse
if ( ssize( vCrvCompo) == 1) {
bool bSomeOpen = false ;
for ( int i = 0 ; i < vCrvCompo.back()->GetCurveCount() && ! bSomeOpen ; ++ i) {
bSomeOpen = ( vCrvCompo.back()->GetCurve( i)->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) ;
@@ -1282,17 +1284,16 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
// controllo se esistono lati aperti interni alla superficie di Trim, in caso positivo, non faccio nulla
const double TOL_PT_INSIDE_STM = 3. ;
for ( auto& pCrvCompo : vCrvCompo) {
for ( PtrOwner<ICurveComposite>& pCrvCompo : vCrvCompo) {
// recupero i tratti omogenei
ICRVCOMPOPOVECTOR vpCrvs ;
GetHomogeneousParts( pCrvCompo, vpCrvs) ;
// scorro i tratti alla ricerca di lati aperti
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) {
if ( vpCrvs[i]->GetTempProp( 0) == TEMP_PROP_OPEN_EDGE) {
// analizzo le sottocurve del tratto
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j) {
// per ogni sottocurva considero punto iniziale, finale e medio per campionarla
// ( si potrebbe in futuro campionare in maniera più fitta )
// per ogni sottocurva considero punto iniziale, finale e medio per campionarla (si potrebbe campionare in maniera più fitta)
PNTVECTOR vPt( 3, P_INVALID) ;
vpCrvs[i]->GetCurve( j)->GetStartPoint( vPt[0]) ;
vpCrvs[i]->GetCurve( j)->GetMidPoint( vPt[1]) ;
@@ -1300,29 +1301,78 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
// classifico tali punti rispetto alla superficie
bool bOpenEdgeInStm = false ;
double dDist = 0. ;
for ( int nPt = 0 ; nPt < int( vPt.size()) && ! bOpenEdgeInStm ; ++ nPt) {
for ( int nPt = 0 ; nPt < ssize( vPt) && ! bOpenEdgeInStm ; ++ nPt) {
DistPointSurfTm DistPtStm( vPt[nPt], *pStmTrim) ;
bOpenEdgeInStm = ( DistPtStm.IsPointInside() &&
DistPtStm.GetDist( dDist) &&
dDist > TOL_PT_INSIDE_STM) ;
}
if ( bOpenEdgeInStm)
return true ; // !!! molto restrittivo, bisogna capire cosa fare...
return true ; // (molto restrittivo)
}
}
}
}
// recupero il volume di svuotatura
PtrOwner<ISurfTriMesh> pStmRawCl( CloneSurfTriMesh( pStmTrim)) ;
PtrOwner<ISurfTriMesh> pStmVol( CloneSurfTriMesh( pStmTrim)) ;
PtrOwner<ISurfTriMesh> pSurfGlob( CloneSurfTriMesh( pSurf)) ;
PtrOwner<ISurfTriMesh> pStmRawCl( CloneSurfTriMesh( pStmTrim)),
pStmVol( CloneSurfTriMesh( pStmTrim)),
pSurfGlob( CloneSurfTriMesh( pSurf)) ;
if ( IsNull( pStmRawCl) || ! pStmRawCl->IsValid() ||
IsNull( pStmVol) || ! pStmVol->IsValid() ||
IsNull( pSurfGlob) || ! pSurfGlob->IsValid() || ! pSurfGlob->ToGlob( frGlob) ||
! pStmVol->Subtract( *pSurfGlob))
return false ;
// modifico il volume se la geometria presenta dei lati chiusi forzati
ISURFFRPOVECTOR vSfrForcedClosedEdges ;
if ( ! vIndCloseEdgesByUS.empty() && lstPC.front() != nullptr && lstPC.front()->IsValid()) {
// converto la curva singola (assunzione) in composita
PtrOwner<ICurveComposite> pCompo( ConvertCurveToComposite( lstPC.front()->Clone())) ;
if ( ! IsNull( pCompo)) {
// recupero la normale della faccia (serve per estrusione della curva)
Vector3d vtFaceN ;
if ( ! pSurf->GetFacetNormal( nFacet, vtFaceN))
return false ;
vtFaceN.ToGlob( frGlob) ;
const double MAX_EXTRUSION = 1e4 ;
// recupero i lati forzati chiusi
for ( int nInd : vIndCloseEdgesByUS) {
const ICurve* pCrvForcedClose = pCompo->GetCurve( nInd) ; // tratto lineare (deriva da trimesh)
if ( pCrvForcedClose != nullptr && pCrvForcedClose->IsValid()) {
PtrOwner<ICurve> pMyCrvForcedClose( pCrvForcedClose->Clone()) ; // tratto lineare (deriva da trimesh)
if ( IsNull( pMyCrvForcedClose))
return false ;
pMyCrvForcedClose->SetExtrusion( vtFaceN) ;
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pMyCrvForcedClose, MAX_EXTRUSION / 2., ICurve::OFF_EXTEND))
return false ;
PtrOwner<ICurve> pCrvOff( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCrvOff))
return false ;
// composizione del perimetro (4 lati)
pCrvOff->Invert() ;
Point3d ptLink ; pCrvOff->GetStartPoint( ptLink) ;
PtrOwner<ICurveComposite> pCompoPerimeter( CreateCurveComposite()) ;
if ( IsNull( pCompoPerimeter))
return false ;
pCompoPerimeter->AddCurve( Release( pMyCrvForcedClose)) ;
pCompoPerimeter->AddLine( ptLink) ;
pCompoPerimeter->AddCurve( Release( pCrvOff)) ;
pCompoPerimeter->Close() ;
// aggiornamento regione limite dei lati aperti orzati come chiusi
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
if ( pSfr->AddExtLoop( Release( pCompoPerimeter)) && pSfr->IsValid()) {
if ( AreOppositeVectorApprox( vtFaceN, pSfr->GetNormVersor()))
pSfr->Invert() ;
vSfrForcedClosedEdges.emplace_back( Release( pSfr)) ;
}
}
}
}
}
#if DEBUG_STM_TOPOLOGY
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "StmFaceTopology") ;
@@ -1331,6 +1381,9 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
m_pGeomDB->SetName( nStmLay, "Stm") ;
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nStmLay, pSurfGlob->Clone()) ;
m_pGeomDB->SetMaterial( nId, TEAL) ;
int nCLForcedCloseEdgesLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetMaterial( nCLForcedCloseEdgesLay, RED) ;
m_pGeomDB->SetName( nCLForcedCloseEdgesLay, "Forced US Closes") ;
int nClISlLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nClISlLay, "Closed_Isl") ;
int nRawLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
@@ -1343,12 +1396,12 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
m_pGeomDB->SetName( nCrvLay, "Result") ;
#endif
// le isole sono considerate estese fino al grezzo; creo dei solidi di estrusione per le isole chiuse
// le isole sono considerate esruse fino al grezzo; creo dei solidi di estrusione per le isole chiuse
if ( ssize( vCrvCompo) > 1) {
Vector3d vtN ; lstPC.back()->GetExtrusion( vtN) ;
Vector3d vtN ; vCrvCompo.front()->GetExtrusion( vtN) ;
const double EXTR_LEN = 1000. ;
SurfFlatRegionByContours SfrByC ;
for ( auto& pCrvCompo : vCrvCompo) {
for ( PtrOwner<ICurveComposite>& pCrvCompo : vCrvCompo) {
if ( ! SfrByC.AddCurve( CloneCurveComposite( pCrvCompo)))
return false ;
}
@@ -1367,7 +1420,7 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
pCrvLoop->Translate( - EXTR_LEN / 2. * vtN) ;
pCrvLoop->SetExtrusion( vtN) ;
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvLoop, 10 * EPS_SMALL, ICurve::OFF_FILLET) ||
if ( ! OffsCrv.Make( pCrvLoop, 10. * EPS_SMALL, ICurve::OFF_FILLET) ||
! pCrvLoop.Set( OffsCrv.GetLongerCurve()))
return false ;
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByExtrusion( pCrvLoop, EXTR_LEN * vtN, true)) ;
@@ -1379,8 +1432,6 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
int nIslId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nClISlLay, CloneSurfTriMesh( pStmExtr)) ;
m_pGeomDB->SetMaterial( nIslId, BLACK) ;
#endif
if ( ! pStmVol->Subtract( *pStmExtr))
return false ;
}
}
}
@@ -1391,6 +1442,10 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
#if DEBUG_STM_TOPOLOGY
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nVolLay, pStmVol->Clone()) ;
m_pGeomDB->SetMaterial( nId, GREEN) ;
if ( ! vSfrForcedClosedEdges.empty()) {
for ( const ISurfFlatRegion* pSfrForcedClosedEdges : vSfrForcedClosedEdges)
m_pGeomDB->AddGeoObj( GDB_ID_NULL, nCLForcedCloseEdgesLay, pSfrForcedClosedEdges->Clone()) ;
}
#endif
// se volume non chiuso, errore
@@ -1420,10 +1475,10 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
Plane3d plProj ;
if ( ! plProj.Set( ptC, vtN))
return false ;
POLYLINEVECTOR vPLVol, vPLRaw ;
if ( ! pStmVol->GetSilhouette( plProj, 20 * EPS_SMALL, vPLVol, false, EPS_SMALL))
POLYLINEVECTOR vPLVol, vPLRaw, vPLForcedClosedEdges ;
if ( ! pStmVol->GetSilhouette( plProj, 20. * EPS_SMALL, vPLVol, false, EPS_SMALL))
return false ;
if ( ! pStmRawCl->GetSilhouette( plProj, 20 * EPS_SMALL, vPLRaw, false, EPS_SMALL))
if ( ! pStmRawCl->GetSilhouette( plProj, 20. * EPS_SMALL, vPLRaw, false, EPS_SMALL))
return false ;
#if DEBUG_STM_TOPOLOGY
@@ -1433,28 +1488,35 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
m_pGeomDB->SetMaterial( nId, LIME) ;
#endif
// recupero le due superfici piane
// recupero le superfici piane
SurfFlatRegionByContours SfrBCVol, SfrBCRaw ;
for ( PolyLine& PL : vPLVol) {
for ( const PolyLine& PL : vPLVol) {
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( ! IsNull( pCompo) && pCompo->FromPolyLine( PL))
SfrBCVol.AddCurve( Release( pCompo)) ;
}
for ( PolyLine& PL : vPLRaw) {
for ( const PolyLine& PL : vPLRaw) {
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( ! IsNull( pCompo) && pCompo->FromPolyLine( PL))
SfrBCRaw.AddCurve( Release( pCompo)) ;
}
PtrOwner<ISurfFlatRegion> pSfrVol( SfrBCVol.GetSurf()) ;
PtrOwner<ISurfFlatRegion> pSfrRaw( SfrBCRaw.GetSurf()) ;
if ( IsNull( pSfrVol) || IsNull( pSfrRaw) ||
! pSfrVol->IsValid() || ! pSfrRaw->IsValid())
PtrOwner<ISurfFlatRegion> pSfrVol( SfrBCVol.GetSurf()),
pSfrRaw( SfrBCRaw.GetSurf()) ;
if ( IsNull( pSfrVol) || IsNull( pSfrRaw) || ! pSfrVol->IsValid() || ! pSfrRaw->IsValid())
return false ;
if ( AreOppositeVectorApprox( vtN, pSfrVol->GetNormVersor()))
pSfrVol->Invert() ;
if ( AreOppositeVectorApprox( vtN, pSfrRaw->GetNormVersor()))
pSfrRaw->Invert() ;
// --- se presenza di lati chiusi forzati, allora sottraggo la rispettiva regione limite
for ( const ISurfFlatRegion* pSfrForcedClosedEdges : vSfrForcedClosedEdges) {
if ( AreOppositeVectorApprox( vtN, pSfrForcedClosedEdges->GetNormVersor()))
pSfrRaw->Invert() ;
pSfrVol->Subtract( *pSfrForcedClosedEdges) ;
pSfrRaw->Subtract( *pSfrForcedClosedEdges) ;
}
#if DEBUG_STM_TOPOLOGY
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawLay, pSfrRaw->Clone()) ;
m_pGeomDB->SetMaterial( nId, BLUE) ;
@@ -1463,23 +1525,21 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
#endif
// se la nuova superficie ricavata contiene un tratto chiuso, allora non faccio nulla
// ( Esempio di una tasca inclinata con gradini )
// (Esempio di una tasca inclinata con gradini)
const double OFFSET_FOR_CLOSE = 1. ; // euristico
PtrOwner<ISurfFlatRegion> pSfrVol_Clone( pSfrVol->CreateOffsetSurf( - OFFSET_FOR_CLOSE, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrVol_Clone))
PtrOwner<ISurfFlatRegion> pSfrVolCL( pSfrVol->CreateOffsetSurf( - OFFSET_FOR_CLOSE, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrVolCL))
return false ;
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
ICRVCOMPOPOVECTOR vpCrvs ;
GetHomogeneousParts( vCrvCompo[i], vpCrvs) ;
for ( int j = 0 ; j < int( vpCrvs.size()) ; ++ j) {
for ( int j = 0 ; j < ssize( vpCrvs) ; ++ j) {
if ( vpCrvs[j]->GetTempProp( 0) == TEMP_PROP_CLOSE_EDGE) {
CRVCVECTOR ccClass ;
if ( pSfrVol_Clone->GetCurveClassification( *vpCrvs[j], EPS_SMALL, ccClass)) {
for ( int k = 0 ; k < int( ccClass.size()) ; ++ k) {
if ( ccClass[k].nClass != CRVC_OUT) {
// non estendo la superficie in quanto rovina il grezzo adiacente ad un chiuso
return true ;
}
if ( pSfrVolCL->GetCurveClassification( *vpCrvs[j], EPS_SMALL, ccClass)) {
for ( int k = 0 ; k < ssize( ccClass) ; ++ k) {
if ( ccClass[k].nClass != CRVC_OUT)
return true ; // non estendo la superficie in quanto rovina il grezzo adiacente ad un chiuso
}
}
else
@@ -1488,12 +1548,39 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
}
}
// definisco i lati aperti della nuova regione da svuotare
// --- i lati aperti sono quelli in comune con la proiezione del grezzo
for ( auto& pCrv : lstPC)
// definisco i lati aperti della nuova regione da svuotare (i lati aperti sono quelli in comune con la proiezione del grezzo)
for ( ICurve*& pCrv : lstPC)
delete( pCrv) ;
lstPC.clear() ;
pSfrRaw->Offset( - 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
pSfrRaw->Offset( - 50. * EPS_SMALL, ICurve::OFF_FILLET) ; // per tolleranza
PNTMATRIX matPtForcedClosed ; // punti di campionamento per le curve di lato chiuso forzato
for ( const ISurfFlatRegion* pSfrForcedClosedEdges : vSfrForcedClosedEdges) {
PtrOwner<ICurveComposite> pCompoForcedClosedEdges( ConvertCurveToComposite( pSfrForcedClosedEdges->GetLoop( 0, 0))) ;
if ( IsNull( pCompoForcedClosedEdges))
return false ;
matPtForcedClosed.emplace_back( PNTVECTOR{}) ;
for ( int i = 0 ; i < pCompoForcedClosedEdges->GetCurveCount() ; ++ i) {
const ICurve* pCrv = pCompoForcedClosedEdges->GetCurve( i) ;
if ( pCrv != nullptr && pCrv->IsValid()) {
Point3d ptStart ; pCrv->GetStartPoint( ptStart) ;
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
#if DEBUG_STM_TOPOLOGY
PtrOwner<IGeoPoint3d> ptGeo( CreateGeoPoint3d()) ; ptGeo->Set( ptStart) ;
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nCLForcedCloseEdgesLay, ptGeo->Clone()) ;
m_pGeomDB->SetMaterial( nId, ORANGE) ;
ptGeo->Set( ptMid) ;
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nCLForcedCloseEdgesLay, ptGeo->Clone()) ;
m_pGeomDB->SetMaterial( nId, ORANGE) ;
#endif
matPtForcedClosed.back().push_back( ptStart) ; matPtForcedClosed.back().push_back( ptMid) ;
if ( i == pCompoForcedClosedEdges->GetCurveCount() - 1)
matPtForcedClosed.back().push_back( matPtForcedClosed.back().front()) ;
}
}
}
for ( int nC = 0 ; nC < pSfrVol->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrVol->GetLoopCount( nC) ; ++ nL) {
// recupero il Loop
@@ -1505,15 +1592,36 @@ PocketingNT::AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d
pCompoLoop->GetCurve( nU)->GetStartPoint( vPt[0]) ;
pCompoLoop->GetCurve( nU)->GetMidPoint( vPt[1]) ;
pCompoLoop->GetCurve( nU)->GetEndPoint( vPt[2]) ;
bool bIsClosed = false ;
pCompoLoop->SetCurveTempProp( nU, TEMP_PROP_OPEN_EDGE, 0) ;
for ( int nPt = 0 ; nPt < int( vPt.size()) ; ++ nPt) {
for ( int nPt = 0 ; nPt < ssize( vPt) ; ++ nPt) {
bool bIsInside = true ;
IsPointInsideSurfFr( vPt[nPt], pSfrRaw, EPS_SMALL, bIsInside) ;
if ( bIsInside) {
bIsClosed = true ;
pCompoLoop->SetCurveTempProp( nU, TEMP_PROP_CLOSE_EDGE, 0) ;
break ;
}
}
// se il tratto è aperto, controllo anche le regioni di forzatura dei chiusi mediante user notes
if ( ! matPtForcedClosed.empty() && ! bIsClosed) {
const ICurve* pCrv = pCompoLoop->GetCurve( nU) ;
if ( pCrv == nullptr || ! pCrv->IsValid())
return false ;
for ( int i = 0 ; i < ssize( matPtForcedClosed) ; ++ i) {
for ( int nPt = 0 ; nPt < ssize( matPtForcedClosed[i]) - 2 ; nPt += 2) {
const Point3d& ptStart = matPtForcedClosed[i][nPt] ;
const Point3d& ptMid = matPtForcedClosed[i][nPt + 1] ;
const Point3d& ptEnd = matPtForcedClosed[i][nPt + 2] ;
if ( pCrv->IsPointOn( ptStart, 40. * EPS_SMALL) &&
pCrv->IsPointOn( ptMid, 40. * EPS_SMALL) &&
pCrv->IsPointOn( ptEnd, 40. * EPS_SMALL)) {
pCompoLoop->SetCurveTempProp( nU, TEMP_PROP_CLOSE_EDGE, 0) ;
break ;
}
}
}
}
}
#if DEBUG_STM_TOPOLOGY
@@ -1637,6 +1745,7 @@ PocketingNT::GetCurves( const SelData& Id, const ISurfTriMesh* pStmRaw, const IS
return false ;
// per ogni loop recupero le curve composite
ICURVEPLIST lstCrvLoops ;
INTVECTOR vIndCloseEdgesByUS ; // indice lati chiusi forzati da note utente
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
pCrvCompo->FromPolyLine( vPL[i]) ;
@@ -1678,6 +1787,21 @@ PocketingNT::GetCurves( const SelData& Id, const ISurfTriMesh* pStmRaw, const IS
pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
// la porto in globale
pCrvCompo->ToGlob( frGlob) ;
// verifico se devo chiudere eventuali lati mediante note utente
if ( lstCrvLoops.empty()) {
if ( GetValInNotes( m_Params.m_sUserNotes, UN_CLOSED_EDGES, vIndCloseEdgesByUS) && ! vIndCloseEdgesByUS.empty()) {
INTVECTOR vInds ; vInds.reserve( vIndCloseEdgesByUS.size()) ;
for ( int nInd : vIndCloseEdgesByUS) {
// verifico che il lato sia effettivamente aperto
int nTmpProp = TEMP_PROP_INVALID ; pCrvCompo->GetCurveTempProp( nInd, nTmpProp, 0) ;
if ( nTmpProp == TEMP_PROP_OPEN_EDGE) {
pCrvCompo->SetCurveTempProp( nInd, TEMP_PROP_CLOSE_EDGE) ;
vInds.push_back( nInd) ;
}
}
swap( vInds, vIndCloseEdgesByUS) ;
}
}
// sistemazioni varie
AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, V_NULL, {}, 0) ;
// la restituisco
@@ -1686,8 +1810,8 @@ PocketingNT::GetCurves( const SelData& Id, const ISurfTriMesh* pStmRaw, const IS
lstCrvLoops.emplace_back( Release( pCrvCompo)) ;
}
// aggiusto la topologia della faccia
AdjustCurvesByStmTopology( pSurf, frGlob, ( pStmTrim == nullptr ? pStmRaw : pStmTrim), lstCrvLoops) ;
for ( auto& pCrv : lstCrvLoops)
AdjustCurvesByStmTopology( pSurf, nFacet, frGlob, ( pStmTrim == nullptr ? pStmRaw : pStmTrim), vIndCloseEdgesByUS, lstCrvLoops) ;
for ( ICurve*& pCrv : lstCrvLoops)
lstPC.emplace_back( pCrv) ;
return true ;
}
@@ -1870,6 +1994,7 @@ PocketingNT::Chain( int nGrpDestId)
vInds.emplace_back( Id) ;
}
}
// preparo i dati per il concatenamento
bool bFirst = true ;
Point3d ptNear = ORIG ;
@@ -2432,63 +2557,80 @@ PocketingNT::GetLimitPlane( const Vector3d& vtTool, const ISurfTriMesh* pStmRaw)
return Plane3d() ;
// recupero dalle note utenti il piano
int nGeoPlaneId = GDB_ID_NULL ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_PLANE_ID, nGeoPlaneId) || nGeoPlaneId == GDB_ID_NULL)
return Plane3d() ;
// recupero l'oggetto geometrico e il suo sistema di riferimento
const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nGeoPlaneId) ;
if ( pGeoObj == nullptr || ! pGeoObj->IsValid())
return Plane3d() ;
Frame3d frGlob ; m_pGeomDB->GetGlobFrame( nGeoPlaneId, frGlob) ;
// definisco il piano in base al tipo di oggetto
Plane3d PlaneLimit ;
switch ( pGeoObj->GetType()) {
case CRV_ARC :
case CRV_BEZIER :
case CRV_COMPO : {
// recupero la curva e verifico che sia piana e chiusa (serve per definire l'orientamento del piano)
const ICurve* pCrv = ::GetCurve( pGeoObj) ;
if ( pCrv == nullptr || ! pCrv->IsClosed())
int nGeoPlaneId = GDB_ID_NULL ;
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_PLANE_ID, nGeoPlaneId) && nGeoPlaneId != GDB_ID_NULL) {
// recupero l'oggetto geometrico e il suo sistema di riferimento
const IGeoObj* pGeoObj = m_pGeomDB->GetGeoObj( nGeoPlaneId) ;
if ( pGeoObj == nullptr || ! pGeoObj->IsValid())
return Plane3d() ;
if ( ! pCrv->IsFlat( PlaneLimit, true) || ! PlaneLimit.IsValid())
return Plane3d() ;
}
break ;
case SRF_FLATRGN : {
// recupero la regione piana
const ISurfFlatRegion* pSfr = ::GetSurfFlatRegion( pGeoObj) ;
if ( pSfr == nullptr)
return Plane3d() ;
// recupero il suo piano intrinseco
Point3d ptCentroid ; pSfr->GetCentroid( ptCentroid) ;
PlaneLimit.Set( ptCentroid, pSfr->GetNormVersor()) ;
}
break ;
case SRF_TRIMESH : {
// recupero la TriMesh
const ISurfTriMesh* pStm = ::GetSurfTriMesh( pGeoObj) ;
if ( pStm == nullptr)
return Plane3d() ;
// verifico che sia formata da una sola faccia
if ( pStm->GetFacetCount() != 1)
return Plane3d() ;
// dalla faccia recupero il piano intrinseco
Point3d ptCenter ; Vector3d vtN ; pStm->GetFacetCenter( 0, ptCenter, vtN) ;
PlaneLimit.Set( ptCenter, vtN) ;
}
break ;
default :
Frame3d frGlob ; m_pGeomDB->GetGlobFrame( nGeoPlaneId, frGlob) ;
// definisco il piano in base al tipo di oggetto
switch ( pGeoObj->GetType()) {
case CRV_ARC :
case CRV_BEZIER :
case CRV_COMPO : {
// recupero la curva e verifico che sia piana e chiusa (serve per definire l'orientamento del piano)
const ICurve* pCrv = ::GetCurve( pGeoObj) ;
if ( pCrv == nullptr || ! pCrv->IsClosed())
return Plane3d() ;
if ( ! pCrv->IsFlat( PlaneLimit, true) || ! PlaneLimit.IsValid())
return Plane3d() ;
}
break ;
case SRF_FLATRGN : {
// recupero la regione piana
const ISurfFlatRegion* pSfr = ::GetSurfFlatRegion( pGeoObj) ;
if ( pSfr == nullptr)
return Plane3d() ;
// recupero il suo piano intrinseco
Point3d ptCentroid ; pSfr->GetCentroid( ptCentroid) ;
PlaneLimit.Set( ptCentroid, pSfr->GetNormVersor()) ;
}
break ;
case SRF_TRIMESH : {
// recupero la TriMesh
const ISurfTriMesh* pStm = ::GetSurfTriMesh( pGeoObj) ;
if ( pStm == nullptr)
return Plane3d() ;
// verifico che sia formata da una sola faccia
if ( pStm->GetFacetCount() != 1)
return Plane3d() ;
// dalla faccia recupero il piano intrinseco
Point3d ptCenter ; Vector3d vtN ; pStm->GetFacetCenter( 0, ptCenter, vtN) ;
PlaneLimit.Set( ptCenter, vtN) ;
}
break ;
default :
break ;
}
// il piano limite deve essere valido
if ( ! PlaneLimit.IsValid())
return Plane3d() ;
// porto il piano in globale
PlaneLimit.ToGlob( frGlob) ;
}
double dTabDist = 0. ;
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_TAB_DIST, dTabDist)) {
PlaneLimit = Plane3d() ;
// piano limite valido
if ( ! PlaneLimit.IsValid())
return Plane3d() ;
// recupero la tavola
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return Plane3d() ;
Point3d ptRefTab1 ;
if ( ! pMch->GetCurrTableRef1( ptRefTab1))
return Plane3d() ;
PlaneLimit.Set( ptRefTab1 + Z_AX * dTabDist, Z_AX) ;
// porto il piano in globale
PlaneLimit.ToGlob( frGlob) ;
// il piano limite deve essere valido
if ( ! PlaneLimit.IsValid())
return Plane3d() ;
}
// verifico la normale rispetto alla direzione utensile
double dCos = PlaneLimit.GetVersN() * vtTool ;
@@ -4084,7 +4226,9 @@ bool
PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
{
// aggiorno la ProgressBar del 5% per simulare l'inizio della funzione
ExeProcessEvents( 5, 0) ;
#if USE_PROGRESS_BAR
ExeProcessEvents( 5, 0) ;
#endif
// recupero gruppo per geometria temporanea
const string GRP_TEMP = "Temp" ;
@@ -4250,7 +4394,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
// calcolo l'elevazione al di sopra della geometria originale
double dOrigElev = 0. ;
if ( ! CalcOrigRegionElevation( pSfr, ( pStmTrim == nullptr ? pStmRaw : pStmTrim), vtTool, dDepth, m_TParams.m_dDiam / 2., m_TParams.m_dLen, dOrigElev)) {
if ( ! CalcOrigRegionElevation( pSfr, vtTool, dDepth, m_TParams.m_dDiam / 2., m_TParams.m_dLen, ( pStmTrim == nullptr ? pStmRaw : pStmTrim), dOrigElev)) {
m_pMchMgr->SetLastError( 2433, "Error in PocketingNT : Calc Region Elevation failed") ;
return false ;
}
@@ -4565,8 +4709,9 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
vStepInfo.back().pSfrLimit.Set( pSfrLimit) ;
}
// aggiorno la progressBar
ExeProcessEvents( 5 + nProgressBarStep * 45 / nStep, 0) ;
#if USE_PROGRESS_BAR
ExeProcessEvents( 5 + nProgressBarStep * 45 / nStep, 0) ;
#endif
}
// imposto dati comuni
@@ -4727,8 +4872,8 @@ PocketingNT::CalcRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& v
//----------------------------------------------------------------------------
bool
PocketingNT::CalcOrigRegionElevation( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const Vector3d& vtTool, double dDepth,
double dRad, double dLen, double& dElev) const
PocketingNT::CalcOrigRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dDepth,
double dRad, double dLen, const ISurfTriMesh* pStmRaw, double& dElev) const
{
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid() ||
@@ -5330,7 +5475,9 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty)
}
}
// aggiorno la progressBar
ExeProcessEvents( 50 + i * 50 / ssize( vStepInfo), 0) ;
#if USE_PROGRESS_BAR
ExeProcessEvents( 50 + i * 50 / ssize( vStepInfo), 0) ;
#endif
}
// controllo se la svuotatura è riferita ad un foro chiuso
@@ -5779,7 +5926,9 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
return false ;
// se svuotatura vuota, aggiorno la ProgressBar ed esco
if ( bEmpty) {
ExeProcessEvents( 100, 0) ;
#if USE_PROGRESS_BAR
ExeProcessEvents( 100, 0) ;
#endif
return true ;
}
@@ -6121,7 +6270,9 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
}
// aggiorno per sicurezza la ProgressBar
ExeProcessEvents( 100, 0) ;
#if USE_PROGRESS_BAR
ExeProcessEvents( 100, 0) ;
#endif
return true ;
}
+4 -3
View File
@@ -106,7 +106,8 @@ class PocketingNT : public Machining
private :
bool MyApply( bool bRecalc, bool bPostApply) ;
bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ;
bool AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, const Frame3d& frGlob, const ISurfTriMesh* pStmTrim, ICURVEPLIST& lstPC) ;
bool AdjustCurvesByStmTopology( const ISurfTriMesh* pSurf, int nFacet, const Frame3d& frGlob, const ISurfTriMesh* pStmTrim, const INTVECTOR& vIndCloseEdgesByUS,
ICURVEPLIST& lstPC) const ;
bool GetCurves( const SelData& Id, const ISurfTriMesh* pStmRaw, const ISurfTriMesh* pStmTrim, ICURVEPLIST& lstPC) ;
bool SetCurveAllTempProp( int nCrvId, bool bForcedClose, ICurve* pCurve, bool* pbSomeOpen = nullptr) ;
bool SetSfrLoopsAllTempProp( int nSfrId, ISurfFlatRegion* pSfr) ;
@@ -134,8 +135,8 @@ class PocketingNT : public Machining
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
bool CalcRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dDepth,
double dRad, double dLen, const ISurfTriMesh* pStmRaw, double& dElev) const ;
bool CalcOrigRegionElevation( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const Vector3d& vtTool, double dDepth,
double dRad, double dLen, double& dElev) const ;
bool CalcOrigRegionElevation( const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dDepth,
double dRad, double dLen, const ISurfTriMesh* pStmRaw, double& dElev) const ;
bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ;
bool GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) ;
bool CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, const ISurfTriMesh* pStmRaw,