EgtGeomKernel :

- In CalcPocketing aggiunto controllo su Feed per lati aperti
- In CalcPocketing inizio stesura funzioni per Biarchi.
This commit is contained in:
Riccardo Elitropi
2025-05-20 17:28:05 +02:00
parent 4d9a50cf94
commit 21afe8165c
+203 -122
View File
@@ -76,6 +76,7 @@ struct PocketParams {
double dOpenEdgeRad = 0. ; // raggio effettivo di estensione degli aperti
} ;
static double TOL_TRAPEZOID = 50 * EPS_SMALL ; // tolleranza per casi a trapezio SpiralPocket
static double BIARC_MAX_LEN = 200. ; // massima lunghezza oltre la quale il biarco viene smussato
typedef vector<ICRVCOMPOPOVECTOR> VICRVCOMPOPOVECTOR ;
//---------------------------------------------------------------------------
@@ -389,29 +390,52 @@ CheckSimpleOverlap( const ICurve* pCrv, const ICurveComposite* pCrvOri, int& nSt
//----------------------------------------------------------------------------
static bool
AssignFeedForOpenEdge( ICurveComposite* pCrv, const ICurveComposite* pCrvOF_orig,
AssignFeedForOpenEdge( ICurveComposite* pCrv, const ISurfFlatRegion* pSfrOpenEdges,
const PocketParams& PockParams)
{
// NB. *pSfrOpenEdges deve essere una regione che all'esterno contiene i lati considerati aperti
// Solo ai tratti esterni vengono assegnate le Feed
// se non rischiesto il calcolo della Feed, lascio quella standard
if ( ! PockParams.bCalcFeed)
return AssignMaxFeed( pCrv, PockParams) ;
// controllo se qualche curva passa sopra ad un lato aperto...
if ( pCrvOF_orig != nullptr) {
for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) {
const ICurve* pCrv_u = pCrv->GetCurve( u) ;
if ( pCrv_u == nullptr)
return false ;
int nStat = -1 ;
if ( CheckSimpleOverlap( pCrv_u, pCrvOF_orig, nStat, 1500 * EPS_SMALL) && nStat == 1) {
double dFeed = GetMinFeed( PockParams) ;
GetFeedForParam( PockParams.dOpenEdgeRad, PockParams, dFeed) ;
pCrv->SetCurveTempParam( u, dFeed, 0) ;
// se non ho una regione di classificazione, non faccio nulla
if ( pSfrOpenEdges == nullptr || ! pSfrOpenEdges->IsValid())
return true ;
// classifico la curva in base alla regione
CRVCVECTOR ccClass ;
if ( pSfrOpenEdges->GetCurveClassification( *pCrv, EPS_SMALL, ccClass)) {
PtrOwner<ICurveComposite> pNewCrv( CreateCurveComposite()) ;
if ( IsNull( pNewCrv))
return false ;
for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) {
// recupero il tratto di curva corrente
PtrOwner<ICurveComposite> pCrvRange( ConvertCurveToComposite( pCrv->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ;
if ( ! IsNull( pCrvRange) && pCrvRange->IsValid()) {
// se il tratto non è interno, calcolo la sua Feed
if ( ccClass[i].nClass != CRVC_IN) {
double dFeed = GetMinFeed( PockParams) ;
GetFeedForParam( 2. * PockParams.dRad - PockParams.dOpenEdgeRad, PockParams, dFeed) ;
AssignCustomFeed( pCrvRange, PockParams, dFeed) ;
}
// aggiungo il tratto alla sottocurva
if ( ! pNewCrv->AddCurve( Release( pCrvRange)))
return false ;
}
}
// assegno la curva calcolata
pNewCrv->SetTempProp( pCrv->GetTempProp( 0), 0) ;
pNewCrv->SetTempProp( pCrv->GetTempProp( 1), 1) ;
pNewCrv->SetTempParam( pCrv->GetTempParam( 0), 0) ;
pNewCrv->SetTempParam( pCrv->GetTempParam( 0), 0) ;
double dThick ; pCrv->GetThickness( dThick) ;
pNewCrv->SetThickness( dThick) ;
Vector3d vtExtr ; pCrv->GetExtrusion( vtExtr) ;
pNewCrv->SetExtrusion( vtExtr) ;
pCrv->CopyFrom( pNewCrv) ;
}
else
AssignMaxFeed( pCrv, PockParams) ;
return true ;
}
@@ -516,7 +540,7 @@ SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam,
//----------------------------------------------------------------------------
static bool
AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, bool bIsLink,
bool bFirstOffs, const ICurveComposite* pCrv_orig, const PocketParams& PockParams,
bool bFirstOffs, const ISurfFlatRegion* pSfrOpenEdges, const PocketParams& PockParams,
double dToll)
{
// controllo la validità della curva
@@ -537,7 +561,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo
// se non ho una superificie svuotata, allora esco ( con Feed Minima)
if ( pSrfRemoved == nullptr || ! pSrfRemoved->IsValid() || pSrfRemoved->GetChunkCount() == 0) {
// controllo eventuali sovrapposizioni con lati aperti
return AssignFeedForOpenEdge( pCrv, pCrv_orig, PockParams) ;
return AssignFeedForOpenEdge( pCrv, pSfrOpenEdges, PockParams) ;
}
// parametro di Offset per regione svuotata ( restringo la superficie in maniera appropriata)
@@ -567,9 +591,8 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo
if ( IsNull( pCrv_sez))
continue ; // curva troppo piccola, passo alla successiva
// controllo se interno o fuori alla regione ( regolando quindi la Feed)
double dCurrFeed = GetMinFeed( PockParams) ;
if ( ccClass[i].nClass == CRVC_IN) // se interna alla regione rimossa...
dCurrFeed = GetMaxFeed( PockParams) ;
double dCurrFeed = ( ccClass[i].nClass == CRVC_IN ? GetMaxFeed( PockParams) :
GetMinFeed( PockParams)) ;
// assegno tale Feed ad ogni sottocurva ricavata dal tratto di classificazione
for ( int u = 0 ; u < pCrv_sez->GetCurveCount() ; ++ u)
pCrv_sez->SetCurveTempParam( u, dCurrFeed, 0) ;
@@ -581,13 +604,14 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo
pCrv->Clear() ;
pCrv->AddCurve( Release( pCrv_new)) ;
// cerco di uniformare i tratti ricavati
if ( ! bIsLink) { // ---------------- NEL CASO DI OFFSET ----------------
// creo un intervallo con tutte le Feed Minime
Intervals IntMinFeed ;
for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) {
double dParam ; pCrv->GetCurveTempParam( u, dParam, 0) ;
if ( abs( dParam - GetMinFeed( PockParams)) < 5 * EPS_SMALL)
IntMinFeed.Add( u, u + 1) ;
for ( int nU = 0 ; nU < pCrv->GetCurveCount() ; ++ nU) {
double dFeed ; pCrv->GetCurveTempParam( nU, dFeed, 0) ;
if ( abs( dFeed - GetMinFeed( PockParams)) < 5 * EPS_SMALL)
IntMinFeed.Add( nU, nU + 1) ;
}
double dParS = EPS_SMALL ; double dParE = EPS_SMALL ;
// a questo intervallo tolgo tutti i sottotratti di lunghezza inferiore alla tolleranza richiesta
@@ -600,13 +624,13 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo
IntMinFeed_noSmall.Add( dParS, dParE) ;
bFound = IntMinFeed.GetNext( dParS, dParE) ;
}
for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) {
if ( ! IntMinFeed_noSmall.IsInside( u + 0.5))
pCrv->SetCurveTempParam( u, GetMaxFeed( PockParams), 0) ;
for ( int nU = 0 ; nU < pCrv->GetCurveCount() ; ++ nU) {
if ( ! IntMinFeed_noSmall.IsInside( nU + 0.5))
pCrv->SetCurveTempParam( nU, GetMaxFeed( PockParams), 0) ;
}
}
else { // ---------------- NEL CASO DI LINK ----------------
// le curve con lunghezza < dToll vanno modificate
// le curve con lunghezza inferiore alla tolleranza vanno modificate
for ( int j = 0 ; j < pCrv->GetCurveCount() ; ++ j) {
double dLen = EPS_SMALL ;
pCrv->GetCurve( j)->GetLength( dLen) ;
@@ -646,8 +670,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved, boo
}
if ( bFirstOffs)
AssignFeedForOpenEdge( pCrv, pCrv_orig, PockParams) ;
AssignFeedForOpenEdge( pCrv, pSfrOpenEdges, PockParams) ;
return true ;
}
@@ -4664,7 +4687,7 @@ ModifyBiArc( ICurve* pBiArcLink, double dToll, ICurveComposite* pNewBiArc)
// controllo dei parametri
if ( pBiArcLink == nullptr)
return false ;
if ( dToll > 0.99 || dToll < 0.01)
if ( dToll > 1. - 10. * EPS_SMALL || dToll < 10. * EPS_SMALL)
return false ;
pNewBiArc->Clear() ;
@@ -4673,8 +4696,8 @@ ModifyBiArc( ICurve* pBiArcLink, double dToll, ICurveComposite* pNewBiArc)
pBiArcLink->GetDomain( dUS, dUE) ;
// prendo i due archi della curva BiArco
PtrOwner<ICurve> pArc1( pBiArcLink->CopyParamRange( dUS, ( dUS + dUE) / 2)) ;
PtrOwner<ICurve> pArc2( pBiArcLink->CopyParamRange(( dUS + dUE ) / 2, dUE)) ;
PtrOwner<ICurve> pArc1( pBiArcLink->CopyParamRange( dUS, ( dUS + dUE) / 2.)) ;
PtrOwner<ICurve> pArc2( pBiArcLink->CopyParamRange(( dUS + dUE ) / 2., dUE)) ;
if ( IsNull( pArc1) || ! pArc1->IsValid() || IsNull( pArc2) || ! pArc2->IsValid())
return false ;
@@ -4710,13 +4733,57 @@ ModifyBiArc( ICurve* pBiArcLink, double dToll, ICurveComposite* pNewBiArc)
return true ;
}
//------------------------------------------------------------------------------
static bool
CalcSpecialSmoothBiArc( const ICurveComposite* pCrvBiArc, const ICRVCOMPOPOVECTOR& vOffIslands,
const PocketParams& PockParams, ICurveComposite* pCrvLink)
{
// controllo della curva
if ( pCrvBiArc == nullptr || ! pCrvBiArc->IsValid() ||
pCrvLink == nullptr)
return false ;
pCrvLink->Clear() ;
// controllo che la lunghezza sia sufficiente
double dLen ; pCrvBiArc->GetLength( dLen) ;
if ( dLen < 2 * PockParams.dRad + 50 * EPS_SMALL)
return false ;
// costruisco il tratto lineare
double dULineS, dULineE ;
Point3d ptLineS, ptLineE ;
if ( ! pCrvBiArc->GetParamAtLength( PockParams.dRad, dULineS) ||
! pCrvBiArc->GetPointD1D2( dULineS, ICurve::FROM_MINUS, ptLineS) ||
! pCrvBiArc->GetParamAtLength( dLen - PockParams.dRad, dULineE) ||
! pCrvBiArc->GetPointD1D2( dULineE, ICurve::FROM_MINUS, ptLineE))
return false ;
// costruisco il collegamento lineare
PtrOwner<ICurveComposite> pLine( CreateCurveComposite()) ;
if ( IsNull( pLine) ||
! CalcBoundedLink( ptLineS, ptLineE, vOffIslands, pLine))
return false ;
// creo i due raccordi
PtrOwner<ICurve> pCrvStartJoint( pCrvBiArc->CopyParamRange( 0., dULineS)) ;
PtrOwner<ICurve> pCrvEndJoint( pCrvBiArc->CopyParamRange( dULineE, pCrvBiArc->GetCurveCount())) ;
if ( IsNull( pCrvStartJoint) || IsNull( pCrvEndJoint) ||
! pCrvStartJoint->IsValid() || ! pCrvEndJoint->IsValid())
return false ;
// definisco il BiArco speciale
if ( ! pCrvLink->AddCurve( Release( pCrvStartJoint)) ||
! pCrvLink->AddCurve( Release( pLine)) ||
! pCrvLink->AddCurve( Release( pCrvEndJoint)))
return false ;
// smusso
ModifyCurveToSmoothed( pCrvLink, PockParams, PockParams.dRad / 4., PockParams.dRad / 4., false) ;
return true ;
}
//------------------------------------------------------------------------------
static bool
CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd,
const Vector3d& vtEnd, double dParMeet, const ICRVCOMPOPOVECTOR& vOffIslands,
const PocketParams& PockParams, ICurveComposite* pCrvLink)
const PocketParams& PockParams, ICurveComposite* pCrvLink, bool& bSpecial)
{
// se senza smusso, ritorno tratto lineare
bSpecial = false ;
if ( ! PockParams.bSmooth)
return CalcBoundedLink( ptStart, ptEnd, vOffIslands, pCrvLink) ;
@@ -4739,10 +4806,10 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const
if ( IsNull( pBiArcLink))
return CalcBoundedLink( ptStart, ptEnd, vOffIslands, pCrvLink) ;
// se BiArco troppo grande allora lo modifico
double dLenBiArc ;
pBiArcLink->GetLength( dLenBiArc) ;
if ( dLenBiArc > 200) {
// se BiArco troppo grande allora lo modifico (ne tengo una copia per eventuale gestione speciale)
PtrOwner<ICurveComposite> pCrvBiArc_clone( ConvertCurveToComposite( pBiArcLink->Clone())) ;
double dLenBiArc ; pBiArcLink->GetLength( dLenBiArc) ;
if ( dLenBiArc > BIARC_MAX_LEN) {
PtrOwner<CurveComposite> pCrvNewBiArcS( CreateBasicCurveComposite()) ;
ModifyBiArc( pBiArcLink, 0.2, pCrvNewBiArcS) ;
pBiArcLink.Set( pCrvNewBiArcS) ;
@@ -4856,42 +4923,37 @@ CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, const ICRVCOM
pCrvLink->Clear() ;
// curva finale da restituire
PtrOwner<CurveComposite> ptCrvFinal( CreateBasicCurveComposite()) ;
if ( IsNull( ptCrvFinal))
PtrOwner<CurveComposite> pCrvFinal( CreateBasicCurveComposite()) ;
if ( IsNull( pCrvFinal))
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 ;
pCrvS->GetEndPoint( ptSE) ;
pCrvS->GetStartPoint( ptSS) ;
pCrvE->GetStartPoint( ptES) ;
pCrvE->GetEndPoint( ptEE) ;
pCrvS->GetEndDir( vS) ;
pCrvE->GetStartDir( vE) ;
pCrvS->GetDomain( dUSS, dUSE) ;
pCrvE->GetDomain( dUES, dUEE) ;
pCrvS->GetLength( dLenS) ;
pCrvE->GetLength( dLenE) ;
// recupero gli estremi delle due curve ( S = Start, E = End)
Point3d ptSS ; pCrvS->GetStartPoint( ptSS) ;
Point3d ptSE ; pCrvS->GetEndPoint( ptSE) ;
Point3d ptES ; pCrvE->GetStartPoint( ptES) ;
Point3d ptEE ; pCrvE->GetEndPoint( ptEE) ;
// recupero i versori per il BiArco
Vector3d vS ; pCrvS->GetEndDir( vS) ;
Vector3d vE ; pCrvE->GetStartDir( vE) ;
// recupero i domini delle curve
double dUSS, dUSE ; pCrvS->GetDomain( dUSS, dUSE) ;
double dUES, dUEE ; pCrvE->GetDomain( dUES, dUEE) ;
// recupero le lunghezze delle curve
double dLenS ; pCrvS->GetLength( dLenS) ;
double dLenE ; pCrvE->GetLength( dLenE) ;
// se ho una curva di primo Offset allora non devo accorciarla ... ( si per bordi esterni che per isole)
// se ho una curva di primo Offset allora non devo accorciarla ( sia per bordi esterni che per isole)
for ( int i = 0 ; i < int( vFirstOffset.size()) ; ++ i) {
if ( vFirstOffset[i]->IsPointOn( ptSS) && vFirstOffset[i]->IsPointOn( ptSE))
dLenPercS = 0 ;
dLenPercS = 0. ;
if ( vFirstOffset[i]->IsPointOn( ptES) && vFirstOffset[i]->IsPointOn( ptEE))
dLenPercE = 0 ;
dLenPercE = 0. ;
}
double dLStepS = ( dLenPercS < EPS_SMALL ? 0. : PockParams.dRad) ;
double dLStepE = ( dLenPercE < EPS_SMALL ? 0. : PockParams.dRad) ;
dLenE = 0 ;
/*
calcolo il biArco tra il punto iniziale e finale dei due offset consecutivi
se richiesto lo smusso -> accorcio entrambi i tratti di Offset e, riuscendo, si sotituisce
il biArco calcolato prima con quest'ultimo
*/
// recupero il numero massimo di iterazioni per il calcolo del BiArco
int nMaxIter = 2 ;
if ( ! PockParams.bSmooth)
nMaxIter = 1 ;
@@ -4901,46 +4963,45 @@ CutCurveToConnect( ICurveComposite* pCrvS, ICurveComposite* pCrvE, const ICRVCOM
while ( nIter < nMaxIter) {
// calcolo il biArco
PtrOwner<CurveComposite> ptBiArc( CreateBasicCurveComposite()) ;
if ( ! CalcBoundedSmoothedLink( ptSE, vS, ptES, vE, 0.5, vFirstOffset, PockParams, ptBiArc) ||
ptBiArc->GetCurveCount() == 0)
bool bSpecial = false ;
PtrOwner<CurveComposite> pCrvBiArc( CreateBasicCurveComposite()) ;
if ( IsNull( pCrvBiArc) ||
! CalcBoundedSmoothedLink( ptSE, vS, ptES, vE, 0.5, vFirstOffset, PockParams, pCrvBiArc, bSpecial) ||
pCrvBiArc->GetCurveCount() == 0)
return false ;
pCrvFinal->Clear() ;
pCrvFinal.Set( pCrvBiArc->Clone()) ;
ptCrvFinal->Clear() ;
ptCrvFinal.Set( ptBiArc->Clone()) ;
if ( dLenPercE == 0 && dLenPercS == 0 )
// se non devo cercarne altri, allora tengo quest'ultimo
if ( dLenPercE == 0 && dLenPercS == 0 || bSpecial)
break ;
// se ho trovato un BiArco valido, allora accorcio le due curve di Offset
dLenS -= dLStepS ;
// altrimentik, calcolo un nuovo BiArco, estendendo i suoi estremi
#if 0 // nel caso volessi estendere anche prima del punto finale
dLenS -= dLStepS ;
#endif
dLenE += dLStepE ;
// ricalcolo il punto iniziale e finale
pCrvS->GetParamAtLength( dLenS, dUSE) ;
pCrvS->GetPointD1D2( dUSE, ICurve::FROM_MINUS, ptSE) ;
if ( ! pCrvS->GetPointD1D2( dUSE, ICurve::FROM_MINUS, ptSE, &vS))
return false ;
vS.Normalize() ;
pCrvE->GetParamAtLength( dLenE, dUES) ;
pCrvE->GetPointD1D2( dUES, ICurve::FROM_PLUS, ptES) ;
// ricalcolo il vettore tangente iniziale e finale
PtrOwner<ICurveComposite> pCrvS_clone( CloneCurveComposite( pCrvS)) ;
PtrOwner<ICurveComposite> pCrvE_clone( CloneCurveComposite( pCrvE)) ;
pCrvS_clone->ChangeStartPoint( dUSE) ;
pCrvE_clone->ChangeStartPoint( dUES) ;
pCrvS_clone->GetStartDir( vS) ;
pCrvE_clone->GetStartDir( vE) ;
if ( ! pCrvE->GetPointD1D2( dUES, ICurve::FROM_PLUS, ptES, &vE))
return false ;
vE.Normalize() ;
++ nIter ;
}
pCrvLink->AddCurve( Release( ptCrvFinal)) ; // ultimo arco valido trovato
pCrvLink->AddCurve( Release( pCrvFinal)) ; // ultimo arco valido trovato
return true ;
}
//----------------------------------------------------------
static bool
GetUnclearedRegionAndSetFeed( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks,
const ICurveComposite* pCrv_orig, const PocketParams& PockParams, ISurfFlatRegion* pSrfToCut)
const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, ISurfFlatRegion* pSrfToCut)
{
// controllo dei parametri
@@ -4948,7 +5009,10 @@ GetUnclearedRegionAndSetFeed( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR&
return false ;
pSrfToCut->Clear() ;
// 1) creo la regione esterna
// creo la regione esterna ( definita dalle curve di primo Offset)
// NB. Questa regione è diversa dalla pSfrOrig :
// - i tratti chiusi sono Offsettati di R + OffsR()
// - i tratti aperti sono stati estesi all'esterno
PtrOwner<ISurfFlatRegion> pSrfExtern( CreateSurfFlatRegion()) ;
if ( IsNull( pSrfExtern))
return false ;
@@ -4964,8 +5028,20 @@ GetUnclearedRegionAndSetFeed( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR&
}
}
// ---- le seguenti regioni sono distinte per calcolar emeglio la Feed ----
// Creo la regione svuotata dal Tool negli Offset, nei Links e sia dagli Offsets che dai Links
// 2) creo la regione che all'esterno contiene i lati aperti
// NB. Prendendo la superficie originale ( con lati Open/Close impostati), se effettuo un
// Offset interno dell'estensione degli aperti, tutto ciò che è all'esterno di tale regione è classificato
// come lato aperto
PtrOwner<ISurfFlatRegion> pSfrForOpenEdges( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrForOpenEdges))
return false ;
if ( pSfrOrig != nullptr && pSfrOrig->IsValid()) {
if ( ! pSfrForOpenEdges.Set( CloneSurfFlatRegion( pSfrOrig)) ||
! pSfrForOpenEdges->Offset( 1000 * EPS_SMALL, ICurve::OFF_FILLET))
return false ;
}
// definisco la regione rimossa dall'utensile
PtrOwner<ISurfFlatRegion> pSfrTool( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrTool))
return false ;
@@ -4983,11 +5059,15 @@ GetUnclearedRegionAndSetFeed( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR&
// Feed
bool bFirstOffs = false ;
Point3d ptStart ; vOffs[i]->GetStartPoint( ptStart) ;
for ( int j = 0 ; j < int( vFirstOffs.size()) && ! bFirstOffs ; ++ j)
bFirstOffs = vFirstOffs[j]->IsPointOn( ptStart, 100 * EPS_SMALL) ;
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG || PockParams.nType == POCKET_CONFORMAL_ONEWAY)
bFirstOffs = true ;
else {
Point3d ptStart ; vOffs[i]->GetStartPoint( ptStart) ;
for ( int j = 0 ; j < int( vFirstOffs.size()) && ! bFirstOffs ; ++ j)
bFirstOffs = vFirstOffs[j]->IsPointOn( ptStart, 100 * EPS_SMALL) ;
}
// calcolo gli intervalli di Feed per la curva di Offset
if ( ! AssignFeedSpiral( vOffs[i], pSfrTool, false, bFirstOffs, pCrv_orig, PockParams, 2 * PockParams.dRad / 3))
if ( ! AssignFeedSpiral( vOffs[i], pSfrTool, false, bFirstOffs, pSfrForOpenEdges, PockParams, 2 * PockParams.dRad / 3))
return false ;
// aggiorno la superificie svuotata
PtrOwner<ISurfFlatRegion> pSrfToolRegOffi( GetSurfFlatRegionFromFatCurve( vOffs[i]->Clone() , PockParams.dRad + 5 * EPS_SMALL, false, false)) ;
@@ -5013,7 +5093,7 @@ GetUnclearedRegionAndSetFeed( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR&
PtrOwner<ICurveComposite> pCrvLink( ConvertCurveToComposite( vLinks[nLink_Ind]->Clone())) ;
// calcolo gli intervalli di Feed per la curva di Link
if ( IsNull( pCrvLink) || ! pCrvLink->IsValid() ||
! AssignFeedSpiral( pCrvLink, pSfrTool, true, false, pCrv_orig, PockParams, 2 * PockParams.dRad / 3))
! AssignFeedSpiral( pCrvLink, pSfrTool, true, false, pSfrForOpenEdges, PockParams, 2 * PockParams.dRad / 3))
return false ;
// aggiorno la regione svuotata
PtrOwner<ISurfFlatRegion> pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( pCrvLink->Clone(), PockParams.dRad + 5 * EPS_SMALL, false, false)) ;
@@ -5235,9 +5315,10 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
}
// recupero le due direzioni per i Biarchi
bool bSameDir = AreSameVectorEpsilon( vt1, vt2, 2 * EPS_SMALL) ;
bool bSpecial = false ;
// se parallele, allora trasformo in una circonferenza
if ( bSameDir) {
if ( ! CalcBoundedSmoothedLink( ptMain, V_INVALID, ptCentroid, V_INVALID, 0., vOffsFirstCurve, PockParams, pCrvCurl))
if ( ! CalcBoundedSmoothedLink( ptMain, V_INVALID, ptCentroid, V_INVALID, 0., vOffsFirstCurve, PockParams, pCrvCurl, bSpecial))
continue ;
Vector3d vtStartCheck ; pCrvCurl->GetStartDir( vtStartCheck) ;
if ( AreOppositeVectorApprox( vtStartCheck, vt1))
@@ -5256,8 +5337,8 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
PtrOwner<ICurveComposite> pCrvBiArc1( CreateCurveComposite()) ;
PtrOwner<ICurveComposite> pCrvBiArc2( CreateCurveComposite()) ;
if ( IsNull( pCrvBiArc1) || IsNull( pCrvBiArc2) ||
! CalcBoundedSmoothedLink( ptMain, vt1, ptCentroid, vtDir, bSameDir ? 0. : 0.5, vOffsFirstCurve, PockParams, pCrvBiArc1) ||
! CalcBoundedSmoothedLink( ptCentroid, vtDir, ptMain, vt2, bSameDir ? 0. : 0.5, vOffsFirstCurve, PockParams, pCrvBiArc2))
! CalcBoundedSmoothedLink( ptMain, vt1, ptCentroid, vtDir, bSameDir ? 0. : 0.5, vOffsFirstCurve, PockParams, pCrvBiArc1, bSpecial) ||
! CalcBoundedSmoothedLink( ptCentroid, vtDir, ptMain, vt2, bSameDir ? 0. : 0.5, vOffsFirstCurve, PockParams, pCrvBiArc2, bSpecial))
continue ;
// aggiorno la curva a ricciolo
@@ -5282,6 +5363,7 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
// se la curva a ricciolo non svuota il Chunk nC-esimo -> percorro il bordo di tale Chunk
if ( pSfrChunk->IsValid() || pSfrChunk->GetChunkCount() > 0) {
// so che il punto più vicino alla curva è ptCloser
// ricavo dunque il punto più vicino sul bordo del Chunk nC-esimo
PtrOwner<ICurveComposite> pCompoChunkBorder( ConvertCurveToComposite( pSfrUncleared->GetLoop( nC, 0))) ;
@@ -5297,10 +5379,15 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
double dUS = 0. ;
pCompoChunkBorder->GetParamAtPoint( ptCloserOnChunk, dUS) ;
pCompoChunkBorder->ChangeStartPoint( dUS) ;
/*
Creo due curve composite rappresentanti un piccolo tratto tangente sulla curva di
Offset attuale; questi servono per la partenza e l'arrivo dei biArchi
*/
if ( bSameDir) {
pt1 = ptMain ;
pt2 = ptMain ;
}
PtrOwner<ICurveComposite> pCompoHelpS( CreateCurveComposite()) ;
if ( IsNull( pCompoHelpS) || ! pCompoHelpS->AddPoint( pt1 - vt1 / 4) ||
! vt1.Normalize() || ! pCompoHelpS->AddLine( pt1))
@@ -5309,6 +5396,7 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
if ( IsNull( pCompoHelpE) || ! pCompoHelpE->AddPoint( pt2) ||
! vt2.Normalize() || ! pCompoHelpE->AddLine( pt2 + vt2 / 4))
continue ;
/*
creo il Biarco iniziale
( nel caso non si riuscisse diventa un segmento lineare)
@@ -5330,6 +5418,7 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
// accorgio il bordo dell'Offset in raccordo al BiArco iniziale
if ( dMyU > EPS_SMALL)
pCompoChunkBorder->TrimStartAtParam( dMyU) ;
/*
creo il Biarco finale
( nel caso non si riuscisse diventa un segmento lineare)
@@ -5347,6 +5436,7 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
if ( ! pCrvBiArc2->GetStartPoint( ptMyPoint) ||
! pCompoChunkBorder->GetParamAtPoint( ptMyPoint, dMyU))
continue ;
// la curva a ricciolo ora diventa l'unione di pCrvBiArc1 - pCompoChunkBorder - pCrvBiArc2
pCrvCurl->Clear() ;
// smusso la curva di bordo del Chunk ( è aperta)
@@ -5372,12 +5462,7 @@ RemoveExtraParts( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& vOffs
continue ;
// aggiungo il tratto finale di Offset
pCrvTest->AddCurve( ConvertCurveToBasicComposite( pMyOffs->CopyParamRange( dURef2, pMyOffs->GetCurveCount()))) ;
// nel caso di direzioni parallele manca uno smusso
//if ( bSameDir) {
// double dSmoothPar = PockParams.dRad / 8. ;
// ModifyCurveToSmoothed( pCrvTest, PockParams, dSmoothPar, dSmoothPar, false) ;
//}
// provo a controllare che i punti inzili e finali coincidano, in caso aggiorno il nuovo Offset
// provo a controllare che i punti inziali e finali coincidano, in caso aggiorno il nuovo Offset
Point3d ptStart_Old ; vOffs[nInd]->GetStartPoint( ptStart_Old) ;
Point3d ptEnd_Old ; vOffs[nInd]->GetEndPoint( ptEnd_Old) ;
Point3d ptStart_New ; pCrvTest->GetStartPoint( ptStart_New) ;
@@ -5405,16 +5490,13 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con
// scorro tutte le curva di Offset
for ( int i = 0 ; i < int( vOffs.size()) - 1 ; ++ i) {
// ricavo il punto inziale della curva corrente
Point3d ptS ;
if ( ! vOffs[i]->GetStartPoint( ptS))
return false ;
int nNextInd = -1 ; // indice della curva successiva
double dMinDist = INFINITO ; // distanza tra questa curva e la successiva
Point3d ptStartNext ; // punto iniziale della curva successiva
// tra le curve successive cerco la curva interna e più vicina ad essa
for ( int j = i + 1 ; j < int( vOffs.size()) ; ++ j) {
IntersCurveCurve IntCC( *vOffs[i], *vOffs[j]) ;
@@ -5457,7 +5539,6 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con
// scambio la curva i+1 esima con la j-esima ( se non sono già in ordine)
if ( nNextInd != i + 1)
swap( vOffs[nNextInd], vOffs[i+1]) ;
// cambio il suo punto iniziale nel punto più vicino tovato
double dUS ;
if ( ! vOffs[i+1]->GetParamAtPoint( ptStartNext, dUS, EPS_SMALL))
@@ -5476,31 +5557,30 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con
if ( IsNull( pCrvLink))
return false ;
// NB. Le curve di Offset da tagliare non devono essere quelle di primo Offset
if ( ! CutCurveToConnect( vOffs[i], vOffs[i+1], vOffsFirstCurve, PockParams,
( i == 0 ? 0. : 10 * EPS_SMALL), 10 * EPS_SMALL, pCrvLink) ||
double dLenPercS = ( i == 0 ? 0. : 10 * EPS_SMALL) ;
double dLenPercE = 10 * EPS_SMALL ;
if ( ! CutCurveToConnect( vOffs[i], vOffs[i+1], vOffsFirstCurve, PockParams, dLenPercS, dLenPercE, pCrvLink) ||
! pCrvLink->IsValid()) {
// se non sono riuscito, cerco una strada più semplice
// ripristino le curve
// se non sono riuscito, cerco una strada più semplice ripristinando le curve
pCrvLink->Clear() ;
vOffs[i].Set( pCrv_i) ; // chiuso
vOffs[i+1].Set( pCrv_ii) ; // chiuso
// recupero i vettori tangente iniziali ( le curve sono chiuse )
// recupero i vettori tangenti iniziali ( le curve sono chiuse )
Vector3d vtS, vtE ;
if ( ! vOffs[i]->GetStartDir( vtS) || ! vOffs[i+1]->GetStartDir( vtE))
return false ;
// creo il bi-arco tra esse
if ( CalcBoundedSmoothedLink( ptS, vtS, ptStartNext, vtE, 0.5, vOffsFirstCurve, PockParams, pCrvLink))
bool bSpecial = false ;
if ( CalcBoundedSmoothedLink( ptS, vtS, ptStartNext, vtE, 0.5, vOffsFirstCurve, PockParams, pCrvLink, bSpecial))
vLinks[i + 1].Set( pCrvLink) ; // aggiorno il collegamento
else
return false ;
continue ; // passo alla curva i+1 esima successiva
}
// per sicurezza aggiorno i nuovi punti e i nuovi parametri
double dUNewS, dUNewE ;
if ( ! pCrvLink->GetStartPoint( ptS) ||
! pCrvLink->GetEndPoint( ptStartNext) ||
if ( ! pCrvLink->GetEndPoint( ptStartNext) ||
! vOffs[i]->GetParamAtPoint( ptS, dUNewS) ||
! vOffs[i+1]->GetParamAtPoint( ptStartNext, dUNewE))
return false ;
@@ -5650,7 +5730,7 @@ IsCompoMadeBy2DifferentHomogeneousParts( const ICurveComposite* pCompo, const Po
//----------------------------------------------------------------------------
static bool
CalcSpiral( const ISurfFlatRegion* pSfrPock, const PocketParams& PockParams, int& nReg, Point3d& ptStart,
CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams, int& nReg, Point3d& ptStart,
ICRVCOMPOPOVECTOR& vCrvOrigChunkLoops, ICurveComposite* pMCrv, bool& bMidOut, Vector3d& vtMidOut)
{
// inizializzo il percorso come vuoto
@@ -5814,7 +5894,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const PocketParams& PockParams, int
// controllo eventuali parti non svuotate ( e setto la Feed degli Offset e dei Link)...
PtrOwner<ISurfFlatRegion> pSfrUncleared( CreateSurfFlatRegion()) ;
if ( GetUnclearedRegionAndSetFeed( vOffsFirstCurve, vOffs, vLinks, vCrvOrigChunkLoops[0], PockParams, pSfrUncleared)) {
if ( GetUnclearedRegionAndSetFeed( vOffsFirstCurve, vOffs, vLinks, pSfrOrig, PockParams, pSfrUncleared)) {
// modifico i percorsi
if ( ! RemoveExtraParts( pSfrUncleared, vOffs, vOffsFirstCurve, PockParams))
return false ;
@@ -6379,7 +6459,7 @@ AddSpiralIn( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig,
// calcolo il percorso di svuotatura
bool bSomeOpen ;
Vector3d vtMidOut ;
if ( ! CalcSpiral( pSfrChunk, PockParams, nRegTot, ptStart, vCrvOrigChunkLoops, pMCrv, bSomeOpen, vtMidOut))
if ( ! CalcSpiral( pSfrChunk, pSfrOrig, PockParams, nRegTot, ptStart, vCrvOrigChunkLoops, pMCrv, bSomeOpen, vtMidOut))
return false ;
// se terminate le regioni, esco
@@ -6456,7 +6536,7 @@ AddSpiralOut( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig,
// calcolo il percorso di svuotatura
bool bSomeOpen ;
Vector3d vtMidOut ;
if ( ! CalcSpiral( pSfrChunk, PockParams, nRegTot, ptStart, vCrvOrig, pMCrv, bSomeOpen, vtMidOut))
if ( ! CalcSpiral( pSfrChunk, pSfrOrig, PockParams, nRegTot, ptStart, vCrvOrig, pMCrv, bSomeOpen, vtMidOut))
return false ;
// se terminate le regioni, esco
@@ -7093,7 +7173,8 @@ GetConformalLink( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, Pocket
! pCrvOffs0->GetStartPoint( ptS) || ! pCrvOffs1->GetStartPoint( ptE))
return false ;
// creo il bi-arco tra esse
if ( ! CalcBoundedSmoothedLink( ptS, vtS, ptE, vtE, 0.5, vCrvChunk, PockParams, pCrvLink) ||
bool bSpecial = false ;
if ( ! CalcBoundedSmoothedLink( ptS, vtS, ptE, vtE, 0.5, vCrvChunk, PockParams, pCrvLink, bSpecial) ||
! pCrvLink->IsValid())
return false ;
}
@@ -7621,7 +7702,7 @@ CalcConformalOffsAndLinks( VICRVCOMPOPOVECTOR& vvCrvOffs, const ISurfFlatRegion*
//----------------------------------------------------------------------------
static bool
ExtendConformalOffsAndSetFeed( const ISurfFlatRegion* pSfrPock, const PocketParams& PockParams,
ExtendConformalOffsAndSetFeed( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, const PocketParams& PockParams,
ICRVCOMPOPOVECTOR& vCrvOffs, ICURVEPOVECTOR& vCrvLinks)
{
// controllo dei parametri
@@ -7641,7 +7722,7 @@ ExtendConformalOffsAndSetFeed( const ISurfFlatRegion* pSfrPock, const PocketPara
PtrOwner<ISurfFlatRegion> pSfrUncleared( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrUncleared))
return false ;
if ( GetUnclearedRegionAndSetFeed( vCrvFirstOffs, vCrvOffs, vCrvLinks, nullptr, PockParams, pSfrUncleared)) {
if ( GetUnclearedRegionAndSetFeed( vCrvFirstOffs, vCrvOffs, vCrvLinks, pSfrOrig, PockParams, pSfrUncleared)) {
// estendo i percorsi di Offset se richiesto
if ( ! RemoveExtraParts( pSfrUncleared, vCrvOffs, vCrvFirstOffs, PockParams))
return false ;
@@ -8490,7 +8571,7 @@ AddConformal( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig,
// flag per controllo
bool bOk = true ;
// estendo i percorsi per eventuali regioni non svuotate e calcolo le Feed
bOk = bOk && ExtendConformalOffsAndSetFeed( pSfrPock, PockParams, vCrvOffs, vCrvLink) ;
bOk = bOk && ExtendConformalOffsAndSetFeed( pSfrPock, pSfrOrig, PockParams, vCrvOffs, vCrvLink) ;
// concateno Offset e Links
ICRVCOMPOPOVECTOR vCrvPaths ;
bOk = bOk && ChainConformalOffsWithLinks( vCrvOffs, vCrvLink, vCrvPaths) ;