EgtMachKernel :

- lavorazione precedente. Primo test.
This commit is contained in:
Riccardo Elitropi
2023-12-18 13:10:38 +01:00
parent 790660e549
commit f5a94ee0dd
2 changed files with 330 additions and 167 deletions
+326 -156
View File
@@ -2355,7 +2355,12 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa
if ( ! GetCurvesForOptimizedPocketing( pSfrCurr, vCrvOEWithFlags[j-1]))
return false ;
// modifico la supericie in base alle proprietà di lato aperto/chiuso
if ( ! ModifySurfByOpenEdges( pSfrCurr, pSfrLimit))
PtrOwner<ISurfFlatRegion> pSfrNoExtension( CloneSurfFlatRegion( pSfrCurr)) ;
if ( IsNull( pSfrNoExtension) ||
! ModifySurfByOpenEdges( pSfrCurr, pSfrLimit))
return false ;
// controllo se la superficie deriva da una lavorazione precedente
if ( ! GetNewSfrByAnotherPocketing( pSfrCurr, pSfrNoExtension, pStmVol, pSfrLimit))
return false ;
// inserisco la superficie nel vettore
vSrfSliced.emplace_back( Release( pSfrCurr)) ;
@@ -2365,11 +2370,6 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa
vbChangedPrec[j-1] = true ;
// ...
// controllo se la superficie deriva da una lavorazione precedente
// ... W.I.P
// ...
// ...
// porto la regione limite nel piano Z = 0
if ( pSfrLimit->IsValid())
pSfrLimit->Translate( -vVtTrasl[j-1]) ;
@@ -2379,6 +2379,138 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa
return true ;
}
//----------------------------------------------------------------------------
bool
Pocketing::GetNewSfrByAnotherPocketing( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrNoExtendedByOpenEdges,
const ISurfTriMesh* pStmVol, const ISurfFlatRegion* pSfrLimit)
{
// se non ho una lavorazione precedente o non ho nulla da svuotare, esco
if ( m_dDiam_Prec < EPS_SMALL || ! pSfrPock->IsValid() || ! pSfrNoExtendedByOpenEdges->IsValid())
return true ;
// controllo effettivamente che il nuovo utensile possa svuotare qualcosa nella nuova lavorazione
if ( 0.5 * m_TParams.m_dDiam + GetOffsR() > 0.5 * m_dDiam_Prec + m_dOffsetR_Prec)
return true ;
int o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmVol->Clone()) ;
o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrPock->Clone()) ;
m_pGeomDB->SetMaterial( o, GREEN) ;
// effettuo un Offset verso l'interno ( curve esterne che percorre il centro del Tool)
double dInsideOffs = - 0.5 * m_dDiam_Prec - 0.5 * m_dOffsetR_Prec - 5 * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrToolPath( pSfrPock->CreateOffsetSurf( dInsideOffs, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrToolPath)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
if ( ! pSfrToolPath->IsValid())
return true ;
// effettuo un Offset del raggio del tool precedente per ricavare la regione svuotata in precedenza
double dOutSideOffset = 0.5 * m_dDiam_Prec / 2 + 20 * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrRemoved( pSfrToolPath->CreateOffsetSurf( dOutSideOffset, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrRemoved)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrRemoved->Clone()) ;
m_pGeomDB->SetMaterial( o, PURPLE) ;
// definisco la regione vera a propria da svuotare con il tool attuale
PtrOwner<ISurfFlatRegion> pSfrAct( CloneSurfFlatRegion( pSfrNoExtendedByOpenEdges)) ;
if ( IsNull( pSfrAct) ||
! pSfrAct->Subtract( *pSfrRemoved))
return false ;
o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrAct->Clone()) ;
m_pGeomDB->SetMaterial( o, BLACK) ;
// Questa superficie presenterà diversi Chunks... per ognuno di essi ricavo le properità di lato aperto o chiuso
// NB. Questa supericie non dovrebbe avere isole...
// Posso richiamare la funzione ChooseCloseOrOpenEdge()
// alzo leggermente la supericie per l'ultimi step
pSfrAct->Translate( Z_AX * 50 * EPS_SMALL) ;
if ( ! ChooseCloseOrOpenEdge( pSfrAct, pStmVol))
return false ;
pSfrAct->Translate( - Z_AX * 50 * EPS_SMALL) ;
// Questa funzione ha modificato le TmpProp dei Loops della pSfrAct e le temp prop sono invertite ;
// I lati con tmp prop = 1 sono chiusi, mentre quelli con tmpProp = 0 sono aperti
// modifico il Loop esterno di Ogni chunk della regione, estendendolo presso i lati aperti
// creo quindi una nuova superficie con questi Loops
SurfFlatRegionByContours sfrBC ;
for ( int c = 0 ; c < pSfrAct->GetChunkCount() ; ++ c) {
// ricavo il Loop esterno
PtrOwner<ICurveComposite> pCrvEL( ConvertCurveToComposite( pSfrAct->GetLoop( c, 0))) ;
if ( IsNull( pCrvEL) || ! pCrvEL->IsValid())
return false ;
// inverto le Tmp Props
for ( int u = 0 ; u < pCrvEL->GetCurveCount() ; ++ u)
pCrvEL->SetCurveTempProp( u, pCrvEL->GetCurve( u)->GetTempProp( 0) == 0 ? 1 : 0, 0) ;
// ricavo le isole
ICRVCOMPOPOVECTOR vCrvIsl ;
for ( int l = 1 ; l < pSfrAct->GetLoopCount( c) ; ++ l)
vCrvIsl.emplace_back( ConvertCurveToComposite( pSfrAct->GetLoop( c, l))) ;
// inverto le temp props per le isole trovate
for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i)
for ( int u = 0 ; u < vCrvIsl[i]->GetCurveCount() ; ++ u)
vCrvIsl[i]->SetCurveTempProp( u, vCrvIsl[i]->GetCurve( u)->GetTempProp( 0) == 0 ? 1 : 0, 0) ;
// estendo il loop esterno presso i lati nuovi lati aperti
if ( ! AdjustContourWithOpenEdges( pCrvEL, vCrvIsl, m_TParams.m_dDiam, GetOffsR(), GetSideStep(), pSfrLimit)) {
m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ;
return false ;
}
ICRVCOMPOPOVECTOR vCrvNULL ;
for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i) {
if ( ! AdjustContourWithOpenEdges( vCrvIsl[i], vCrvNULL, m_TParams.m_dDiam, GetOffsR(), GetSideStep(), pSfrLimit)) {
m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ;
return false ;
}
}
for ( int u = 0 ; u < pCrvEL->GetCurveCount() ; ++ u) {
int nProp0 ; pCrvEL->GetCurveTempProp( u, nProp0, 0) ;
int nProp1 ; pCrvEL->GetCurveTempProp( u, nProp1, 1) ;
int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvEL->GetCurve( u)->Clone()) ;
m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
}
for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i) {
for ( int u = 0 ; u < vCrvIsl[i]->GetCurveCount() ; ++ u) {
int nProp0 ; vCrvIsl[i]->GetCurveTempProp( u, nProp0, 0) ;
int nProp1 ; vCrvIsl[i]->GetCurveTempProp( u, nProp1, 1) ;
int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvIsl[i]->GetCurve( u)->Clone()) ;
m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
}
}
// avendo i lati aperti, devo stare attento alle entrate... per sicurezza li imposto tutti come chiusi ( per ora..)
for ( int u = 0 ; u < pCrvEL->GetCurveCount() ; ++ u)
pCrvEL->SetCurveTempProp( u, 0, 0) ;
for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i)
for ( int u = 0 ; u < vCrvIsl[i]->GetCurveCount() ; ++ u)
vCrvIsl[i]->SetCurveTempProp( u, 0, 0) ;
// aggiungo il Loop esterno e le isole
sfrBC.AddCurve( Release( pCrvEL)) ;
for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i)
sfrBC.AddCurve( Release( vCrvIsl[i])) ;
}
// ricavo la nuova superfcicie con i Loops modificati
PtrOwner<ISurfFlatRegion> pSfrFinal( sfrBC.GetSurf()) ;
if ( IsNull( pSfrFinal) || ! pSfrFinal->IsValid())
return false ;
// sostituisco ed esco
pSfrPock->Clear() ;
pSfrPock->CopyFrom( pSfrFinal) ;
return pSfrPock != nullptr && pSfrPock->IsValid() ;
}
//----------------------------------------------------------------------------
bool
Pocketing::SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlane)
@@ -2718,6 +2850,7 @@ Pocketing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pSt
// per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti.
// se tali punti risultano TUTTI non interni alla Part, allora il lato viene considerato aperto
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO DENTRO AL FINITO "
// NB. Aggiungendo delle aree proiettando le parti aperte del volume di Pocketing, alcuni tratti possono risultare
// in parte interni ed in parte esterni alla Part... ( questi lati rimangono chiusi, infatti lasciandoli aperti
// rischierei di rovinare la part al di fuori del volume di svuotatura.
@@ -2810,6 +2943,10 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion*
// I lati aperti vanno estesi seguendo lo geometria dei lati chiusi adiacenti e tenendo conto delle isole chiuse
// vicine ad essi
// NB. Se ho una lavorazione precedente, allora estendo i lati aperti delle quantità relative alla lavorazione
// precedente ( l'attuale infatti svuoterà quello che rimane da svuotare proprio da questa lavorazione)
// Vedi GetNewSfrByAnotherPocketing()
// creo la superifcie da restituire... ( questa superficie sarà estesa presso i lati aperti)
PtrOwner<ISurfFlatRegion> pSrfFinal( CreateSurfFlatRegion()) ;
if ( IsNull( pSrfFinal))
@@ -2865,7 +3002,7 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion*
bSomeOpen = true ;
}
if ( bSomeOpen) { // se trovo dei lati aperti ...
// 4.1) se l'isola è tutta aperta e "trascurabile" la talgo
// 4.1) se l'isola è tutta aperta e "trascurabile" la tolgo
bool bRemove = false ;
if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam,
bRemove))
@@ -2935,126 +3072,129 @@ bool
Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad,
double& dElev) const
{
// inizializzo l'elevazione
dElev = 0 ;
// affondamento come vettore
Vector3d vtDepth = vtTool * dDepth ;
// Offsetto la curva della quantità stabvilità per la ricerca di proiezioni
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCompo, m_dMaxLenRawProj, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
PtrOwner<ICurveComposite> pCompoExtended( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
if ( IsNull( pCompoExtended) || ! pCompoExtended->IsValid())
return false ;
// DA ADATTARE !
// Campiono il contorno
int nMaxInd = pCompoExtended->GetCurveCount() - 1 ;
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
// curva corrente
const ICurve* pCrvC = pCompoExtended->GetCurve( i) ;
Point3d ptStart ; pCrvC->GetStartPoint( ptStart) ;
Point3d ptMid ; pCrvC->GetMidPoint( ptMid) ;
Point3d ptEnd ; pCrvC->GetEndPoint( ptEnd) ;
// elevazione della curva
double dCurrElev ;
if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) {
if ( dCurrElev > dElev)
dElev = dCurrElev ;
}
else {
m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
return false ;
}
}
//// inizializzo l'elevazione
// dElev = 0 ;
//// affondamento come vettore
// Vector3d vtDepth = vtTool * dDepth ;
// Campiono l'interno con una griglia (uso linee parallele a X)
// determino il riferimento di base
Frame3d frPocket ;
Point3d ptCen ; pCompoExtended->GetCentroid( ptCen) ;
frPocket.Set( ptCen, vtTool) ;
// copio il contorno e lo porto nel riferimento
PtrOwner<ICurveComposite> pCompoL( pCompoExtended->Clone()) ;
if ( IsNull( pCompoL) || ! pCompoL->ToLoc( frPocket)) {
m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
return false ;
}
// ingombro del contorno in locale
BBox3d b3Pocket ;
pCompoL->GetLocalBBox( b3Pocket) ;
Point3d ptMin ; double dDimX, dDimY, dDimZ ;
b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
//// Offsetto la curva della quantità stabvilità per la ricerca di proiezioni
// OffsetCurve OffsCrv ;
// if ( ! OffsCrv.Make( pCompo, m_dMaxLenRawProj, ICurve::OFF_FILLET)) {
// m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
// return false ;
// }
// PtrOwner<ICurveComposite> pCompoExtended( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
// if ( IsNull( pCompoExtended) || ! pCompoExtended->IsValid())
// return false ;
// passi in Y
const double STEP = m_TParams.m_dDiam ;
int nYStep = max( int( ceil( ( dDimY - 20 * EPS_SMALL) / STEP)), 2) ;
double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ;
// calcolo le linee di svuotatura
for ( int i = 1 ; i < nYStep ; ++ i) {
// definisco la linea
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
const double EXP_LEN = 1.0 ;
Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ;
if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) {
m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
return false ;
}
//// Campiono il contorno
// int nMaxInd = pCompoExtended->GetCurveCount() - 1 ;
// for ( int i = 0 ; i <= nMaxInd ; ++ i) {
// // curva corrente
// const ICurve* pCrvC = pCompoExtended->GetCurve( i) ;
// Point3d ptStart ; pCrvC->GetStartPoint( ptStart) ;
// Point3d ptMid ; pCrvC->GetMidPoint( ptMid) ;
// Point3d ptEnd ; pCrvC->GetEndPoint( ptEnd) ;
// // elevazione della curva
// double dCurrElev ;
// if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) {
// if ( dCurrElev > dElev)
// dElev = dCurrElev ;
// }
// else {
// m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
// return false ;
// }
// }
// calcolo la classificazione della curva rispetto al contorno
IntersCurveCurve intCC( *pLine, *pCompoL) ;
CRVCVECTOR ccClass ;
if ( intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) {
// determino gli intervalli di curva interni
Intervals inOk ;
for ( auto& ccOne : ccClass) {
if ( ccOne.nClass == CRVC_IN) {
// ricavo punto iniziale e finale
Point3d ptStart ;
pLine->GetPointD1D2( ccOne.dParS, ICurve::FROM_PLUS, ptStart) ;
Point3d ptEnd ;
pLine->GetPointD1D2( ccOne.dParE, ICurve::FROM_MINUS, ptEnd) ;
// calcolo la distanza tra questi due punti
double dDist = Dist( ptStart, ptEnd) ;
// il tratto interno lo campiono rispetto ad X
for ( int j = 0 ; j <= int( dDist / STEP) + 1 ; ++ j) {
Point3d ptCurr ;
pLine->GetPointD1D2( ccOne.dParS + j * ( ccOne.dParE - ccOne.dParS) / ( dDist / STEP + 1), ICurve::FROM_PLUS, ptCurr) ;
ptCurr.ToGlob( frPocket) ;
double dCurrElev ;
if ( GetElevation( m_nPhase, ptCurr - vtDepth, vtTool, dCurrElev)) {
if ( dCurrElev > dElev)
dElev = dCurrElev ;
}
else {
m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
return false ;
}
}
}
}
}
// altrimenti uso tutta la curva
else {
Point3d ptStart ;
pLine->GetStartPoint( ptStart) ;
ptStart.ToGlob( frPocket) ;
Point3d ptEnd ;
pLine->GetEndPoint( ptEnd) ;
ptEnd.ToGlob( frPocket) ;
// elevazione della curva
double dCurrElev ;
if ( GetElevation( m_nPhase, ptStart - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) {
if ( dCurrElev > dElev)
dElev = dCurrElev ;
}
else {
m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
return false ;
}
}
}
//// Campiono l'interno con una griglia (uso linee parallele a X)
//// determino il riferimento di base
// Frame3d frPocket ;
// Point3d ptCen ; pCompoExtended->GetCentroid( ptCen) ;
// frPocket.Set( ptCen, vtTool) ;
//// copio il contorno e lo porto nel riferimento
// PtrOwner<ICurveComposite> pCompoL( pCompoExtended->Clone()) ;
// if ( IsNull( pCompoL) || ! pCompoL->ToLoc( frPocket)) {
// m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
// return false ;
// }
//// ingombro del contorno in locale
// BBox3d b3Pocket ;
// pCompoL->GetLocalBBox( b3Pocket) ;
// Point3d ptMin ; double dDimX, dDimY, dDimZ ;
// b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
//// passi in Y
// const double STEP = m_TParams.m_dDiam ;
// int nYStep = max( int( ceil( ( dDimY - 20 * EPS_SMALL) / STEP)), 2) ;
// double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ;
//// calcolo le linee di svuotatura
// for ( int i = 1 ; i < nYStep ; ++ i) {
// // definisco la linea
// PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
// const double EXP_LEN = 1.0 ;
// Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ;
// if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) {
// m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
// return false ;
// }
// // calcolo la classificazione della curva rispetto al contorno
// IntersCurveCurve intCC( *pLine, *pCompoL) ;
// CRVCVECTOR ccClass ;
// if ( intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) {
// // determino gli intervalli di curva interni
// Intervals inOk ;
// for ( auto& ccOne : ccClass) {
// if ( ccOne.nClass == CRVC_IN) {
// // ricavo punto iniziale e finale
// Point3d ptStart ;
// pLine->GetPointD1D2( ccOne.dParS, ICurve::FROM_PLUS, ptStart) ;
// Point3d ptEnd ;
// pLine->GetPointD1D2( ccOne.dParE, ICurve::FROM_MINUS, ptEnd) ;
// // calcolo la distanza tra questi due punti
// double dDist = Dist( ptStart, ptEnd) ;
// // il tratto interno lo campiono rispetto ad X
// for ( int j = 0 ; j <= int( dDist / STEP) + 1 ; ++ j) {
// Point3d ptCurr ;
// pLine->GetPointD1D2( ccOne.dParS + j * ( ccOne.dParE - ccOne.dParS) / ( dDist / STEP + 1), ICurve::FROM_PLUS, ptCurr) ;
// ptCurr.ToGlob( frPocket) ;
// double dCurrElev ;
// if ( GetElevation( m_nPhase, ptCurr - vtDepth, vtTool, dCurrElev)) {
// if ( dCurrElev > dElev)
// dElev = dCurrElev ;
// }
// else {
// m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
// return false ;
// }
// }
// }
// }
// }
// // altrimenti uso tutta la curva
// else {
// Point3d ptStart ;
// pLine->GetStartPoint( ptStart) ;
// ptStart.ToGlob( frPocket) ;
// Point3d ptEnd ;
// pLine->GetEndPoint( ptEnd) ;
// ptEnd.ToGlob( frPocket) ;
// // elevazione della curva
// double dCurrElev ;
// if ( GetElevation( m_nPhase, ptStart - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) {
// if ( dCurrElev > dElev)
// dElev = dCurrElev ;
// }
// else {
// m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ;
// return false ;
// }
// }
// }
return true ;
}
@@ -4355,7 +4495,7 @@ Pocketing::CalcZigZagLink( ICurveComposite* pCrv1, ICurveComposite* pCrv2, ICurv
PtrOwner<ICurveComposite> pCrv_Seg1_Isl( CreateCurveComposite()) ; // curva unione di pSeg1 e pCrvLink smussata
pCrv_Seg1_Isl->AddCurve( pCrvH1->Clone()) ;
pCrv_Seg1_Isl->AddCurve( pCrvTempLink->Clone()) ;
ModifyCurveToSmoothed( pCrv_Seg1_Isl, dTollLeft, dTollRight) ;
ModifyCurveToSmoothed( pCrv_Seg1_Isl, dTollLeft, dTollRight, true) ;
// raccordo questa curva con pSeg2
double dUS_1IH, dUE_1IH, dToTLen ;
@@ -4366,7 +4506,7 @@ Pocketing::CalcZigZagLink( ICurveComposite* pCrv1, ICurveComposite* pCrv2, ICurv
PtrOwner<ICurveComposite> pCrv_smoothed( CreateCurveComposite()) ; // curva unione del primo smusso con pSeg2
pCrv_smoothed->AddCurve( pCrv_Seg1_Isl->Clone()) ;
pCrv_smoothed->AddCurve( pCrvH2->Clone()) ;
ModifyCurveToSmoothed( pCrv_smoothed, dTollLeft, dTollRight) ;
ModifyCurveToSmoothed( pCrv_smoothed, dTollLeft, dTollRight, true) ;
// recupero i parametri del nuovo collegamento che si è creato dallo smusso
pCrvH1->Clear() ;
@@ -4515,11 +4655,11 @@ Pocketing::OptimizedZigZag( ISurfFlatRegion* pSrf, const Vector3d& vtTool, doubl
}
// Offset per i bordi e percorsi a ZigZag
if ( ! pSfrZigZag->Offset( - dMyOffs, ICurve::OFF_FILLET)) {
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)) {
if ( ! pSfrForCrv->Offset( - dMyOffs , ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
}
@@ -6282,14 +6422,14 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
for ( int i = 0 ; i < int( vOffs.size()) ; ++i ) {
if ( i != 0)
ModifyCurveToSmoothed( vOffs[i], 0.01, 0.01) ;
ModifyCurveToSmoothed( vOffs[i], m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16, false) ;
vOffs[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
vOffsClosedCurves[i].Set( vOffs[i]->Clone()) ;
}
for ( int i = 0 ; i < int( vOffsFirstCurve.size()) ; ++ i) {
if ( i != 0)
ModifyCurveToSmoothed( vOffsFirstCurve[i], 0.01, 0.01) ;
ModifyCurveToSmoothed( vOffsFirstCurve[i], m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16, false) ;
vOffsFirstCurve[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
}
@@ -6353,7 +6493,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
PtrOwner<ICurveComposite> pOff_i1( CloneCurveComposite( vOffs[i + 1])) ;
// cerco di tagliare le curve, ottenendo il collegamento
// NB. se la curva di offset è la prima, non devo tagliarla, accorcio solo le successive ...
if ( ! CutCurveToConnect( vOffs[i], vOffs[i+1], vOffsClosedCurves, vOffsFirstCurve, pCrvTest, i == 0 ? 0 : 0.01)) {
if ( ! CutCurveToConnect( vOffs[i], vOffs[i+1], vOffsClosedCurves, vOffsFirstCurve, pCrvTest, i == 0 ? 0 : 0.01, 0.01, 2)) {
// se non sono riuscito, ritorno alla configurazione iniziale
PtrOwner<ICurveComposite> pCrvLink( CreateCurveComposite()) ;
Vector3d vS, vE ;
@@ -6478,11 +6618,11 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
//----------------------------------------------------------------------------
bool
Pocketing::ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightPer, double dLeftPer)
Pocketing::ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightLen, double dLeftLen, bool bAsParam)
{
// controllo parametri
if ( pCrv == nullptr)
if ( pCrv == nullptr || dLeftLen < EPS_SMALL || dRightLen < EPS_SMALL)
return false ;
ICURVEPOVECTOR vCrvStepsToFill ; // vettore delle Curve da raccordare (curve della composita)
@@ -6501,6 +6641,8 @@ Pocketing::ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightPer, doubl
// controllo se la curva è chiusa (nel caso inserisco nel vettore la prima curva due volte, all'inizio e alla fine)
if ( pCrv->IsClosed()) {
const ICurve* pMyCrvFirst = pCrv->GetFirstCurve() ;
if ( pMyCrvFirst == nullptr)
return false ;
vCrvStepsToFill.emplace_back( pMyCrvFirst->Clone()) ;
}
@@ -6518,14 +6660,25 @@ Pocketing::ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightPer, doubl
continue ;
}
// cerco i paramentri al dRightPer% e dLeftPer% della lunghezza della prima e della seconda curva ( per raccordarli )
double dU_cm_S = 0 ; double dULast1 = 1 ; double dULast2 = 1 ;
vCrvStepsToFill[i]->GetDomain( dU_cm_S, dULast1) ;
dUE_ref = ( 1 - dRightPer) * dULast1 ;
// ricavo i valori parametrici associati
double dLen_act ; vCrvStepsToFill[i]->GetLength( dLen_act) ;
double dLen_succ ; vCrvStepsToFill[i+1]->GetLength( dLen_succ) ;
double dUE_ref = 1. ;
if ( dLen_act > dLeftLen)
dUE_ref -= dLeftLen / dLen_act ;
double dUS_ref = 0. ;
if ( dLen_succ > dRightLen)
dUS_ref = dRightLen / dLen_succ ;
vCrvStepsToFill[i+1]->GetDomain( dU_cm_S, dULast2) ;
dUS_ref = dLeftPer * dULast2 ;
// se valori trattati come parametri...
if ( bAsParam) {
// ... cerco i parametri corrispondenti sulle due curve
double dU_cm_S = 0 ; double dULast1 = 1 ; double dULast2 = 1 ;
vCrvStepsToFill[i]->GetDomain( dU_cm_S, dULast1) ;
dUE_ref = ( 1 - dRightLen) * dULast1 ;
vCrvStepsToFill[i+1]->GetDomain( dU_cm_S, dULast2) ;
dUS_ref = dLeftLen * dULast2 ;
}
// prendo i punti sulle due curve rispetto a tali parametri
Point3d ptS, ptE ;
@@ -6559,11 +6712,11 @@ Pocketing::ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightPer, doubl
// se ho intersezioni tra archi o l'arco creato non è valido, allora provo altre nMaxTestForArcs volte a ricrearlo avvicinando i punti
while (( IsNull( pCrvArc) || IntersBTWArcs) && nIterForArcs < nMaxTestForArcs) {
dUE_ref = ( dULast1 + dUE_ref ) * 0.5 ;
dUE_ref = ( 1 + dUE_ref ) * 0.5 ;
dUS_ref = dUS_ref * 0.5 ;
if ( ! vCrvStepsToFill[i]->GetPointD1D2( dUE_ref, ICurve::FROM_PLUS, ptS)
|| ! vCrvStepsToFill[i+1]->GetPointD1D2( dUS_ref, ICurve::FROM_MINUS, ptE))
if ( ! vCrvStepsToFill[i]->GetPointD1D2( dUE_ref, ICurve::FROM_PLUS, ptS) ||
! vCrvStepsToFill[i+1]->GetPointD1D2( dUS_ref, ICurve::FROM_MINUS, ptE))
return false ;
dRadius = Dist( ptS, ptE) ;
@@ -6695,8 +6848,10 @@ Pocketing::CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, IC
return false ;
// Prendo i punti, i vettori tangenti e i parametri di essi per le curve
Point3d ptSS, ptSE, ptES, ptEE ; Vector3d vS, vE ; double dUSS, dUSE, dUES, dUEE, dLenS, dLenE ;
dUSS = 0; dUSE = 0;
Point3d ptSS, ptSE, ptES, ptEE ;
Vector3d vS, vE ;
double dUSS, dUSE, dUES, dUEE, dLenS, dLenE ;
dUSS = 0 ; dUSE = 0 ;
pCrvS->GetEndPoint( ptSE) ;
pCrvS->GetStartPoint( ptSS);
@@ -6712,13 +6867,12 @@ Pocketing::CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, IC
// se ho una curva di primo Offset allora non devo accorciarla ...
for ( int i = 0 ; i < int( vFirstOffset.size()) ; ++ i) {
if ( vFirstOffset[i]->IsPointOn( ptSS) && vFirstOffset[i]->IsPointOn( ptSE))
dLenPercS = 0 ;
dLenPercS = EPS_SMALL * 0.5 ;
if ( vFirstOffset[i]->IsPointOn( ptES) && vFirstOffset[i]->IsPointOn( ptEE))
dLenPercE = 0 ;
dLenPercE = EPS_SMALL * 0.5 ;
}
double dLStepS = dLenPercS * dLenS ;
double dLStepE = dLenPercE * dLenE ;
double dLStepS = dLenPercS < EPS_SMALL ? 0. : m_TParams.m_dDiam * 0.5 ;
double dLStepE = dLenPercE < EPS_SMALL ? 0. : m_TParams.m_dDiam * 0.5 ;
dLenE = 0 ;
// calcolo i possibili BiArchi tra le due curve
@@ -6735,7 +6889,7 @@ Pocketing::CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, IC
ptCrvFinal->Clear() ;
ptCrvFinal.Set( ptBiArc->Clone()) ;
if ( dLenPercE == 0 && dLenPercS == 0 )
if ( dLenPercE < EPS_SMALL && dLenPercS < EPS_SMALL)
break ;
// se il BiArco creato interseca le altre curve di Offset allora mi fermo...
@@ -7193,7 +7347,7 @@ Pocketing::GetNewCurvetWithCentroid( const ICurveComposite* pCrvH1, const ICurve
return false ;
double dUCrvS ;
ModifyCurveToSmoothed( pPath1, 0.075, 0.075) ;
ModifyCurveToSmoothed( pPath1, 0.075, 0.075, true) ;
if ( pPath1->IsClosed()) {
pPath1->GetParamAtPoint( ptCrvS, dUCrvS) ;
pPath1->ChangeStartPoint( dUCrvS) ;
@@ -7421,7 +7575,7 @@ Pocketing::ManageSmoothAndAutoInters( ICurveComposite* pCrv, ICurveComposite* pC
! pCrvTwoSeg->AddCurve( pLine1->Clone()))
return false ;
ModifyCurveToSmoothed( pCrvTwoSeg, 0.2, 0.2) ;
ModifyCurveToSmoothed( pCrvTwoSeg, 0.2, 0.2, true) ;
PtrOwner<ICurveComposite> ptNewCrv( CreateCurveComposite()) ;
if ( ptNewCrv->AddCurve( pPath1->Clone()) &&
@@ -7622,7 +7776,7 @@ Pocketing::RemoveExtraPartByMedialAxis( const ISurfFlatRegion* pChunkToCut, ICRV
}
// smusso la curva
ModifyCurveToSmoothed( pCrvMedAx, 0.025, 0.025) ;
ModifyCurveToSmoothed( pCrvMedAx, 0.025, 0.025, true) ;
// se curva valida la inserisco nel vettore, altrimenti forzo il centroide
if ( pCrvMedAx->IsValid())
vCrvCoMedAxi.emplace_back( pCrvMedAx->Clone()) ;
@@ -7956,7 +8110,7 @@ Pocketing::CalcBoundedSmootedLink( const Point3d& ptStart, const Vector3d& vtSta
}
}
ModifyCurveToSmoothed( pCompo, 0.05, 0.05) ;
ModifyCurveToSmoothed( pCompo, 0.05, 0.05, true) ;
pCrvLink->AddCurve( Release( pCompo)) ;
return true ;
@@ -9098,6 +9252,13 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE
return false ;
}
// controllo se la curva è un'isola
bool bIsIsland = false ;
double dArea ; Plane3d plCheck ;
if ( ! pCrvCompo->GetArea( plCheck, dArea))
return false ;
bIsIsland = AreSameVectorEpsilon( plCheck.GetVersN(), - Z_AX, 10 * EPS_SMALL) ;
// recupero la curva di bordo del lato aperto corrente
PtrOwner<ICurveComposite> pCrvNewBorder( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 0))) ;
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
@@ -9106,17 +9267,26 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE
for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u)
pCrvNewBorder->SetCurveTempProp( u, 1, 0) ;
// se la curva originale era tutta aperta, allora tengo solo il nuovo loop esterno della regione di incidenza
// se la curva originale era tutta aperta...
if ( bIsAllOpen) {
// pulisco la curva originale
pCrvBorder->Clear() ;
if ( bIsIsland) { // se isola inserisco il loop interno della regione
pCrvNewBorder.Set( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 1))) ;
if ( IsNull( pCrvNewBorder) || ! pCrvNewBorder->IsValid())
return false ;
// imposto la curva come tutta aperta ( gira come girava già l'isola)
for ( int u = 0 ; u < pCrvNewBorder->GetCurveCount() ; ++ u)
pCrvNewBorder->SetCurveTempProp( u, 1, 0) ;
}
// se bordo esterno inserisco il bordo esterno
return pCrvBorder->AddCurve( Release( pCrvNewBorder)) ;
}
// altrimenti la spezzo il loop della regione di incidenza nei punti iniziali e finali della curva aperta originale
Point3d ptStart ; pCrvBorder->GetStartPoint( ptStart) ;
Point3d ptEnd ; pCrvBorder->GetEndPoint( ptEnd) ;
double dUTrimS, dUTrimE ;;
double dUTrimS, dUTrimE ;
pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 300 * EPS_SMALL) ;
pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 300 * EPS_SMALL) ;
// pulisco la curva originale
@@ -9143,7 +9313,7 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad
PtrOwner<ISurfFlatRegion> pSfrInc_tmp( GetSurfFlatRegionFromFatCurve( pCrv->Clone(), dRad + EPS_SMALL, false, false)) ;
if ( IsNull( pSfrInc_tmp) || ! pSfrInc_tmp->IsValid())
return false ;
pSfrInc->CopyFrom( pSfrInc_tmp) ;
pSfrInc->CopyFrom( pSfrInc_tmp) ; // pSfrInc ha sempre normale Z_AX !
// La regione di incidenza non deve avere un bordo distante dRad dagli estremi del tratto aperto
// per questo motivo, creo due FlatRegion a rettangolo che andrò a sottrarre alla pSfrInc_tmp
+4 -11
View File
@@ -107,8 +107,10 @@ class Pocketing : public Machining
bool GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStmPart, const ISurfTriMesh* pStmVol, ISurfFlatRegion* pSfrProj) ;
bool CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, const ISurfFlatRegion* pSfrLimit,
ISurfFlatRegion* pSfrInc) ;
bool GetNewSfrByAnotherPocketing( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrNoExtendedByOpenEdges,
const ISurfTriMesh* pStmVol, const ISurfFlatRegion* pSfrLimit) ;
bool GetHomogeneousParts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCrvs) ;
bool ModifyCurveToSmoothed( ICurveComposite* pCrvOffset, double dRightPer, double dleftPer) ;
bool ModifyCurveToSmoothed( ICurveComposite* pCrv, double dRightLen, double dLeftLen, bool bAsParam) ;
bool OrderCurvesByLastPntOfPath( ICRVCOMPOPOVECTOR& vCrv, Point3d ptEnd, PNTVECTOR& vPtStart,
VCT3DVECTOR& vVtOut, BOOLVECTOR& vbMidOut) ;
bool SetBetterPtStartForSubChunks( ICurveComposite* pCrv0, const ISurfFlatRegion* pSrfToWork, Point3d& ptStart,
@@ -303,19 +305,10 @@ class Pocketing : public Machining
AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto
bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo
double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto
PtrOwner<ISurfTriMesh> m_pStmVolPocket ; // volume delle svuotatura
bool m_bIntersRaw = true ; // flag per intersezione con grezzo
bool m_bProjectRaw = true ; // flag di proiezione del grezzo
bool m_bHasShape = true ; // flag per presenza di geometria voluta
PtrOwner<ISurfTriMesh> m_pStmShape ; // puntatore alla superficie TriMesh da seguire
double m_dMaxLenRawProj = 100 ; // lunghezza massima per contatto di proiezione
bool m_bOptOffset = true ; // flag per ottimizzazione numero di Offset necessari
bool m_bOptOffsetCM = false ; // flag per ottimizzazione numero di Offset necessari con centroidi e medial Axis
bool m_bAssignFeed = false ; // flag per controllo della Feed
double m_dDiam_Prec = 0.0 ; // diametro utensile per precedente svuotatura
double m_dDiam_Prec = 50.0 ; // diametro utensile per precedente svuotatura
double m_dOffsetR_Prec = 0.0 ; // offset radiale della svuotatura precedente
double m_dSideStep_Prec = 0.0 ; // side Step della svuotatura precedente