EgtGeomKernel :
- in CalcPocketing aggiunta lavorazione CONFORMAL_ZIGZAG - migliorie varie.
This commit is contained in:
+600
-67
@@ -71,6 +71,7 @@ struct PocketParams {
|
||||
bool bAllClosed = true ; // flag per indicare se tutti i bordi sono chiusi
|
||||
double dOffsExtra = 2. ; // Offset aggiuntivo per percosi a ZigZag/OneWay se richieste le curve di bordo
|
||||
Frame3d frLocXY ; // frame per conti nel piano XY
|
||||
int nOffsType = ICurve::OFF_FILLET ; // tipologia di Offset per estensione degli aperti
|
||||
} ;
|
||||
|
||||
static double TOL_TRAPEZOID = 50 * EPS_SMALL ; // tolleranza per casi a trapezio SpiralPocket
|
||||
@@ -724,6 +725,62 @@ AssignFeedSpiralOpt( const int nOptType, const PocketParams& PockParams, ICurveC
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
AssignFeedConformalZigZag( ICurveComposite* pCompoPath, const ICurveComposite* pCrvLoop,
|
||||
const PocketParams& PockParams)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCompoPath == nullptr || ! pCompoPath->IsValid())
|
||||
return false ;
|
||||
|
||||
// controllo se il Flag per assegnare la Feed è attivo
|
||||
if ( ! PockParams.bCalcFeed)
|
||||
return AssignMaxFeed( pCompoPath, PockParams) ;
|
||||
|
||||
// imposto di Default la Feed minima per ogni sottocurva
|
||||
AssignMinFeed( pCompoPath, PockParams) ;
|
||||
|
||||
// creo la superficie rimossa ( creata con il raggio utensile)
|
||||
// creo la superficie di classificazione ( creata mediante raggio utensile e SideStep)
|
||||
// creo la curva da restituire con le Feed Assegnate
|
||||
PtrOwner<ISurfFlatRegion> pSfrRemoved( CreateSurfFlatRegion()) ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrClass( CreateSurfFlatRegion()) ;
|
||||
PtrOwner<ICurveComposite> pCompoPathWithFeed( CreateCurveComposite()) ;
|
||||
if ( IsNull( pSfrRemoved) || IsNull( pSfrClass) || IsNull( pCompoPathWithFeed))
|
||||
return false ;
|
||||
ICRVCOMPOPOVECTOR vCrvEmpty ;
|
||||
|
||||
// scorro tutte le curve del percorso
|
||||
for ( int i = 0 ; i < pCompoPath->GetCurveCount() ; ++ i) {
|
||||
// recupero la singola curva come composita
|
||||
PtrOwner<ICurveComposite> pSingleCompo( ConvertCurveToComposite( pCompoPath->GetCurve( i)->Clone())) ;
|
||||
if ( IsNull( pSingleCompo) || ! pSingleCompo->IsValid())
|
||||
return false ;
|
||||
|
||||
// calcolo la Feed per tale curva
|
||||
AssignFeedSpiral( pSingleCompo, pSfrClass, false, vCrvEmpty, pCrvLoop, PockParams, 2 * PockParams.dRad / 3) ;
|
||||
|
||||
// aggiorno la regione svuotata dal Tool
|
||||
PtrOwner<ISurfFlatRegion> pSfrSingleCompo( GetSurfFlatRegionFromFatCurve( pSingleCompo->Clone(), PockParams.dRad + 5 * EPS_SMALL, false, false)) ;
|
||||
if ( ! IsNull( pSfrSingleCompo) || ! pSfrSingleCompo->IsValid()) {
|
||||
if ( ! pSfrClass->IsValid())
|
||||
pSfrClass->CopyFrom( pSfrSingleCompo) ;
|
||||
else
|
||||
pSfrClass->Add( *pSfrSingleCompo) ;
|
||||
}
|
||||
|
||||
if ( ! pCompoPathWithFeed->AddCurve( Release( pSingleCompo)))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// restituisco la curva se valida
|
||||
if ( pCompoPathWithFeed->IsValid())
|
||||
pCompoPath->CopyFrom( pCompoPathWithFeed) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ResetCurveTempProps( ICurveComposite* pCrvCompo)
|
||||
@@ -1026,7 +1083,7 @@ ExtendPath( ICurveComposite* pCompo, const ISurfFlatRegion* pSfr, const PocketPa
|
||||
pCompo->AddLine( ptFall, bEndOrStart) ;
|
||||
pCompo->SetCurveTempProp( ( bEndOrStart ? pCompo->GetCurveCount() - 1 : 0), TEMP_PROP_OUT_START, 0) ;
|
||||
pCompo->SetCurveTempParam( ( bEndOrStart ? pCompo->GetCurveCount() - 1 : 0),
|
||||
( bEndOrStart ? GetMaxFeed( PockParams) : GetMinFeed( PockParams), 0)) ;
|
||||
( bEndOrStart ? GetMaxFeed( PockParams) : GetMinFeed( PockParams)), 0) ;
|
||||
bOkExtended = true ;
|
||||
return true ;
|
||||
}
|
||||
@@ -1231,8 +1288,9 @@ GetHomogeneousParts( ICurveComposite* pCrvCompo, const PocketParams& PockParams,
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
static bool
|
||||
CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, const Vector3d& vtTanE_,
|
||||
const double dRad, ISurfFlatRegion* pSfrInc)
|
||||
CreateSurfFrIncidence( const ICurveComposite* pCrv, const PocketParams& PockParams,
|
||||
const Vector3d& vtTanS_, const Vector3d& vtTanE_, const double dRad,
|
||||
ISurfFlatRegion* pSfrInc)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid())
|
||||
@@ -1252,7 +1310,7 @@ CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, con
|
||||
OffsetCurve OffsCrv ;
|
||||
PtrOwner<ICurve> pOffsExt( CreateCurveComposite()) ;
|
||||
if ( IsNull( pOffsExt) ||
|
||||
! OffsCrv.Make( pCrv, dRad, ICurve::OFF_FILLET) ||
|
||||
! OffsCrv.Make( pCrv, dRad, PockParams.nOffsType) ||
|
||||
! pOffsExt.Set( OffsCrv.GetLongerCurve()) ||
|
||||
IsNull( pOffsExt))
|
||||
return false ;
|
||||
@@ -1261,7 +1319,7 @@ CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, con
|
||||
PtrOwner<ICurve> pOffsInt( CreateCurveComposite()) ;
|
||||
if ( IsNull( pOffsInt))
|
||||
return false ;
|
||||
if ( OffsCrv.Make( pCrv, - dRad, ICurve::OFF_FILLET)) {
|
||||
if ( OffsCrv.Make( pCrv, - dRad, PockParams.nOffsType)) {
|
||||
PtrOwner<ICurve> pMyCrv( OffsCrv.GetLongerCurve()) ;
|
||||
if ( ! IsNull( pMyCrv) && pMyCrv->IsValid())
|
||||
pOffsInt.Set( pMyCrv) ;
|
||||
@@ -1336,7 +1394,7 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
// definisco la regione di incidenza
|
||||
PtrOwner<ISurfFlatRegion> pSfrInc( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrInc) ||
|
||||
! CreateSurfFrIncidence( pCrvBorder, vtTanS, vtTanE, dRad + 75 * EPS_SMALL, pSfrInc))
|
||||
! CreateSurfFrIncidence( pCrvBorder, PockParams, vtTanS, vtTanE, dRad + 75 * EPS_SMALL, pSfrInc))
|
||||
return false ;
|
||||
|
||||
// creo un vettore con tutte le curve che potrebbero cadere, in parte, nella regione di incidenza
|
||||
@@ -1376,13 +1434,15 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
continue ;
|
||||
// 4) effettuo l'Offset della curva di metà dDiamJ
|
||||
OffsetCurve OffsCrv ;
|
||||
if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5 - 20 * EPS_SMALL, ICurve::OFF_FILLET))
|
||||
if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5 - 20 * EPS_SMALL, PockParams.nOffsType))
|
||||
return false ;
|
||||
// 5) scorro tutte le curve di Offset che si sono formate, prendendo sempre la più lunga tra le rimanenti
|
||||
PtrOwner<ICurve> pOffLongestCrv( OffsCrv.GetLongerCurve()) ;
|
||||
while ( ! IsNull( pOffLongestCrv)) {
|
||||
// 6) creo la regione di incidenza di tale curva ( "Curva a fagiolo")
|
||||
PtrOwner<ISurfFlatRegion> pSfrBean( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrv), dDiamJ * 0.5, false, false)) ;
|
||||
bool bSquareEnds = ( PockParams.nOffsType == ICurve::OFF_CHAMFER) ;
|
||||
bool bSquareMids = ( PockParams.nOffsType == ICurve::OFF_CHAMFER) ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrBean( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrv), dDiamJ * 0.5, bSquareEnds, bSquareMids)) ;
|
||||
if ( IsNull( pSfrBean) || ! pSfrBean->IsValid())
|
||||
return false ;
|
||||
// inverto se necessario
|
||||
@@ -1585,6 +1645,10 @@ AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvI
|
||||
if ( PockParams.bAllowZigZagOneWayBorders &&
|
||||
( PockParams.nType == POCKET_ZIGZAG || PockParams.nType == POCKET_ONEWAY))
|
||||
dRad += PockParams.dOffsExtra ;
|
||||
// se lavorazione a ZigZag con smusso, esco di Step/2 per pulire gli aperti
|
||||
if ( PockParams.nType == POCKET_ZIGZAG && PockParams.bSmooth)
|
||||
dRad += max( PockParams.dSideStep / 2, PockParams.dRad / 8) ;
|
||||
|
||||
|
||||
// ricavo i tratti omogenei
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
@@ -2026,6 +2090,9 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams, ICRVCOMP
|
||||
++ nChunkOneCurve ;
|
||||
continue ;
|
||||
}
|
||||
// controllo se la lavorazione ammatte estensione da aperti
|
||||
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG)
|
||||
continue ;
|
||||
|
||||
// vettore delle isole che userò ( le isole aperte piccole sono trascurate)
|
||||
ICRVCOMPOPOVECTOR vCrvToTIsland ;
|
||||
@@ -5950,7 +6017,7 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, const int nOffsCount,
|
||||
CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs,
|
||||
const int nIter, const PocketParams& PockParams, bool& bInsert)
|
||||
{
|
||||
|
||||
@@ -5964,73 +6031,534 @@ CheckIfOffsetIsNecessary( const ICurveComposite* pCrvOffs, const double dOffs, c
|
||||
return true ;
|
||||
|
||||
if ( nIter != 0) { // controllo se sono almeno al secondo offset...
|
||||
|
||||
// per ogni curva controllo se il controOffset + 5 * EPS_SMALL genera una regione ...
|
||||
OffsetCurve OffsCrv ; // considero anche i casi in cui ho bSmallRad
|
||||
if ( OffsCrv.Make( pCrvOffs, - PockParams.dRad + dOffs - 5 * EPS_SMALL , ICurve::OFF_FILLET)) {
|
||||
// se questa curva sparisce -> non serve inserirla come offset, non svuota parti aggiuntive
|
||||
if ( OffsCrv.GetCurveCount() == 0) {
|
||||
bInsert = false ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
else
|
||||
return true ;
|
||||
|
||||
// controllo se richista ottimizzazione per Offsets mediante centroidi e medial Axis
|
||||
if ( ! PockParams.bOptOffsetsAdv || OffsCrv.GetCurveCount() > 1)
|
||||
return true ;
|
||||
|
||||
PtrOwner<ICurve> pCrvOffLonger( OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvOffLonger) || ! pCrvOffLonger->IsValid())
|
||||
return true ;
|
||||
|
||||
// Immagine del tool con centro nel centroide della zona da svuotare
|
||||
Point3d ptC ; pCrvOffLonger->GetCentroid( ptC) ;
|
||||
PtrOwner<ICurveArc> pCrvTool( CreateCurveArc()) ;
|
||||
if( IsNull( pCrvTool))
|
||||
// per ogni curva controllo se il suo Offset massimo non genera alcuna regione
|
||||
double dMaxOffs ;
|
||||
if ( ! CalcCurveLimitOffset( *pCrvOffs, dMaxOffs))
|
||||
return false ;
|
||||
pCrvTool->SetXY( ptC, PockParams.dRad - 5 * EPS_SMALL) ;
|
||||
|
||||
CRVCVECTOR ccClass ;
|
||||
IntersCurveCurve intCC( *pCrvOffLonger, *pCrvTool) ;
|
||||
intCC.GetCurveClassification( 1, EPS_SMALL, ccClass) ;
|
||||
if ( int(ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) {
|
||||
// centroide
|
||||
// se questa curva sparisce -> non serve inserirla come offset, non svuota parti aggiuntive
|
||||
if ( dMaxOffs < PockParams.dRad - dOffs + 5 * EPS_SMALL) {
|
||||
bInsert = false ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
else
|
||||
return true ;
|
||||
|
||||
// recupero la PolyLine per altezza e lunghezza del Box2D ( rettangolo)
|
||||
PolyLine pl ;
|
||||
if ( ! pCrvOffLonger->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, pl))
|
||||
return true ;
|
||||
Vector3d vtX ;
|
||||
double dLen = 0 ; double dHeight = 0 ;
|
||||
if ( ! pl.GetMinAreaRectangleXY( ptC, vtX, dLen, dHeight))
|
||||
return true ;
|
||||
// se non richiesto percorso avanzato
|
||||
if ( ! PockParams.bOptOffsetsAdv)
|
||||
return true ;
|
||||
|
||||
// frame locale, recupero DimX e DimY
|
||||
Frame3d frLoc ; frLoc.Set( ptC, Z_AX, vtX) ;
|
||||
if ( ! frLoc.IsValid())
|
||||
return true ;
|
||||
BBox3d bBox ;
|
||||
frLoc.Invert() ;
|
||||
pCrvOffLonger->GetBBox( frLoc, bBox) ;
|
||||
double dDimX = bBox.GetDimX() ;
|
||||
double dDimY = bBox.GetDimY() ;
|
||||
OffsetCurve OffsCrv ; // considero anche i casi in cui ho bSmallRad
|
||||
if ( ! OffsCrv.Make( pCrvOffs, - PockParams.dRad + dOffs - 5 * EPS_SMALL , ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
|
||||
// se dimensioni accettabili, inserisco
|
||||
if ( dDimX < 2 * PockParams.dRad - 100 * EPS_SMALL ||
|
||||
dDimY < 2 * 2 * PockParams.dRad - 100 * EPS_SMALL) {
|
||||
bInsert = false ;
|
||||
return true ;
|
||||
}
|
||||
// controllo se richista ottimizzazione per Offsets mediante centroidi e medial Axis
|
||||
if ( OffsCrv.GetCurveCount() > 1)
|
||||
return true ;
|
||||
|
||||
PtrOwner<ICurve> pCrvOffLonger( OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvOffLonger) || ! pCrvOffLonger->IsValid())
|
||||
return true ;
|
||||
|
||||
// Immagine del tool con centro nel centroide della zona da svuotare
|
||||
Point3d ptC ; pCrvOffLonger->GetCentroid( ptC) ;
|
||||
PtrOwner<ICurveArc> pCrvTool( CreateCurveArc()) ;
|
||||
if( IsNull( pCrvTool))
|
||||
return false ;
|
||||
pCrvTool->SetXY( ptC, PockParams.dRad - 5 * EPS_SMALL) ;
|
||||
|
||||
CRVCVECTOR ccClass ;
|
||||
IntersCurveCurve intCC( *pCrvOffLonger, *pCrvTool) ;
|
||||
intCC.GetCurveClassification( 1, EPS_SMALL, ccClass) ;
|
||||
if ( int(ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) {
|
||||
// centroide
|
||||
bInsert = false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// recupero la PolyLine per altezza e lunghezza del Box2D ( rettangolo)
|
||||
PolyLine pl ;
|
||||
if ( ! pCrvOffLonger->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, pl))
|
||||
return true ;
|
||||
Vector3d vtX ;
|
||||
double dLen = 0 ; double dHeight = 0 ;
|
||||
if ( ! pl.GetMinAreaRectangleXY( ptC, vtX, dLen, dHeight))
|
||||
return true ;
|
||||
|
||||
// frame locale, recupero DimX e DimY
|
||||
Frame3d frLoc ; frLoc.Set( ptC, Z_AX, vtX) ;
|
||||
if ( ! frLoc.IsValid())
|
||||
return true ;
|
||||
BBox3d bBox ;
|
||||
frLoc.Invert() ;
|
||||
pCrvOffLonger->GetBBox( frLoc, bBox) ;
|
||||
double dDimX = bBox.GetDimX() ;
|
||||
double dDimY = bBox.GetDimY() ;
|
||||
|
||||
// se dimensioni accettabili, inserisco
|
||||
if ( dDimX < 2 * PockParams.dRad - 100 * EPS_SMALL ||
|
||||
dDimY < 2 * 2 * PockParams.dRad - 100 * EPS_SMALL) {
|
||||
bInsert = false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ExtendGuideByIteration( ICurveComposite* pCompoTempGuide, const ICurveComposite* pCompoPerimeter,
|
||||
bool bInverted)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCompoTempGuide == nullptr || ! pCompoTempGuide->IsValid() ||
|
||||
pCompoPerimeter == nullptr || ! pCompoPerimeter->IsValid())
|
||||
return false ;
|
||||
|
||||
const double EXTENSION_VAL = 1000. ;
|
||||
|
||||
// ricavo il punto finale della guida
|
||||
Point3d ptEndGuide ; pCompoTempGuide->GetEndPoint( ptEndGuide) ;
|
||||
// direzione finale della guida
|
||||
Vector3d vtEndGuide ; pCompoTempGuide->GetEndDir( vtEndGuide) ;
|
||||
// creo un segmento diretto come il chiuso
|
||||
PtrOwner<ICurveLine> pSeg( CreateCurveLine()) ;
|
||||
if ( IsNull( pSeg) ||
|
||||
! pSeg->Set( ptEndGuide, ptEndGuide + EXTENSION_VAL * vtEndGuide))
|
||||
return false ;
|
||||
// calcolo l'intersezione tra questo segmento e la curva di perimetro aperta
|
||||
IntersCurveCurve ICC( *pSeg, *pCompoPerimeter) ;
|
||||
// se l'unica intersezione è il punto iniziale del segmento, allora non estendo la guida
|
||||
// ( vale anche nel caso di intersezione con Overlap)
|
||||
if ( ICC.GetIntersCount() == 1) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
if ( ICC.GetIntCrvCrvInfo( 0, aInfo)) {
|
||||
if ( AreSamePointApprox( aInfo.IciB[0].ptI, ptEndGuide))
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
// passo alla PolyLine del perimetro
|
||||
PolyLine PL ;
|
||||
pCompoPerimeter->ApproxWithLines( EPS_SMALL, EPS_ANG_SMALL, ICurve::APL_STD, PL) ;
|
||||
// cerco il punto più esterno rispetto alla direzione del chiuso
|
||||
Point3d ptPoly ;
|
||||
PL.GetFirstPoint( ptPoly) ;
|
||||
while ( PL.GetNextPoint( ptPoly)) {
|
||||
if ( ! pSeg->Set( ptEndGuide, ptEndGuide + ( ptPoly - ptEndGuide) * EXTENSION_VAL))
|
||||
return false ;
|
||||
// calcolo l'intersezione tra questo segmento e la curva di perimetro aperta
|
||||
IntersCurveCurve ICC( *pSeg, *pCompoPerimeter) ;
|
||||
// se una intersezione, allora di Overlap con punto iniziale e finale definito
|
||||
if ( ICC.GetIntersCount() == 1) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
if ( ICC.GetIntCrvCrvInfo( 0, aInfo)) {
|
||||
if ( aInfo.bOverlap) {
|
||||
if ( AreSamePointApprox( aInfo.IciB[0].ptI, ptEndGuide) &&
|
||||
AreSamePointApprox( aInfo.IciB[1].ptI, ptPoly))
|
||||
return ( pCompoTempGuide->AddLine( ptPoly)) ;
|
||||
}
|
||||
else {
|
||||
if ( AreSamePointApprox( aInfo.IciB[0].ptI, ptEndGuide))
|
||||
return ( pCompoTempGuide->AddLine( ptPoly)) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se più di una intersezione, allora il perimetro deve essere tutto Interno al segmento
|
||||
// ( Out nel caso in cui ho le curve invertite)
|
||||
IntCrvCrvInfo aInfo ;
|
||||
bool bOk = true ;
|
||||
for ( int i = 0 ; i < ICC.GetIntersCount() && bOk ; ++ i) {
|
||||
bOk = ( ICC.GetIntCrvCrvInfo( i, aInfo)) ;
|
||||
bOk = ( aInfo.bOverlap ||
|
||||
( aInfo.IciB[0].nPrevTy != ( ! bInverted ? CRVC_OUT : CRVC_IN) &&
|
||||
aInfo.IciB[0].nNextTy != ( ! bInverted ? CRVC_OUT : CRVC_IN))) ;
|
||||
}
|
||||
if ( bOk)
|
||||
return ( pCompoTempGuide->AddLine( ptPoly)) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
IsCompoMadeBy2DifferentHomogeneousParts( const ICurveComposite* pCompo, const PocketParams& PockParams,
|
||||
bool& bOk, ICRVCOMPOPOVECTOR& vpCrvs)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCompo == nullptr || ! pCompo->IsValid())
|
||||
return false ;
|
||||
bOk = false ;
|
||||
vpCrvs.clear() ;
|
||||
|
||||
// clono la curva composita ( cambierà il suo punto iniziale)
|
||||
PtrOwner<ICurveComposite> pCompoCL( CloneCurveComposite( pCompo)) ;
|
||||
if ( IsNull( pCompoCL) || ! pCompoCL->IsValid())
|
||||
return false ;
|
||||
|
||||
// recupero i tratti con proprietà uniformi
|
||||
GetHomogeneousParts( pCompoCL, PockParams, vpCrvs) ;
|
||||
if ( vpCrvs.size() > 1) {
|
||||
// unisco il primo e l'ultimo se estremi compatibili
|
||||
Point3d ptE ; vpCrvs.back()->GetEndPoint( ptE) ;
|
||||
Point3d ptS ; vpCrvs[0]->GetStartPoint( ptS) ;
|
||||
if ( AreSamePointApprox( ptS, ptE)) {
|
||||
vpCrvs[0]->AddCurve( Release( vpCrvs.back()), false) ;
|
||||
vpCrvs.erase( vpCrvs.end() - 1) ;
|
||||
}
|
||||
}
|
||||
|
||||
// controlloo che la curva abbia esattamente due tratti omogenei
|
||||
bOk = ( int( vpCrvs.size()) == 2) ;
|
||||
if ( ! bOk)
|
||||
vpCrvs.clear() ;
|
||||
return true ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CalcCrvGuideConformalZigZag( const ISurfFlatRegion* pSfrChunk, PocketParams& PockParams, ICurveComposite* pCompoGuide,
|
||||
ICurveComposite* pCompoClass)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCompoGuide == nullptr || pCompoClass == nullptr ||
|
||||
pSfrChunk == nullptr || ! pSfrChunk->IsValid())
|
||||
return false ;
|
||||
pCompoGuide->Clear() ;
|
||||
pCompoClass->Clear() ;
|
||||
|
||||
// la superficie deve avere un Chunk e non avere isole
|
||||
if ( pSfrChunk->GetChunkCount() > 1 || pSfrChunk->GetLoopCount( 0) > 1)
|
||||
return true ;
|
||||
|
||||
// ricavo la curva di bordo ( la curva che definisce il perimetro)
|
||||
PtrOwner<ICurveComposite> pCompoPerimeter( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, 0))) ;
|
||||
if ( IsNull( pCompoPerimeter) || ! pCompoPerimeter->IsValid())
|
||||
return false ;
|
||||
// controllo che sia formata da esattamente due tratti omogenei
|
||||
bool b2HP = false ;
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
if ( ! IsCompoMadeBy2DifferentHomogeneousParts( pCompoPerimeter, PockParams, b2HP, vpCrvs))
|
||||
return false ;
|
||||
if ( ! b2HP)
|
||||
return true ;
|
||||
|
||||
// allargo curva di Bordo secondo le specifiche di una lavorazione a SpiralIn
|
||||
double dRad = PockParams.dRad ;
|
||||
int nOffsType = PockParams.nOffsType ;
|
||||
PockParams.dRad = max( dRad / 8, PockParams.dSideStep / 2) ;
|
||||
PockParams.nOffsType = ICurve::OFF_CHAMFER ;
|
||||
ICRVCOMPOPOVECTOR vCrvEmpty ;
|
||||
if ( ! AdjustContourWithOpenEdges( pCompoPerimeter, vCrvEmpty, PockParams))
|
||||
return false ;
|
||||
PockParams.dRad = dRad ;
|
||||
PockParams.nOffsType = nOffsType ;
|
||||
|
||||
// reucupero ora i due tratti uniformi ( della curva allargata)
|
||||
if ( ! IsCompoMadeBy2DifferentHomogeneousParts( pCompoPerimeter, PockParams, b2HP, vpCrvs) ||
|
||||
! b2HP)
|
||||
return false ;
|
||||
|
||||
// la guida inizialmente è data dal tratto chiuso
|
||||
// il perimetro coincide con il tratto aperto
|
||||
PtrOwner<ICurveComposite> pCompoTempGuide( Release( vpCrvs[0])) ;
|
||||
if ( IsNull( pCompoTempGuide) || ! pCompoTempGuide->IsValid())
|
||||
return false ;
|
||||
|
||||
// estendo la curva nel suo tratto finale ed iniziale
|
||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
||||
if ( ! ExtendGuideByIteration( pCompoTempGuide, vpCrvs[1], ( i == 1)))
|
||||
return false ;
|
||||
// se la guida diventa diventa chiusa, allora esco
|
||||
if ( ! pCompoTempGuide->IsValid() || pCompoTempGuide->IsClosed())
|
||||
return true ;
|
||||
pCompoTempGuide->Invert() ;
|
||||
vpCrvs[1]->Invert() ;
|
||||
}
|
||||
|
||||
// tratto iniziale
|
||||
Vector3d vtStart ; pCompoTempGuide->GetStartDir( vtStart) ;
|
||||
Point3d ptStart ; pCompoTempGuide->GetStartPoint( ptStart) ;
|
||||
PtrOwner<ICurveLine> pLineStart( CreateCurveLine()) ;
|
||||
if ( IsNull( pLineStart) || ! pLineStart->Set( ptStart - 1000. * vtStart, ptStart))
|
||||
return false ;
|
||||
// tratto finale ( potrebbe intersecare il tratto iniziale)
|
||||
Vector3d vtEnd ; pCompoTempGuide->GetEndDir( vtEnd) ;
|
||||
Point3d ptEnd ; pCompoTempGuide->GetEndPoint( ptEnd) ;
|
||||
PtrOwner<ICurveLine> pLineEnd( CreateCurveLine()) ;
|
||||
if ( IsNull( pLineEnd) || ! pLineEnd->Set( ptEnd, ptEnd + 1000. * vtEnd))
|
||||
return false ;
|
||||
IntersCurveCurve ICC( *pLineStart, *pLineEnd) ;
|
||||
if ( ICC.GetIntersCount() > 0) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
if ( ICC.GetIntCrvCrvInfo( 0, aInfo)) {
|
||||
pLineStart->TrimStartAtParam( aInfo.IciA[0].dU) ;
|
||||
pLineEnd->TrimEndAtParam( aInfo.IciB[0].dU) ;
|
||||
}
|
||||
}
|
||||
// le due estensioni vanno tagliate presso i bordi dei lati aperti estesi
|
||||
IntersCurveCurve ICCLS( *pLineStart, *vpCrvs[1]) ;
|
||||
if ( ICCLS.GetIntersCount() > 0) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
for ( int i = 0 ; i < ICCLS.GetCrossIntersCount() ; ++ i) {
|
||||
if ( ICCLS.GetIntCrvCrvInfo( i, aInfo)) {
|
||||
if ( ! AreSamePointApprox( aInfo.IciA[ aInfo.bOverlap ? 1 : 0].ptI, ptStart))
|
||||
pLineStart->ModifyStart( aInfo.IciA[aInfo.bOverlap ? 1 : 0].ptI) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
IntersCurveCurve ICCLE( *pLineEnd, *vpCrvs[1]) ;
|
||||
if ( ICCLE.GetIntersCount() > 0) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
for ( int i = 0 ; i < ICCLE.GetCrossIntersCount() ; ++ i) {
|
||||
if ( ICCLE.GetIntCrvCrvInfo( 0, aInfo)) {
|
||||
if ( ! AreSamePointApprox( aInfo.IciA[0].ptI, ptEnd))
|
||||
pLineEnd->ModifyEnd( aInfo.IciA[0].ptI) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
pCompoTempGuide->AddCurve( Release( pLineStart), false) ;
|
||||
pCompoTempGuide->AddCurve( Release( pLineEnd), true) ;
|
||||
|
||||
// recupero la curva guida
|
||||
pCompoGuide->CopyFrom( pCompoTempGuide) ;
|
||||
|
||||
// recupero la curva di classificazione ( abballendola)
|
||||
PolyLine PL ;
|
||||
pCompoPerimeter->ApproxWithLines( 10 * LIN_TOL_MIN, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) ;
|
||||
PL.RemoveAlignedPoints( 500 * EPS_SMALL) ;
|
||||
pCompoPerimeter->Clear() ;
|
||||
pCompoPerimeter->FromPolyLine( PL) ;
|
||||
pCompoPerimeter->RemoveSmallDefects( 10 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||
pCompoPerimeter->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
pCompoClass->CopyFrom( pCompoPerimeter) ;
|
||||
ResetCurveTempProps( pCompoClass) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
AddAddConformalZigZag( const ISurfFlatRegion* pSfr, PocketParams& PockParams,
|
||||
ICRVCOMPOPOVECTOR& vCrvCompoRes)
|
||||
{
|
||||
/*
|
||||
Calcolo ottimizzato di svuotatura mediante Offset progressivi di una guida, raccordati
|
||||
rispetto al bordo della superficie di Pocketing mediante logica ZigZag
|
||||
*/
|
||||
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
||||
return false ;
|
||||
vCrvCompoRes.clear() ;
|
||||
|
||||
// ciclo sui chunk della regione
|
||||
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) {
|
||||
// recupero il Chunk nC-esimo
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk( pSfr->CloneChunk( nC)) ;
|
||||
if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid())
|
||||
return false ;
|
||||
|
||||
// recupero il massimo Offset del Chunk nC-esimo
|
||||
double dMaxOffs ;
|
||||
pSfrChunk->GetMaxOffset( dMaxOffs) ;
|
||||
// se inferiore del Tool ( ho già svuotato tale Chunk in precedenza)
|
||||
if ( dMaxOffs < PockParams.dRad + 200 * EPS_SMALL)
|
||||
continue ;
|
||||
|
||||
// ricavo la guida ideale e la curva su cui tagliare gli Offset a partire dal Chunk nC-esimo
|
||||
PtrOwner<ICurveComposite> pCrvGuideExt( CreateCurveComposite()) ;
|
||||
PtrOwner<ICurveComposite> pCrvClass( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvGuideExt) || IsNull( pCrvClass) ||
|
||||
! CalcCrvGuideConformalZigZag( pSfr, PockParams, pCrvGuideExt, pCrvClass))
|
||||
return false ;
|
||||
// se non è stata trovata una guida ideale, allora passo al Chunk successivo
|
||||
if ( ! pCrvGuideExt->IsValid() || pCrvGuideExt->GetCurveCount() == 0 ||
|
||||
! pCrvClass->IsValid() || pCrvClass->GetCurveCount() == 0) {
|
||||
return true ;
|
||||
}
|
||||
|
||||
// memorizzo le curve di Offset tagliate a seconda dalla geometria del perimetro
|
||||
ICRVCOMPOPOVECTOR vCompoInternalOffs ;
|
||||
const int MAX_ITER = 100 ;
|
||||
double dOffs = PockParams.dRad + PockParams.dRadialOffset ;
|
||||
for ( int i = 0 ; i < MAX_ITER ; ++ i) {
|
||||
OffsetCurve OffsCrv ;
|
||||
if ( ! OffsCrv.Make( pCrvGuideExt, - dOffs, ICurve::OFF_FILLET))
|
||||
return false ;
|
||||
// se invece ne ottengo più di una, controllo se è necessaria
|
||||
if ( OffsCrv.GetCurveCount() > 1) {
|
||||
// recupero le curve extra ( tutte tranne la più lunga)
|
||||
for ( int j = 0 ; j < OffsCrv.GetCurveCount() - 1 ; ++ j) {
|
||||
// recupero la curva più corta
|
||||
PtrOwner<ICurveComposite> pCrvShorter( ConvertCurveToComposite( OffsCrv.GetShorterCurve())) ;
|
||||
if ( ! IsNull( pCrvShorter) && pCrvShorter->IsValid()) {
|
||||
// controllo se è davvero necessaria per non lasciare materiale
|
||||
bool bSkip = false ;
|
||||
if ( pCrvShorter->IsClosed()) {
|
||||
CheckIfOffsetIsNecessary( pCrvShorter, ( i == 0 ? dOffs : PockParams.dSideStep),
|
||||
i, PockParams, bSkip) ;
|
||||
if ( bSkip)
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non ottengo nessuna curva, allora ho finito
|
||||
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvOffs) || ! pCrvOffs->IsValid())
|
||||
break ;
|
||||
// se ottengo una curva chiusa, lavorazione non ammessa
|
||||
if ( pCrvOffs->IsClosed())
|
||||
return true ;
|
||||
// la inverto se numero di Offset progressivo dispari
|
||||
if ( ( ! IsEven( i) && ! PockParams.bInvert) ||
|
||||
( IsEven( i) && PockParams.bInvert))
|
||||
pCrvOffs->Invert() ;
|
||||
// classifico la curva rispetto al perimetro, devo tenere solo le parti interne
|
||||
CRVCVECTOR ccClass ;
|
||||
IntersCurveCurve ICC( *pCrvOffs, *pCrvClass) ;
|
||||
if ( ! ICC.GetCurveClassification( 0, EPS_SMALL, ccClass))
|
||||
return true ;
|
||||
// scorro tutte le classificazioni ottenute
|
||||
for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) {
|
||||
// tengo quelle strettamente interne
|
||||
if ( ccClass[j].nClass == CRVC_IN) {
|
||||
// recupero la porzione di Offset
|
||||
PtrOwner<ICurve> pCrvOffs_Int( pCrvOffs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
|
||||
if ( ! IsNull( pCrvOffs_Int) && pCrvOffs_Int->IsValid()) {
|
||||
// salvo la curva
|
||||
vCompoInternalOffs.emplace_back( ConvertCurveToComposite( Release( pCrvOffs_Int))) ;
|
||||
// salvo come prima propeità temporanea, il numero di Offset progressivo
|
||||
vCompoInternalOffs.back()->SetTempProp( i, 0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
dOffs += PockParams.dSideStep ;
|
||||
}
|
||||
// se non ho ottenuto Offset, passo al Chunk successivo
|
||||
if ( vCompoInternalOffs.empty())
|
||||
return true ;
|
||||
|
||||
/*
|
||||
Creo la curva di Svuotatura come unione di due curve :
|
||||
- La curva che non deve essere smussata ( curve di primo Offset e raccordi)
|
||||
- La Curva che necessita di smusso ( le altre)
|
||||
NB. Nel caso non sia richiesto lo smusso, allora la seconda curva non viene smussata, ma la
|
||||
logica rimane la stessa.
|
||||
*/
|
||||
|
||||
PtrOwner<ICurveComposite> pCompoNoSmooth( CreateCurveComposite()) ;
|
||||
PtrOwner<ICurveComposite> pCompoSmooth( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCompoNoSmooth) || IsNull( pCompoSmooth))
|
||||
return false ;
|
||||
|
||||
|
||||
// scorro i tratti di Offset interni e aggiungo i raccordi sul bordo esterno
|
||||
// raccordo il tratto di Offset interno corrente al successivo
|
||||
const double TOL_JOINT = 25. * EPS_SMALL ;
|
||||
double dHalfLenPerimeter ;
|
||||
pCrvClass->GetLength( dHalfLenPerimeter) ;
|
||||
dHalfLenPerimeter /= 2. ;
|
||||
for ( int i = 0 ; i < int( vCompoInternalOffs.size()) - 1 ; ++ i) {
|
||||
// recupero il parametro iniziale del raccordo sulla curva di perimetro
|
||||
Point3d ptS ; vCompoInternalOffs[i]->GetEndPoint( ptS) ;
|
||||
double dUS ; pCrvClass->GetParamAtPoint( ptS, dUS) ;
|
||||
// recupero il parametro finale del raccordo sulla curva di perimetro
|
||||
Point3d ptE ; vCompoInternalOffs[i+1]->GetStartPoint( ptE) ;
|
||||
double dUE ; pCrvClass->GetParamAtPoint( ptE, dUE) ;
|
||||
// aggiungo il tratto di Offset interno corrente alla curva di svuotatura
|
||||
if ( vCompoInternalOffs[i]->GetTempProp() == 0) {
|
||||
// se deriva dal primo Offset
|
||||
if ( ! pCompoNoSmooth->AddCurve( Release( vCompoInternalOffs[i]), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
// se deriva da Offset successivi
|
||||
if ( ! pCompoSmooth->AddCurve( Release( vCompoInternalOffs[i]), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
// recupero il tratto di curva di interesse
|
||||
PtrOwner<ICurve> pCrvJoint( pCrvClass->CopyParamRange( dUS, dUE)) ;
|
||||
if ( ! IsNull( pCrvJoint) && pCrvJoint->IsValid()) {
|
||||
double dLen ;
|
||||
pCrvJoint->GetLength( dLen) ;
|
||||
if ( dLen > dHalfLenPerimeter) {
|
||||
pCrvJoint.Set( pCrvClass->CopyParamRange( dUE, dUS)) ;
|
||||
pCrvJoint->Invert() ;
|
||||
}
|
||||
// aggiungo il tratto di percorso
|
||||
if ( vCompoInternalOffs[i+1]->GetTempProp() == 0) {
|
||||
// se l'offset successivo deriva ancora dal primo
|
||||
if ( ! pCompoNoSmooth->AddCurve( Release( pCrvJoint), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
// se l'Offset successivo non deriva dal primo Offset
|
||||
if ( ! pCompoSmooth->AddCurve( Release( pCrvJoint), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// aggiungo l'ultimo tratto di Offset
|
||||
if ( vCompoInternalOffs.back()->GetTempProp() == 0) {
|
||||
if ( ! pCompoNoSmooth->AddCurve( Release( vCompoInternalOffs.back()), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
if ( ! pCompoSmooth->AddCurve( vCompoInternalOffs.back()->Clone(), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
// porto l'ultima curva del percorso NoSmooth nel percorso Smooth per avere un raccordo anche
|
||||
// sul tratto di giunzione tra esse
|
||||
if ( pCompoSmooth->IsValid() && pCompoNoSmooth->IsValid()) {
|
||||
PtrOwner<ICurve> pCrv( pCompoNoSmooth->GetLastCurve()->Clone()) ;
|
||||
if ( IsNull( pCrv) || ! pCrv->IsValid() ||
|
||||
! pCompoSmooth->AddCurve( Release( pCrv), false, TOL_JOINT))
|
||||
return false ;
|
||||
delete( pCompoNoSmooth->RemoveFirstOrLastCurve( true)) ;
|
||||
}
|
||||
|
||||
// smusso dove necessario
|
||||
ModifyCurveToSmoothed( pCompoSmooth, PockParams, PockParams.dRad / 8, PockParams.dRad / 8, false) ;
|
||||
// creo il percorso di svuotatura
|
||||
PtrOwner<ICurveComposite> pCompoTempPath( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCompoTempPath))
|
||||
return false ;
|
||||
if ( pCompoNoSmooth->IsValid() && pCompoNoSmooth->GetCurveCount() > 0) {
|
||||
if ( ! pCompoTempPath.Set( pCompoNoSmooth))
|
||||
return false ;
|
||||
}
|
||||
if ( pCompoSmooth->IsValid()) {
|
||||
if ( ! pCompoTempPath->AddCurve( Release( pCompoSmooth), true, TOL_JOINT))
|
||||
return false ;
|
||||
}
|
||||
// se la curva finale di Pocketing è valida, allora la resituisco
|
||||
if ( pCompoTempPath->IsValid()) {
|
||||
// inverto l'ordine delle curve di Offset ( in modo da partire sempre ad eseguire il percorso
|
||||
// più lontano dal dai lati chiusi)
|
||||
pCompoTempPath->Invert() ;
|
||||
// calcolo la Feed del percorso trovato
|
||||
if ( ! AssignFeedConformalZigZag( pCompoTempPath, pCrvClass, PockParams))
|
||||
return false ;
|
||||
// aggiugno il tratto iniziale e finale per entrate da fuori
|
||||
Vector3d vtStart ; pCompoTempPath->GetStartDir( vtStart) ;
|
||||
vtStart.Invert() ;
|
||||
bool bExt = false ;
|
||||
if ( ! ExtendPath( pCompoTempPath, pSfr, PockParams, vtStart, false, bExt))
|
||||
return false ;
|
||||
Vector3d vtEnd ; pCompoTempPath->GetEndDir( vtEnd) ;
|
||||
if ( ! ExtendPath( pCompoTempPath, pSfr, PockParams, vtEnd, true, bExt))
|
||||
return false ;
|
||||
// sostituisco la curva
|
||||
if ( pCompoTempPath->IsValid())
|
||||
vCrvCompoRes.emplace_back( Release( pCompoTempPath)) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
@@ -6166,7 +6694,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int
|
||||
pCrvCompoBorder->Invert() ;
|
||||
// controllo quali regioni di Offset possono essere sostituite
|
||||
bool bInsert = true ;
|
||||
if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, int( vOffs.size()), nIter, PockParams, bInsert))
|
||||
if ( ! CheckIfOffsetIsNecessary( pCrvCompoBorder, dOffs - dOffsPrec, nIter, PockParams, bInsert))
|
||||
return false ;
|
||||
if ( bInsert)
|
||||
vOffs.emplace_back( Release( pCrvCompoBorder)) ;
|
||||
@@ -7317,7 +7845,8 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid() ||
|
||||
dStep < 10 * EPS_SMALL ||
|
||||
( nType != POCKET_ZIGZAG && nType != POCKET_ONEWAY && nType != POCKET_SPIRALIN && nType != POCKET_SPIRALOUT))
|
||||
( nType != POCKET_ZIGZAG && nType != POCKET_ONEWAY && nType != POCKET_SPIRALIN &&
|
||||
nType != POCKET_SPIRALOUT && nType != POCKET_CONFORMAL_ZIGZAG))
|
||||
return false ;
|
||||
|
||||
// pulizia vettore delle curve elementari
|
||||
@@ -7381,7 +7910,11 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double
|
||||
return false ;
|
||||
break ;
|
||||
case POCKET_SPIRALOUT :
|
||||
if ( ! AddSpiralOut( pSfrAdj, pSfr, myParams, vCrvCompoRes))
|
||||
if ( ! AddSpiralOut( pSfrAdj, pSfr_Loc, myParams, vCrvCompoRes))
|
||||
return false ;
|
||||
break ;
|
||||
case POCKET_CONFORMAL_ZIGZAG :
|
||||
if ( ! AddAddConformalZigZag( pSfr_Loc, myParams, vCrvCompoRes))
|
||||
return false ;
|
||||
break ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user