EgtGeomKernel 3.1a8 :

- in CalcPocketing migliorati i casi a trapezio.
This commit is contained in:
Riccardo Elitropi
2026-02-12 15:46:42 +01:00
parent 2e129d7b06
commit 6faf5ccde2
2 changed files with 142 additions and 75 deletions
+142 -75
View File
@@ -3441,18 +3441,18 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
Vector3d vtX ; pCrvPocket->GetCurve( 1)->GetStartDir( vtX) ;
Frame3d frDim ; frDim.Set( ptOrig, Z_AX, vtX) ; frDim.Invert() ;
BBox3d b3Dim ; pCrvPocket->GetBBox( frDim, b3Dim, BBF_EXACT) ;
dMaxLarg = ( vnProp[0] != 0 ? b3Dim.GetDimY() : dPocketSize) ;
dMaxLarg = ( vnProp[0] != TEMP_PROP_CLOSE_EDGE ? b3Dim.GetDimY() : dPocketSize) ;
}
// calcolo percorso di svuotatura
// se lati obliqui sono entrambi chiusi e dimensione svuotatura è maggiore di diametro fresa e minore del doppio gestione speciale
if ( ( bRealTrap && dMaxLarg > PockParams.dRad * 2 + 10 * EPS_SMALL) &&
if ( ( bRealTrap && dMaxLarg > dDiam + 10. * EPS_SMALL) &&
( ( ( vnProp[0] != TEMP_PROP_CLOSE_EDGE && vnProp[2] != TEMP_PROP_CLOSE_EDGE) &&
( vnProp[3] == TEMP_PROP_CLOSE_EDGE && vnProp[1] == TEMP_PROP_CLOSE_EDGE) &&
( max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL)) ||
( max( dLen0, dLen2) < 2. * dDiam + EPS_SMALL)) ||
( ( vnProp[1] != TEMP_PROP_CLOSE_EDGE && vnProp[3] != TEMP_PROP_CLOSE_EDGE) &&
( vnProp[0] == TEMP_PROP_CLOSE_EDGE && vnProp[2] == TEMP_PROP_CLOSE_EDGE) &&
( max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL)))) {
( max( dLen0, dLen2) < 2. * dDiam + EPS_SMALL)))) {
if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, ( vnProp[0] == TEMP_PROP_CLOSE_EDGE), pCrvPocket, PockParams, ptRef)) {
pMCrv->Clear() ;
return false ;
@@ -3605,14 +3605,8 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
if ( pMCrv->GetCurveCount() == 0)
return true ;
pMCrv->ToGlob( frTrap) ;
if ( PockParams.bInvert) {
pMCrv->Invert() ;
// inverto le proprietà in modo che nProp3 sia sempre legata al punto iniziale e nProp1 a quello finale
swap( vnProp[1], vnProp[3]) ;
}
// segno i lati aperti come temp prop della curva
int nOpenEdges = vnProp[0] + vnProp[1] * 2 + vnProp[2] * 4 + vnProp[3] * 8 ;
pMCrv->SetTempProp( nOpenEdges, 0) ;
@@ -3622,6 +3616,131 @@ CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTrap, double
return true ;
}
//----------------------------------------------------------------------------
static bool
IsForcedStepTrapezoid( const ICurveComposite* pCrvTrap, const PocketParams& PockParam,
int nBase, int nSecondBase, bool& bForced)
{
bForced = false ;
// se la curva non è valida, allora non può essere forzato
if ( pCrvTrap == nullptr || ! pCrvTrap->IsValid())
return false ;
// scorro la curva e ricavo le TempProps
array<int, 4> vnProps ;
int nClose = 0 ;
for ( int i = 0 ; i < 4 ; ++ i) {
if ( ! pCrvTrap->GetCurveTempProp( i, vnProps[i], 0))
return false ;
if ( vnProps[i] == TEMP_PROP_CLOSE_EDGE)
++ nClose ;
}
double dDiam = 2. * PockParam.dRad ;
switch ( nClose) {
// se trapezio tutto aperto, allora non è forzato
case 0 :
bForced = false ;
break ;
// se ho un lato chiuso, non è forzato
case 1 :
bForced = false ;
break ;
// se ho due lati chiusi
case 2 : {
if ( nBase < 0 || nBase > 4 || nSecondBase < 0 || nSecondBase > 4)
return false ;
// se entrambe le basi sono chiuse, è forzato
if ( vnProps[nBase] == TEMP_PROP_CLOSE_EDGE && vnProps[nSecondBase] == TEMP_PROP_CLOSE_EDGE)
bForced = true ;
// se entrambe le basi sono aperte
else if ( vnProps[nBase] == TEMP_PROP_OPEN_EDGE && vnProps[nSecondBase] == TEMP_PROP_OPEN_EDGE) {
const ICurve* pCrvOpenBase = pCrvTrap->GetCurve( nBase) ;
const ICurve* pCrvOpenSecondBase = pCrvTrap->GetCurve( nSecondBase) ;
if ( pCrvOpenBase == nullptr || ! pCrvOpenBase->IsValid() ||
pCrvOpenSecondBase == nullptr || ! pCrvOpenSecondBase->IsValid())
return false ;
double dLenOpenBase ; pCrvOpenBase->GetLength( dLenOpenBase) ;
double dLenSecondOpenBase ; pCrvOpenSecondBase->GetLength( dLenSecondOpenBase) ;
bForced = ( dLenOpenBase < dDiam + 10. * EPS_SMALL &&
dLenSecondOpenBase < dDiam + 10. * EPS_SMALL) ;
}
// se alternate, non forzo
else
bForced = false ;
}
break ;
// se ho tre lati chiusi
case 3 : {
// diventa forzato se il lato aperto non è grande
double dLenOpen = 0. ;
for ( int i = 0 ; i < 4 ; ++ i) {
if ( vnProps[i] == TEMP_PROP_OPEN_EDGE) {
const ICurve* pCrvOpen = pCrvTrap->GetCurve( i) ;
if ( pCrvOpen == nullptr || ! pCrvOpen->IsValid())
return false ;
pCrvOpen->GetLength( dLenOpen) ;
break ;
}
}
bForced = ( dLenOpen < dDiam + 10. * EPS_SMALL) ;
}
break ;
// se tutto chiuso, è forzato
case 4 :
bForced = true ;
break ;
default :
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
static bool
AdjustTrapeziodLeadIn( ICurveComposite* pCrvRes, const PocketParams& PockParam,
const ISurfFlatRegion* pSfrChunk)
{
// recupero la TempProp
int nTmpProp = pCrvRes->GetTempProp( 0) ;
// se esiste almeno un aperto
if ( nTmpProp > 0) {
// se solo lato3 aperto
bool bCheckHead = ( nTmpProp != 8 && nTmpProp != 2) ;
if ( nTmpProp == 2)
pCrvRes->Invert() ; // entro dall'unico aperto
if ( bCheckHead) {
// recupero gli estremi della curva corrente e la inverto in base alla Testa
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
Point3d ptE ; pCrvRes->GetEndPoint( ptE) ;
Point3d ptSGlob = GetToGlob( ptS, PockParam.frLocXY) ;
Point3d ptEGlob = GetToGlob( ptE, PockParam.frLocXY) ;
if ( ( PockParam.bAboveHead && ptEGlob.z > ptSGlob.z) ||
( ! PockParam.bAboveHead && ptEGlob.z < ptSGlob.z))
pCrvRes->Invert() ;
}
}
// Assegno la Feed
AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ;
// Se curva da invertire, inverto
if ( PockParam.bInvert)
pCrvRes->Invert() ;
// se esiste almeno un aperto, provo ad estendere il percorso
if ( nTmpProp > 0) {
// Calcolo eventuale entrata da fuori
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsStartExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
static bool
GetZigZagOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams& PockParam,
@@ -3651,11 +3770,10 @@ GetZigZagOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
int nBase, nSecondBase ;
bool bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ;
if ( bOkTrap && pCrvTrap->IsValid()) {
// se la base principale e secondaria sono entrambe chiuse, trascuro il SideStep
int nTmpProp = TEMP_PROP_INVALID ;
bool bBaseCL = ( pCrvTrap->GetCurveTempProp( nBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ;
bool bSecondBaseCL = ( pCrvTrap->GetCurveTempProp( nSecondBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ;
if ( ! bBaseCL || ! bSecondBaseCL)
// verifico se il trapezio ottenuto deve o meno rispettare il SideStep
bool bForcedTrap = false ;
IsForcedStepTrapezoid( pCrvTrap, PockParam, nBase, nSecondBase, bForcedTrap) ;
if ( ! bForcedTrap)
bOkTrap = ( dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ;
}
if ( bOkTrap && pCrvTrap->IsValid()) {
@@ -3674,33 +3792,8 @@ GetZigZagOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
pCrvRes->Clear() ;
}
}
if ( bOkTrap) {
// calcolo eventuali uscite e ingressi
if ( pCrvRes->GetTempProp( 0) > 0) {
// Recupero gli estremi della curva corrente e la inverto in base alla Testa
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
Point3d ptE ; pCrvRes->GetEndPoint( ptE) ;
Point3d ptSGlob = GetToGlob( ptS, PockParam.frLocXY) ;
Point3d ptEGlob = GetToGlob( ptE, PockParam.frLocXY) ;
if ( ( PockParam.bAboveHead && ptEGlob.z > ptSGlob.z) ||
( ! PockParam.bAboveHead && ptEGlob.z < ptSGlob.z))
pCrvRes->Invert() ;
if ( PockParam.bInvert)
pCrvRes->Invert() ;
// Assegno la Feed
AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ;
// Calcolo eventuale entrata da fuori
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsStartExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
return false ;
}
else {
if ( PockParam.bInvert)
pCrvRes->Invert() ;
}
}
if ( bOkTrap)
AdjustTrapeziodLeadIn( pCrvRes, PockParam, pSfrChunk) ;
}
}
@@ -3755,7 +3848,7 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT) ;
// NB. una versione più complessa dovrebbe verificare se la sottrazione tra la
// superficie dell'utensile e la regione limite non genera un'altra circonferenza...
// In questo caso si la sottrazione potrebbe essere trattata come una circonferenza
// In questo caso la sottrazione potrebbe essere trattata come una circonferenza
// chiusa ed essere ancora svotata a spirale...
}
}
@@ -3798,11 +3891,10 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
int nBase, nSecondBase ;
bool bOkTrap = GetTrapezoidFromShape( pCrvBorder, pCrvTrap, frTrap, PockParam, dPocketSize, nBase, nSecondBase) ;
if ( bOkTrap && pCrvTrap->IsValid()) {
// se la base principale e secondaria sono entrambe chiuse, trascuro il SideStep
int nTmpProp = TEMP_PROP_INVALID ;
bool bBaseCL = ( pCrvTrap->GetCurveTempProp( nBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ;
bool bSecondBaseCL = ( pCrvTrap->GetCurveTempProp( nSecondBase, nTmpProp, 0) && nTmpProp == TEMP_PROP_CLOSE_EDGE) ;
if ( ! bBaseCL || ! bSecondBaseCL)
// verifico se il trapezio ottenuto deve o meno rispettare il SideStep
bool bForcedTrap = false ;
IsForcedStepTrapezoid( pCrvTrap, PockParam, nBase, nSecondBase, bForcedTrap) ;
if ( ! bForcedTrap)
bOkTrap = ( dPocketSize < PockParam.dMaxOptSize + 10. * EPS_SMALL) ;
}
if ( bOkTrap && pCrvTrap->IsValid()) {
@@ -3821,33 +3913,8 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
pCrvRes->Clear() ;
}
}
if ( bOkTrap) {
// calcolo eventuali uscite e ingressi
if ( pCrvRes->GetTempProp( 0) > 0) {
// Recupero gli estremi della curva corrente e la inverto in base alla Testa
Point3d ptS ; pCrvRes->GetStartPoint( ptS) ;
Point3d ptE ; pCrvRes->GetEndPoint( ptE) ;
Point3d ptSGlob = GetToGlob( ptS, PockParam.frLocXY) ;
Point3d ptEGlob = GetToGlob( ptE, PockParam.frLocXY) ;
if ( ( PockParam.bAboveHead && ptEGlob.z > ptSGlob.z) ||
( ! PockParam.bAboveHead && ptEGlob.z < ptSGlob.z))
pCrvRes->Invert() ;
if ( PockParam.bInvert)
pCrvRes->Invert() ;
// Assegno la Feed
AssignFeedSpiralOpt( 1, PockParam, pCrvRes) ;
// Calcolo eventuale entrata da fuori
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
vtRef.Invert() ;
bool bIsStartExtended = false ;
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
return false ;
}
else {
if ( PockParam.bInvert)
pCrvRes->Invert() ;
}
}
if ( bOkTrap)
AdjustTrapeziodLeadIn( pCrvRes, PockParam, pSfrChunk) ;
}
}
BIN
View File
Binary file not shown.