Merge branch 'master' into FasterVMill5Axis_Bez3x1
This commit is contained in:
+276
-164
@@ -55,6 +55,7 @@ struct PocketParams {
|
||||
double dOpenMinSafe = 5. ; // estensione minima di sicurezza
|
||||
double dMaxOptSize = 0. ; // dimensione per ottimizzazione
|
||||
double dAngle = 0. ; // angolo per orientare le passate OneWay e ZigZag
|
||||
double dSmooth = 5. ; // parametro di smusso per link ( raccordo )
|
||||
double dLiTang = INFINITO ; // valore di LeadIn in ingresso
|
||||
bool bCalcUnclearedRegs = true ; // flag per calcolare o meno le regioni non svuotate
|
||||
bool bOptOffsets = true ; // flag per evitare Offset non necessari
|
||||
@@ -1015,7 +1016,7 @@ GetIndOfHypoteticalChunk( const ICRVCOMPOPOVECTOR& vCrv, const ICurveComposite*
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ExtendPath( ICurveComposite* pCompo, const ISurfFlatRegion* pSfr, const PocketParams& PockParams,
|
||||
const Vector3d& vtFirstOut, bool bEndOrStart, bool& bOkExtended)
|
||||
const Vector3d& vtFirstOut, bool bEndOrStart, double dExtension, bool& bOkExtended)
|
||||
{
|
||||
/*
|
||||
Estensione della curva pCompo con un segmento lineare.
|
||||
@@ -1056,7 +1057,7 @@ ExtendPath( ICurveComposite* pCompo, const ISurfFlatRegion* pSfr, const PocketPa
|
||||
// ruoto il versore d'uscita
|
||||
Vector3d vtRotOut = GetRotate( vtFirstOut, Z_AX, - vAngles[i]) ;
|
||||
// calcolo il punto di caduta dell'utensile
|
||||
Point3d ptFall = pt + vtRotOut * ( PockParams.dRad + PockParams.dOpenMinSafe) ;
|
||||
Point3d ptFall = pt + vtRotOut * dExtension ;
|
||||
// controllo che sia sufficientemente distante dalla superficie limite
|
||||
bool bInside = true ;
|
||||
bool bOkOut = true ;
|
||||
@@ -1170,29 +1171,10 @@ GetHomogeneousParts( ICurveComposite* pCrvCompo, const PocketParams& PockParams,
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
GetFirstOffsCrvFromSfr( const ISurfFlatRegion* pSfr, double dOffs, ICRVCOMPOPOVECTOR& vCrvFirstOffs)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
||||
return false ;
|
||||
vCrvFirstOffs.clear() ;
|
||||
|
||||
// creo la regione mediante Offset
|
||||
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfr->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ;
|
||||
if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid())
|
||||
return false ;
|
||||
|
||||
// inserisco le curve orientante
|
||||
return ( GetSfrCrvCompoLoops( pSfrOffs, vCrvFirstOffs)) ;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
static bool
|
||||
CreateSurfFrIncidence( const ICurveComposite* pCrv, const PocketParams& PockParams,
|
||||
const Vector3d& vtTanS_, const Vector3d& vtTanE_, const double dRad,
|
||||
ISurfFlatRegion* pSfrInc)
|
||||
const double dRad, ISurfFlatRegion* pSfrInc)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid())
|
||||
@@ -1318,11 +1300,11 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
pCrvBorder == nullptr || ! pCrvBorder->IsValid() || pCrvBorder->GetCurveCount() == 0)
|
||||
return false ;
|
||||
|
||||
// definisco la regione di incidenza
|
||||
// definisco la regione di incidenza ( leggermente più grande )
|
||||
PtrOwner<ISurfFlatRegion> pSfrInc( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrInc))
|
||||
return false ;
|
||||
if ( ! CreateSurfFrIncidence( pCrvBorder, PockParams, vtTanS, vtTanE, dRad + 75 * EPS_SMALL, pSfrInc)) {
|
||||
if ( ! CreateSurfFrIncidence( pCrvBorder, PockParams, dRad + 75. * EPS_SMALL, pSfrInc)) {
|
||||
pSfrInc.Set( GetSurfFlatRegionFromFatCurve( CloneCurveComposite( pCrvBorder), dRad + 75 * EPS_SMALL, false, false)) ;
|
||||
if ( IsNull( pSfrInc) || ! pSfrInc->IsValid())
|
||||
return false ;
|
||||
@@ -1347,12 +1329,12 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
double dArea ; Plane3d plCheck ;
|
||||
if ( ! pCrvCompo->GetArea( plCheck, dArea))
|
||||
return false ;
|
||||
bIsIsland = AreSameVectorEpsilon( plCheck.GetVersN(), - Z_AX, 10 * EPS_SMALL) ;
|
||||
bIsIsland = AreSameVectorEpsilon( plCheck.GetVersN(), - Z_AX, 10. * EPS_SMALL) ;
|
||||
|
||||
// scorro il vettore creato...
|
||||
for ( int c = 0 ; c < int( vCrvToCheck.size()) ; ++ c) {
|
||||
for ( int i = 0 ; i < int( vCrvToCheck.size()) ; ++ i) {
|
||||
// 1) recupero la curva corrente
|
||||
PtrOwner<ICurveComposite> pCrvCurr( vCrvToCheck[c]->Clone()) ;
|
||||
PtrOwner<ICurveComposite> pCrvCurr( vCrvToCheck[i]->Clone()) ;
|
||||
if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid())
|
||||
return false ;
|
||||
// 2) ricavo i tratti con proprietà uniformi ( Aperti/Chiusi )
|
||||
@@ -1360,12 +1342,12 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
if ( ! GetHomogeneousParts( pCrvCurr, PockParams, vpCrvs))
|
||||
return false ;
|
||||
// 3) considero solo i tratti chiusi
|
||||
for ( int cl = 0 ; cl < int( vpCrvs.size()) ; ++ cl) {
|
||||
if ( vpCrvs[cl]->GetTempProp() == TEMP_PROP_OPEN_EDGE)
|
||||
for ( int nU = 0 ; nU < int( vpCrvs.size()) ; ++ nU) {
|
||||
if ( vpCrvs[nU]->GetTempProp() == TEMP_PROP_OPEN_EDGE)
|
||||
continue ;
|
||||
// 4) effettuo l'Offset della curva di metà dDiamJ
|
||||
OffsetCurve OffsCrv ;
|
||||
if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5 - 20 * EPS_SMALL, PockParams.nOffsType))
|
||||
if ( ! OffsCrv.Make( vpCrvs[nU], - dDiamJ / 2. - 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()) ;
|
||||
@@ -1373,7 +1355,7 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
// 6) creo la regione di incidenza di tale curva ( "Curva a fagiolo")
|
||||
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)) ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrBean( GetSurfFlatRegionFromFatCurve( Release( pOffLongestCrv), dDiamJ / 2., bSquareEnds, bSquareMids)) ;
|
||||
if ( IsNull( pSfrBean) || ! pSfrBean->IsValid())
|
||||
return false ;
|
||||
// inverto se necessario
|
||||
@@ -1381,7 +1363,8 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
pSfrBean->Invert() ;
|
||||
// 7) se la "Regione a fagiolo" non influenza la regione di incidenza, la transcuro
|
||||
bool bDiscard = false ;
|
||||
if ( ! bIsIsland) { // se tratto un loop esterno
|
||||
if ( ! bIsIsland) {
|
||||
// se tratto un loop esterno
|
||||
PtrOwner<ISurfFlatRegion> pSfrBean_test( CloneSurfFlatRegion( pSfrBean)) ;
|
||||
if ( IsNull( pSfrBean_test) || ! pSfrBean_test->IsValid())
|
||||
return false ;
|
||||
@@ -1390,7 +1373,8 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
! pSfrBean_test->IsValid() ||
|
||||
pSfrBean_test->GetChunkCount() == 0) ;
|
||||
}
|
||||
else if ( bIsAllOpen && bIsIsland) { // se isola aperta
|
||||
else if ( bIsAllOpen && bIsIsland) {
|
||||
// se isola aperta
|
||||
for ( int cI = 0 ; cI < pSfrInc->GetChunkCount() && ! bDiscard ; ++ cI) {
|
||||
for ( int cB = 0 ; cB < pSfrBean->GetChunkCount() && ! bDiscard ; ++ cB) {
|
||||
if ( pSfrInc->GetChunkSimpleClassification( cI, *pSfrBean, cB) == REGC_IN1) {
|
||||
@@ -1424,8 +1408,7 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
PtrOwner<ISurfFlatRegion> pSfrLimit( PockParams.SfrLimit.Clone()) ;
|
||||
if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid())
|
||||
return false ;
|
||||
// piccolo Offset per sicurezza
|
||||
pSfrLimit->Offset( 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
|
||||
pSfrLimit->Offset( 50. * EPS_SMALL, ICurve::OFF_FILLET) ;
|
||||
pSfrInc->Subtract( *pSfrLimit) ; // rimuovo la regione limite
|
||||
|
||||
// può capitare che la regione Limite mi crei più Chunk sulla pSfrInc
|
||||
@@ -1574,7 +1557,6 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1601,9 +1583,14 @@ 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
|
||||
// se lavorazione a ZigZag con smusso
|
||||
if ( PockParams.nType == POCKET_ZIGZAG && PockParams.bSmooth)
|
||||
dRad += max( PockParams.dSideStep / 2, PockParams.dRad / 8) ;
|
||||
dRad += PockParams.bSmooth ;
|
||||
// se lavorazione Conformal
|
||||
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG || PockParams.nType == POCKET_CONFORMAL_ONEWAY) {
|
||||
if ( PockParams.dRad - PockParams.dSideStep > 0)
|
||||
dRad -= PockParams.dSideStep ;
|
||||
}
|
||||
|
||||
// salvo il raggio trovato
|
||||
PockParams.dOpenEdgeRad = dRad ;
|
||||
@@ -1639,25 +1626,21 @@ AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvI
|
||||
// controllo che sia almeno lungo quanto il diametro utensile
|
||||
double dLen = 0. ;
|
||||
vpCrvs[i]->GetLength( dLen) ;
|
||||
if ( dLen > PockParams.dRad * 2 - 5 * EPS_SMALL) {
|
||||
// ricavo la tangenze dei lati chiusi agli estremi di questa curva
|
||||
Vector3d vtTanS = V_INVALID ;
|
||||
Vector3d vtTanE = V_INVALID ;
|
||||
if ( i != 0) {
|
||||
if ( ! vpCrvs[i-1]->GetEndDir( vtTanS) || // tangente finale del chiuso precedente
|
||||
! vpCrvs[( i + 1) % int( vpCrvs.size())]->GetStartDir( vtTanE)) // tangente iniziale del chiuso successivo...
|
||||
return false ;
|
||||
vtTanE.Invert() ; // invertita
|
||||
}
|
||||
if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, vtTanS, vtTanE, dRad, dDiamJ, PockParams, vpCrvs[i]))
|
||||
// ricavo la tangenze dei lati chiusi agli estremi di questa curva
|
||||
Vector3d vtTanS = V_INVALID ;
|
||||
Vector3d vtTanE = V_INVALID ;
|
||||
if ( i != 0) {
|
||||
if ( ! vpCrvs[i-1]->GetEndDir( vtTanS) || // tangente finale del chiuso precedente
|
||||
! vpCrvs[( i + 1) % int( vpCrvs.size())]->GetStartDir( vtTanE)) // tangente iniziale del chiuso successivo...
|
||||
return false ;
|
||||
vtTanE.Invert() ; // invertita
|
||||
}
|
||||
else
|
||||
nCurrTmpProp = TEMP_PROP_CLOSE_EDGE ;
|
||||
if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, vtTanS, vtTanE, dRad, dDiamJ, PockParams, vpCrvs[i]))
|
||||
return false ;
|
||||
}
|
||||
// assegno le proprietà di lato Aperto/Chiuso per la curva corrente
|
||||
for ( int u = 0 ; u < vpCrvs[i]->GetCurveCount() ; ++ u)
|
||||
vpCrvs[i]->SetCurveTempProp( u, nCurrTmpProp, 0) ;
|
||||
vpCrvs[i]->SetCurveTempProp( u, nCurrTmpProp, TEMP_PROP_CLOSE_EDGE) ;
|
||||
// aggiungo la curva ricavata ( se chiusa -> la copio, se aperta -> copio l'estesa)
|
||||
if ( ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone())) {
|
||||
// per sicurezza, se gli estremi non coincidono, creo un piccolo raccordo lineare
|
||||
@@ -1840,14 +1823,14 @@ AdvanceExtendCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const ISurfFlatRegion* pSfr,
|
||||
Vector3d vtStart ; vCrvCompo[i]->GetStartDir( vtStart) ;
|
||||
vtStart.Invert() ;
|
||||
bool bIsStartExtended = false ;
|
||||
if ( ! ExtendPath( vCrvCompo[i], pSfr, PockParams, vtStart, false, bIsStartExtended))
|
||||
if ( ! ExtendPath( vCrvCompo[i], pSfr, PockParams, vtStart, false, PockParams.dRad + PockParams.dOpenMinSafe, bIsStartExtended))
|
||||
return false ;
|
||||
// se aperta, controllo la fine
|
||||
if ( ! bIsClosed) {
|
||||
// ricavo vettore tangente finale e provo ad estendere
|
||||
Vector3d vtEnd ; vCrvCompo[i]->GetEndDir( vtEnd) ;
|
||||
bool bIsEndExtended = false ;
|
||||
if ( ! ExtendPath( vCrvCompo[i], pSfr, PockParams, vtEnd, true, bIsEndExtended))
|
||||
if ( ! ExtendPath( vCrvCompo[i], pSfr, PockParams, vtEnd, true, PockParams.dRad + PockParams.dOpenMinSafe, bIsEndExtended))
|
||||
return false ;
|
||||
if ( bIsEndExtended)
|
||||
break ;
|
||||
@@ -2155,7 +2138,6 @@ GetSinglePocketingCurves( ISurfFlatRegion* pSfr, PocketParams& PockParams,
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams)
|
||||
@@ -2295,7 +2277,6 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, PocketParams& PockParams)
|
||||
if ( ! pSrfFinal->IsValid())
|
||||
return false ;
|
||||
|
||||
|
||||
// chiudo le isole che risultano ambigue ( quindi non omgenee)
|
||||
for ( int nC = 0 ; nC < pSrfFinal->GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 1 ; nL < pSrfFinal->GetLoopCount( nC) ; ++ nL) {
|
||||
@@ -3662,7 +3643,7 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
|
||||
pCrvRes->GetStartDir( vtMidOut) ;
|
||||
vtMidOut.Rotate( pSfrChunk->GetNormVersor(), PockParam.bInvert ? ANG_RIGHT : - ANG_RIGHT) ;
|
||||
bool bIsExtended ;
|
||||
ExtendPath( pCrvRes, pSfrChunk, PockParam, vtMidOut, false, bIsExtended) ;
|
||||
ExtendPath( pCrvRes, pSfrChunk, PockParam, vtMidOut, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsExtended) ;
|
||||
}
|
||||
// se invece lavorazione in SpiralOut, inverto il percorso
|
||||
else if ( PockParam.nType == POCKET_SPIRALOUT)
|
||||
@@ -3694,11 +3675,11 @@ GetSpiralOptimizedCurves( const ISurfFlatRegion* pSfrChunk, const PocketParams&
|
||||
Vector3d vtRef ; pCrvRes->GetStartDir( vtRef) ;
|
||||
vtRef.Invert() ;
|
||||
bool bIsStartExtended = false ;
|
||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, bIsStartExtended))
|
||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, false, PockParam.dRad + PockParam.dOpenMinSafe, bIsStartExtended))
|
||||
return false ;
|
||||
pCrvRes->GetEndDir( vtRef) ;
|
||||
bool bIsEndExtended = false ;
|
||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, true, bIsEndExtended))
|
||||
if ( ! ExtendPath( pCrvRes, pSfrChunk, PockParam, vtRef, true, PockParam.dRad + PockParam.dOpenMinSafe, bIsEndExtended))
|
||||
return false ;
|
||||
if ( bIsEndExtended && ! bIsStartExtended)
|
||||
pCrvRes->Invert() ;
|
||||
@@ -4943,7 +4924,7 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const
|
||||
return false ;
|
||||
}
|
||||
// La curva necessita di un ulteriore smusso, in quanto tagliata su un bordo
|
||||
ModifyCurveToSmoothed( pCompoTest, PockParams, PockParams.dRad / 4., PockParams.dRad / 4., false) ;
|
||||
ModifyCurveToSmoothed( pCompoTest, PockParams, PockParams.dSmooth, PockParams.dSmooth, false) ;
|
||||
// nel caso speciale della circonferenza, devo impostare il punto iniziale
|
||||
if ( dParMeet < EPS_ZERO) {
|
||||
if ( pCompoTest->IsClosed()) { // sempre...
|
||||
@@ -6064,7 +6045,7 @@ CalcSpiral( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig, co
|
||||
}
|
||||
|
||||
// smusso le curve di offset ( ad eccezione di quelle di primo Offset)
|
||||
double dSmoothPar = PockParams.dRad / 8. ;
|
||||
double dSmoothPar = PockParams.dSmooth / SQRT2 ;
|
||||
for ( int i = 0 ; i < int( vOffs.size()) ; ++ i) {
|
||||
if ( i >= nCrvFirstOffs)
|
||||
ModifyCurveToSmoothed( vOffs[i], PockParams, dSmoothPar, dSmoothPar, false) ;
|
||||
@@ -6664,7 +6645,7 @@ AddSpiralIn( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig,
|
||||
|
||||
bool bIsExtended = false ;
|
||||
if ( bSomeOpen)
|
||||
ExtendPath( pMCrv, pSfrOrig, PockParams, vtMidOut, false, bIsExtended) ;
|
||||
ExtendPath( pMCrv, pSfrOrig, PockParams, vtMidOut, false, PockParams.dRad + PockParams.dOpenMinSafe, bIsExtended) ;
|
||||
|
||||
// inserisco le curve nel vettore
|
||||
vCrvCompoRes.emplace_back( Release( pMCrv)) ;
|
||||
@@ -6946,10 +6927,10 @@ AddZigZag( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
|
||||
Vector3d vtRef ; vpCrvs[nU]->GetStartDir( vtRef) ;
|
||||
vtRef.Invert() ;
|
||||
bool bIsExtended = false ;
|
||||
if ( ! ExtendPath( vpCrvs[nU], pSfrOrig, PockParams, vtRef, false,bIsExtended))
|
||||
if ( ! ExtendPath( vpCrvs[nU], pSfrOrig, PockParams, vtRef, false, PockParams.dRad + PockParams.dOpenMinSafe, bIsExtended))
|
||||
return false ;
|
||||
vpCrvs[nU]->GetEndDir( vtRef) ;
|
||||
if ( ! ExtendPath( vpCrvs[nU], pSfrOrig, PockParams, vtRef, true, bIsExtended))
|
||||
if ( ! ExtendPath( vpCrvs[nU], pSfrOrig, PockParams, vtRef, true, PockParams.dRad + PockParams.dOpenMinSafe, bIsExtended))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
@@ -7147,10 +7128,10 @@ AddOneWay( ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, PocketPar
|
||||
Vector3d vtRef ; pCrvSegCompo->GetStartDir( vtRef) ;
|
||||
vtRef.Invert() ;
|
||||
bool bIsExtended = false ;
|
||||
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, false,bIsExtended))
|
||||
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, false, PockParams.dRad + PockParams.dOpenMinSafe, bIsExtended))
|
||||
return false ;
|
||||
pCrvSegCompo->GetEndDir( vtRef) ;
|
||||
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, true, bIsExtended))
|
||||
if ( ! ExtendPath( pCrvSegCompo, pSfrOrig, PockParams, vtRef, true, PockParams.dRad + PockParams.dOpenMinSafe, bIsExtended))
|
||||
return false ;
|
||||
}
|
||||
vCrvCompoRes.emplace_back( Release( pCrvSegCompo)) ;
|
||||
@@ -7412,7 +7393,7 @@ CalcConformalLink( ICurveComposite* pCrvOffs0, ICurveComposite* pCrvOffs1, Pocke
|
||||
if ( PockParams.nType == POCKET_CONFORMAL_ZIGZAG) {
|
||||
// effettuo smusso del tratto lineare
|
||||
SmoothLinkByOffs( pCrvOffs0, pCrvOffs1, pCrvLink, PockParams, bFirstIterOffs0, bFirstIterOffs1,
|
||||
PockParams.dRad / 5., TOL) ;
|
||||
PockParams.dSmooth, TOL) ;
|
||||
// per sicurezza aggiorno i nuovi punti e i nuovi parametri
|
||||
double dUNewE ;
|
||||
Point3d ptStartNext ;
|
||||
@@ -7953,21 +7934,37 @@ ExtendConformalOffsAndSetFeed( const ISurfFlatRegion* pSfrPock, const ISurfFlatR
|
||||
return false ;
|
||||
if ( vCrvOffs.empty())
|
||||
return true ;
|
||||
/*
|
||||
dalla superificie estesa presso i lati aperti, effettuo un Offset interno pari alla somma del
|
||||
raggio utensile e dell'offset radiale. La ricerca delle zone non svuotate avviene all'interno
|
||||
di questa regione
|
||||
*/
|
||||
ICRVCOMPOPOVECTOR vCrvFirstOffs ;
|
||||
if ( ! GetFirstOffsCrvFromSfr( pSfrPock, - PockParams.dRad - PockParams.dRadialOffset, vCrvFirstOffs))
|
||||
|
||||
// definisco la regione di ricerca delle aree non svuotate come la regione originale
|
||||
PtrOwner<ISurfFlatRegion> pSfrBorder( CloneSurfFlatRegion( pSfrPock)) ;
|
||||
if ( IsNull( pSfrBorder) || ! pSfrBorder->IsValid())
|
||||
return false ;
|
||||
|
||||
// dalla superficie originale, rimuovo le parti definite dai lati chiusi
|
||||
double dOffs = PockParams.dRad + PockParams.dRadialOffset - 2. * EPS_SMALL ;
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
for ( int nC = 0 ; nC < pSfrPock->GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < pSfrPock->GetLoopCount( nC) ; ++ nL) {
|
||||
PtrOwner<ICurveComposite> pCompoLoop( ConvertCurveToComposite( pSfrPock->GetLoop( nC, nL))) ;
|
||||
if ( IsNull( pCompoLoop) || ! pCompoLoop->IsValid())
|
||||
return false ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrToDiscard( GetSurfFlatRegionFromFatCurve( pCompoLoop->Clone(), dOffs, false, false)) ;
|
||||
if ( IsNull( pSfrToDiscard) || ! pSfrToDiscard->IsValid())
|
||||
return false ;
|
||||
if ( ! pSfrBorder->Subtract( *pSfrToDiscard))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
ICRVCOMPOPOVECTOR vCrvBorder ;
|
||||
if ( ! GetSfrCrvCompoLoops( pSfrBorder, vCrvBorder))
|
||||
return false ;
|
||||
// determino eventuale regioni con parti non svuotate e imposto la Feed alle curve
|
||||
PtrOwner<ISurfFlatRegion> pSfrUncleared( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrUncleared))
|
||||
return false ;
|
||||
if ( GetUnclearedRegionAndSetFeed( vCrvFirstOffs, vCrvOffs, vCrvLinks, pSfrOrig, PockParams, pSfrUncleared)) {
|
||||
if ( GetUnclearedRegionAndSetFeed( vCrvBorder, vCrvOffs, vCrvLinks, pSfrOrig, PockParams, pSfrUncleared)) {
|
||||
// estendo i percorsi di Offset se richiesto
|
||||
if ( ! RemoveUnclearedRegions( pSfrUncleared, vCrvOffs, vCrvFirstOffs, PockParams))
|
||||
if ( ! RemoveUnclearedRegions( pSfrUncleared, vCrvOffs, vCrvBorder, PockParams))
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -8058,14 +8055,24 @@ AddLeadInLeadOutToCurveConformalPaths( const ISurfFlatRegion* pSfrOrig, const IS
|
||||
}
|
||||
|
||||
// estendo il percorso sul tratto iniziale e finale ( se ammissibile)
|
||||
Vector3d vtTan ; vCrvPaths[i]->GetStartDir( vtTan) ;
|
||||
vtTan.Invert() ;
|
||||
bool bOkExtension ;
|
||||
if ( ! ExtendPath( vCrvPaths[i], pSfrOrig, PockParams, vtTan, false, bOkExtension))
|
||||
return false ;
|
||||
vCrvPaths[i]->GetEndDir( vtTan) ;
|
||||
if ( ! ExtendPath( vCrvPaths[i], pSfrOrig, PockParams, vtTan, true, bOkExtension))
|
||||
return false ;
|
||||
Vector3d vtTanS, vtTanE ;
|
||||
vCrvPaths[i]->GetStartDir( vtTanS) ; vtTanS.Invert() ;
|
||||
vCrvPaths[i]->GetEndDir( vtTanE) ;
|
||||
const int MAXTRY = 8 ;
|
||||
bool bOkStartExtension = false, bOkEndExtension = false ;
|
||||
for ( int j = 0 ; j <= MAXTRY ; ++ j) {
|
||||
if ( bOkStartExtension && bOkEndExtension)
|
||||
break ;
|
||||
double dDist = PockParams.dOpenMinSafe + j * ( PockParams.dRad / ( 1. * MAXTRY)) ;
|
||||
if ( ! bOkStartExtension) {
|
||||
if ( ! ExtendPath( vCrvPaths[i], pSfrOrig, PockParams, vtTanS, false, dDist, bOkStartExtension))
|
||||
return false ;
|
||||
}
|
||||
if ( ! bOkEndExtension) {
|
||||
if ( ! ExtendPath( vCrvPaths[i], pSfrOrig, PockParams, vtTanE, true, dDist, bOkEndExtension))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -8336,7 +8343,7 @@ ExtendGuideByIteration( ICurveComposite* pCompoTempGuide, const ICurveComposite*
|
||||
pCompoPerimeter == nullptr || ! pCompoPerimeter->IsValid())
|
||||
return false ;
|
||||
|
||||
const double EXTENSION_VAL = 1000. ;
|
||||
const double EXTENSION_VAL = 5000. ;
|
||||
|
||||
// ricavo il punto finale della guida
|
||||
Point3d ptEndGuide ; pCompoTempGuide->GetEndPoint( ptEndGuide) ;
|
||||
@@ -8365,7 +8372,9 @@ ExtendGuideByIteration( ICurveComposite* pCompoTempGuide, const ICurveComposite*
|
||||
Point3d ptPoly ;
|
||||
PL.GetFirstPoint( ptPoly) ;
|
||||
while ( PL.GetNextPoint( ptPoly)) {
|
||||
if ( ! pSeg->Set( ptEndGuide, ptEndGuide + ( ptPoly - ptEndGuide) * EXTENSION_VAL))
|
||||
Vector3d vtDir = ptPoly - ptEndGuide ;
|
||||
vtDir.Normalize() ;
|
||||
if ( ! pSeg->Set( ptEndGuide, ptEndGuide + vtDir * EXTENSION_VAL))
|
||||
return false ;
|
||||
// calcolo l'intersezione tra questo segmento e la curva di perimetro aperta
|
||||
IntersCurveCurve ICC( *pSeg, *pCompoPerimeter) ;
|
||||
@@ -8582,7 +8591,6 @@ GetConformalOffsets( const ISurfFlatRegion* pSfrChunk, const ISurfFlatRegion* pS
|
||||
ICRVCOMPOPOVECTOR vpCrvs ;
|
||||
PtrOwner<ICurveComposite> pCrvExtLoop( ConvertCurveToComposite( pSfrChunk->GetLoop( 0, 0))) ;
|
||||
if ( IsNull( pCrvExtLoop) || ! pCrvExtLoop->IsValid() ||
|
||||
! AdjustCloseEdgesForConformalGuide( pCrvExtLoop, PockParam) ||
|
||||
! IsCompoMadeBy2DifferentHomogeneousParts( pCrvExtLoop, PockParam, bOk, vpCrvs))
|
||||
return false ;
|
||||
if ( ! bOk)
|
||||
@@ -8747,10 +8755,94 @@ GetConformalOffsets( const ISurfFlatRegion* pSfrChunk, const ISurfFlatRegion* pS
|
||||
}
|
||||
|
||||
// smusso le curve di Offset ( ad eccezione di quelle generate alla prima iterazione)
|
||||
double dSmoothPar = PockParam.dRad / 8. ;
|
||||
for ( int i = 1 ; i < int( vCrvOffs.size()) ; ++ i) {
|
||||
for ( int j = 0 ; j < int( vCrvOffs[i].size()) ; ++ j)
|
||||
ModifyCurveToSmoothed( vCrvOffs[i][j], PockParam, dSmoothPar, dSmoothPar, false) ;
|
||||
ModifyCurveToSmoothed( vCrvOffs[i][j], PockParam, PockParam.dSmooth, PockParam.dSmooth, false) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CalcSpiralPocketing( const ISurfFlatRegion* pSfr, int nType, const PocketParams& PockParams,
|
||||
ICRVCOMPOPOVECTOR& vCrvCompoRes)
|
||||
{
|
||||
// verifica validità della superficie
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
||||
return false ;
|
||||
// il tipo può essere solo SpiralIn o SpiralOut
|
||||
if ( nType != POCKET_SPIRALIN && nType != POCKET_SPIRALOUT)
|
||||
return false ;
|
||||
// calcolo il percorso di svuotatura spiral
|
||||
return ( CalcPocketing( pSfr, PockParams.dRad, PockParams.dRadialOffset, PockParams.dSideStep,
|
||||
PockParams.dAngle, PockParams.dOpenMinSafe, nType, PockParams.bSmooth,
|
||||
PockParams.bCalcUnclearedRegs, PockParams.bInvert, PockParams.bAvoidOpt,
|
||||
PockParams.bAllowZigZagOneWayBorders, PockParams.bCalcFeed, PockParams.ptStart,
|
||||
PockParams.SfrLimit.IsValid() ? PockParams.SfrLimit.Clone() : CreateSurfFlatRegion(),
|
||||
PockParams.bAvoidOpt, PockParams.dMaxOptSize, PockParams.dLiTang, PockParams.nLiType,
|
||||
vCrvCompoRes)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
GetOrigChunkForConformal( const ISurfFlatRegion* pSfrChunk, const ISurfFlatRegion* pSfrOrig,
|
||||
set<int>& setChunks)
|
||||
{
|
||||
// NB. funzione migliorabile... potrei calcolare tutto all'inizio senza ripetere le intersezioni
|
||||
// controllo validità delle regioni
|
||||
if ( pSfrChunk == nullptr || ! pSfrChunk->IsValid() ||
|
||||
pSfrOrig == nullptr || ! pSfrOrig->IsValid())
|
||||
return false ;
|
||||
|
||||
// se la superficie originale ha un solo Chunk allora è lui stesso
|
||||
if ( pSfrOrig->GetChunkCount() == 1) {
|
||||
setChunks.insert( 0) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// essendo la pSfrChunk estesa, cerco quale chunk di pSfrOrig ha una intersezione valida
|
||||
for ( int nC = 0 ; nC < pSfrOrig->GetChunkCount() ; ++ nC) {
|
||||
// se il Chunk è già stato analizzato in precedenza, passo al successivo
|
||||
if ( setChunks.find( nC) != setChunks.end())
|
||||
continue ;
|
||||
// recupero il Chunk corrente
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunkOrig( pSfrOrig->CloneChunk( nC)) ;
|
||||
if ( IsNull( pSfrChunkOrig) || ! pSfrChunkOrig->IsValid())
|
||||
return false ;
|
||||
// controllo se esiste l'intersezione
|
||||
if ( pSfrChunkOrig->Intersect( *pSfrChunk) && pSfrChunkOrig->IsValid())
|
||||
setChunks.insert( nC) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CreateSurfFromOtherChunks( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrOther, const set<int>& setChunks)
|
||||
{
|
||||
// controllo della regione
|
||||
if ( pSfr == nullptr ||
|
||||
pSfrOther == nullptr || ! pSfrOther->IsValid())
|
||||
return false ;
|
||||
|
||||
// se non ho indici di Chunk non faccio nulla
|
||||
if ( setChunks.empty())
|
||||
return true ;
|
||||
|
||||
// scorro gli indici dei Chunks
|
||||
for ( auto it = setChunks.begin() ; it != setChunks.end() ; ++ it) {
|
||||
// recupero l'indice del Chunk
|
||||
int nChunk = *it ;
|
||||
// recupero il Chunk come regione piana
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk( pSfrOther->CloneChunk( nChunk)) ;
|
||||
if ( ! IsNull( pSfrChunk) && pSfrChunk->IsValid()) {
|
||||
if ( ! pSfr->IsValid())
|
||||
pSfr->CopyFrom( pSfrChunk) ;
|
||||
else if ( ! pSfr->Add( *pSfrChunk))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
@@ -8767,99 +8859,119 @@ AddConformal( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrOrig,
|
||||
return true ;
|
||||
|
||||
// se superifice tutta aperta, lavoro in SPIRAL_IN
|
||||
if ( PockParams.bAllOpen) {
|
||||
PockParams.nType = POCKET_SPIRALIN ;
|
||||
return ( AddSpiralIn( pSfrPock, pSfrOrig, PockParams, vCrvCompoRes)) ;
|
||||
}
|
||||
if ( PockParams.bAllOpen)
|
||||
return ( CalcSpiralPocketing( pSfrOrig, POCKET_SPIRALIN, PockParams, vCrvCompoRes)) ;
|
||||
// se superficie tutta chiusa, lavoro in SPIRAL_OUT
|
||||
if ( PockParams.bAllClosed) {
|
||||
PockParams.nType = POCKET_SPIRALOUT ;
|
||||
return ( AddSpiralOut( pSfrPock, pSfrOrig, PockParams, vCrvCompoRes)) ;
|
||||
}
|
||||
if ( PockParams.bAllClosed)
|
||||
return ( CalcSpiralPocketing( pSfrOrig, POCKET_SPIRALOUT, PockParams, vCrvCompoRes)) ;
|
||||
|
||||
// definisco eventuali regioni da lavorare in SpiralIn e SpiralOut
|
||||
PtrOwner<ISurfFlatRegion> pSfrSpiralIn( CreateSurfFlatRegion()) ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrSpiralOut( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrSpiralIn) || IsNull( pSfrSpiralOut))
|
||||
return false ;
|
||||
// NB. La supercicie pSfrPock è estesa presso i lati aperti, quindi il suo numero di Chunk potrebbe
|
||||
// essere differente dal numero di Chunk della superficie originale di svuotatura. Tengo un insieme di
|
||||
// di indici dei Chunk che devono essere lavorati in SpiralIn e in SpiralOut
|
||||
set<int> setIndChunkSpiralIn ;
|
||||
set<int> setIndChunkSpiralOut ;
|
||||
|
||||
// scorro i chunk della superficie da lavorare
|
||||
for ( int nC = 0 ; nC < pSfrPock->GetChunkCount() ; ++ nC) {
|
||||
|
||||
// controllo se il Chunk ha tutte proprietà omogenee tra loro
|
||||
bool bClose, bOpen ;
|
||||
if ( ! IsChunkAllHomogeneous( pSfrPock, nC, bClose, bOpen))
|
||||
return false ;
|
||||
|
||||
// recupero il Chunk come regione piana
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk( pSfrPock->CloneChunk( nC)) ;
|
||||
if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid())
|
||||
return false ;
|
||||
// se Chunk tutto aperto, lo lavoro in SPIRAL_IN
|
||||
|
||||
// --- se Chunk tutto aperto, aggiorno i Chunk della superficie originale da lavorare in SpiralIn
|
||||
if ( bOpen) {
|
||||
int nType = PockParams.nType ;
|
||||
PockParams.nType = POCKET_SPIRALIN ;
|
||||
if ( ! AddSpiralIn( pSfrChunk, pSfrOrig, PockParams, vCrvCompoRes))
|
||||
if ( ! GetOrigChunkForConformal( pSfrChunk, pSfrOrig, setIndChunkSpiralIn))
|
||||
return false ;
|
||||
PockParams.nType = nType ;
|
||||
continue ;
|
||||
}
|
||||
// se Chunk tutto chiuso, lo lavoro in SPIRAL_OUT
|
||||
// --- se Chunk tutto chiuso, lo lavoro in SPIRAL_OUT
|
||||
else if ( bClose) {
|
||||
int nType = PockParams.nType ;
|
||||
PockParams.nType = POCKET_SPIRALOUT ;
|
||||
if ( ! AddSpiralOut( pSfrChunk, pSfrOrig, PockParams, vCrvCompoRes))
|
||||
return false ;
|
||||
PockParams.nType = nType ;
|
||||
if ( ! GetOrigChunkForConformal( pSfrChunk, pSfrOrig, setIndChunkSpiralOut))
|
||||
continue ;
|
||||
}
|
||||
// se Chunk non omogeneo
|
||||
else {
|
||||
// ricavo gli Offset ( se possibili) dei tratti chiusi del Chunk
|
||||
VICRVCOMPOPOVECTOR vvCrvOffs ;
|
||||
if ( ! GetConformalOffsets( pSfrChunk, pSfrChunk, pSfrOrig, PockParams, vvCrvOffs))
|
||||
// --- se chunk non omogoneo, ricavo gli Offset ( se possibili) dei tratti chiusi del Chunk
|
||||
VICRVCOMPOPOVECTOR vvCrvOffs ;
|
||||
if ( ! GetConformalOffsets( pSfrChunk, pSfrChunk, pSfrOrig, PockParams, vvCrvOffs))
|
||||
return false ;
|
||||
|
||||
// se non ottengo Curve di Offset, lavoro in SpiralIn ( il Chunk ha dei lati aperti)
|
||||
if ( vvCrvOffs.empty()) {
|
||||
if ( ! GetOrigChunkForConformal( pSfrChunk, pSfrOrig, setIndChunkSpiralIn))
|
||||
return false ;
|
||||
// se non ottengo Curve di Offset, lavoro in SpiralIn ( il Chunk ha dei lati aperti)
|
||||
if ( vvCrvOffs.empty()) {
|
||||
int nType = PockParams.nType ;
|
||||
PockParams.nType = POCKET_SPIRALIN ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk_cl( CloneSurfFlatRegion( pSfrChunk)) ;
|
||||
if ( IsNull( pSfrChunk_cl) || ! pSfrChunk_cl->IsValid() ||
|
||||
! AddSpiralIn( pSfrChunk_cl, pSfrOrig, PockParams, vCrvCompoRes))
|
||||
return false ;
|
||||
PockParams.nType = nType ;
|
||||
}
|
||||
else {
|
||||
// definisco vettore degli Offset e dei Link
|
||||
ICRVCOMPOPOVECTOR vCrvOffs ;
|
||||
ICURVEPOVECTOR vCrvLink ;
|
||||
// ordino le curve di Offset e raccordo
|
||||
if ( ! CalcConformalOffsAndLinks( vvCrvOffs, pSfrChunk, pSfrPock, PockParams, vCrvOffs, vCrvLink)) {
|
||||
// se calcolare i raccordi risulta troppo ambiguo o complesso, ritorno a SpiralIn
|
||||
int nType = PockParams.nType ;
|
||||
PockParams.nType = POCKET_SPIRALIN ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk_cl( CloneSurfFlatRegion( pSfrChunk)) ;
|
||||
if ( IsNull( pSfrChunk_cl) || ! pSfrChunk_cl->IsValid() ||
|
||||
! AddSpiralIn( pSfrChunk_cl, pSfrOrig, PockParams, vCrvCompoRes))
|
||||
return false ;
|
||||
PockParams.nType = nType ;
|
||||
continue ;
|
||||
}
|
||||
// flag per controllo
|
||||
bool bOk = true ;
|
||||
// estendo i percorsi per eventuali regioni non svuotate e calcolo le Feed
|
||||
bOk = bOk && ExtendConformalOffsAndSetFeed( pSfrPock, pSfrOrig, PockParams, vCrvOffs, vCrvLink) ;
|
||||
// concateno Offset e Links
|
||||
ICRVCOMPOPOVECTOR vCrvPaths ;
|
||||
bOk = bOk && ChainConformalOffsWithLinks( vCrvOffs, vCrvLink, vCrvPaths) ;
|
||||
// estendo per lati aperti ed ordino i percorsi trovati
|
||||
bOk = bOk && OrderAndExtendConformalPaths( vCrvPaths, pSfrChunk, pSfrOrig, PockParams) ;
|
||||
if ( ! bOk) {
|
||||
// se qualche passaggio restituisce errore, provo in SpiralIn
|
||||
int nType = PockParams.nType ;
|
||||
PockParams.nType = POCKET_SPIRALIN ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrChunk_cl( CloneSurfFlatRegion( pSfrChunk)) ;
|
||||
if ( IsNull( pSfrChunk_cl) || ! pSfrChunk_cl->IsValid() ||
|
||||
! AddSpiralIn( pSfrChunk_cl, pSfrOrig, PockParams, vCrvCompoRes))
|
||||
return false ;
|
||||
PockParams.nType = nType ;
|
||||
}
|
||||
else {
|
||||
// aggiungo i percorsi ricavati
|
||||
for ( int i = 0 ; i < int( vCrvPaths.size()) ; ++ i)
|
||||
vCrvCompoRes.emplace_back( Release( vCrvPaths[i])) ;
|
||||
}
|
||||
}
|
||||
continue ;
|
||||
}
|
||||
|
||||
// definisco i vettori ordinati degli Offset e dei Link
|
||||
ICRVCOMPOPOVECTOR vCrvOffs ;
|
||||
ICURVEPOVECTOR vCrvLink ;
|
||||
if ( ! CalcConformalOffsAndLinks( vvCrvOffs, pSfrChunk, pSfrPock, PockParams, vCrvOffs, vCrvLink)) {
|
||||
if ( ! GetOrigChunkForConformal( pSfrChunk, pSfrOrig, setIndChunkSpiralIn))
|
||||
return false ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
// flag per controllo
|
||||
bool bOk = true ;
|
||||
// estendo i percorsi per eventuali regioni non svuotate e calcolo le Feed
|
||||
bOk = bOk && ExtendConformalOffsAndSetFeed( pSfrPock, pSfrOrig, PockParams, vCrvOffs, vCrvLink) ;
|
||||
// concateno Offset e Links
|
||||
ICRVCOMPOPOVECTOR vCrvPaths ;
|
||||
bOk = bOk && ChainConformalOffsWithLinks( vCrvOffs, vCrvLink, vCrvPaths) ;
|
||||
// estendo per lati aperti ed ordino i percorsi trovati
|
||||
bOk = bOk && OrderAndExtendConformalPaths( vCrvPaths, pSfrChunk, pSfrOrig, PockParams) ;
|
||||
|
||||
// se qualche passaggio restituisce errore, provo in SpiralIn
|
||||
if ( ! bOk) {
|
||||
if ( ! GetOrigChunkForConformal( pSfrChunk, pSfrOrig, setIndChunkSpiralIn))
|
||||
return false ;
|
||||
continue ;
|
||||
}
|
||||
// altrimenti aggiungo i percorsi ricavati
|
||||
for ( int i = 0 ; i < int( vCrvPaths.size()) ; ++ i)
|
||||
vCrvCompoRes.emplace_back( Release( vCrvPaths[i])) ;
|
||||
}
|
||||
|
||||
// se ho superfici da lavorare in SpiralIn, aggiungo le curve
|
||||
if ( ! setIndChunkSpiralIn.empty()) {
|
||||
// costruisco la regione di SpiralIn
|
||||
PtrOwner<ISurfFlatRegion> pSfrSpiralIn( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrSpiralIn) ||
|
||||
! CreateSurfFromOtherChunks( pSfrSpiralIn, pSfrOrig, setIndChunkSpiralIn))
|
||||
return false ;
|
||||
// recupero le curve di Pocketing SpiralIn
|
||||
ICRVCOMPOPOVECTOR vCrvSpiralIn ;
|
||||
if ( ! CalcSpiralPocketing( pSfrSpiralIn, POCKET_SPIRALIN, PockParams, vCrvSpiralIn))
|
||||
return false ;
|
||||
for ( int i = 0 ; i < int( vCrvSpiralIn.size()) ; ++ i) {
|
||||
if ( vCrvSpiralIn[i] != nullptr && vCrvSpiralIn[i]->IsValid())
|
||||
vCrvCompoRes.emplace_back( Release( vCrvSpiralIn[i])) ;
|
||||
}
|
||||
}
|
||||
// se ho superfici da lavorare in SpiralOut, aggiungo le curve
|
||||
if ( ! setIndChunkSpiralOut.empty()) {
|
||||
// costruisco la regione di SpiralOut
|
||||
PtrOwner<ISurfFlatRegion> pSfrSpiralOut( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfrSpiralIn) ||
|
||||
! CreateSurfFromOtherChunks( pSfrSpiralOut, pSfrOrig, setIndChunkSpiralOut))
|
||||
return false ;
|
||||
// recupero le curve di Pocketing SpiralOut
|
||||
ICRVCOMPOPOVECTOR vCrvSpiralOut ;
|
||||
if ( ! CalcSpiralPocketing( pSfrSpiralOut, POCKET_SPIRALOUT, PockParams, vCrvSpiralOut))
|
||||
return false ;
|
||||
for ( int i = 0 ; i < int( vCrvSpiralOut.size()) ; ++ i) {
|
||||
if ( vCrvSpiralOut[i] != nullptr && vCrvSpiralOut[i]->IsValid())
|
||||
vCrvCompoRes.emplace_back( Release( vCrvSpiralOut[i])) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -320,6 +320,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||
<ClCompile Include="IntersLineSurfBez.cpp" />
|
||||
<ClCompile Include="MultiGeomDB.cpp" />
|
||||
<ClCompile Include="SurfTriMeshOffset.cpp" />
|
||||
<ClCompile Include="VolZmapOffset.cpp" />
|
||||
<ClCompile Include="PolygonElevation.cpp" />
|
||||
@@ -340,6 +341,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkMultiGeomDB.h" />
|
||||
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
||||
<ClInclude Include="..\Include\EGkQuaternion.h" />
|
||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
||||
|
||||
@@ -552,6 +552,9 @@
|
||||
<ClCompile Include="SurfTriMeshOffset.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MultiGeomDB.cpp">
|
||||
<Filter>File di origine\Gdb</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -1235,6 +1238,9 @@
|
||||
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkMultiGeomDB.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+14
@@ -101,6 +101,20 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::CopyStippleDataFrom( const GdbObj* pSou)
|
||||
{
|
||||
// se l'oggetto sorgente non esiste
|
||||
if ( pSou == nullptr)
|
||||
return false ;
|
||||
// copio stipple
|
||||
m_nStpFactor = pSou->m_nStpFactor ;
|
||||
m_nStpPattern = pSou->m_nStpPattern ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::CopyAttribsFrom( const GdbObj* pSou)
|
||||
|
||||
@@ -57,6 +57,7 @@ class GdbObj
|
||||
GdbObj( void) ;
|
||||
bool CopyFrom( const GdbObj* pSou) ;
|
||||
bool CopyAttribsFrom( const GdbObj* pSou) ;
|
||||
bool CopyStippleDataFrom( const GdbObj* pSou) ;
|
||||
bool CopyTextureDataFrom( const GdbObj* pSou) ;
|
||||
bool CopyUserObjFrom( const GdbObj* pSou) ;
|
||||
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ using namespace std ;
|
||||
class LockAddErase
|
||||
{
|
||||
public :
|
||||
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
LockAddErase( atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
{ if ( ! m_bUse) return ;
|
||||
while ( m_bAddEraseOn.test_and_set()) {
|
||||
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
|
||||
@@ -51,7 +51,7 @@ class LockAddErase
|
||||
} ;
|
||||
|
||||
private :
|
||||
std::atomic_flag& m_bAddEraseOn ;
|
||||
atomic_flag& m_bAddEraseOn ;
|
||||
bool m_bUse ;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ class GeomDB : public IGeomDB
|
||||
friend class GdbObj ;
|
||||
friend class GdbGroup ;
|
||||
friend class GdbGeo ;
|
||||
friend int CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
friend int CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
|
||||
public :
|
||||
~GeomDB( void) override ;
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : MultiGeomDB.cpp Data : 08.10.25 Versione : 2.7j1
|
||||
// Contenuto : Implementazione delle funzioni tra due GeomDB.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.10.25 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeomDB.h"
|
||||
#include "/EgtDev/Include/EGkMultiGeomDB.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// verifico i puntatori ai GeomDB
|
||||
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||
return GDB_ID_NULL ;
|
||||
// recupero l'oggetto da copiare dal GeomDB sorgente
|
||||
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
|
||||
if ( IsNull( pGObj))
|
||||
return GDB_ID_NULL ;
|
||||
// se in globale
|
||||
if ( bGlob) {
|
||||
// recupero il riferimento del sorgente
|
||||
Frame3d frSou ;
|
||||
if ( ! pSouGDB->GetGlobFrame( nSouId, frSou))
|
||||
return GDB_ID_NULL ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||
return GDB_ID_NULL ;
|
||||
// porto la copia da riferimento sorgente a quello destinazione
|
||||
pGObj->LocToLoc( frSou, frDest) ;
|
||||
}
|
||||
// lo inserisco nel GeomDB destinazione
|
||||
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, nSonBeforeAfter, Release( pGObj)) ;
|
||||
if ( nNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// recupero il riferimento del gruppo
|
||||
Frame3d frFrame ;
|
||||
pSouGDB->GetGroupFrame( nSouId) ;
|
||||
// se in globale
|
||||
if ( bGlob) {
|
||||
// recupero il riferimento del gruppo in globale
|
||||
if ( ! pSouGDB->GetGlobFrame( nSouId, frFrame))
|
||||
return GDB_ID_NULL ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||
return GDB_ID_NULL ;
|
||||
// porto la copia da riferimento sorgente a quello destinazione
|
||||
frFrame.ToLoc( frDest) ;
|
||||
}
|
||||
// inserisco un nuovo gruppo nel GeomDB destinazione
|
||||
int nNewId = pDstGDB->InsertGroup( nDestId, nRefId, nSonBeforeAfter, frFrame) ;
|
||||
if ( nNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
// copio gli eventuali figli
|
||||
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
|
||||
while ( nSonSouId != GDB_ID_NULL) {
|
||||
// nuovo identificativo oggetto destinazione
|
||||
int nSonNewId = GDB_ID_NULL ;
|
||||
// recupero il tipo di oggetto sorgente
|
||||
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
|
||||
// se l'oggetto da copiare è geometrico
|
||||
if ( nSonSouType == GDB_TY_GEO)
|
||||
nSonNewId = CopyGeoObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||
// se altrimenti è un gruppo
|
||||
else if ( nSonSouType == GDB_TY_GROUP)
|
||||
nSonNewId = CopyGroupObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||
// se copia non riuscita, esco con errore
|
||||
if ( nSonNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// passo al figlio successivo
|
||||
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// adatto e verifico i GeomDB
|
||||
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
|
||||
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
|
||||
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||
return GDB_ID_NULL ;
|
||||
// nuovo identificativo oggetto destinazione
|
||||
int nNewId = GDB_ID_NULL ;
|
||||
// recupero il tipo di oggetto sorgente
|
||||
int nSouType = pSouGDB->GetGdbType( nSouId) ;
|
||||
// se l'oggetto da copiare è geometrico
|
||||
if ( nSouType == GDB_TY_GEO) {
|
||||
nNewId = CopyGeoObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||
}
|
||||
// se altrimenti è un gruppo
|
||||
else if ( nSouType == GDB_TY_GROUP) {
|
||||
nNewId = CopyGroupObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||
{
|
||||
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, false) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
CopyGlob( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||
{
|
||||
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, true) ;
|
||||
}
|
||||
+208
-118
@@ -1,4 +1,4 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2016
|
||||
//----------------------------------------------------------------------------
|
||||
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
|
||||
@@ -563,10 +563,10 @@ VolZmap::GetPartLocalBBox( int nPart, BBox3d& b3Loc, int nFlag) const
|
||||
// Verifico lo stato.
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// Se una sola mappa o il numero di componenti è indefinito, vi è un errore.
|
||||
// Se una sola mappa o il numero di componenti è indefinito, vi è un errore.
|
||||
if ( m_nMapNum == 1 || m_nConnectedCompoCount == - 1)
|
||||
return false ;
|
||||
// Se la componente richiesta non esiste, vi è un errore.
|
||||
// Se la componente richiesta non esiste, vi è un errore.
|
||||
if ( nPart < 0 || nPart > m_nConnectedCompoCount - 1)
|
||||
return false ;
|
||||
// Calcolo Bounding-box
|
||||
@@ -614,10 +614,10 @@ VolZmap::GetPartBBox( int nPart, const Frame3d& frRef, BBox3d& b3Ref, int nFlag)
|
||||
// Verifico lo stato.
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// Se una sola mappa o il numero di componenti è indefinito, vi è un errore.
|
||||
// Se una sola mappa o il numero di componenti è indefinito, vi è un errore.
|
||||
if ( m_nMapNum == 1 || m_nConnectedCompoCount == - 1)
|
||||
return false ;
|
||||
// Se la componente richiesta non esiste, vi è un errore.
|
||||
// Se la componente richiesta non esiste, vi è un errore.
|
||||
if ( nPart < 0 || nPart > m_nConnectedCompoCount - 1)
|
||||
return false ;
|
||||
// Calcolo Bounding-box
|
||||
@@ -689,7 +689,7 @@ VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dell'asse di rotazione
|
||||
// verifico validità dell'asse di rotazione
|
||||
if ( vtAx.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -722,7 +722,7 @@ VolZmap::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del piano di specchiatura
|
||||
// verifico validità del piano di specchiatura
|
||||
if ( vtNorm.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -736,7 +736,7 @@ VolZmap::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei parametri
|
||||
// verifico validità dei parametri
|
||||
if ( vtNorm.IsSmall() || vtDir.IsSmall())
|
||||
return false ;
|
||||
|
||||
@@ -750,11 +750,11 @@ VolZmap::ToGlob( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
@@ -773,11 +773,11 @@ VolZmap::ToLoc( const Frame3d& frRef)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità del frame
|
||||
// verifico validità del frame
|
||||
if ( frRef.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se frame identità, non devo fare alcunché
|
||||
// se frame identità, non devo fare alcunché
|
||||
if ( IsGlobFrame( frRef))
|
||||
return true ;
|
||||
|
||||
@@ -796,11 +796,11 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// verifico validità dei frame
|
||||
// verifico validità dei frame
|
||||
if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR)
|
||||
return false ;
|
||||
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
|
||||
@@ -816,10 +816,10 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
int
|
||||
VolZmap::GetPartCount( void) const
|
||||
{
|
||||
// Se mono-dexel la connessione è incalcolabile.
|
||||
// Se mono-dexel la connessione è incalcolabile.
|
||||
if ( m_nMapNum == 1)
|
||||
return - 1 ;
|
||||
// Se il numero delle componenti è indefinito
|
||||
// Se il numero delle componenti è indefinito
|
||||
// lo ricalcolo e restituisco il risultato.
|
||||
if ( m_nConnectedCompoCount == - 1) {
|
||||
const_cast<VolZmap*>(this)->CheckMapConnection() ;
|
||||
@@ -870,7 +870,7 @@ VolZmap::CheckMapConnection( void)
|
||||
IntervalsToProcessStackVec.resize( nThreadMax) ;
|
||||
// Mi espando dal primo intervallo mettendo gli intervalli che intersecano nei vari thread
|
||||
FirstExpansionFromZ( nThreadMax, NewInt, IntervalsToProcessStackVec) ;
|
||||
// Lancio in parallelo più ricerche
|
||||
// Lancio in parallelo più ricerche
|
||||
int nActiveThread = 0 ;
|
||||
vector<future<bool>> vRes ;
|
||||
vRes.resize( nThreadMax) ;
|
||||
@@ -891,7 +891,7 @@ VolZmap::CheckMapConnection( void)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se l'intervallo non attraversa un nodo o ha già
|
||||
// Se l'intervallo non attraversa un nodo o ha già
|
||||
// un indice assegnato salto questa iterazione.
|
||||
else
|
||||
continue ;
|
||||
@@ -935,7 +935,7 @@ VolZmap::ExpandFromXInterval( IntContainer& IntCont)
|
||||
double dZmin = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMin ;
|
||||
double dZmax = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dZmin - 2 * EPS_SMALL < dZ &&
|
||||
dZmax + 2 * EPS_SMALL > dZ &&
|
||||
@@ -955,7 +955,7 @@ VolZmap::ExpandFromXInterval( IntContainer& IntCont)
|
||||
double dYmin = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMin ;
|
||||
double dYmax = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dYmin - 2 * EPS_SMALL < dY &&
|
||||
dYmax + 2 * EPS_SMALL > dY &&
|
||||
@@ -1006,7 +1006,7 @@ VolZmap::ExpandFromYInterval( IntContainer& IntCont)
|
||||
double dZmin = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMin ;
|
||||
double dZmax = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dZmin - 2 * EPS_SMALL < dZ &&
|
||||
dZmax + 2 * EPS_SMALL > dZ &&
|
||||
@@ -1026,7 +1026,7 @@ VolZmap::ExpandFromYInterval( IntContainer& IntCont)
|
||||
double dXmin = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMin ;
|
||||
double dXmax = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dXmin - 2 * EPS_SMALL < dX &&
|
||||
dXmax + 2 * EPS_SMALL > dX &&
|
||||
@@ -1077,7 +1077,7 @@ VolZmap::ExpandFromZInterval( IntContainer& IntCont)
|
||||
double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ;
|
||||
double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dXmin - 2 * EPS_SMALL < dX &&
|
||||
dXmax + 2 * EPS_SMALL > dX &&
|
||||
@@ -1097,7 +1097,7 @@ VolZmap::ExpandFromZInterval( IntContainer& IntCont)
|
||||
double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ;
|
||||
double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dYmin - 2 * EPS_SMALL < dY &&
|
||||
dYmax + 2 * EPS_SMALL > dY &&
|
||||
@@ -1146,7 +1146,7 @@ VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContaine
|
||||
double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ;
|
||||
double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dXmin - 2 * EPS_SMALL < dX &&
|
||||
dXmax + 2 * EPS_SMALL > dX &&
|
||||
@@ -1167,7 +1167,7 @@ VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContaine
|
||||
double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ;
|
||||
double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ;
|
||||
// Se i segmenti si incrociano e il nuovo trovato non
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// ha già un indice assegnato, assegno l'indice e
|
||||
// aggiungo l'intervallo trovato allo stack.
|
||||
if ( dYmin - 2 * EPS_SMALL < dY &&
|
||||
dYmax + 2 * EPS_SMALL > dY &&
|
||||
@@ -1214,13 +1214,13 @@ VolZmap::ClonePart( int nPart) const
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
// Se è definita una sola griglia non sono definibili le parti, errore
|
||||
// Se è definita una sola griglia non sono definibili le parti, errore
|
||||
if ( m_nMapNum == 1)
|
||||
return nullptr ;
|
||||
// Se è richiesta una componente fuori intervallo, errore
|
||||
// Se è richiesta una componente fuori intervallo, errore
|
||||
if ( nPart < 0 || nPart >= m_nConnectedCompoCount)
|
||||
return nullptr ;
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo.
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo.
|
||||
if ( m_nConnectedCompoCount == - 1)
|
||||
const_cast<VolZmap*>(this)->CheckMapConnection() ;
|
||||
// Se non vi sono componenti, errore
|
||||
@@ -1291,7 +1291,7 @@ VolZmap::ClonePart( int nPart) const
|
||||
pVolume->m_Values[nMap].resize( pVolume->m_nDim[nMap]) ;
|
||||
}
|
||||
|
||||
// Se almeno una griglia è nulla, non ha senso Zmap
|
||||
// Se almeno una griglia è nulla, non ha senso Zmap
|
||||
if ( pVolume->m_nDim[0] == 0 ||
|
||||
pVolume->m_nDim[1] == 0 ||
|
||||
pVolume->m_nDim[2] == 0)
|
||||
@@ -1343,8 +1343,8 @@ VolZmap::ClonePart( int nPart) const
|
||||
dNewOy = nMinIndJ[0] * m_dStep ;
|
||||
dNewOz = nMinIndJ[1] * m_dStep ;
|
||||
|
||||
// Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali,
|
||||
// infatti i sistemi di riferimento in gioco differiscono al più per una traslazione.
|
||||
// Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali,
|
||||
// infatti i sistemi di riferimento in gioco differiscono al più per una traslazione.
|
||||
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
||||
// Quote estreme Z
|
||||
switch ( nMap) {
|
||||
@@ -1407,10 +1407,10 @@ VolZmap::RemovePart( int nPart)
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// Se è definita una sola griglia non sono definibili le parti, errore
|
||||
// Se è definita una sola griglia non sono definibili le parti, errore
|
||||
if ( m_nMapNum == 1)
|
||||
return false ;
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo
|
||||
if ( m_nConnectedCompoCount == - 1)
|
||||
CheckMapConnection() ;
|
||||
// Se non vi sono componenti, abbiamo finito
|
||||
@@ -1452,7 +1452,7 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const
|
||||
// Verifico lo stato e che siano definibili le componenti connesse
|
||||
if ( m_nStatus != OK || m_nMapNum == 1)
|
||||
return - 1 ;
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo
|
||||
// Se il numero di componenti è indefinito, lo ricalcolo
|
||||
if ( m_nConnectedCompoCount == -1)
|
||||
const_cast<VolZmap*>( this)->CheckMapConnection() ;
|
||||
// Se non vi sono componenti, abbiamo finito
|
||||
@@ -1485,7 +1485,7 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const
|
||||
swap( ptEn.y, ptEn.z) ;
|
||||
swap( ptEn.x, ptEn.z) ;
|
||||
}
|
||||
// Calcolo la distanza del punto dal segmento corrente. Se è minore della minima distanza aggiorno quest'ultima
|
||||
// Calcolo la distanza del punto dal segmento corrente. Se è minore della minima distanza aggiorno quest'ultima
|
||||
// e la corrispondente componente connessa di minima distanza con la distanza e la componente connessa correnti.
|
||||
double dDist ;
|
||||
DistPointLine DistCalc( ptPL, ptSt, ptEn) ;
|
||||
@@ -1677,107 +1677,197 @@ VolZmap::SubtractSurfTm( const ISurfTriMesh* pStm)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::MakeUniform( double dToler)
|
||||
VolZmap::MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum)
|
||||
{
|
||||
// controllo validità dello Zmap
|
||||
// Controllo validità dello Zmap
|
||||
if ( ! IsValid())
|
||||
return false ;
|
||||
// la tolleranza deve essere minore dello step
|
||||
dToler = min( dToler, 0.95 * m_dStep) ;
|
||||
|
||||
// creo lo Zmpa che andrà a sostituire il corrente
|
||||
PtrOwner<VolZmap> pOldVolZmap( CloneBasicVolZmap( this)) ;
|
||||
if ( IsNull( pOldVolZmap))
|
||||
// creo lo ZMap per i riferimenti degli intervalli sulle griglie
|
||||
PtrOwner<VolZmap> pZMapCopy( CloneBasicVolZmap( this)) ;
|
||||
if ( IsNull( pZMapCopy) || ! pZMapCopy->IsValid())
|
||||
return false ;
|
||||
|
||||
// ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
|
||||
// salvo lo Zmap prima di modificare gli spilloni
|
||||
PtrOwner<VolZmap> pVolZMapCurrGrid( CloneBasicVolZmap( this)) ;
|
||||
if ( IsNull( pVolZMapCurrGrid))
|
||||
// creo uno ZMap per gli intervalli da aggiungere o da rimuovere
|
||||
PtrOwner<VolZmap> pZMapExtra( CreateBasicVolZmap()) ;
|
||||
if ( IsNull( pZMapExtra) ||
|
||||
! pZMapExtra->CreateEmpty( m_MapFrame.Orig(), m_dMaxZ[1] - m_dMinZ[1],
|
||||
m_dMaxZ[2] - m_dMinZ[2], m_dMaxZ[0] - m_dMinZ[0],
|
||||
m_dStep, IsTriDexel()))
|
||||
return false ;
|
||||
// ciclo sul numero di dexel presenti
|
||||
for ( int nDex = 0 ; nDex < int( m_Values[nGrid].size()) ; ++ nDex) {
|
||||
// se il dexel corrente non ha sotto-intervalli passo al successivo
|
||||
if ( int( m_Values[nGrid][nDex].size()) == 0)
|
||||
|
||||
// Dovendo effettuare estensioni, allargo gli ingobri nelle direzioni principali
|
||||
m_dMinZ[0] -= dToler ;
|
||||
m_dMinZ[1] -= dToler ;
|
||||
m_dMinZ[2] -= dToler ;
|
||||
m_dMaxZ[0] += dToler ;
|
||||
m_dMaxZ[1] += dToler ;
|
||||
m_dMaxZ[2] += dToler ;
|
||||
|
||||
// NB. Tutti i parametri sono sempre presi dalla Copia dello ZMap corrente
|
||||
// Ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < pZMapCopy->m_nMapNum ; ++ nGrid) {
|
||||
// Ciclo sul numero di dexel presenti nella Copia
|
||||
for ( int nDex = 0 ; nDex < int( pZMapCopy->m_Values[nGrid].size()) ; ++ nDex) {
|
||||
// Se il dexel corrente non ha sotto-intervalli passo al successivo
|
||||
if ( pZMapCopy->m_Values[nGrid][nDex].empty())
|
||||
continue ;
|
||||
// indici del dexel
|
||||
// Indici del dexel
|
||||
int nI = nDex % m_nNx[nGrid] ;
|
||||
int nJ = nDex / m_nNx[nGrid] ;
|
||||
// salvo le informazioni dei sotto-intervalli del dexel corrente
|
||||
vector<Data> vInfo ;
|
||||
for ( int nExtr = 0 ; nExtr < int( m_Values[nGrid][nDex].size()) ; ++ nExtr)
|
||||
vInfo.push_back( m_Values[nGrid][nDex][nExtr]) ;
|
||||
// per ogni sotto-intervallo, estendo a destra e a sinistra della tolleranza
|
||||
int nSub_intervals = int( vInfo.size()) ;
|
||||
// scorro gli intervalli
|
||||
for ( int nInfo = 0 ; nInfo < int( pVolZMapCurrGrid->m_Values[nGrid][nDex].size()) ; ++ nInfo) {
|
||||
// estremo inferiore
|
||||
if ( vInfo[nInfo].dMin - dToler > m_dMinZ[nGrid]) {
|
||||
AddIntervals( nGrid, nI, nJ,
|
||||
vInfo[nInfo].dMin - dToler,
|
||||
vInfo[nInfo].dMin + dToler,
|
||||
vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN, vInfo[nInfo].nToolMin,
|
||||
true) ;
|
||||
// se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due
|
||||
// direzioni nel voxel corrispondente
|
||||
if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL &&
|
||||
nSub_intervals != int( m_Values[nGrid][nDex].size())) {
|
||||
nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti
|
||||
// l'intervallo corrente si è unito con il precedente...
|
||||
AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMin, dToler,
|
||||
vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN,
|
||||
vInfo[nInfo].nToolMin) ;
|
||||
// Recupero il numero di intervalli presenti nel Dexel corrente
|
||||
int nIntervals = int( pZMapCopy->m_Values[nGrid][nDex].size()) ;
|
||||
// Scorro gli intervalli presenti
|
||||
for ( int nInfo = 0 ; nInfo < int( pZMapCopy->m_Values[nGrid][nDex].size()) ; ++ nInfo) {
|
||||
// Recupero l'intervallo corrente
|
||||
Data& Interval = pZMapCopy->m_Values[nGrid][nDex][nInfo] ;
|
||||
// --- Se richiesta prima estensione
|
||||
if ( bIsExtensionFirst) {
|
||||
// *** Estremo inferiore -> Intervallo : [ dMin - dToler, dMin + dToler ]
|
||||
// Aggiungo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy)
|
||||
AddIntervals( nGrid, nI, nJ, Interval.dMin - dToler, Interval.dMin + dToler,
|
||||
Interval.vtMinN, Interval.vtMinN, nToolNum, true) ;
|
||||
// Se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due direzioni
|
||||
if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) {
|
||||
// Aggiorno gli intervalli correnti ( dato che il corrente si è unito al precedente)
|
||||
// ( lascio invariato lo ZMapCopy)
|
||||
nIntervals = int( m_Values[nGrid][nDex].size()) ;
|
||||
pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ,
|
||||
pZMapCopy->m_Values[nGrid][nDex][nInfo-1].dMax,
|
||||
Interval.dMin, dToler, true,
|
||||
nToolNum, V_INVALID, V_INVALID) ;
|
||||
}
|
||||
// *** Estremo superiore -> Intervallo : [ dMax - dToler, dMax + dToler ]
|
||||
// Aggiungo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy)
|
||||
AddIntervals( nGrid, nI, nJ, Interval.dMax - dToler, Interval.dMax + dToler,
|
||||
Interval.vtMaxN, Interval.vtMaxN, nToolNum, true) ;
|
||||
// Se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due direzioni
|
||||
if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) {
|
||||
// Aggiorno gli intervalli correnti ( dato che il corrente si è unito al successivo)
|
||||
// ( lascio invariato lo ZMapCopy)
|
||||
nIntervals = int( m_Values[nGrid][nDex].size()) ;
|
||||
pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ,
|
||||
Interval.dMax,
|
||||
pZMapCopy->m_Values[nGrid][nDex][nInfo+1].dMin, dToler, true,
|
||||
nToolNum, V_INVALID, V_INVALID) ;
|
||||
}
|
||||
}
|
||||
// estremo superiore
|
||||
if ( vInfo[nInfo].dMax + dToler < m_dMaxZ[nGrid]) {
|
||||
AddIntervals( nGrid, nI, nJ,
|
||||
vInfo[nInfo].dMax - dToler,
|
||||
vInfo[nInfo].dMax + dToler,
|
||||
vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN, vInfo[nInfo].nToolMax,
|
||||
true) ;
|
||||
if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL &&
|
||||
nSub_intervals != int( m_Values[nGrid][nDex].size())) {
|
||||
nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti
|
||||
AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMax, dToler,
|
||||
vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN,
|
||||
vInfo[nInfo].nToolMax) ;
|
||||
// --- Se richiesta prima restrizione
|
||||
else {
|
||||
// *** Estremo inferiore -> Intervallo : [ dMin - dToler, dMin + dToler ]
|
||||
// Sottraggo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy)
|
||||
SubtractIntervals( nGrid, nI, nJ, Interval.dMin - dToler, Interval.dMin + dToler,
|
||||
Interval.vtMinN, Interval.vtMinN, nToolNum, true) ;
|
||||
// Se l'intervallo si è annullato, potrei dover sottrarre degli spilloni nelle altre due direzioni
|
||||
if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) {
|
||||
// Aggiorno gli intervalli correnti ( lascio invariato lo ZMapCopy)
|
||||
nIntervals = int( m_Values[nGrid][nDex].size()) ;
|
||||
pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ,
|
||||
Interval.dMin,
|
||||
Interval.dMax, dToler, true,
|
||||
Tool::UNDEF, V_INVALID, V_INVALID) ;
|
||||
}
|
||||
// *** Estremo superiore -> Intervallo : [ dMax - dToler, dMax + dToler ]
|
||||
// Sottraggo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy)
|
||||
SubtractIntervals( nGrid, nI, nJ, Interval.dMax - dToler, Interval.dMax + dToler,
|
||||
Interval.vtMaxN, Interval.vtMaxN, nToolNum, true) ;
|
||||
// Se l'intervallo si è annullato, potrei dover sottrarre degli spilloni nelle altre due direzioni
|
||||
if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) {
|
||||
// Aggiorno gli intervalli correnti ( lascio invariato lo ZMapCopy)
|
||||
nIntervals = int( m_Values[nGrid][nDex].size()) ;
|
||||
pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ,
|
||||
Interval.dMin,
|
||||
Interval.dMax, dToler, true,
|
||||
Tool::UNDEF, V_INVALID, V_INVALID) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// per ogni sotto-intervallo ricavato fino ad ora, restringo della tolleranza
|
||||
// ( NB. avendo aggiunto intervalli, il dexel può modificare la sua struttura interna )
|
||||
for ( int nInfo = 0 ; nInfo < int( m_Values[nGrid][nDex].size()) ; ++ nInfo) {
|
||||
// ( NB. la rimozione di un intervallo ora va definita per intervalli a destra e a sinistra,
|
||||
// altrimenti rimuovo parti in eccesso )
|
||||
if ( ! pVolZMapCurrGrid->m_Values[nGrid][nDex].empty()) {
|
||||
if ( nInfo != 0 ||
|
||||
pVolZMapCurrGrid->m_Values[nGrid][nDex][0].dMin - dToler > m_dMinZ[nGrid])
|
||||
m_Values[nGrid][nDex][nInfo].dMin += dToler ;
|
||||
if ( nInfo != int( m_Values[nGrid][nDex].size()) - 1 ||
|
||||
pVolZMapCurrGrid->m_Values[nGrid][nDex].back().dMax + dToler < m_dMaxZ[nGrid])
|
||||
m_Values[nGrid][nDex][nInfo].dMax -= dToler ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sulle griglie ( uso lo Zmap Corrente, lascio invariato pZMapCopy)
|
||||
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
|
||||
// Ciclo sul numero di dexel presenti
|
||||
for ( int nDex = 0 ; nDex < int( m_Values[nGrid].size()) ; ++ nDex) {
|
||||
// Se l'intervallo è vuoto, non faccio nulla
|
||||
if ( m_Values[nGrid][nDex].empty())
|
||||
continue ;
|
||||
// Per ogni intervallo ricavato fino ad ora, restringo della tolleranza
|
||||
for ( int nInfo = 0 ; nInfo < int( m_Values[nGrid][nDex].size()) ; ++ nInfo) {
|
||||
// --- Se richiesta prima estensione
|
||||
if ( bIsExtensionFirst) {
|
||||
m_Values[nGrid][nDex][nInfo].dMin += dToler ;
|
||||
m_Values[nGrid][nDex][nInfo].dMax -= dToler ;
|
||||
}
|
||||
// --- Se richiesta prima restrizione
|
||||
else {
|
||||
m_Values[nGrid][nDex][nInfo].dMin -= dToler ;
|
||||
m_Values[nGrid][nDex][nInfo].dMax += dToler ;
|
||||
}
|
||||
// Definisco il colore
|
||||
for ( int nOrigInfo = 0 ; nOrigInfo < int( pZMapCopy->m_Values[nGrid][nDex].size()) ; ++ nOrigInfo) {
|
||||
if ( pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].dMin - m_Values[nGrid][nDex][nInfo].dMin < EPS_SMALL)
|
||||
m_Values[nGrid][nDex][nInfo].nToolMin = pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].nToolMin ;
|
||||
if ( pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].dMax - m_Values[nGrid][nDex][nInfo].dMax < EPS_SMALL)
|
||||
m_Values[nGrid][nDex][nInfo].nToolMax = pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].nToolMax ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gestisco le parti Extra ricavate
|
||||
// Ciclo sulle griglie ( uso lo ZmapExtra, lascio invariato pZMapCopy)
|
||||
for ( int nGrid = 0 ; nGrid < pZMapExtra->m_nMapNum ; ++ nGrid) {
|
||||
// Ciclo sul numero di dexel presenti
|
||||
for ( int nDex = 0 ; nDex < int( pZMapExtra->m_Values[nGrid].size()) ; ++ nDex) {
|
||||
// Se l'intervallo è vuoto, non faccio nulla
|
||||
if ( pZMapExtra->m_Values[nGrid][nDex].empty())
|
||||
continue ;
|
||||
// Indici del dexel
|
||||
int nI = nDex % m_nNx[nGrid] ;
|
||||
int nJ = nDex / m_nNx[nGrid] ;
|
||||
// Per ogni intervallo ricavato fino ad ora...
|
||||
for ( int nInfo = 0 ; nInfo < int( pZMapExtra->m_Values[nGrid][nDex].size()) ; ++ nInfo) {
|
||||
double dMin = pZMapExtra->m_Values[nGrid][nDex][nInfo].dMin ;
|
||||
double dMax = pZMapExtra->m_Values[nGrid][nDex][nInfo].dMax ;
|
||||
Vector3d vtNMin = pZMapExtra->m_Values[nGrid][nDex][nInfo].vtMinN ;
|
||||
Vector3d vtNMax = pZMapExtra->m_Values[nGrid][nDex][nInfo].vtMaxN ;
|
||||
// --- Se richiesta prima estensione
|
||||
if ( bIsExtensionFirst) {
|
||||
// ... aggiungo i contributi
|
||||
AddIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, true) ;
|
||||
}
|
||||
// --- Se richiesta prima restrizione
|
||||
else {
|
||||
// ... sottraggo i contributi
|
||||
SubtractIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, true) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restringo gli ingombri espensi in precedenza
|
||||
m_dMinZ[0] += dToler ;
|
||||
m_dMinZ[1] += dToler ;
|
||||
m_dMinZ[2] += dToler ;
|
||||
m_dMaxZ[0] -= dToler ;
|
||||
m_dMaxZ[1] -= dToler ;
|
||||
m_dMaxZ[2] -= dToler ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
|
||||
{
|
||||
// Controllo sulla validità della griglia
|
||||
// Controllo sulla validità della griglia
|
||||
if ( nGrid < 0 || nGrid > 2)
|
||||
return false ;
|
||||
// Controllo sulla validità del dexel
|
||||
// Controllo sulla validità del dexel
|
||||
if ( nDex <= - 1 || nDex >= int( m_Values[nGrid].size()))
|
||||
return false ;
|
||||
// Controllo sulla validità dell'intervallo
|
||||
// Controllo sulla validità dell'intervallo
|
||||
if ( nInt <= - 1 || nInt >= int( m_Values[nGrid][nDex].size()))
|
||||
return false ;
|
||||
|
||||
@@ -1957,7 +2047,7 @@ VolZmap::IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, do
|
||||
bool
|
||||
VolZmap::IsBox( void)
|
||||
{
|
||||
// Se non tridexel, non posso stabilire con il metodo seguente se è un box
|
||||
// Se non tridexel, non posso stabilire con il metodo seguente se è un box
|
||||
// Verifico solo che gli spilloni di una mappa o sono nulli o hanno gli stessi estremi
|
||||
if ( m_nMapNum == 1)
|
||||
return false ;
|
||||
@@ -1976,7 +2066,7 @@ VolZmap::IsBox( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Caso di più thread
|
||||
// Caso di più thread
|
||||
m_bIsBox = true ;
|
||||
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
|
||||
vector< future<bool>> vRes ;
|
||||
@@ -2021,7 +2111,7 @@ VolZmap::IsBox( void)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se uno dei thread trova che la sua porzione non è un box, non lo può essere il solido intero.
|
||||
// Se uno dei thread trova che la sua porzione non è un box, non lo può essere il solido intero.
|
||||
if ( ! m_bIsBox)
|
||||
return false ;
|
||||
// Controllo che gli estremi Z siano uguali.
|
||||
@@ -2058,7 +2148,7 @@ VolZmap::Cut( const Plane3d& plPlane)
|
||||
}
|
||||
// Ciclo sui dexel della mappa
|
||||
for ( int nD = 0 ; nD < int( m_Values[nMap].size()) ; ++ nD) {
|
||||
// Se spillone già vuoto, passo al successivo
|
||||
// Se spillone già vuoto, passo al successivo
|
||||
if ( m_Values[nMap][nD].empty())
|
||||
continue ;
|
||||
// Indici di spillone
|
||||
@@ -2074,20 +2164,20 @@ VolZmap::Cut( const Plane3d& plPlane)
|
||||
double dEnDist = DistPointPlane( ptEn, plMyPlane) ;
|
||||
// Se entrambi sotto il piano
|
||||
if ( dStDist < EPS_SMALL && dEnDist < EPS_SMALL)
|
||||
// Non devo fare alcunché
|
||||
// Non devo fare alcunché
|
||||
;
|
||||
// se altrimenti entrambi gli estremi sono oltre il piano
|
||||
else if ( dStDist > -EPS_SMALL && dEnDist > -EPS_SMALL) {
|
||||
// Si elimina tutto
|
||||
SubtractIntervals( nMap, nI, nJ, dMin, dMax, V_NULL, V_NULL, 1) ;
|
||||
}
|
||||
// se altrimenti è da tenere il punto iniziale
|
||||
// se altrimenti è da tenere il punto iniziale
|
||||
else if ( dStDist < 0) {
|
||||
// Si elimina la parte tra intersezione e punto finale
|
||||
double dInt = dMin + ( dMax - dMin) * abs( dStDist) / ( abs( dStDist) + abs( dEnDist)) ;
|
||||
SubtractIntervals( nMap, nI, nJ, dInt, dMax, plMyPlane.GetVersN(), V_NULL, 1) ;
|
||||
}
|
||||
// se altrimenti è da tenere il punto finale
|
||||
// se altrimenti è da tenere il punto finale
|
||||
else if (dEnDist < 0) {
|
||||
// Si elimina la parte tra punto iniziale e intersezione
|
||||
double dInt = dMin + ( dMax - dMin) * abs( dStDist) / ( abs( dStDist) + abs( dEnDist)) ;
|
||||
@@ -2177,7 +2267,7 @@ VolZmap::Compact( void)
|
||||
}
|
||||
}
|
||||
|
||||
// Se non vi è materiale
|
||||
// Se non vi è materiale
|
||||
if ( ! bNotEmptyGrid) {
|
||||
m_nStatus = TO_VERIFY ;
|
||||
m_nNumBlock = 0 ;
|
||||
@@ -2199,8 +2289,8 @@ VolZmap::Compact( void)
|
||||
double dNewOy = nMinJ[0] * m_dStep ;
|
||||
double dNewOz = nMinJ[1] * m_dStep ;
|
||||
|
||||
// Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali,
|
||||
// infatti i sistemi di riferimento in gioco differiscono al più per una traslazione.
|
||||
// Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali,
|
||||
// infatti i sistemi di riferimento in gioco differiscono al più per una traslazione.
|
||||
for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) {
|
||||
// Quote estreme Z
|
||||
switch ( nMap) {
|
||||
|
||||
@@ -151,7 +151,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
int GetPartMinDistFromPoint( const Point3d& ptP) const override ;
|
||||
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
|
||||
bool SubtractSurfTm( const ISurfTriMesh* pStm) override ;
|
||||
bool MakeUniform( double dToler) override ;
|
||||
bool MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum) override ;
|
||||
bool Offset( double dOffs, int nType) override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
@@ -260,10 +260,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool AddIntervals( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
int nToolNum, bool bSkipSwap = false) ;
|
||||
bool AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler,
|
||||
Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum) ;
|
||||
bool AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
|
||||
Vector3d& vtMin, Vector3d& vtMax) ;
|
||||
bool UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin, double dZMax,
|
||||
double dToler, bool bAdd, int nToolNum, const Vector3d& vtToolMin,
|
||||
const Vector3d& vtToolMax) ;
|
||||
bool ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
|
||||
Vector3d& vtMin, Vector3d& vtMax) ;
|
||||
// Spostamenti utensile
|
||||
bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ;
|
||||
bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
||||
|
||||
+137
-120
@@ -617,134 +617,157 @@ VolZmap::AddIntervals( int nGrid, int nI, int nJ,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK,
|
||||
double& dMin, double& dMax, Vector3d& vtMin, Vector3d& vtMax)
|
||||
VolZmap::ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK,
|
||||
double& dMin, double& dMax, Vector3d& vtMin, Vector3d& vtMax)
|
||||
{
|
||||
// se non Tridex, esco
|
||||
// Se non Tridex, esco
|
||||
if ( ! IsTriDexel())
|
||||
return true ;
|
||||
|
||||
|
||||
// Controllo che il numero di griglia sia entro i limiti
|
||||
if ( nGrid < 0 || nGrid > 2)
|
||||
return false ;
|
||||
|
||||
// Controllo che indici nI, nJ siano entro i limiti
|
||||
if ( nI < 0 && nI >= m_nNx[nGrid] &&
|
||||
nJ < 0 && nJ >= m_nNy[nGrid])
|
||||
if ( nI < 0 && nI >= m_nNx[nGrid] && nJ < 0 && nJ >= m_nNy[nGrid])
|
||||
return false ;
|
||||
|
||||
// valori di default
|
||||
vector<double> vTdMin = { -1., -1., -1., -1.} ;
|
||||
vector<double> vTdMax = { -1., -1., -1., -1.} ;
|
||||
VCT3DVECTOR vtNMin = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ;
|
||||
VCT3DVECTOR vtNMax = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ;
|
||||
// Valori di Default
|
||||
DBLVECTOR vdMin = { -1., -1., -1., -1.} ;
|
||||
DBLVECTOR vdMax = { -1., -1., -1., -1.} ;
|
||||
VCT3DVECTOR vNMin = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ;
|
||||
VCT3DVECTOR vNMax = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ;
|
||||
|
||||
// se esiste un precedente lungo x-locale
|
||||
// Se esiste un voxel precedente lungo x-locale ( nI - 1, nJ)
|
||||
if ( nI != 0) {
|
||||
int nPos = nJ * m_nNx[nGrid] + ( nI - 1) ; // recupero posizione dexel
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
// Ne recupero la posizione
|
||||
int nPos = nJ * m_nNx[nGrid] + ( nI - 1) ;
|
||||
// Scorro tutti gli intervalli del dexel in (nI - 1, nJ)
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// Se nei pressi dell'estremo superiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vTdMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
// Memorizzo i parametri
|
||||
vNMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vdMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
}
|
||||
// Se nei pressi dell'estremo inferiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vTdMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
// Memorizzo i parametri
|
||||
vNMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vdMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se esiste il successivo lungo x-locale
|
||||
if ( nI != m_dMaxZ[( nGrid + 2) % 3]) {
|
||||
int nPos = nJ * m_nNx[nGrid] + ( nI + 1) ; // recupero posizione dexel
|
||||
|
||||
// Se esiste un voxel successivo lungo x-locale, ne recupero la posizione
|
||||
int nPos = nJ * m_nNx[nGrid] + ( nI + 1) ;
|
||||
if ( nPos < int( VolZmapRef->m_Values[nGrid].size())) {
|
||||
// Cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
// Se nei pressi dell'estremo superiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vTdMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
// Memorizzo i parametri
|
||||
vNMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vdMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
}
|
||||
// Se nei pressi dell'estremo inferiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vTdMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
// Memorizzo i parametri
|
||||
vNMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vdMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se esiste il precedente lungo y-locale
|
||||
|
||||
// Se esiste un voxel precedente lungo y-locale
|
||||
if ( nJ != 0) {
|
||||
int nPos = ( nJ - 1) * m_nNx[nGrid] + nI ; // recupero posizione dexel
|
||||
// Ne recupero la posizione
|
||||
int nPos = ( nJ - 1) * m_nNx[nGrid] + nI ;
|
||||
// Cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
// Se nei pressi dell'estremo superiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vTdMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
// Memorizzo i parametri
|
||||
vNMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vdMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
}
|
||||
// Se nei pressi dell'estremo inferiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vTdMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se esiste il successivo lungo y-locale
|
||||
if ( nJ != m_dMaxZ[( nGrid + 1) % 3]) {
|
||||
int nPos = ( nJ + 1) * m_nNx[nGrid] + nI ; // recupero posizione dexel
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vTdMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
}
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
vtNMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vTdMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
// Memorizzo i parametri
|
||||
vNMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vdMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scelgo le normali che si discostano il meno possibile dalla normale della faccia del voxel
|
||||
// Se esiste un voxel successivo lungo y-locale, ne recupero la posizione
|
||||
nPos = ( nJ + 1) * m_nNx[nGrid] + nI ;
|
||||
if ( nPos < int( VolZmapRef->m_Values[nGrid].size())) {
|
||||
// Cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// Se nei pressi dell'estremo superiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
// Memorizzo i parametri
|
||||
vNMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vdMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ;
|
||||
}
|
||||
// Se nei pressi dell'estremo inferiore
|
||||
if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep &&
|
||||
VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) {
|
||||
// Memorizzo i parametri
|
||||
vNMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vdMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// analisi dei massimi e delle normali ---------------------------
|
||||
// 1) angolo minimo tra la normale trovata la faccia del voxel
|
||||
// --- Scelgo le normali che si discostano il meno possibile dalla normale della faccia del voxel
|
||||
|
||||
// 1) Angolo minimo tra la normale trovata la faccia del voxel
|
||||
double dMinAngle = ANG_FULL ;
|
||||
// 2) vettore di riferimento per la direzione della normale
|
||||
// 2) Vettore di riferimento per la direzione della normale
|
||||
vtMax = ( nGrid == 0 ? m_MapFrame.VersZ() :
|
||||
( nGrid == 1 ? m_MapFrame.VersX() : m_MapFrame.VersY())) ;
|
||||
nGrid == 1 ? m_MapFrame.VersX() :
|
||||
nGrid == 2 ? m_MapFrame.VersY() :
|
||||
V_INVALID) ;
|
||||
Vector3d vtRef = vtMax ;
|
||||
// 3) determino il massimo per questo intervallo
|
||||
// 3) Determino il massimo per questo intervallo
|
||||
dMax = ( nK + 1) * m_dStep ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i) { // scorro le normali
|
||||
if ( vtNMax[i].IsValid()) { // se normale trovata, quindi valida...
|
||||
double dCurrAngle ; // angolo corrente tra la normale della TriMesh e quella della faccia del voxel
|
||||
vtNMax[i].GetAngle( vtRef, dCurrAngle) ;
|
||||
if ( abs( dCurrAngle) < dMinAngle) { // se angolo minore del minimo trovato...
|
||||
// aggiorno i parametri
|
||||
for ( int i = 0 ; i < 4 ; ++ i) {
|
||||
// Scorro le normali valide trovate
|
||||
if ( vNMax[i].IsValid()) {
|
||||
// Angolo corrente tra la normale di riferimento e quella della faccia del voxel
|
||||
double dCurrAngle ; vNMax[i].GetAngle( vtRef, dCurrAngle) ;
|
||||
// Se angolo minore del minimo trovato...
|
||||
if ( abs( dCurrAngle) < dMinAngle) {
|
||||
// ... Aggiorno i parametri
|
||||
dMinAngle = dCurrAngle ;
|
||||
vtMax = vtNMax[i] ;
|
||||
dMax = vTdMax[i] ;
|
||||
vtMax = vNMax[i] ;
|
||||
dMax = vdMax[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// analisi dei minimi e delle normali ---------------------------
|
||||
// Ripeto lo stesso ragionamento per le normali dei massimi
|
||||
dMinAngle = ANG_FULL ;
|
||||
vtRef.Invert() ;
|
||||
dMin = nK * m_dStep ;
|
||||
vtMin = vtRef ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i) {
|
||||
if ( vtNMin[i].IsValid()) {
|
||||
if ( vNMin[i].IsValid()) {
|
||||
double dCurrAngle ;
|
||||
vtNMin[i].GetAngle( vtRef, dCurrAngle) ;
|
||||
vNMin[i].GetAngle( vtRef, dCurrAngle) ;
|
||||
if ( abs( dCurrAngle) < dMinAngle) {
|
||||
dMinAngle = dCurrAngle ;
|
||||
vtMin = vtNMin[i] ;
|
||||
dMin = vTdMin[i] ;
|
||||
vtMin = vNMin[i] ;
|
||||
dMin = vdMin[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -754,72 +777,66 @@ VolZmap::AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler,
|
||||
Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum)
|
||||
VolZmap::UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin,
|
||||
double dZMax, double dToler, bool bAdd, int nToolNum, const Vector3d& vtToolMin,
|
||||
const Vector3d& vtToolMax)
|
||||
{
|
||||
|
||||
// se non Tridex, esco
|
||||
// Se non Tridex, esco
|
||||
if ( ! IsTriDexel())
|
||||
return true ;
|
||||
|
||||
|
||||
// Controllo che il numero di griglia sia entro i limiti
|
||||
if ( nGrid < 0 || nGrid > 2)
|
||||
return false ;
|
||||
|
||||
// Controllo che indici nI, nJ siano entro i limiti
|
||||
if ( nI < 0 && nI >= m_nNx[nGrid] &&
|
||||
nJ < 0 && nJ >= m_nNy[nGrid])
|
||||
if ( nI < 0 && nI >= m_nNx[nGrid] && nJ < 0 && nJ >= m_nNy[nGrid])
|
||||
return false ;
|
||||
|
||||
// passo da indici di dexel a indici di voxel
|
||||
nI /= m_nDexVoxRatio ;
|
||||
nJ /= m_nDexVoxRatio ;
|
||||
// Numero di voxel contenuti nel dexel corrente ( uguale per ogni dexel di una specifica griglia)
|
||||
int nVoxNum = int( m_nNy[(( nGrid + 1) % 3)] / m_nDexVoxRatio +
|
||||
( m_nNy[(( nGrid + 1) % 3)] % m_nDexVoxRatio == 0 ? 1 : 2)) ;
|
||||
|
||||
// numero di voxel nel dexel corrente
|
||||
int nVoxNum = int( m_nNy[(( nGrid+1) % 3)] / m_nDexVoxRatio +
|
||||
( m_nNy[(( nGrid+1) % 3)] % m_nDexVoxRatio == 0 ? 1 : 2)) ;
|
||||
|
||||
int nK = 0 ;
|
||||
for ( int i = 0 ; i < nVoxNum ; ++ i) {
|
||||
// controllo se sono nel voxel corrente
|
||||
if ( i * m_dStep < dZ && ( i + 1) * m_dStep > dZ) {
|
||||
nK = i ;
|
||||
break ;
|
||||
// Scorro i Voxel correnti
|
||||
for ( int nVox = 0 ; nVox < nVoxNum ; ++ nVox) {
|
||||
// Considero solo i Voxel interni all'intervallo corrente
|
||||
if ( dZMin - m_dStep / 2. < nVox * m_dStep && nVox * m_dStep < dZMax + m_dStep / 2.) {
|
||||
// recupero gli indici per la griglia successiva
|
||||
int nMyGrid = ( nGrid + 1) % 3 ;
|
||||
int nMyI = nJ ;
|
||||
int nMyJ = nVox ;
|
||||
int nMyK = nI ;
|
||||
double dMyMinZ = nMyK * m_dStep ; // shift di -Step / 2
|
||||
double dMyMaxZ = ( nMyK + 1) * m_dStep ; // shift di Step / 2
|
||||
Vector3d vtMyMaxN = ( vtToolMax.IsValid() ? vtToolMax :
|
||||
nMyGrid == 0 ? m_MapFrame.VersZ() :
|
||||
nMyGrid == 1 ? m_MapFrame.VersX() :
|
||||
m_MapFrame.VersY()) ;
|
||||
Vector3d vtMyMinN = ( vtToolMin.IsValid() ? vtToolMin : - vtMyMaxN) ;
|
||||
if ( bAdd)
|
||||
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ;
|
||||
else
|
||||
SubtractIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ;
|
||||
// recupero gli indici della griglia precedente
|
||||
nMyGrid = ( nGrid + 2) % 3 ;
|
||||
nMyI = nVox ;
|
||||
nMyJ = nI ;
|
||||
nMyK = nJ ;
|
||||
dMyMinZ = nMyK * m_dStep ; // shift di -Step / 2
|
||||
dMyMaxZ = ( nMyK + 1) * m_dStep ; // shift di Step / 2
|
||||
vtMyMaxN = ( vtToolMax.IsValid() ? vtToolMax :
|
||||
nMyGrid == 0 ? m_MapFrame.VersZ() :
|
||||
nMyGrid == 1 ? m_MapFrame.VersX() :
|
||||
m_MapFrame.VersY()) ;
|
||||
vtMyMinN = ( vtToolMin.IsValid() ? vtToolMin : - vtMyMaxN) ;
|
||||
if ( bAdd)
|
||||
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ;
|
||||
else
|
||||
SubtractIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- griglia successiva -----------
|
||||
{
|
||||
int nMyGrid = ( nGrid + 1) % 3 ;
|
||||
int nMyI = nJ ;
|
||||
int nMyJ = nK ;
|
||||
int nMyK = nI ;
|
||||
double dMyMin ;
|
||||
double dMyMax ;
|
||||
Vector3d vtMyMin ;
|
||||
Vector3d vtMyMax ;
|
||||
AddSubIntervalInVoxel( VolZmapRef, nMyGrid, nMyI, nMyJ, nMyK, dMyMin, dMyMax, vtMyMin, vtMyMax) ;
|
||||
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMin - EPS_SMALL, dMyMax + EPS_SMALL, vtMyMin, vtMyMax,
|
||||
nToolNum, true) ;
|
||||
}
|
||||
|
||||
// ----------- griglia precedente -----------
|
||||
{
|
||||
int nMyGrid = ( nGrid + 2) % 3 ;
|
||||
int nMyI = nK ;
|
||||
int nMyJ = nI ;
|
||||
int nMyK = nJ ;
|
||||
double dMyMin ;
|
||||
double dMyMax ;
|
||||
Vector3d vtMyMin ;
|
||||
Vector3d vtMyMax ;
|
||||
AddSubIntervalInVoxel( VolZmapRef, nMyGrid, nMyI, nMyJ, nMyK, dMyMin, dMyMax, vtMyMin, vtMyMax) ;
|
||||
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMin - EPS_SMALL, dMyMax + EPS_SMALL, vtMyMin, vtMyMax,
|
||||
nToolNum, true) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
}
|
||||
|
||||
// ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user