EgtMachKernel :

- in PocketingNT aggiunto parametro da note utente "LimitPlaneId".
This commit is contained in:
Riccardo Elitropi
2026-07-23 14:42:33 +02:00
parent 043a81366f
commit f746731ea3
3 changed files with 193 additions and 19 deletions
+1
View File
@@ -55,6 +55,7 @@ static const std::string UN_ADJUSTFEED = "AdjustFeed" ;
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" ;
// Solo per Sawing
static const std::string UN_DOWNSE = "DownSE" ;
+187 -16
View File
@@ -107,6 +107,7 @@ static double FEED_MAX_COEFF = 1000. ;
// 2443 = "Error in PocketingNT : Calc Limit Region failed"
// 2444 = "Error in PocketingNT : Slicing Raw failed"
// 2445 = "Error in PocketingNT : Error in Connecting Start Point"
// 2446 = "Error in PocketingNT : Limit Plane cut failed"
// 2451 = "Warning in PocketingNT : Skipped entity (xx)"
// 2452 = "Warning in PocketingNT : No pocket"
// 2453 = "Warning in PocketingNT : Tool name changed (xx)"
@@ -117,13 +118,14 @@ static double FEED_MAX_COEFF = 1000. ;
// 2458 = "Warning in PocketingNT : machining depth (xxx) bigger than MaxMaterial (yyy)"
// 2459 = "Warning in PocketingNT : No compensation in tool, so no compensation in machine"
// 2460 = "Warning in PocketingNT : Machining toolpath empty"
// 2461 = "Warning in PocketingNT : Limit Plane ignored"
//----------------------------------------------------------------------------
// Debug
#define DEBUG_STM_TOPOLOGY 0 // Debug per topologia faccia selezionata per pStm
#define DEBUG_OPEN_EDGE_EXTENSION 0 // Debug estensione dei lati aperti
#define DEBUG_OPEN_EDGE_IN_RAW 0 // Debug gestione lati aperti interni al grezzo
#define DEBUG_SFR_STEPS 0 // Debug Sfr ( Pock e Limit) nei vari step ( risultato finale per CalcPocketing)
#define DEBUG_SFR_STEPS 0 // Debug Sfr (Pock e Limit) nei vari step (risultato finale per CalcPocketing)
#define DEBUG_SFR_RAW 0 // Debug intersezioni tra SurfFlatRegion e SurfTriMesh
#define DEBUG_STM_EXTRUSION 0 // Debug superficie TriMesh di estrusione dei lati chiusi
#define DEBUG_SFR_GEO_EXT 0 // Debug FlatRegion per geometrie dei lati chiusi (in Processpath)
@@ -138,6 +140,7 @@ static double FEED_MAX_COEFF = 1000. ;
#define DEBUG_TOOL_COMPENSATION 0 // Debug per Tool Compensation
#define DEBUG_SILHOUETTE 0 // Debug Silhouette
#define DEBUG_USER_PTSTART 0 // Debug punto iniziale stabilito dall'utente
#define DEBUG_LIMIT_PLANE 0 // Debug per piano limite
#define DEBUG 0 // Debug
#if DEBUG_STM_TOPOLOGY || DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_SFR_STEPS || DEBUG_SFR_RAW || DEBUG_SFR_GEO_EXT || \
DEBUG_GLIDE || DEBUG_SAFETY_LINK || DEBUG_FEED || DEBUG_START_POINT || DEBUG_PATH_CL || DEBUG_ZIGZAG_LEADIN || DEBUG_DOUBLE_PARALLEL || \
@@ -2339,7 +2342,7 @@ PocketingNT::GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, doubl
//----------------------------------------------------------------------------
ISurfFlatRegion*
PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr,
const Vector3d& vtTool, const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil)
const Vector3d& vtTool, const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil) const
{
// controllo dei parametri
if ( pStmRaw == nullptr || ! pStmRaw->IsValid() || pSfr == nullptr || ! pSfr->IsValid())
@@ -2420,6 +2423,128 @@ PocketingNT::GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRe
return Release( pSfrRaw) ;
}
//----------------------------------------------------------------------------
Plane3d
PocketingNT::GetLimitPlane( const Vector3d& vtTool, const ISurfTriMesh* pStmRaw) const
{
// verifico la validità del grezzo
if ( pStmRaw == nullptr || ! pStmRaw->IsValid())
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())
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 ;
}
// piano limite valido
if ( ! PlaneLimit.IsValid())
return Plane3d() ;
// porto il piano in globale
PlaneLimit.ToGlob( frGlob) ;
// verifico la normale rispetto alla direzione utensile
double dCos = PlaneLimit.GetVersN() * vtTool ;
if ( dCos > - EPS_SMALL) {
return PlaneLimit ;
#if DEBUG_LIMIT_PLANE
PtrOwner<ICurveArc> pPlane( CreateCurveArc()) ; pPlane->Set( PlaneLimit.GetPoint(), PlaneLimit.GetVersN(), 1e5) ;
PtrOwner<ISurfFlatRegion> pSfrPlane( CreateSurfFlatRegion()) ; pSfrPlane->AddExtLoop( ::Release( pPlane)) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrPlane->Clone()) ;
#endif
}
else if ( cos( -135. * DEGTORAD) < dCos && dCos < 0.) {
// recupero il bordo che si ottiene dall'intersezione di tale piano con il grezzo
PtrOwner<ISurfTriMesh> pStmRawCut( CloneSurfTriMesh( pStmRaw)) ;
if ( IsNull( pStmRawCut) || ! pStmRawCut->IsValid() || ! pStmRawCut->Cut( PlaneLimit, false))
return Plane3d() ;
POLYLINEVECTOR vPL ;
if ( ! pStmRawCut->GetLoops( vPL) || vPL.empty()) {
m_pMchMgr->SetWarning( 2461, "Warning in PocketingNT : Limit Plane ignored") ;
return Plane3d() ;
}
// recupero la nuova normale del piano (perpendicolare a vtTool)
Vector3d vNewPlaneN = OrthoCompo( PlaneLimit.GetVersN(), vtTool) ; vNewPlaneN.Normalize() ;
// Rispetto a questa normale cerco il punto a Zlocale maggiore, questo diventerà il nuovo punto del piano
Frame3d frPlaneDir ; frPlaneDir.Set( ORIG, vNewPlaneN) ;
vPL[0].ToLoc( frPlaneDir) ;
PNTULIST& pointUList = vPL[0].GetUPointList() ;
Point3d ptZMax = P_INVALID ;
double dMaxZ = - INFINITO ;
for ( PNTULIST::iterator Iter = pointUList.begin() ; Iter != pointUList.end() ; ++ Iter) {
if ( Iter->first.z > dMaxZ) {
dMaxZ = Iter->first.z ;
ptZMax = Iter->first ;
}
}
if ( ! ptZMax.IsValid()) {
m_pMchMgr->SetWarning( 2461, "Warning in PocketingNT : Limit Plane ignored") ;
return Plane3d() ;
}
// definisco il nuovo piano limite
PlaneLimit.Set( GetToGlob( ptZMax, frPlaneDir), vNewPlaneN) ;
#if DEBUG_LIMIT_PLANE
PtrOwner<ICurveArc> pPlane( CreateCurveArc()) ; pPlane->Set( PlaneLimit.GetPoint(), PlaneLimit.GetVersN(), 1e5) ;
PtrOwner<ISurfFlatRegion> pSfrPlane( CreateSurfFlatRegion()) ; pSfrPlane->AddExtLoop( ::Release( pPlane)) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrPlane->Clone()) ;
#endif
return PlaneLimit ;
}
else {
m_pMchMgr->SetWarning( 2461, "Warning in PocketingNT : Limit Plane ignored") ;
return Plane3d() ;
}
return Plane3d() ;
}
//----------------------------------------------------------------------------
Point3d
PocketingNT::GetStartPointByUser( const ISurfFlatRegion* pSfr) const
@@ -3003,14 +3128,14 @@ PocketingNT::ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm)
//----------------------------------------------------------------------------
bool
PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) const
PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion, const Plane3d& PlaneLimit) const
{
// controllo parametri :
if ( pSfr == nullptr || ! pSfr->IsValid() || pStmExtrusion == nullptr)
return false ;
// se non ho una superificie di estrusione, allora è tutto aperto
if ( ! pStmExtrusion->IsValid() || pStmExtrusion->GetTriangleCount() == 0) {
// se non ho una superificie di estrusione e piani limite, allora è tutto aperto
if ( ( ! pStmExtrusion->IsValid() || pStmExtrusion->GetTriangleCount() == 0) && ! PlaneLimit.IsValid()) {
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) {
for ( int nU = 0 ; nU < pSfr->GetLoopCurveCount( nC, nL) ; ++ nU)
@@ -3047,10 +3172,17 @@ PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* p
if ( ! pCrv->GetPointD1D2( dPar, ICurve::FROM_PLUS, ptPar))
return false ;
// scorro il vettore relativo alla regione di riferimento
DistPointSurfTm distCalculator( ptPar, *pStmExtrusion) ;
double dDist = 0. ;
distCalculator.GetDist( dDist) ;
bIsOnStm = ( dDist < DIST_TOL) ;
if ( pStmExtrusion->IsValid() && pStmExtrusion->GetTriangleCount() > 0) {
DistPointSurfTm distCalculator( ptPar, *pStmExtrusion) ;
double dDist = 0. ;
distCalculator.GetDist( dDist) ;
bIsOnStm = ( dDist < DIST_TOL) ;
}
// se esiste un piano di taglio, verifico la distanza da esso
if ( ! bIsOnStm && PlaneLimit.IsValid()) {
double dDist = abs( DistPointPlane( ptPar, PlaneLimit)) ;
bIsOnStm = ( dDist < DIST_TOL) ;
}
}
if ( bIsOnStm)
pSfr->SetCurveTempProp( nC, nL, nU, TEMP_PROP_CLOSE_EDGE, 0) ;
@@ -3058,22 +3190,24 @@ PocketingNT::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* p
}
}
return true ;
return true ;
}
//----------------------------------------------------------------------------
bool
PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit)
PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, const Plane3d& PlaneLimit,
const Vector3d& vtTool, ISurfFlatRegion* pSfrLimit) const
{
// controllo dei parametri
if ( pSfrPock == nullptr || ! pSfrPock->IsValid() ||
pSfrRaw == nullptr || ! pSfrRaw->IsValid())
pSfrRaw == nullptr || ! pSfrRaw->IsValid() ||
pSfrLimit == nullptr)
return false ;
pSfrLimit->Clear() ;
// la superficie limite è data dalla sottrazione tra il grezzo e la superficie da svuotare
pSfrLimit->CopyFrom( pSfrRaw) ;
if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid())
if ( ! pSfrLimit->IsValid())
return false ;
// piccolo Offset di correzione
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfrPock->CreateOffsetSurf( 10. * EPS_SMALL, ICurve::OFF_FILLET)) ;
@@ -3122,6 +3256,27 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe
}
}
// se presente un piano limite
if ( PlaneLimit.IsValid()) {
// recupero la regione corrente
PtrOwner<ISurfFlatRegion> pSfrLimitPlane( CloneSurfFlatRegion( pSfrPock)) ;
if ( IsNull( pSfrLimitPlane) || ! pSfrLimitPlane->IsValid())
return false ;
// effettuo un Offset di sicurezza per aggiungere eventuali regioni Limite al di sotto del Piano Limite
if ( ! pSfrLimitPlane->Offset( 4. * m_TParams.m_dDiam, ICurve::OFF_EXTEND))
return false ;
// taglio la regione con il piano invertito
Plane3d PlaneLimitInv = PlaneLimit ; PlaneLimitInv.Invert() ;
if ( ! pSfrLimitPlane->Cut( PlaneLimitInv))
return false ;
if ( ! IsNull( pSfrLimitPlane) && pSfrLimitPlane->IsValid()) {
if ( pSfrLimit->IsValid())
pSfrLimit->Add( *pSfrLimitPlane) ;
else
pSfrLimit->CopyFrom( pSfrLimitPlane) ;
}
}
// se richiesto non controllo dei lati aperti
if ( m_bOpenOutRaw && pSfrLimit->IsValid()) {
double dExtension = 4. * m_TParams.m_dDiam + max( 0., m_dOpenMinSafe) + EPS_SMALL ;
@@ -3704,7 +3859,8 @@ PocketingNT::CheckMaxDepth( const ISurfFlatRegion* pSfr, double dDepth, const Ve
return true ; // ??? ( non deve capitare)
// determino i lati aperti della regione ricavata
if ( ! ChooseCloseOrOpenEdge( pSfrAdj, pStmExtrusion)) {
Plane3d PlaneDummy ; PlaneDummy.Set( P_INVALID, V_NULL) ;
if ( ! ChooseCloseOrOpenEdge( pSfrAdj, pStmExtrusion, PlaneDummy)) {
m_pMchMgr->SetLastError( 2441, "Error in PocketingNT : Detecting open edges failed") ;
return false ;
}
@@ -4305,6 +4461,11 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
ISURFFRPOVECTOR vSfrGeoExt ;
CalcGeoExtSurfFr( pSfr, vtTool, dDepth - dElev + vdSteps.back(), ( pStmTrim == nullptr ? pStmRaw : pStmTrim), vGeoSel, vSfrGeoExt) ;
// recupero, se presente il piano limite
Plane3d PlaneLimit = GetLimitPlane( vtTool, pStmRaw) ;
if ( PlaneLimit.IsValid())
PlaneLimit.Invert() ; // user friendly
for ( int j = 0 ; j < ssize( vdSteps) ; ++ j) {
// per i contatori non controllo se effettivamente svuoto una superficie o meno
++ nProgressBarStep ; // aggiorno step per progressBar
@@ -4350,6 +4511,16 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
// se regione risultante non vuota
if ( pSfrPock->IsValid() && pSfrPock->GetChunkCount() > 0) {
// se presente un piano limite devo tagliare tale regione
if ( PlaneLimit.IsValid()) {
if ( ! pSfrPock->Cut( PlaneLimit)) {
m_pMchMgr->SetLastError( 2446, "Error in PocketingNT : Limit Plane cut failed") ;
return false ;
}
// se la regione risultante non è valida, mi fermo
if ( ! pSfrPock->IsValid() || pSfrPock->GetChunkCount() == 0)
continue ;
}
// Verifico se bloccare gli step in base all'elevazione o meno
if ( bBlockStepByElev) {
@@ -4363,7 +4534,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
}
// determino i lati aperti
if ( ! ChooseCloseOrOpenEdge( pSfrPock, pStmExtrusion)) {
if ( ! ChooseCloseOrOpenEdge( pSfrPock, pStmExtrusion, PlaneLimit)) {
m_pMchMgr->SetLastError( 2441, "Error in PocketingNT : Detecting open edges failed") ;
return false ;
}
@@ -4376,7 +4547,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
// determino la regione limite
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrLimit) ||
! CalcLimitRegion( pSfrPock, pSfrTrim, pSfrLimit)) {
! CalcLimitRegion( pSfrPock, pSfrTrim, PlaneLimit, vtTool, pSfrLimit)) {
m_pMchMgr->SetLastError( 2443, "Error in PocketingNT : Calc Limit Region failed") ;
return false ;
}
+5 -3
View File
@@ -118,7 +118,8 @@ class PocketingNT : public Machining
ISurfTriMesh* GetStmRawSliced( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr, const Vector3d& vtTool) const ;
ISurfFlatRegion* GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, double dDist, double dSmallOffs = 0) const ;
ISurfFlatRegion* GetSfrRawProjection( const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSfr,
const Vector3d& vtTool, const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil = nullptr) ;
const Vector3d& vtTool, const Frame3d& frAtTop, ICAvParSilhouettesSurfTm** ppCavParSil = nullptr) const ;
Plane3d GetLimitPlane( const Vector3d& vtTool, const ISurfTriMesh* pStmRaw) const ;
Point3d GetStartPointByUser( const ISurfFlatRegion* pSfr) const ;
Point3d GetStartPointsByHead( const STEPINFOPOVECTOR& vStepInfo) const ;
Point3d GetStartPointsBySteps( const STEPINFOPOVECTOR& vStepInfo, int nCrvType) const ;
@@ -127,7 +128,7 @@ class PocketingNT : public Machining
bool ManageOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmPart) ;
bool GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) const ;
bool ExtendOpenEdges( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm) ;
bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion) const ;
bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmExtrusion, const Plane3d& PlaneLimit) const ;
bool CheckMaxDepth( const ISurfFlatRegion* pSfr, double dDepth, const Vector3d& vtTool, const ISurfTriMesh* pStmRaw,
const ISurfTriMesh* pStmExtrusion, const IntersParPlanesSurfTm& IPPStm, bool& bSkipMaxDepth) const ;
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
@@ -139,7 +140,8 @@ class PocketingNT : public Machining
bool GeneratePocketingPv( int nPathId, const ICurveComposite* pCompo) ;
bool CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, const ISurfTriMesh* pStmRaw,
const SELVECTOR& vGeoSel, ISURFFRPOVECTOR& vSfrGeoExt) ;
bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ;
bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, const Plane3d& PlaneLimit,
const Vector3d& vtTool, ISurfFlatRegion* pSfrLimit) const ;
bool CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty) ;
bool CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath,
const Vector3d& vtTool, bool bHolePocketing, const Point3d& ptHoleDest, bool bToolComp, bool bInVsOut, ICurveComposite* pCrvGlide) ;