EgtGeomKernel :

- In CalcPocketing, migliorati i percorsi Conformal.
This commit is contained in:
Riccardo Elitropi
2024-09-26 12:22:51 +02:00
parent dc070c4556
commit 4ffb7087bd
+224 -108
View File
@@ -6750,7 +6750,7 @@ GetSfrByOpenEdgeExtension( const ISurfFlatRegion* pSfrOrig, PocketParams& PockPa
//----------------------------------------------------------------------------
static bool
SmoothLinkByOffs( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, ICurveComposite* pCrvLink,
const PocketParams& PockParams, bool bSmoothLeft, bool bSmoothRight, double dSmoothPar, double dTol)
const PocketParams& PockParams, bool bFirstOffs0, bool bFirstOffs1, double dSmoothPar, double dTol)
{
// controllo dei parametri
@@ -6758,17 +6758,12 @@ SmoothLinkByOffs( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, ICurve
pCrvOffs1 == nullptr || ! pCrvOffs1->IsValid() ||
pCrvLink == nullptr || ! pCrvLink->IsValid())
return false ;
/*
- Data la curva di Link, come prima cosa aggiungo l'ultima curva dell'Offset precedente
e la prima curva dell'Offset successivo.
- Effettuo lo Smusso del Link
- Rimvuovo la prima e l'ultima curva del Link smussato ( Gli estremi del link non vengono
modificati durante l'operazione di smusso
*/
// curva precedente e successiva
PtrOwner<ICurve> pCrvBef( pCrvOffs0->GetLastCurve()->Clone()) ;
PtrOwner<ICurve> pCrvBef ;
if ( bFirstOffs0 && pCrvOffs0->IsClosed())
pCrvBef.Set( pCrvOffs0->GetFirstCurve()->Clone()) ;
else
pCrvBef.Set( pCrvOffs0->GetLastCurve()->Clone()) ;
PtrOwner<ICurve> pCrvAft( pCrvOffs1->GetFirstCurve()->Clone()) ;
if ( IsNull( pCrvBef) || IsNull( pCrvAft) ||
! pCrvBef->IsValid() || ! pCrvAft->IsValid())
@@ -6782,16 +6777,19 @@ SmoothLinkByOffs( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, ICurve
pCrvLink->RemoveFirstOrLastCurve( false) ;
pCrvLink->RemoveFirstOrLastCurve( true) ;
// modifico Offset0 per raccordarlo al nuovo Link
Point3d ptS ; pCrvLink->GetStartPoint( ptS) ;
double dUE ; pCrvOffs0->GetParamAtPoint( ptS, dUE, dTol) ;
if ( ! bSmoothLeft && pCrvOffs0->IsClosed())
pCrvOffs0->ChangeStartPoint( dUE) ;
else
if ( bFirstOffs0 && pCrvOffs0->IsClosed()) {
pCrvOffs0->AddCurve( pCrvLink->GetFirstCurve()->Clone()) ;
pCrvLink->RemoveFirstOrLastCurve( false) ;
}
else {
Point3d ptS ; pCrvLink->GetStartPoint( ptS) ;
double dUE ; pCrvOffs0->GetParamAtPoint( ptS, dUE, dTol) ;
pCrvOffs0->TrimEndAtParam( dUE) ;
}
// modifico Offset1 per raccordarlo al nuovo Link
Point3d ptE ; pCrvLink->GetEndPoint( ptE) ;
double dUS ; pCrvOffs1->GetParamAtPoint( ptE, dUS, dTol) ;
if ( ! bSmoothRight && pCrvOffs1->IsClosed())
if ( bFirstOffs1 && pCrvOffs1->IsClosed())
pCrvOffs1->ChangeStartPoint( dUS) ;
else
pCrvOffs1->TrimStartAtParam( dUS) ;
@@ -6849,7 +6847,7 @@ GetConformalLinkForOpenCrv( const ICurveComposite* pCrvOffs0, const ICurveCompos
//----------------------------------------------------------------------------
static bool
GetConformalLink( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, PocketParams& PockParams,
const ICRVCOMPOPOVECTOR& vCrvClassBorder, const ICRVCOMPOPOVECTOR& vCrvExtendedBorders,
const ICRVCOMPOPOVECTOR& vCrvClassBorder, const ICRVCOMPOPOVECTOR& vCrvExtendedBorders,
ICurveComposite* pCrvLink)
{
// controllo validità delle due curve di Offset
@@ -6870,7 +6868,7 @@ GetConformalLink( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, Pocket
return false ;
// smusso il Link raccordandolo
if ( pCrvLink->IsValid())
SmoothLinkByOffs( pCrvOffs0, pCrvOffs1, pCrvLink, PockParams, true, true, PockParams.dRad / 8., TOL) ;
SmoothLinkByOffs( pCrvOffs0, pCrvOffs1, pCrvLink, PockParams, false, false, PockParams.dRad / 8., TOL) ;
}
else {
// clono le due curve di Offset
@@ -6905,7 +6903,7 @@ GetConformalLink( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, Pocket
return false ;
}
PockParams.bSmooth = bSmooth ;
SmoothLinkByOffs( pCrvOffs0, pCrvOffs1, pCrvLink, PockParams, ! bFirstIterOffs0, ! bFirstIterOffs1,
SmoothLinkByOffs( pCrvOffs0, pCrvOffs1, pCrvLink, PockParams, bFirstIterOffs0, bFirstIterOffs1,
PockParams.dRad / 16., TOL) ;
// per sicurezza aggiorno i nuovi punti e i nuovi parametri
double dUNewE ;
@@ -7302,47 +7300,9 @@ ModifyConformalStartPoint( ICurveComposite* pCrvFirst, const PocketParams& PockP
//----------------------------------------------------------------------------
static bool
CalcConformalOneWayOffs( VICRVCOMPOPOVECTOR& vvCrvOffs, const PocketParams& PockParams,
const ISurfFlatRegion* pSfrPock, ICRVCOMPOPOVECTOR& vCrvOffs)
{
// pulizia del vettore degli Offset
vCrvOffs.clear() ;
// inverto il vettore degli Offset, in modo da partire dalle curve più distanti dai chiusi
reverse( vvCrvOffs.begin(), vvCrvOffs.end()) ;
// determino il punto iniziale della prima curva di Offset
if ( ! ModifyConformalStartPoint( vvCrvOffs[0][0], PockParams, pSfrPock))
return false ;
// le curve di Offset vengono riodinate in base alla loro iterazione nel vettore
for ( int i = 0 ; i < int( vvCrvOffs.size()) ; ++ i) {
for ( int j = 0 ; j < int( vvCrvOffs[i].size()) ; ++ j) {
// se la curva corrente è chiusa, cambio il punto iniziale rispetto alla curva precedente
if ( vvCrvOffs[i][j]->IsClosed()) {
if ( ! vCrvOffs.empty()) {
// ricavo il punto finale della curva precedente
Point3d ptEndPrec ; vCrvOffs.back()->GetEndPoint( ptEndPrec) ;
DistPointCurve DistPtCrv( ptEndPrec, *vvCrvOffs[i][j]) ;
double dParS ;
int nFlag ;
// cambio il punto inziale della curva corrente
if ( DistPtCrv.GetParamAtMinDistPoint( 0, dParS, nFlag))
vvCrvOffs[i][j]->ChangeStartPoint( dParS) ;
}
}
vCrvOffs.emplace_back( Release( vvCrvOffs[i][j])) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
static bool
CalcConformalZigZagOffsAndLinks( VICRVCOMPOPOVECTOR& vvCrvOffs, const ISurfFlatRegion* pSfrChunk,
const ISurfFlatRegion* pSfrClass, PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvOffs,
ICURVEPOVECTOR& vCrvLink)
CalcConformalOffsAndLinks( VICRVCOMPOPOVECTOR& vvCrvOffs, const ISurfFlatRegion* pSfrChunk,
const ISurfFlatRegion* pSfrClass, PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvOffs,
ICURVEPOVECTOR& vCrvLink)
{
// controllo dei parametri
if ( pSfrChunk == nullptr || ! pSfrChunk->IsValid() ||
@@ -7373,21 +7333,21 @@ CalcConformalZigZagOffsAndLinks( VICRVCOMPOPOVECTOR& vvCrvOffs, const ISurfFlatR
if ( ! ModifyConformalStartPoint( vvCrvOffs[0][0], PockParams, pSfrChunk))
return false ;
/* NB.
I link che collegano due curve di Offset aperte devono partire dalla prima e, seguendo il
bordo della regione di classificazione ( pSfrClass) arrivano alla seconda.
*/
ICRVCOMPOPOVECTOR vCrvSfrClass ;
if ( ! GetSfrCrvCompoLoops( pSfrClass, vCrvSfrClass))
return false ;
/* NB.
I link che collegano due curve di Offset chiuse tra di loro vengono calcolati esattamente
come per i percorsi SPIRAL, pertanto devo definire un insieme di curve di primo Offset sui
quali smussare i Link per evitare di uscire dalla regione di svuotatura
*/
ICRVCOMPOPOVECTOR vCrvSfrExtended ;
if ( ! GetConformalBordersCrvs( pSfrChunk, PockParams, vCrvSfrExtended))
return false ;
/* NB.
I link che collegano due curve di Offset aperte devono partire dalla prima e, seguendo il
bordo della regione di classificazione ( pSfrClass) arrivano alla seconda.
*/
ICRVCOMPOPOVECTOR vCrvSfrClass ;
if ( ! GetSfrCrvCompoLoops( pSfrClass, vCrvSfrClass))
return false ;
/* NB.
I link che collegano due curve di Offset chiuse tra di loro vengono calcolati esattamente
come per i percorsi SPIRAL, pertanto devo definire un insieme di curve di primo Offset sui
quali smussare i Link per evitare di uscire dalla regione di svuotatura
*/
ICRVCOMPOPOVECTOR vCrvSfrExtended ;
if ( ! GetConformalBordersCrvs( pSfrChunk, PockParams, vCrvSfrExtended))
return false ;
/* NB.
Se POCKET_CONFORMAL_ZIGZAG :
- vCrvCompoOffs contiene gli Offset ordinati
@@ -7425,25 +7385,29 @@ CalcConformalZigZagOffsAndLinks( VICRVCOMPOPOVECTOR& vvCrvOffs, const ISurfFlatR
return true ;
// ------------ Definisco i Link ------------
// per definizione il primo Link è nullo
vCrvLink.resize( 1) ;
// scorro le curve di Offset a coppie
for ( int i = 0 ; i < int( vCrvOffs.size()) - 1 ; ++ i) {
// controllo se bisogna calcolare il Link tra i due Offset
bool bCalcLink = true ;
if ( ! CheckConformalRetractLink( vCrvOffs[i], vCrvOffs[i+1], vCrvSfrClass, PockParams, bCalcLink))
return false ;
if ( bCalcLink) {
// se link da calcolare, lo ricavo
PtrOwner<ICurveComposite> pCrvLink( CreateCurveComposite()) ;
if ( IsNull( pCrvLink) ||
! GetConformalLink( vCrvOffs[i], vCrvOffs[i+1], PockParams, vCrvSfrClass, vCrvSfrExtended, pCrvLink))
return false ;
// lo salvo nel vettore dei Link
vCrvLink.emplace_back( Release( pCrvLink)) ;
if ( PockParams.nType == POCKET_CONFORMAL_ONEWAY)
vCrvLink.resize( vCrvOffs.size()) ;
else {
// per definizione il primo Link è nullo
vCrvLink.resize( 1) ;
// scorro le curve di Offset a coppie
for ( int i = 0 ; i < int( vCrvOffs.size()) - 1 ; ++ i) {
// controllo se bisogna calcolare il Link tra i due Offset
bool bCalcLink = true ;
if ( ! CheckConformalRetractLink( vCrvOffs[i], vCrvOffs[i+1], vCrvSfrClass, PockParams, bCalcLink))
return false ;
if ( bCalcLink) {
// se link da calcolare, lo ricavo
PtrOwner<ICurveComposite> pCrvLink( CreateCurveComposite()) ;
if ( IsNull( pCrvLink) ||
! GetConformalLink( vCrvOffs[i], vCrvOffs[i+1], PockParams, vCrvSfrClass, vCrvSfrExtended, pCrvLink))
return false ;
// lo salvo nel vettore dei Link
vCrvLink.emplace_back( Release( pCrvLink)) ;
}
else
vCrvLink.resize( int( vCrvLink.size()) + 1) ;
}
else
vCrvLink.resize( int( vCrvLink.size()) + 1) ;
}
return true ;
@@ -7590,6 +7554,166 @@ AddLeadInToCurveConformalPaths( const ISurfFlatRegion* pSfrOrig, const ISurfFlat
return true ;
}
//----------------------------------------------------------------------------
static bool
OrderConformalPaths( ICRVCOMPOPOVECTOR& vCrvPaths, const ISurfFlatRegion* pSfrChunk, const ISurfFlatRegion* pSfrOrig,
PocketParams& PockParams)
{
// controllo dei parametri
if ( pSfrChunk == nullptr || ! pSfrChunk->IsValid() ||
pSfrOrig == nullptr || ! pSfrOrig->IsValid())
return false ;
if ( int( vCrvPaths.size()) < 2)
return true ;
// superficie di controllo per parti isolate
PtrOwner<ISurfFlatRegion> pSfrToRemove( CloneSurfFlatRegion( pSfrChunk)) ;
if ( IsNull( pSfrToRemove) || ! pSfrToRemove->IsValid() ||
! pSfrToRemove->Intersect( *pSfrOrig))
return false ;
// creo le regioni piane di svuotatura dei percorsi
ISURFFRPOVECTOR vSfrRemoved ; vSfrRemoved.resize( vCrvPaths.size()) ;
for ( int i = 0 ; i < int( vCrvPaths.size()) ; ++ i) {
// creo la regione di svuotatura di tale percorso
vSfrRemoved[i].Set( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( vCrvPaths[i]), PockParams.dRad, false, false)) ;
if ( IsNull( vSfrRemoved[i]) || ! vSfrRemoved[i]->IsValid())
return false ;
}
// scorro i percorsi ricavati
INTVECTOR vInds ; vInds.resize( vCrvPaths.size(), -1) ;
int nChunkRef = pSfrToRemove->GetChunkCount() ;
for ( int i = 0 ; i < int( vInds.size()) ; ++ i) {
int j = 0 ;
INTVECTOR vTempInds ;
for ( ; j < int( vCrvPaths.size()) ; ++ j) {
// se indice già presente
if ( find( vInds.begin(), vInds.end(), j) != vInds.end())
continue ;
// se sottraendo questa regione a quella originale ottengo più isole, allora non è il percorso ideale
PtrOwner<ISurfFlatRegion> pSfrRemain( CloneSurfFlatRegion( pSfrToRemove)) ;
if ( IsNull( pSfrRemain) || ! pSfrRemain->IsValid())
continue ;
pSfrRemain->Subtract( *vSfrRemoved[j]) ;
// se aumento il numero di Chunk, allora non è il percorso ideale
if ( pSfrRemain->GetChunkCount() > nChunkRef)
continue ;
vTempInds.push_back( j) ;
}
if ( vTempInds.empty()) {
// se non ho trovato curva candidate, prendo l'indice disponibile più basso
for ( int k = 0 ; k < int( vInds.size()) ; ++ k) {
if ( find( vInds.begin(), vInds.end(), k) != vInds.end())
continue ;
vInds[i] = k ;
break ;
}
}
else if ( int( vTempInds.size()) == 1) {
// se la candidata è singola, allora è lei
vInds[i] = vTempInds[0] ;
if ( PockParams.nType == POCKET_CONFORMAL_ONEWAY) {
if ( vCrvPaths[vInds[i]]->IsClosed() && i > 0) {
Point3d ptS ; vCrvPaths[vInds[i-1]]->GetStartPoint( ptS) ;
DistPointCurve DistCalculator( ptS, *vCrvPaths[vInds[i]]) ;
int nFlag ; double dUS ;
DistCalculator.GetParamAtMinDistPoint( 0, dUS, nFlag) ;
vCrvPaths[vInds[i]]->ChangeStartPoint( dUS) ;
}
}
}
else {
// se lavorazione conformal ZigZag
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG) {
// se ne ho trovate di più, allora euristicamente prendo la più corta
double dMinLen = INFINITO ;
for ( int k = 0 ; k < int( vTempInds.size()) ; ++ k) {
// privilegio le aperte
if ( vCrvPaths[vTempInds[k]]->IsClosed())
continue ;
double dLen ; vCrvPaths[vTempInds[k]]->GetLength( dLen) ;
if ( dLen < dMinLen) {
dMinLen = dLen ;
vInds[i] = vTempInds[k] ;
}
}
// cerco solo tra le chiuse se non ho aperte
if ( dMinLen > INFINITO - 1) {
for ( int k = 0 ; k < int( vTempInds.size()) ; ++ k) {
if ( vCrvPaths[vTempInds[k]]->IsClosed()) {
double dLen ; vCrvPaths[vTempInds[k]]->GetLength( dLen) ;
if ( dLen < dMinLen) {
dMinLen = dLen ;
vInds[i] = vTempInds[k] ;
}
}
}
}
}
// se lavorazione conformal OneWay
else {
// se ne ho trovate di più, cerco euristicamente la più vicina al punto iniziale della curva
// se prima in assoluto, allora prendo la più corta
if ( i == 0) {
double dMinLen = INFINITO ;
for ( int k = 0 ; k < int( vTempInds.size()) ; ++ k) {
double dLen ; vCrvPaths[vTempInds[k]]->GetLength( dLen) ;
if ( dLen < dMinLen) {
dMinLen = dLen ;
vInds[i] = vTempInds[k] ;
}
}
}
// altrimenti
else {
double dSqMinDist = INFINITO ;
Point3d ptS ; vCrvPaths[vInds[i-1]]->GetStartPoint( ptS) ;
Point3d ptTmpS ;
for ( int k = 0 ; k < int( vTempInds.size()) ; ++ k) {
if ( vCrvPaths[vTempInds[k]]->IsClosed())
continue ;
vCrvPaths[vTempInds[k]]->GetStartPoint( ptTmpS) ;
double dMyDist = SqDist( ptS, ptTmpS) ;
if ( dMyDist < dSqMinDist) {
dSqMinDist = dMyDist ;
vInds[i] = vTempInds[k] ;
}
}
if ( dSqMinDist > INFINITO - 1) {
for ( int k = 0 ; k < int( vTempInds.size()) ; ++ k) {
if ( vCrvPaths[vTempInds[k]]->IsClosed()) {
DistPointCurve DistCalculator( ptS, *vCrvPaths[vTempInds[k]]) ;
double dMySqDist ;
DistCalculator.GetSqDist( dMySqDist) ;
if ( dMySqDist < dSqMinDist) {
dSqMinDist = dMySqDist ;
vInds[i] = vTempInds[k] ;
double dUS ;
int nFlag ;
DistCalculator.GetParamAtMinDistPoint( 0, dUS, nFlag) ;
vCrvPaths[vTempInds[k]]->ChangeStartPoint( dUS) ;
}
}
}
}
}
}
}
// aggiorno la regione da svuotare e il numero di Chunk che si sono formati
pSfrToRemove->Subtract( *vSfrRemoved[vInds[i]]) ;
nChunkRef = pSfrToRemove->GetChunkCount() ;
}
// riordino i percorsi trovati
ICRVCOMPOPOVECTOR vCrvOrderedPaths ; vCrvOrderedPaths.resize( vCrvPaths.size()) ;
for ( int i = 0 ; i < int( vInds.size()) ; ++ i)
vCrvOrderedPaths[i].Set( vCrvPaths[vInds[i]]) ;
swap( vCrvOrderedPaths, vCrvPaths) ;
return true ;
}
//----------------------------------------------------------------------------
static bool
ChainConformalOffsWithLinks( ICRVCOMPOPOVECTOR& vCrvOffs, ICURVEPOVECTOR& vCrvLink,
@@ -8053,20 +8177,9 @@ AddConformal( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig,
// definisco vettore degli Offset e dei Link
ICRVCOMPOPOVECTOR vCrvOffs ;
ICURVEPOVECTOR vCrvLink ;
// se lavorazione CONFORMAL_ZIGZAG
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG) {
// ordino le curve di Offset e raccordo
if ( ! CalcConformalZigZagOffsAndLinks( vvCrvOffs, pSfrChunk, pSfrClassChunk, PockParams, vCrvOffs, vCrvLink))
return false ;
}
// se lavorazione CONFORMAL_ONEWAY
else if ( PockParams.nType == POCKET_CONFORMAL_ONEWAY) {
// ordino le curve di Offset
if ( ! CalcConformalOneWayOffs( vvCrvOffs, PockParams, pSfrChunk, vCrvOffs))
return false ;
// i Link non esistono
vCrvLink.resize( int( vCrvOffs.size())) ;
}
// ordino le curve di Offset e raccordo
if ( ! CalcConformalOffsAndLinks( vvCrvOffs, pSfrChunk, pSfrClassChunk, PockParams, vCrvOffs, vCrvLink))
return false ;
// estendo i percorsi per eventuali regioni non svuotate e calcolo le Feed
if ( ! ExtendConformalOffsAndSetFeed( pSfrPock, PockParams, vCrvOffs, vCrvLink))
return false ;
@@ -8077,6 +8190,9 @@ AddConformal( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig,
// estendo i percorsi per entrate/uscite dai lati aperti
if ( ! AddLeadInToCurveConformalPaths( pSfrOrig, pSfrChunk, PockParams, vCrvPaths))
return false ;
// ordino i percorsi trovati
if ( ! OrderConformalPaths( vCrvPaths, pSfrChunk, pSfrOrig, PockParams))
return false ;
// aggiungo i percorsi ricavati
for ( int i = 0 ; i < int( vCrvPaths.size()) ; ++ i)
vCrvCompoRes.emplace_back( Release( vCrvPaths[i])) ;