EgtMachKernel :

- codice per casi ottimizzati ZigZag.
This commit is contained in:
Riccardo Elitropi
2023-11-07 17:46:49 +01:00
parent 4d02f573d2
commit 7ca922c9b6
+283 -193
View File
@@ -2436,7 +2436,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
! OrderCurvesByLastPntOfPath( vCrvIslMergeBorders, ptEnd, vPtStart, vVtMidOut, vbMidOut))
return false ;
int nOff_index = int( vCrvInfo.size()) ;
int nOff_index = int( vpCrvs.size()) ;
for ( int x = 0 ; x < int( vCrvIslMergeBorders.size()) ; ++ x) {
vCrvInfo[nOff_index + x].pCrvCompo.Set( Release( vCrvIslMergeBorders[x])) ;
vCrvInfo[nOff_index + x].nCrvType = CRV_BORDER ;
@@ -2465,6 +2465,13 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( ! pSrfForCrv->IsValid()) {
pSrfForCrv.Set( CloneSurfFlatRegion( pSrfChunkFinal)) ;
if ( ! pSrfForCrv->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
}
// Avendo effettuato due Offsets ( -dOffs-dExtra e -dOffs ) non è detto che il numero di Chunks tra le nuove
// superifici sia uguale... Inizio a scorre i chunks della superficie per le curve di contorno e,
// per ognuna di esse, cerco il/i Chunck per il percorso a ZigZag contenuti.
@@ -2581,16 +2588,15 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
bool bOptTwoOpposite = vChunkInfo[vCrvInfo[u].nChunk].bOptTwoOpposite ;
// se un lato chiuso
if ( nClosedSide == 1) {
// inverto il percorso
// inverto il percorso ( parto dall'aperto)
pCrvCurr->Invert() ;
// verifico se attacco fuori dal grezzo
// verifico se attacco fuori dal grezzo ( allungandolo)
Point3d ptStart ;
pCrvCurr->GetStartPoint( ptStart) ;
Vector3d vtDir ;
pCrvCurr->GetStartDir( vtDir) ;
Point3d ptTest = ptStart + ( - vtDir) *
( m_TParams.m_dDiam / 2 - dOffsOpt + dSafeZ) ;
ptTest += - vtTool * dDepth ;
Point3d ptTest = ptStart + ( - vtDir) * ( m_TParams.m_dDiam / 2 - dOffsOpt + dSafeZ) ;
ptTest.Translate( vVtTrasl[j-1]) ;
double dTestElev ;
// se è nel grezzo provo a ruotare di 90 gradi
if ( GetElevation( m_nPhase, ptTest, vtTool,
@@ -2611,6 +2617,7 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
}
}
// Spostare dentro caso ottimizzato (?)
// se due lati chiusi consecutivi o tre lati chiusi...
else if (( nClosedSide == 2 || nClosedSide == 3) && ! bOptTwoOpposite) {
// inverto il percorso
@@ -2630,7 +2637,8 @@ Pocketing::AddZigZag( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool, c
}
// estendo la fine del percorso
if ( ! ( nClosedSide == 3 && bOptTwoOpposite))
//if ( ! ( nClosedSide == 3 && bOptTwoOpposite))
if (( nClosedSide == 2 && ! bOptTwoOpposite) || ( nClosedSide == 3 && ! bOptTwoOpposite))
pCrvCurr->ExtendEndByLen( max( m_TParams.m_dDiam / 4 - dOffsOpt, 0.0)) ;
// aggiungo il tratto per l'entrata, verifico se attacco fuori dal grezzo
@@ -2933,7 +2941,7 @@ Pocketing::CalcZigZag( const ISurfFlatRegion* pSrfZigZag, ICRVCOMPOPOVECTOR& vpC
{
// check parametri
if ( pSrfZigZag == nullptr)
if ( pSrfZigZag == nullptr || ! pSrfZigZag->IsValid())
return true ;
// creo il vettore dei contorni
@@ -3492,7 +3500,7 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl
return false ;
// recupero la curva ORIGINALE che delimita la svuotatura (questa curva non risente dell'offset fatto dalla superificie creata dopo)
PtrOwner<ICurveComposite> pCrvForId( GetCurveComposite( pSrfPocket->GetLoop( 0, 0))) ;
/*PtrOwner<ICurveComposite> pCrvForId( GetCurveComposite( pSrfPocket->GetLoop( 0, 0))) ;
int nCrvId = pCrvForId->GetTempProp( 0) ;
PtrOwner<ICurveComposite> pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ;
bool bSrfOriIsCut = false ;
@@ -3501,16 +3509,21 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl
if ( IsNull( pCrvPocket) || pCrvPocket->GetCurveCount() == 0)
return true ;
bSrfOriIsCut = true ;
}
}*/
// recupero la curva dal bordo della superficie
PtrOwner<ICurveComposite> pCrvPocket( ConvertCurveToComposite( pSrfPocket->GetLoop( 0, 0))) ;
if ( IsNull( pCrvPocket))
return false ;
// porto la curva nel sistema di riferimento locale
pCrvPocket->ToLoc( frPocket) ;
//pCrvPocket->ToLoc( frPocket) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvPocket->Clone()) ;
// setto proprietà sulle curve
if ( ! bSrfOriIsCut)
SetCurveAllTempProp( nCrvId, GetForcedClosed(), pCrvPocket) ;
//if ( ! bSrfOriIsCut)
// SetCurveAllTempProp( nCrvId, GetForcedClosed(), pCrvPocket) ;
pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
// sistemo senso antiorario visto dalla direzione di estrusione
@@ -3562,96 +3575,66 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl
vtDir.GetAngleXY( X_AX, dAng) ;
if ( nClosedSides == 0)
dAng += m_Params.m_dSideAngle ;
pSrfPocket->ToGlob( frPocket) ;
pCrvPocket->ToGlob( frPocket) ;
Frame3d frameH( frPocket) ;
Point3d ptCen = frPocket.Orig() ;
Vector3d vtExtr = frPocket.VersZ() ;
frPocket.Rotate( ptCen, vtExtr, -dAng) ;
pSrfPocket->ToLoc( frPocket) ;
pCrvPocket->ToLoc( frPocket) ;
// vettore contenente le curve di primo Offset ottimizzate ( bordo esterno Optimized e isole )
ICRVCOMPOPOVECTOR vFirstOffsets ;
vFirstOffsets.emplace_back( pCrvPocket->Clone()) ; // la curva esterna modificata
// parametri per Offset
double dTRad = m_TParams.m_dDiam / 2 ;
double dMyOffs = dTRad + GetOffsR() ;
double dExtra = (( m_TParams.m_nType != TT_MILL_POLISHING) ? min( 0.1 * m_TParams.m_dDiam, 2.0) : 0) ;
// Offsetto la superficie per ricavare informazioni su eventuali isole e sulle loro possibili unioni
PtrOwner<ISurfFlatRegion> pSrfPocketClone( CloneSurfFlatRegion( pSrfPocket)) ;
if ( IsNull( pSrfPocketClone))
return false ;
if ( ! pSrfPocketClone->Offset( - dMyOffs - dExtra, ICurve::OFF_FILLET)) { // le isole interne vanno Offsettate
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
// creo la superficie per svuotatura ZigZag
PtrOwner<ISurfFlatRegion> pSfrZigZag( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrZigZag) || ! pSfrZigZag->AddExtLoop( *pCrvPocket))
return false ;
// creo la superficie per le curve di bordo
PtrOwner<ISurfFlatRegion> pSfrForCrv( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrForCrv) || ! pSfrForCrv->AddExtLoop( *pCrvPocket))
PtrOwner<ISurfFlatRegion> pSfrForCrv( CloneSurfFlatRegion( pSfrZigZag)) ;
if ( IsNull( pSfrForCrv))
return false ;
// creo una superficie come somma delle isole
PtrOwner<ISurfFlatRegion> pSfrToTIsl( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrToTIsl))
return false ;
// prendo i loop interni dalla superficie originale !
for ( int c = 0 ; c < pSrfPocket->GetChunkCount() ; ++ c) { // sempre 1... (?)
for ( int l = 1 ; l < pSrfPocket->GetLoopCount( c) ; ++ l) {
PtrOwner<ICurveComposite> pCrvIslLoop( ConvertCurveToComposite( pSrfPocket->GetLoop( c, l))) ;
if ( IsNull( pCrvIslLoop) || ! pCrvIslLoop->IsValid())
return false ;
pCrvIslLoop->ToGlob( frameH) ;
pCrvIslLoop->ToLoc( frPocket) ;
// creo la superficie dal bordo dell'isola
// ( NB. facendo l'offset di un'isola non è detto che ottengo una sola curva)
PtrOwner<ISurfFlatRegion> pSfrIslOff1( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrIslOff1) || ! pSfrIslOff1->AddExtLoop( *pCrvIslLoop))
return false ;
// per sottrarre devono essere coerenti
if ( AreOppositeVectorApprox( pSfrIslOff1->GetNormVersor(), pSfrZigZag->GetNormVersor()))
pSfrIslOff1->Invert() ;
PtrOwner<ISurfFlatRegion> pSfrIslOff2( CloneSurfFlatRegion( pSfrIslOff1)) ;
if ( IsNull( pSfrIslOff2))
return false ;
// Offset 1 ed Offset 2
if ( ! pSfrIslOff1->Offset( dMyOffs + dExtra, ICurve::OFF_FILLET) ||
! pSfrIslOff2->Offset( dMyOffs, ICurve::OFF_FILLET))
return false ;
// aggiorno la regione totale delle isole
if ( ! pSfrToTIsl->IsValid() || pSfrToTIsl->GetChunkCount() == 0)
pSfrToTIsl.Set( pSfrIslOff1->Clone()) ;
else
pSfrToTIsl->Add( *pSfrIslOff1) ;
// sottraggo
if ( ! pSfrZigZag->Subtract( *pSfrIslOff1) || ! pSfrForCrv->Subtract( *pSfrIslOff2)) {
if ( ! pSfrZigZag->Subtract( *pSfrIslOff1)) {
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZigZag->Clone()) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrIslOff1->Clone()) ;
}
else {
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrForCrv->Clone()) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrIslOff2->Clone()) ;
}
return false ;
}
for ( int l = 1 ; l < pSrfPocket->GetLoopCount( 0) ; ++ l) {
PtrOwner<ICurve> pCrvLoopIsl( pSrfPocket->GetLoop( 0, l)) ;
if ( IsNull( pCrvLoopIsl))
return false ;
// aggiungo alla pSrfForCurves ( così non considero il dExtra)
pSfrForCrv->AddIntLoop( *pCrvLoopIsl) ;
// effettuo l'offset di dExtra ( cos' considero il dExtra come distanza dal bordo delle isole)
pCrvLoopIsl->Invert() ;
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrvLoopIsl, dExtra, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
PtrOwner<ICurve> pCrvBorderIsl( OffsCrv.GetLongerCurve()) ;
if ( ! pSfrZigZag->AddIntLoop( *pCrvBorderIsl))
return false ;
}
// Offset per i bordi e percorsi a ZigZag
if ( ! pSfrZigZag->Offset( - dMyOffs, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( ! pSfrForCrv->Offset( - dMyOffs , ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( ! pSfrForCrv->IsValid()) {
bOptimizedZigZag = false ;
return true ;
}
// calcolo il percorso di svuotatura
pSfrZigZag->ToGlob( frPocket) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZigZag->Clone()) ;
pSfrZigZag->ToLoc( frPocket) ;
if ( ! CalcZigZag( pSfrZigZag, vpCrvs))
return false ;
@@ -3660,15 +3643,55 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl
double dAreaPrec, dAreaAft ;
const ICurve* pCrvExtLoop = pSfrForCrv->GetLoop( 0, 0) ;
Plane3d plH ;
if ( ! pCrvPocket->GetArea( plH, dAreaPrec) ||
PtrOwner<ISurfFlatRegion> pSfrByCrvPocket( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrByCrvPocket) || ! pSfrByCrvPocket->AddExtLoop( *pCrvPocket))
return false ;
if ( ! pSfrByCrvPocket->Offset( - dMyOffs, ICurve::OFF_CHAMFER))
return false ;
if ( ! pSfrByCrvPocket->GetArea( dAreaPrec) ||
! pCrvExtLoop->GetArea( plH, dAreaAft))
return false ;
// se l'area è cambiata...
if ( abs( dAreaPrec - dAreaAft) > 5000 * EPS_SMALL) {
ICURVEPOVECTOR vCrv ;
ChainCurves ChainC ;
// creo una superficie come somma delle isole
PtrOwner<ISurfFlatRegion> pSfrToTIsl( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrToTIsl))
return false ;
// prendo i loop interni dalla superficie originale !
for ( int c = 0 ; c < pSrfPocket->GetChunkCount() ; ++ c) { // sempre 1... (?)
for ( int l = 1 ; l < pSrfPocket->GetLoopCount( c) ; ++ l) {
PtrOwner<ICurveComposite> pCrvIslLoop( ConvertCurveToComposite( pSrfPocket->GetLoop( c, l))) ;
if ( IsNull( pCrvIslLoop) || ! pCrvIslLoop->IsValid())
return false ;
// creo la superficie dal bordo dell'isola
// ( NB. facendo l'offset di un'isola non è detto che ottengo una sola curva)
PtrOwner<ISurfFlatRegion> pSfrIslOff1( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrIslOff1) || ! pSfrIslOff1->AddExtLoop( *pCrvIslLoop))
return false ;
// per sottrarre devono essere coerenti
if ( AreOppositeVectorApprox( pSfrIslOff1->GetNormVersor(), pSfrZigZag->GetNormVersor()))
pSfrIslOff1->Invert() ;
// Offset 1 ed Offset 2
if ( ! pSfrIslOff1->Offset( dMyOffs + 50 * EPS_SMALL, ICurve::OFF_FILLET))
return false ;
// aggiorno la regione totale delle isole
if ( ! pSfrToTIsl->IsValid() || pSfrToTIsl->GetChunkCount() == 0)
pSfrToTIsl.Set( pSfrIslOff1->Clone()) ;
else
pSfrToTIsl->Add( *pSfrIslOff1) ;
}
}
// il bordo esterno si è unito all'isola => devo percorrere la parte di bordo interna all'isola
for ( int c = 0 ; c < pSfrForCrv->GetChunkCount() ; ++ c) {
const ICurve* pCrvExt = pSfrForCrv->GetLoop( c, 0) ;
@@ -3744,8 +3767,18 @@ Pocketing::ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOpt
pCrvPocket->GetCurve( nMax)->GetStartDir( vtDir) ;
// aggiorno pCrvPocket con eventuale offset per regioni residue
if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 0, {}, dOffs))
return true ;
//if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 0, {}, dOffs))
// return true ;
OffsetCurve CrvOffs ;
if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
pCrvPocket->Clear() ;
pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ;
if ( ! pCrvPocket->IsValid())
return false ;
bOptimizedZigZag = true ;
return true ;
@@ -3753,8 +3786,8 @@ Pocketing::ZigZagOptimizedNoClosedEdges( ICurveComposite* pCrvPocket, bool& bOpt
//------------------------------------------------------------------
bool
Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClosedId, bool& bOptimizedZigZag, Vector3d& vtDir,
double& dOffs)
Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClosedId, bool& bOptimizedZigZag,
Vector3d& vtDir, double& dOffs)
{
// verifico che il lato chiuso sia una linea
PtrOwner<ICurveLine> pCrv( CloneCurveLine( pCrvPocket->GetCurve( nClosedId))) ;
@@ -3763,22 +3796,41 @@ Pocketing::ZigZagOptimizedOneClosedEdge( ICurveComposite* pCrvPocket, int nClose
// aggiorno pCrvPocket con eventuale offset per regioni residue
pCrv->GetStartDir( vtDir) ;
if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, {nClosedId}, dOffs))
return true ;
// setto il vettore estrusione per eseguire correttamente offset
Vector3d vtExtr ;
pCrvPocket->GetExtrusion( vtExtr) ;
pCrv->SetExtrusion( vtExtr) ;
//if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, {nClosedId}, dOffs))
// return true ;
pCrv->SimpleOffset( -m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL) ;
// Offset
OffsetCurve CrvOffs ;
if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
pCrv->ExtendStartByLen( 300) ;
pCrv->ExtendEndByLen( 300) ;
// sarà la prima curva del percorso
if ( ! CutCurveWithLine( pCrvPocket, pCrv))
pCrvPocket->Clear() ;
pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ;
if ( ! pCrvPocket->IsValid() || ! CutCurveWithLine( pCrvPocket, pCrv))
return false ;
pCrvPocket->ChangeStartPoint( nClosedId) ;
// setto il vettore estrusione per eseguire correttamente offset
// Vector3d vtExtr ;
// pCrvPocket->GetExtrusion( vtExtr) ;
// pCrv->SetExtrusion( vtExtr) ;
// pCrv->SimpleOffset( -m_TParams.m_dDiam / 2 - GetOffsR() + 10 * EPS_SMALL) ;
// pCrv->ExtendStartByLen( 300) ;
// pCrv->ExtendEndByLen( 300) ;
//// sarà la prima curva del percorso
// if ( ! CutCurveWithLine( pCrvPocket, pCrv))
// return false ;
bOptimizedZigZag = true ;
return true ;
}
@@ -3817,41 +3869,48 @@ Pocketing::ZigZagOptimizedTwoClosedEdges( ICurveComposite* pCrvPocket, const INT
}
// setto il vettore estrusione per eseguire correttamente offset
Vector3d vtExtr ;
pCrvPocket->GetExtrusion( vtExtr) ;
pCrv1->SetExtrusion( vtExtr) ;
pCrv2->SetExtrusion( vtExtr) ;
//Vector3d vtExtr ;
//pCrvPocket->GetExtrusion( vtExtr) ;
//pCrv1->SetExtrusion( vtExtr) ;
//pCrv2->SetExtrusion( vtExtr) ;
// determino la curva chiusa più lunga
double dLen1 ; pCrv1->GetLength( dLen1) ;
double dLen2 ; pCrv2->GetLength( dLen2) ;
// se non opposti, verifico che almeno una delle due sia corta
if ( ! bOpposite && dLen1 > 1.5 * m_TParams.m_dDiam && dLen2 > 1.5 * m_TParams.m_dDiam)
if ( ! bOpposite && dLen1 > /*1.5 **/ m_TParams.m_dDiam && dLen2 > /*1.5 **/ m_TParams.m_dDiam)
return true ;
// trovo la direzione principale della svuotatura
if ( dLen1 > dLen2)
pCrv1->GetStartDir( vtDir) ;
else
pCrv2->GetStartDir( vtDir) ;
// taglio per ultima la curva più lunga
if ( dLen1 > dLen2) {
swap( pCrv1, pCrv2) ;
swap( vtDir1, vtDir2) ;
}
vtDir = vtDir2 ;
//if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, bOpposite ? 2 : 1, vnClosedIds, dOffs))
// return true ;
// aggiorno pCrvPocket con eventuale offset per regioni residue
if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, bOpposite ? 2 : 1, vnClosedIds, dOffs))
return true ;
OffsetCurve CrvOffs ;
if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
pCrvPocket->Clear() ;
pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ;
double dMyOffs = m_TParams.m_dDiam / 2 + GetOffsR() - 10 * EPS_SMALL ;
pCrv1->SimpleOffset( -dMyOffs) ;
pCrv1->ExtendStartByLen( 300) ;
pCrv1->ExtendEndByLen( 300) ;
if ( ! CutCurveWithLine( pCrvPocket, pCrv1))
return false ;
// sarà la prima curva del percorso
pCrv2->SimpleOffset( -dMyOffs) ;
pCrv2->ExtendStartByLen( 300) ;
pCrv2->ExtendEndByLen( 300) ;
if ( ! CutCurveWithLine( pCrvPocket, pCrv2))
if ( ! pCrvPocket->IsValid() ||
! CutCurveWithLine( pCrvPocket, pCrv1) ||
! CutCurveWithLine( pCrvPocket, pCrv2))
return false ;
bOptimizedZigZag = true ;
@@ -3883,6 +3942,7 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I
pCrv3->GetStartPoint( ptStart3) ;
Point3d ptEnd3 ;
pCrv3->GetEndPoint( ptEnd3) ;
if ( AreSamePointApprox( ptEnd1, ptStart2) && AreSamePointApprox( ptEnd2, ptStart3))
;
else if ( AreSamePointApprox( ptEnd2, ptStart3) && AreSamePointApprox( ptEnd3, ptStart1)) {
@@ -3900,45 +3960,42 @@ Pocketing::ZigZagOptimizedThreeClosedEdges( ICurveComposite* pCrvPocket, const I
double dLen2 ; pCrv2->GetLength( dLen2) ;
double dLen3 ; pCrv3->GetLength( dLen3) ;
if ( dLen2 > dLen1 && dLen2 > dLen3) {
if ( dLen1 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL || dLen3 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL)
if ( dLen2 > dLen1 && dLen2 > dLen3) {
if ( dLen1 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL || dLen3 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL)
return true ;
pCrv2->GetStartDir( vtDir) ;
bOpposite = false ;
}
else {
if ( dLen2 > /*1.5 **/ m_TParams.m_dDiam / 2 + 5 * EPS_SMALL)
return true ;
pCrv3->GetStartDir( vtDir) ;
bOpposite = true ;
return true ;
//if ( dLen2 > m_TParams.m_dDiam * 0.5 + 5 * EPS_SMALL)
// return true ;
//pCrv3->GetStartDir( vtDir) ;
//bOpposite = true ;
}
// aggiorno pCrvPocket con eventuale offset per regioni residue
if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, vnClosedIds, dOffs))
return true ;
//if ( ! ZigZagOptimizedComputeOffset( pCrvPocket, vtDir, 1, vnClosedIds, dOffs))
// return true ;
// setto il vettore estrusione per eseguire correttamente offset
Vector3d vtExtr ;
pCrvPocket->GetExtrusion( vtExtr) ;
pCrv1->SetExtrusion( vtExtr) ;
pCrv2->SetExtrusion( vtExtr) ;
pCrv3->SetExtrusion( vtExtr) ;
OffsetCurve CrvOffs ;
if ( ! CrvOffs.Make( pCrvPocket, 0.5 * m_TParams.m_dDiam, ICurve::OFF_CHAMFER)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
pCrvPocket->Clear() ;
pCrvPocket->AddCurve( CrvOffs.GetLongerCurve()) ;
double dMyOffs = m_TParams.m_dDiam / 2 + GetOffsR() - 10 * EPS_SMALL ;
pCrv1->SimpleOffset( - dMyOffs) ;
pCrv1->ExtendStartByLen( 300) ;
pCrv1->ExtendEndByLen( 300) ;
if ( ! CutCurveWithLine( pCrvPocket, pCrv1))
return false ;
pCrv3->SimpleOffset( -dMyOffs) ;
pCrv3->ExtendStartByLen( 300) ;
pCrv3->ExtendEndByLen( 300) ;
if ( ! CutCurveWithLine( pCrvPocket, pCrv3))
return false ;
// sarà la prima curva del percorso
pCrv2->SimpleOffset( -dMyOffs) ;
pCrv2->ExtendStartByLen( 300) ;
pCrv2->ExtendEndByLen( 300) ;
if ( ! CutCurveWithLine( pCrvPocket, pCrv2))
@@ -3953,7 +4010,7 @@ bool
Pocketing::ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vector3d& vtMainDir, int nOffsettedEdgesOnY,
const INTVECTOR& vnClosedIds, double& dOffs)
{
// calcolo il side step che verr utilizzato in CalcZigZag
// calcolo il side step che verrà utilizzato in CalcZigZag
Frame3d frLoc ;
if ( ! frLoc.Set( ORIG, Z_AX, vtMainDir))
return true ;
@@ -3968,6 +4025,11 @@ Pocketing::ZigZagOptimizedComputeOffset( ICurveComposite* pCrvPocket, const Vect
dDimY -= nOffsettedEdgesOnY * ( 0.5 * m_TParams.m_dDiam + GetOffsR()) ;
int nYStep = static_cast<int>( ceil( ( dDimY - 30 * EPS_SMALL) / GetSideStep())) ;
double dYSideStep = ( nYStep > 0 ? ( dDimY - 30 * EPS_SMALL) / nYStep : 0) ;
dOffs = dYSideStep * 0.5 ;
return true ;
// ---- check
// individuo i lati vicini a quelli closed
for ( int i = 0 ; i < ( int)vnClosedIds.size() ; i ++) {
@@ -5445,16 +5507,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
if ( nReg == 0) {
CalcTrapezoidSpiral( pCrvTrap, frTrap, dPocketSize, nBase, nSecondBase, pMCrv, pRCrv, bOptimizedTrap) ;
if ( bOptimizedTrap) {
// ----
pCrvTrap->ToGlob( frPocket) ;
if ( pCrvTrap->IsValid()) {
for ( int u = 0 ; u < pCrvTrap->GetCurveCount() ; ++ u) {
const ICurve* pCrv = pCrvTrap->GetCurve( u) ;
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( a, pCrv->GetTempProp( 0) == 0 ? BLUE : RED) ;
}
}
// ----
pMCrv->ToGlob( frPocket) ;
pRCrv->ToGlob( frPocket) ;
nReg = 1 ;
@@ -5464,7 +5516,6 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
else
return true ;
}
return false ;
}
// porto la superficie nel frame della svuotatura
@@ -5489,6 +5540,15 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
//m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ;
return false ;
}
if ( ! pSrfAct->IsValid()) {
// VRONOI ?
pSrfAct.Set( pSrfPrec->Clone()) ;
if ( ! pSrfAct->Offset( - dOffs + 5 * EPS_SMALL, ICurve::OFF_FILLET)) {
//int nbadOffs = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfPrec->Clone()) ;
//m_pGeomDB->Save( nbadOffs, "C:\\Users\\riccardo.elitropi\\Desktop\\Err_offs" + ToString( nbadOffs) + "__m" + ToString( dOffs) + ".nge") ;
return false ;
}
}
// estraggo il contorno della FlatRegion (ciclo i Chunks e prendo i rispettivi Loops)
if ( nIter == 0) {
@@ -5499,7 +5559,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
pSrfAct.Set( pSrfChunknReg) ;
}
int nChunks = pSrfAct->GetChunkCount();
int nChunks = pSrfAct->GetChunkCount() ;
for ( int i = 0 ; i < nChunks ; ++ i) {
// per ogni chunk...
@@ -7579,7 +7639,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr
pCrvPocket->ToLoc( frTrap) ;
// calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso)
double dLen0, dLen1, dLen2, dLen3 ;
double dLen0, dLen1, dLen2, dLen3, dMaxLarg = 0. ;
pCrvPocket->GetCurve( nBase)->GetLength( dLen0) ;
pCrvPocket->GetCurve( nSecondBase)->GetLength( dLen2) ;
bool bRealTrap = pCrvPocket->GetCurveCount() == 4 ;
@@ -7588,13 +7648,20 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr
if ( bRealTrap) {
pCrvPocket->GetCurve( nBase + 1)->GetLength( dLen1) ;
pCrvPocket->GetCurve( nSecondBase + 1)->GetLength( dLen3) ;
// calcolo la larghezza massima della svuotatura (riferimento con X parallelo a primo lato chiuso)
Point3d ptOrig ; pCrvPocket->GetCurve( 1)->GetStartPoint( ptOrig) ;
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) ;
}
// 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 &&
( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL) ||
vnProp[1] != 0 && vnProp[3] != 0 && vnProp[0] == 0 && vnProp[2] == 0 && max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL) {
if ( bRealTrap && dMaxLarg > m_TParams.m_dDiam + 10 * EPS_SMALL &&
(( vnProp[0] != 0 && vnProp[2] != 0 && vnProp[3] == 0 && vnProp[1] == 0 && max( dLen0, dLen2) < 2 * dDiam + EPS_SMALL) ||
vnProp[1] != 0 && vnProp[3] != 0 && vnProp[0] == 0 && vnProp[2] == 0 && max( dLen1, dLen3) < 2 * dDiam + EPS_SMALL)) {
if ( ! SpecialAdjustTrapezoidSpiralForAngles( pMCrv, vnProp[0] == 0, pCrvPocket)) {
pMCrv->Clear() ;
return false ;
@@ -7620,41 +7687,51 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr
Point3d ptStart( dXCoordStart, dYCoord) ;
Point3d ptEnd( dXCoordEnd, dYCoord) ;
//if ( AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && vnProp[0] != 0) {
// Vector3d vtDir1, vtDir3 ;
// pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ;
// pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ;
// // gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile
// if ( AreOppositeVectorApprox( vtDir1, vtDir3)) {
// PtrOwner<ICurveLine> pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ;
// PtrOwner<ICurveLine> pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ;
// if ( IsNull( pLine1) || IsNull( pLine3))
// return true ;
// if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ||
// ! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()))
// return true ;
if ( bRealTrap && AreSamePointEpsilon( ptStart, ptEnd, 500 * EPS_SMALL) && ( vnProp[0] != 0 || vnProp[2] != 0)) {
Vector3d vtDir1, vtDir3 ;
pCrvPocket->GetCurve( 1)->GetStartDir( vtDir1) ;
pCrvPocket->GetCurve( 3)->GetStartDir( vtDir3) ;
// gestisco il caso speciale di un parallelogramma in cui anche l'altra dimensione della svuotatura è pari al diametro utensile
if ( AreOppositeVectorApprox( vtDir1, vtDir3)) {
PtrOwner<ICurveLine> pLine1( GetCurveLine( pCrvPocket->GetCurve( 1)->Clone())) ;
PtrOwner<ICurveLine> pLine3( GetCurveLine( pCrvPocket->GetCurve( 3)->Clone())) ;
if ( IsNull( pLine1) || IsNull( pLine3))
return false ;
if ( ! pLine1->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()) ||
! pLine3->SimpleOffset( - 0.5 * m_TParams.m_dDiam - GetOffsR()))
return false ;
// Point3d ptS, ptE ;
// if ( vtDir3 * X_AX > EPS_SMALL) {
// pLine1->GetStartPoint( ptS) ;
// pLine3->GetStartPoint( ptE) ;
// }
// else {
// pLine1->GetEndPoint( ptE) ;
// pLine3->GetEndPoint( ptS) ;
// }
Point3d ptS, ptE ;
if ( vtDir3 * X_AX > EPS_SMALL) {
pLine1->GetStartPoint( ptS) ;
pLine3->GetStartPoint( ptE) ;
}
else {
pLine1->GetEndPoint( ptE) ;
pLine3->GetEndPoint( ptS) ;
}
// pMCrv->AddPoint( ptS) ;
// if ( vnProp[2] != 0)
// pMCrv->AddLine( ptE) ;
// else
// pMCrv->AddLine( ptStart) ;
if ( vnProp[0] != 0) {
pMCrv->AddPoint( ptS) ;
if ( vnProp[2] != 0)
pMCrv->AddLine( ptE) ;
else
pMCrv->AddLine( ptStart) ;
}
else {
pMCrv->AddPoint( ptE) ;
if ( vnProp[0] != 0)
pMCrv->AddLine( ptS) ;
else
pMCrv->AddLine( ptStart) ;
pMCrv->Invert() ;
}
// pMCrv->SetCurveTempProp( 0, 1) ;
// }
//}
//else {
if ( ! pMCrv->AddPoint( ptStart))
pMCrv->SetCurveTempProp( 0, 1) ;
}
}
else {
if ( ! pMCrv->AddPoint( ptStart))
return true ;
if ( ! pMCrv->AddLine( ptEnd))
return true ;
@@ -7703,7 +7780,7 @@ Pocketing::CalcTrapezoidSpiral( ICurveComposite* pCrvPocket, const Frame3d& frTr
}
//}
}
}
if ( pMCrv->GetCurveCount() == 0)
@@ -14905,6 +14982,14 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
}
if ( ! CalcTrapezoidSpiralLocalFrame( pCrvTrap, vtDir, frTrap))
return false ;
bool bBaseOpen = false ;
bBaseOpen = ( pCrvTrap->GetCurve( 0)->GetTempProp( 0) == 1 || pCrvTrap->GetCurve( 2)->GetTempProp( 0) == 1 ) ;
// controllo dimensioni della svuotatura
if ( ! ( bBaseOpen && dPocketSize < dDiam + EPS_SMALL) &&
abs( dPocketSize - dDiam) > EPS_SMALL) {
pCrvTrap->Clear() ;
return true ;
}
// recupero flag aperto/chiuso dei lati
if ( pCrvTrap->GetCurve( 1)->GetTempProp( 0) == 0 && pCrvTrap->GetCurve( 3)->GetTempProp( 0) == 0) {
double dLen0, dLen2 ;
@@ -14913,6 +14998,7 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
if ( dLen0 < dDiam - EPS_SMALL || dLen2 < dDiam - EPS_SMALL)
pCrvTrap->Clear() ;
}
// imposto le basi
nBase = 0 ;
nSecondBase = 2 ;
@@ -15077,15 +15163,19 @@ Pocketing::GetTrapezoidFromShape( const ICurveComposite* pCrvCompo, double dDiam
if ( ! CheckSecondBaseTrapezoid( pCrvCompo_c, i, nSecondBase))
return false ;
if ( nSecondBase != -1) {
// se ho trovato la seconda base
if ( ! PreparareTrapezoidTwoBases( pCrvCompo_c, BBox, i, nSecondBase, bOk, pCrvTrap))
return false ;
if ( bOk) {
// pCrvTrap contiene il trapezio
nBase = 0 ;
dPocketSize = BBox.GetDimY() ;
pCrvTrap->ToGlob( frTrap) ;
bBaseFound = true ;
// verifico che una delle due sia chiusa ( TO DO)
if ( pCrvCompo_c->GetCurve( nBase)->GetTempProp( 0) == 0 ||
pCrvCompo_c->GetCurve( nSecondBase)->GetTempProp( 0) == 0) {
// se ho trovato la seconda base
if ( ! PreparareTrapezoidTwoBases( pCrvCompo_c, BBox, i, nSecondBase, bOk, pCrvTrap))
return false ;
if ( bOk) {
// pCrvTrap contiene il trapezio
nBase = 0 ;
dPocketSize = BBox.GetDimY() ;
pCrvTrap->ToGlob( frTrap) ;
bBaseFound = true ;
}
}
}
}