EgtMachKernel :
- in Finiture ZLevel migliorato l'ordinamento delle curve.
This commit is contained in:
+414
-230
@@ -110,12 +110,13 @@ enum {
|
||||
#define DEBUG 0
|
||||
#define DEBUG_SFR 0
|
||||
#define ENABLE_ZCONST_DEBUG 0
|
||||
#define ENABLE_ZCONST_PATH_DEBUG 0
|
||||
#define ENABLE_OPTIMAL_DEBUG 0
|
||||
#define ENABLE_OPTIMAL_SOFT_DEBUG 0
|
||||
#define ENABLE_OPTIMAL_FINAL_CURVES_DEBUG 0
|
||||
#define ENABLE_PENCIL_DEBUG 0
|
||||
#define ENABLE_LINK_DEBUG 0
|
||||
#if DEBUG || DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG || ENABLE_PENCIL_DEBUG || ENABLE_OPTIMAL_FINAL_CURVES_DEBUG || ENABLE_LINK_DEBUG
|
||||
#if DEBUG || DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_ZCONST_PATH_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG || ENABLE_PENCIL_DEBUG || ENABLE_OPTIMAL_FINAL_CURVES_DEBUG || ENABLE_LINK_DEBUG
|
||||
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
||||
#include "/EgtDev/Include/EgtPerfCounter.h"
|
||||
@@ -2532,278 +2533,461 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSu
|
||||
{
|
||||
// funzione per collegare le curve trovate creando quindi i percorsi di lavoro
|
||||
// NB. Nel primo TempParam deve essere memorizzata la distanza del piano della curva con il piano della Sfr
|
||||
// NB. Vengono memorizzate le seguenti informazioni :
|
||||
// - la prima tempProp della curva è il numero del piano in cui giace il punto iniziale
|
||||
// - la seconda tempProp della curva è il numero del piano in cui giace il punto finale
|
||||
|
||||
// controllo dei parametri
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
||||
return false ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrClass( CloneSurfFlatRegion( pSfr)) ;
|
||||
if ( IsNull( pSfrClass) || ! pSfrClass->IsValid())
|
||||
return false ;
|
||||
|
||||
// porto il tool nel frame della superficie
|
||||
Vector3d vtToolLoc = GetToLoc( vtTool, frSurf) ;
|
||||
|
||||
// porto tutte le curve nel piano XY locale alla pSfr
|
||||
// porto tutte le curve nel piano XY locale alla pSfr e, per ognuna di esse, definisco la regione
|
||||
// piana di proiezione del materiale rimosso orientato a sinistra della curva
|
||||
Frame3d frXY ;
|
||||
Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ;
|
||||
if ( ! frXY.Set( ptCenter, vtToolLoc))
|
||||
return false ;
|
||||
vector<ISURFFRPOVECTOR> vSfrRemMatCol ; vSfrRemMatCol.resize( vCrvCompo.size()) ; // RemovedMaterialColumn
|
||||
double dRadSignOffs = m_Params.m_bInvert ? m_TParams.m_dDiam / 2. : - m_TParams.m_dDiam / 2. ;
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nGrp, "Crv & Sfr") ;
|
||||
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;
|
||||
#endif
|
||||
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
|
||||
vSfrRemMatCol[i].resize( vCrvCompo[i].size()) ;
|
||||
for ( int j = 0 ; j < int( vCrvCompo[i].size()) ; ++ j) {
|
||||
// --- Frame locale XY
|
||||
vCrvCompo[i][j]->ToLoc( frXY) ;
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvCompo[i][j]->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, OLIVE) ;
|
||||
vCrvCompo[i][j]->SetExtrusion( m_Params.m_bInvert ? - Z_AX : Z_AX) ;
|
||||
SurfFlatRegionByContours SfrBC ;
|
||||
// --- Se curva chiusa
|
||||
if ( vCrvCompo[i][j]->IsClosed()) {
|
||||
SfrBC.AddCurve( CloneCurveComposite( vCrvCompo[i][j])) ;
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( vCrvCompo[i][j], dRadSignOffs, ICurve::OFF_FILLET) ;
|
||||
PtrOwner<ICurve> pCrvIsl( OffsCrv.GetLongerCurve()) ;
|
||||
while ( ! IsNull( pCrvIsl)) {
|
||||
SfrBC.AddCurve( Release( pCrvIsl)) ;
|
||||
pCrvIsl.Set( OffsCrv.GetLongerCurve()) ;
|
||||
}
|
||||
}
|
||||
// --- Se curva aperta
|
||||
else {
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( vCrvCompo[i][j], dRadSignOffs, ICurve::OFF_FILLET) ;
|
||||
// [euristico, migliorabile/da_correggere]
|
||||
PtrOwner<ICurve> pCrvInt( OffsCrv.GetLongerCurve()) ;
|
||||
if ( ! IsNull( pCrvInt)) {
|
||||
pCrvInt->Invert() ;
|
||||
Point3d ptS ; pCrvInt->GetStartPoint( ptS) ;
|
||||
Point3d ptE ; vCrvCompo[i][j]->GetStartPoint( ptE) ;
|
||||
PtrOwner<ICurveComposite> pSfrLoop( CreateCurveComposite()) ;
|
||||
if ( IsNull( pSfrLoop))
|
||||
return false ;
|
||||
pSfrLoop->AddCurve( CloneCurveComposite( vCrvCompo[i][j])) ;
|
||||
pSfrLoop->AddLine( ptS) ;
|
||||
pSfrLoop->AddCurve( Release( pCrvInt)) ;
|
||||
pSfrLoop->AddLine( ptE) ;
|
||||
SfrBC.AddCurve( Release( pSfrLoop)) ;
|
||||
}
|
||||
}
|
||||
vSfrRemMatCol[i][j].Set( SfrBC.GetSurf()) ;
|
||||
if ( IsNull( vSfrRemMatCol[i][j]) || ! vSfrRemMatCol[i][j]->IsValid())
|
||||
vSfrRemMatCol[i][j].Set( GetSurfFlatRegionFromFatCurve( vCrvCompo[i][j]->Clone(), m_TParams.m_dDiam / 2., false, false)) ;
|
||||
// tutte rivolte come Z_AX ( vtTool locale)
|
||||
if ( AreOppositeVectorApprox( vSfrRemMatCol[i][j]->GetNormVersor(), Z_AX))
|
||||
vSfrRemMatCol[i][j]->Invert() ;
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
Color myCol = Color( double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, 1.) ;
|
||||
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nLay, ToString( vCrvCompo[i][j]->GetTempParam( 0))) ;
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, vCrvCompo[i][j]->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, vSfrRemMatCol[i][j]->Clone()) ;
|
||||
myCol.SetAlpha( .25) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// tengo una copia dei bordi della regione
|
||||
pSfrClass->ToLoc( frXY) ;
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrClass->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, Color( 0., 1., 0., .15)) ;
|
||||
|
||||
// definisco le relazioni delle curve mediante le superfici create
|
||||
int nRowSize = int( vCrvCompo.size()) ;
|
||||
int nColSize = 0 ;
|
||||
for ( int i = 0 ; i < nRowSize ; ++ i)
|
||||
nColSize = max( nColSize, int( vCrvCompo[i].size())) ;
|
||||
unordered_map<int, INTINTVECTOR> MapLock ;
|
||||
unordered_map<int, INTINTVECTOR> MapUnlock ;
|
||||
for ( int nR = int( vCrvCompo.size()) - 1 ; nR >= 1 ; -- nR) {
|
||||
for ( int nC = 0 ; nC < int( vCrvCompo[nR].size()) ; ++ nC) {
|
||||
for ( int nCol = 0 ; nCol < int( vCrvCompo[nR - 1].size()) ; ++ nCol) {
|
||||
PtrOwner<ISurfFlatRegion> pSfrCheck( CloneSurfFlatRegion( vSfrRemMatCol[nR][nC])) ;
|
||||
if ( ! IsNull( pSfrCheck)) {
|
||||
pSfrCheck->Intersect( *vSfrRemMatCol[nR - 1][nCol]) ;
|
||||
if ( pSfrCheck->IsValid() && pSfrCheck->GetChunkCount() > 0) {
|
||||
int nKeyLock = nR * nColSize + nC ;
|
||||
int nKeyUnLock = ( nR - 1) * nColSize + nCol ;
|
||||
MapLock[nKeyLock].emplace_back( make_pair( nR - 1, nCol)) ;
|
||||
MapUnlock[nKeyUnLock].emplace_back( make_pair( nR, nC)) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// definisco i gruppi di curve indpendenti; Un insieme di curve risulta indipendente da un altro
|
||||
// insieme se l'ordine di esecuzione di essi è indifferente ;
|
||||
// [non esiste alcuna curva nel gruppo A che interferisce con una curva del gruppo B)
|
||||
vector<ICRVCOMPOPOVECTOR> vIndependentCurveGroup ;
|
||||
bool bGroup = true ;
|
||||
int nCont = 0 ;
|
||||
while ( bGroup && nCont < nRowSize * nColSize) {
|
||||
++ nCont ;
|
||||
bGroup = false ;
|
||||
// cerco la prima curva non ancora inserita in un gruppo
|
||||
for ( int nR = int( vCrvCompo.size()) - 1 ; nR >= 0 && ! bGroup ; -- nR) {
|
||||
// scorro sulle colonne ( dalla prima all'ultima) [ordine casuale]
|
||||
for ( int nC = 0 ; nC < int( vCrvCompo[nR].size()) && ! bGroup ; ++ nC) {
|
||||
// se la curva attuale già in un gruppo ( quindi nullptr), passo alla successiva
|
||||
if ( vCrvCompo[nR][nC] == nullptr)
|
||||
continue ;
|
||||
// se trovo una curva, allora ho un nuovo gruppo da analizzare
|
||||
bGroup = true ;
|
||||
// creazione spazio per un nuovo gruppo
|
||||
vIndependentCurveGroup.resize( vIndependentCurveGroup.size() + 1) ;
|
||||
INTINTVECTOR vMapIndCheck = { make_pair( nR, nC)} ;
|
||||
// finchè ho indici di riga-colonna da verificare
|
||||
while ( ! vMapIndCheck.empty()) {
|
||||
// memorizzo gli indici correnti
|
||||
int nCurrRow = vMapIndCheck.back().first ;
|
||||
int nCurrCol = vMapIndCheck.back().second ;
|
||||
// tolgo l'elemento ( non devo ricontrollarlo all'iterazione successiva)
|
||||
vMapIndCheck.pop_back() ;
|
||||
// aggiungo la curva al percorso corrente
|
||||
vIndependentCurveGroup.back().emplace_back( Release( vCrvCompo[nCurrRow][nCurrCol])) ;
|
||||
// --- se la curva non è bloccata da nessun'altra
|
||||
auto itLock = MapLock.find( nCurrRow * nColSize + nCurrCol) ;
|
||||
if ( itLock == MapLock.end()) {
|
||||
; // non faccio nulla ( ultimo piano locale)
|
||||
}
|
||||
// --- altrimenti
|
||||
else {
|
||||
// --- scorro le curve che bloccano quella corrente
|
||||
for ( int i = 0 ; i < int( itLock->second.size()) ; ++ i) {
|
||||
int nBR = itLock->second[i].first ;
|
||||
int nBC = itLock->second[i].second ;
|
||||
INTINT Key = make_pair( nBR, nBC) ;
|
||||
auto itUnLock = MapUnlock.find( nBR * nColSize + nBC) ;
|
||||
// verifico che non ci siano altre curve bloccate
|
||||
bool bLock = false ;
|
||||
for ( int j = 0 ; j < int( itUnLock->second.size()) && ! bLock ; ++ j)
|
||||
bLock = ( vCrvCompo[itUnLock->second[j].first][itUnLock->second[j].second] != nullptr) ;
|
||||
if ( ! bLock)
|
||||
vMapIndCheck.emplace_back( Key) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nGrp, "Independent Groups") ;
|
||||
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;
|
||||
vector<Color> vCol ;
|
||||
vector<int> vLay ;
|
||||
for ( int nPath = 0 ; nPath < int( vIndependentCurveGroup.size()) ; ++ nPath) {
|
||||
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
vLay.emplace_back( nLay) ;
|
||||
Color myCol = Color( double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, 1.) ;
|
||||
vCol.emplace_back( myCol) ;
|
||||
for ( auto& pCrv : vIndependentCurveGroup[nPath]) {
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, CloneCurveComposite( pCrv)) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// definisco il piano locale della regione piana ( frXY è centrato su di essa)
|
||||
Plane3d plProjection ;
|
||||
if ( ! plProjection.Set( ORIG, Z_AX))
|
||||
return false ;
|
||||
|
||||
// ordino i gruppi di curve indipendenti
|
||||
typedef pair<int, pair<double, double>> INTDBLDBL ; // <Ind, <ZMax, ZMin>>
|
||||
vector<INTDBLDBL> vMapGrpZLoc ;
|
||||
vMapGrpZLoc.reserve( vIndependentCurveGroup.size()) ;
|
||||
for ( int i = 0 ; i < int( vIndependentCurveGroup.size()) ; ++ i) {
|
||||
// scorro le curve del gruppo cercando quella più in alto ( rispetto alla Zlocale di frXY)
|
||||
double dZMax = - INFINITO ;
|
||||
double dZMin = INFINITO ;
|
||||
for ( auto& pCrv : vIndependentCurveGroup[i]) {
|
||||
double dCurrZ = pCrv->GetTempParam( 0) ;
|
||||
dZMax = max( dZMax, dCurrZ) ;
|
||||
dZMin = min( dZMin, dCurrZ) ;
|
||||
}
|
||||
vMapGrpZLoc.emplace_back( make_pair( i, make_pair( dZMax, dZMin))) ;
|
||||
}
|
||||
// ordino
|
||||
sort( vMapGrpZLoc.begin(), vMapGrpZLoc.end(), []( const INTDBLDBL& GrpA, const INTDBLDBL& GrpB) {
|
||||
// Se ZMax coincidenti, viene prima quello con ZMin superiore
|
||||
if ( abs( GrpA.second.first - GrpB.second.first) < 10 * EPS_SMALL)
|
||||
return ( GrpA.second.second > GrpB.second.second) ;
|
||||
// Se diffeenti, viene prima quello con ZMax superiore
|
||||
return ( GrpA.second > GrpB.second) ;
|
||||
}) ;
|
||||
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nGrp, "Ordered Independent Groups") ;
|
||||
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;;
|
||||
vLay.clear() ;
|
||||
for ( int nPath = 0 ; nPath < int( vMapGrpZLoc.size()) ; ++ nPath) {
|
||||
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
vLay.emplace_back( nLay) ;
|
||||
for ( auto& pCrv : vIndependentCurveGroup[vMapGrpZLoc[nPath].first]) {
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, CloneCurveComposite( pCrv)) ;
|
||||
m_pGeomDB->SetMaterial( nId, vCol[vMapGrpZLoc[nPath].first]) ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// tengo una copia dei bordi della regione ( servono per limitare i collegamenti tra le curve dei Path)
|
||||
PtrOwner<ISurfFlatRegion> pSfrClass( CloneSurfFlatRegion( pSfr)) ;
|
||||
if ( IsNull( pSfrClass) || ! pSfrClass->IsValid() || ! pSfrClass->ToLoc( frXY))
|
||||
return false ;
|
||||
ICRVCOMPOPOVECTOR vCrvSfrLoops ;
|
||||
for ( int nC = 0 ; nC < pSfrClass->GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < pSfrClass->GetLoopCount( nC) ; ++ nL) {
|
||||
PtrOwner<ICurveComposite> pCrvLoop( ConvertCurveToComposite( pSfrClass->GetLoop( nC, nL))) ;
|
||||
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
|
||||
return false ;
|
||||
// tutti i loop sono orientati come il loop esterno ( aiuta per la classificazione della curve)
|
||||
// tutti i loop sono orientati come il loop esterno
|
||||
// NB. Per classificare i collegamenti si usa la regione, non queste curve !
|
||||
// [ Vengono utilizzate per non inizializzare ogni volta una curva corrispondente al bordo
|
||||
// della superficie di classificazione]
|
||||
if ( nL > 0)
|
||||
pCrvLoop->Invert() ;
|
||||
vCrvSfrLoops.emplace_back( Release( pCrvLoop)) ;
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvSfrLoops.back()->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _a, PURPLE) ;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
// definisco il piano locale della regione piana
|
||||
Plane3d plProjection ;
|
||||
if ( ! plProjection.Set( ORIG, Z_AX))
|
||||
return false ;
|
||||
|
||||
int nCurrRow = 0 ;
|
||||
// scorro le righe
|
||||
for ( ; nCurrRow < int( vCrvCompo.size()) - 1 ; ++ nCurrRow) {
|
||||
// scorro sulle colonne
|
||||
for ( int nCurrCol = 0 ; nCurrCol < int( vCrvCompo[nCurrRow].size()) ; ++ nCurrCol) {
|
||||
// se la curva attuale è nulla, passo alla successiva
|
||||
if ( vCrvCompo[nCurrRow][nCurrCol] == nullptr)
|
||||
continue ;
|
||||
// recupero il punto finale della curva corrente
|
||||
Point3d ptCurrEnd ; vCrvCompo[nCurrRow][nCurrCol]->GetEndPoint( ptCurrEnd) ;
|
||||
// recupero la distanza con la Sfr
|
||||
double dSfrDistCurr = vCrvCompo[nCurrRow][nCurrCol]->GetTempParam( 0) ;
|
||||
// inizializzo spazio per un nuovo percorso ( inserisco la curva corrente)
|
||||
vCrvPath.resize( vCrvPath.size() + 1) ;
|
||||
vCrvPath.back().Set( vCrvCompo[nCurrRow][nCurrCol]) ;
|
||||
// salvo come prima temp prop il numero del piano a cui sono
|
||||
vCrvPath.back()->SetTempProp( nCurrRow + 1, 0) ;
|
||||
// scorro sulle righe successive
|
||||
for ( int nNextRow = nCurrRow + 1 ; nNextRow < int( vCrvCompo.size()) ; ++ nNextRow) {
|
||||
// cerco le curve valide tra le colonne
|
||||
double dMinSqDist = INFINITO ; // euristico
|
||||
int nNextCol_path = -1 ;
|
||||
for ( int nNextCol = 0 ; nNextCol < int( vCrvCompo[nNextRow].size()) ; ++ nNextCol) {
|
||||
// se curva già in un Path, cerco la successiva
|
||||
if ( vCrvCompo[nNextRow][nNextCol] == nullptr)
|
||||
continue ;
|
||||
// se la curva successiva è aperta
|
||||
if ( ! vCrvCompo[nNextRow][nNextCol]->IsClosed()) {
|
||||
// controllo la distanza con il punto iniziale della curva
|
||||
Point3d ptS ; vCrvCompo[nNextRow][nNextCol]->GetStartPoint( ptS) ;
|
||||
double dNextSqDist = SqDist( ptS, ptCurrEnd) ;
|
||||
if ( dNextSqDist < dMinSqDist) {
|
||||
dMinSqDist = dNextSqDist ;
|
||||
nNextCol_path = nNextCol ;
|
||||
}
|
||||
// controllo la distanza con il punto finale della curva
|
||||
Point3d ptE ; vCrvCompo[nNextRow][nNextCol]->GetEndPoint( ptE) ;
|
||||
dNextSqDist = SqDist( ptE, ptCurrEnd) ;
|
||||
if ( dNextSqDist < dMinSqDist) {
|
||||
dMinSqDist = dNextSqDist ;
|
||||
nNextCol_path = nNextCol ;
|
||||
vCrvCompo[nNextRow][nNextCol]->Invert() ; // inverto
|
||||
}
|
||||
}
|
||||
// se la curva successiva è chiusa
|
||||
else {
|
||||
// cerco il punto a minima distanza
|
||||
DistPointCurve DistPtCrv( ptCurrEnd, *vCrvCompo[nNextRow][nNextCol]) ;
|
||||
double dNextSqDist = 0. ;
|
||||
if ( DistPtCrv.GetSqDist( dNextSqDist)) {
|
||||
if ( dNextSqDist < dMinSqDist) {
|
||||
dMinSqDist = dNextSqDist ;
|
||||
nNextCol_path = nNextCol ;
|
||||
double dMinPar = 0. ;
|
||||
int nFlag = 0 ;
|
||||
if ( DistPtCrv.GetParamAtMinDistPoint( 0., dMinPar, nFlag))
|
||||
vCrvCompo[nNextRow][nNextCol]->ChangeStartPoint( dMinPar) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// definisco i collegamenti tra i percorsi
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nGrp, "Paths") ;
|
||||
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;
|
||||
#endif
|
||||
const double LINK_TOL = 25. * EPS_SMALL ;
|
||||
Point3d ptRef = P_INVALID ;
|
||||
for ( int i = 0 ; i < int( vMapGrpZLoc.size()) ; ++ i) {
|
||||
// recupero l'indice ordinato del percorso
|
||||
int nPath = vMapGrpZLoc[i].first ;
|
||||
// inverto il vettore delle curve di bordo del percorso corrente
|
||||
reverse( vIndependentCurveGroup[nPath].begin(), vIndependentCurveGroup[nPath].end()) ;
|
||||
// definisco il vettore dei collegamenti creati tra le curve
|
||||
// NB. Un collegamento potrebbe non essere valido e non realizzabile
|
||||
// NB. Il collegamento i-esimo collega la curva di bordo (i-1)-esima con la curva di bordo i-esima
|
||||
ICRVCOMPOPOVECTOR vCompoLink ;
|
||||
vCompoLink.resize( vIndependentCurveGroup[nPath].size()) ; // nullptr per ogni Link
|
||||
|
||||
// --- se non ho curve, passo al gruppo successivo
|
||||
if ( vIndependentCurveGroup[nPath].empty())
|
||||
continue ;
|
||||
|
||||
// --- se ho una sola curva, allora controllo se posso cambiare il suo punto d'inizio
|
||||
// nel caso non sia la prima in assoluto [ -> controllo ptRef]
|
||||
if ( int( vIndependentCurveGroup[nPath].size()) == 1) {
|
||||
if ( ptRef.IsValid()) {
|
||||
// --- se la curva di bordo singola è aperta
|
||||
if ( ! vIndependentCurveGroup[nPath][0]->IsClosed()) {
|
||||
// ... se necessario la inverto per recuperare l'estremo più vicino a ptRef
|
||||
// [ per ora le curve aperte possono essere invertite nelle finiture a ZLevel]
|
||||
Point3d ptS ; vIndependentCurveGroup[nPath][0]->GetStartPoint( ptS) ;
|
||||
Point3d ptE ; vIndependentCurveGroup[nPath][0]->GetEndPoint( ptE) ;
|
||||
if ( SqDist( ptE, ptRef) < SqDist( ptS, ptRef))
|
||||
vIndependentCurveGroup[nPath][0]->Invert() ;
|
||||
}
|
||||
// se non ho trovato nessuna colonna valida
|
||||
if ( nNextCol_path == -1) {
|
||||
nCurrRow = 0 ; // azzero il contatore delle righe
|
||||
break ; // interrompo ciclo sulle righe successive di ricerca
|
||||
}
|
||||
// altrimenti creo raccordo e aggiungo la curva al percorso
|
||||
// --- se la curva di bordo singola è chiusa
|
||||
else {
|
||||
// definisco un tratto lineare che collega gli estremi
|
||||
Point3d ptStartLink = ptCurrEnd ;
|
||||
Point3d ptEndLink ; vCrvCompo[nNextRow][nNextCol_path]->GetStartPoint( ptEndLink) ;
|
||||
PtrOwner<ICurveLine> pLineLink( CreateCurveLine()) ;
|
||||
if ( IsNull( pLineLink) || ! pLineLink->Set( ptStartLink, ptEndLink) ||
|
||||
! pLineLink->IsValid()) {
|
||||
// se tratto lineare non valido, non creo il collegamento
|
||||
nCurrRow = 0 ; // azzero il contatore delle righe
|
||||
break ; // interrompo ciclo sulle righe successive di ricerca
|
||||
}
|
||||
// se la linea è parallela a vtTool( Z_AX), allora ho una parete verticale (localmente)
|
||||
Vector3d vtLineLink ; pLineLink->GetStartDir( vtLineLink) ;
|
||||
if ( AreSameOrOppositeVectorEpsilon( vtLineLink, Z_AX, 100 * EPS_SMALL)) {
|
||||
// in questo caso la proiezione del link è automaticamente sul bordo della pSrfClass
|
||||
vCrvPath.back()->AddCurve( Release( pLineLink), true, 1500 * EPS_SMALL) ;
|
||||
vCrvPath.back()->AddCurve( Release( vCrvCompo[nNextRow][nNextCol_path]), true, 1500 * EPS_SMALL) ;
|
||||
// cerco il punto a minima distanza da ptRef ( non inverto, tengo il senso di lavorazione)
|
||||
double dMinPar = 0. ;
|
||||
int nFlag = 0 ;
|
||||
DistPointCurve( ptRef, *vIndependentCurveGroup[nPath][0]).GetParamAtMinDistPoint( 0., dMinPar, nFlag) ;
|
||||
vIndependentCurveGroup[nPath][0]->ChangeStartPoint( dMinPar) ;
|
||||
}
|
||||
}
|
||||
// inserisco la curva nel percorso
|
||||
vCrvPath.emplace_back( Release( vIndependentCurveGroup[nPath][0])) ;
|
||||
// aggiorno il punto di riferimento
|
||||
vCrvPath.back()->GetEndPoint( ptRef) ;
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
m_pGeomDB->SetName( nLay, "Single") ;
|
||||
Color myCol = Color( double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, 1.) ;
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, CloneCurveComposite( vCrvPath.back())) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
#endif
|
||||
continue ;
|
||||
}
|
||||
|
||||
// --- se ho più curve di bordo, scorro le curve a due a due per creare i collegamenti
|
||||
for ( int nCompo = 0 ; nCompo < int( vIndependentCurveGroup[nPath].size()) - 1 ; ++ nCompo) {
|
||||
// se prima curva di bordo e ho un punto di riferimento valido
|
||||
if ( nCompo == 0 && ptRef.IsValid()) {
|
||||
// --- se la prima curva di bordo è aperta
|
||||
if ( ! vIndependentCurveGroup[nPath][0]->IsClosed()) {
|
||||
// ... se necessario la inverto per recuperare l'estremo più vicino a ptRef
|
||||
// [ per ora le curve aperte possono essere invertite nelle finiture a ZLevel]
|
||||
Point3d ptS ; vIndependentCurveGroup[nPath][0]->GetStartPoint( ptS) ;
|
||||
Point3d ptE ; vIndependentCurveGroup[nPath][0]->GetEndPoint( ptE) ;
|
||||
if ( SqDist( ptE, ptRef) < SqDist( ptS, ptRef))
|
||||
vIndependentCurveGroup[nPath][0]->Invert() ;
|
||||
}
|
||||
// --- se la prima curva di bordo è chiusa
|
||||
else {
|
||||
// cerco il punto a minima distanza da ptRef ( non inverto, tengo il senso di lavorazione)
|
||||
double dMinPar = 0. ;
|
||||
int nFlag = 0 ;
|
||||
DistPointCurve( ptRef, *vIndependentCurveGroup[nPath][0]).GetParamAtMinDistPoint( 0., dMinPar, nFlag) ;
|
||||
vIndependentCurveGroup[nPath][0]->ChangeStartPoint( dMinPar) ;
|
||||
}
|
||||
}
|
||||
// come riferimento imposto inizialmente il punto finale della curva corrente
|
||||
vIndependentCurveGroup[nPath][nCompo]->GetEndPoint( ptRef) ;
|
||||
// --- se la curva di bordo successiva è aperta...
|
||||
if ( ! vIndependentCurveGroup[nPath][nCompo + 1]->IsClosed()) {
|
||||
// ... se necessario la inverto per recuperare l'estremo più vicino a quello corrente
|
||||
// [ per ora le curve aperte possono essere invertite nelle finiture a ZLevel]
|
||||
Point3d ptS ; vIndependentCurveGroup[nPath][nCompo + 1]->GetStartPoint( ptS) ;
|
||||
Point3d ptE ; vIndependentCurveGroup[nPath][nCompo + 1]->GetEndPoint( ptE) ;
|
||||
if ( SqDist( ptE, ptRef) < SqDist( ptS, ptRef))
|
||||
vIndependentCurveGroup[nPath][nCompo + 1]->Invert() ;
|
||||
}
|
||||
// --- se la curva successiva è chiusa
|
||||
else {
|
||||
// cerco il punto a minima distanza ( non inverto, tengo il senso di lavorazione)
|
||||
double dMinPar = 0. ;
|
||||
int nFlag = 0 ;
|
||||
DistPointCurve( ptRef, *vIndependentCurveGroup[nPath][nCompo + 1]).GetParamAtMinDistPoint( 0., dMinPar, nFlag) ;
|
||||
vIndependentCurveGroup[nPath][nCompo + 1]->ChangeStartPoint( dMinPar) ;
|
||||
}
|
||||
|
||||
// definisco il collegamento diretto come tratto lineare
|
||||
Point3d ptStartLink ; vIndependentCurveGroup[nPath][nCompo]->GetEndPoint( ptStartLink) ;
|
||||
Point3d ptEndLink ; vIndependentCurveGroup[nPath][nCompo + 1]->GetStartPoint( ptEndLink) ;
|
||||
PtrOwner<ICurveLine> pLineLink( CreateCurveLine()) ;
|
||||
if ( IsNull( pLineLink) || ! pLineLink->Set( ptStartLink, ptEndLink) || ! pLineLink->IsValid())
|
||||
continue ; // il Link rimane nullptr
|
||||
|
||||
// --- se il Link è parallelo a vtTool ( Z_AX in locale), allora ho una parete verticale ( localemente)
|
||||
Vector3d vtDirLink ; pLineLink->GetStartDir( vtDirLink) ;
|
||||
if ( AreSameOrOppositeVectorEpsilon( vtDirLink, Z_AX, 100 * EPS_SMALL)) {
|
||||
// la proiezione del Link è automaticamente all'interno della superficie di classificazione
|
||||
vCompoLink[nCompo + 1].Set( ConvertCurveToComposite( Release( pLineLink))) ;
|
||||
}
|
||||
// --- se il tratto lineare è troppo lungo, non considero il collegamento come valido
|
||||
else {
|
||||
if ( SqDist( ptStartLink, ptEndLink) > 4. * m_TParams.m_dDiam * m_TParams.m_dDiam)
|
||||
continue ; // il Link rimane nullptr
|
||||
|
||||
// proietto la curva nel piano locale della superficie di classificazione ( Z=0 ; Z_AX)
|
||||
PtrOwner<ICurve> pLineLinkProj( ProjectCurveOnPlane( *pLineLink, plProjection)) ;
|
||||
if ( IsNull( pLineLinkProj) || ! pLineLinkProj->IsValid())
|
||||
return false ;
|
||||
// effettuo la classificazione
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrClass->GetCurveClassification( *pLineLinkProj, EPS_SMALL, ccClass))
|
||||
continue ; // il Link rimane nullptr
|
||||
|
||||
// inizializzo il link come curva vuota e scorro le classificazioni ottenute
|
||||
vCompoLink[nCompo + 1].Set( CreateCurveComposite()) ;
|
||||
for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) {
|
||||
// recupero il tratto di curve corrente
|
||||
PtrOwner<ICurve> pSubCrv( pLineLinkProj->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE)) ;
|
||||
if ( IsNull( pSubCrv) || ! pSubCrv->IsValid()) // troppo piccolo...
|
||||
continue ; // passo al tratto di classificazione successivo
|
||||
// --- se la curva non è esterna alla regione, la conservo
|
||||
if ( ccClass[i].nClass != CRVC_OUT) {
|
||||
if ( ! vCompoLink[nCompo + 1]->AddCurve( Release( pSubCrv), true, LINK_TOL))
|
||||
return false ;
|
||||
}
|
||||
// --- se la curva è esterna, devo seguire il bordo della regione di classificazione
|
||||
else {
|
||||
// altrimenti, se i punti sono distanti, allora non considero valido il collegamento
|
||||
if ( SqDist( ptStartLink, ptEndLink) > 2. * m_TParams.m_dDiam) {
|
||||
nCurrRow = 0 ; // azzero il contatore delle righe
|
||||
break ; // interrompo ciclo sulle righe successive di ricerca
|
||||
}
|
||||
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pLineLink->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _b, ORANGE) ;
|
||||
#endif
|
||||
|
||||
// proietto la curva nel piano locale della pSfrClass ( Z=0 ; Z_AX)
|
||||
PtrOwner<ICurve> pLineLinkProjected( ProjectCurveOnPlane( *pLineLink, plProjection)) ;
|
||||
if ( IsNull( pLineLinkProjected) || ! pLineLinkProjected->IsValid())
|
||||
return false ;
|
||||
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _c = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pLineLinkProjected->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _c, YELLOW) ;
|
||||
#endif
|
||||
|
||||
// classifico la curva proiettata in base alla superficie
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ! pSfrClass->GetCurveClassification( *pLineLinkProjected, EPS_SMALL, ccClass))
|
||||
return false ;
|
||||
// inizializzo la nuova curva di Link
|
||||
PtrOwner<ICurveComposite> pCompoLink( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCompoLink))
|
||||
return false ;
|
||||
// scorro sulle classificazioni ottenute
|
||||
for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) {
|
||||
// recupero il tratto di curva corrente
|
||||
PtrOwner<ICurve> pCrv( pLineLinkProjected->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE)) ;
|
||||
if ( IsNull( pCrv) || ! pCrv->IsValid()) // troppo piccolo...
|
||||
continue ; // passo al tratto di classificazione successivo
|
||||
// se la curva non è esterna alla regione, allora la conservo (non rivina le Stm)
|
||||
if ( ccClass[i].nClass != CRVC_OUT) {
|
||||
if ( ! pCompoLink->AddCurve( Release( pCrv), true, 25 * EPS_SMALL))
|
||||
// recupero gli estremi del segmento di classificazione esterno alla pSfrClass
|
||||
Point3d ptS_sfr ; pLineLinkProj->GetPointD1D2( ccClass[i].dParS, ICurve::FROM_MINUS, ptS_sfr) ;
|
||||
Point3d ptE_sfr ; pLineLinkProj->GetPointD1D2( ccClass[i].dParE, ICurve::FROM_MINUS, ptE_sfr) ;
|
||||
// scorro tutti i loop della regione di classificazione
|
||||
for ( int j = 0 ; j < int( vCrvSfrLoops.size()) ; ++ j) {
|
||||
// se i punti trovati sono sul loop corrente
|
||||
if ( vCrvSfrLoops[j]->IsPointOn( ptS_sfr, LINK_TOL) &&
|
||||
vCrvSfrLoops[j]->IsPointOn( ptE_sfr, LINK_TOL)) {
|
||||
// devo orientare la SubCrv secondo il giusto verso di percorrenza
|
||||
double dUS ; vCrvSfrLoops[j]->GetParamAtPoint( ptS_sfr, dUS, LINK_TOL) ;
|
||||
double dUE ; vCrvSfrLoops[j]->GetParamAtPoint( ptE_sfr, dUE, LINK_TOL) ;
|
||||
PtrOwner<ICurve> pCrvA( ( vCrvSfrLoops[j]->CopyParamRange( dUS, dUE))) ;
|
||||
PtrOwner<ICurve> pCrvB( ( vCrvSfrLoops[j]->CopyParamRange( dUE, dUS))) ;
|
||||
double dLenA = INFINITO ; double dLenB = INFINITO ;
|
||||
if ( ! IsNull( pCrvA) && pCrvA->IsValid())
|
||||
pCrvA->GetLength( dLenA) ;
|
||||
if ( ! IsNull( pCrvB) && pCrvB->IsValid()) {
|
||||
// sempre percorsa in senso opposto
|
||||
pCrvB->Invert() ;
|
||||
pCrvB->GetLength( dLenB) ;
|
||||
}
|
||||
// aggiungo la curva
|
||||
if ( ! vCompoLink[nCompo + 1]->AddCurve( dLenA < dLenB ? Release( pCrvA) : Release( pCrvB), true, LINK_TOL))
|
||||
return false ;
|
||||
}
|
||||
// se la curva è esterna, allora devo seguire il bordo della regione di classificazione
|
||||
else {
|
||||
// recupero gli estremi del segmento di classificazione esterno alla pSfrClass
|
||||
Point3d ptS_sfr ; pLineLinkProjected->GetPointD1D2( ccClass[i].dParS, ICurve::FROM_MINUS, ptS_sfr) ;
|
||||
Point3d ptE_sfr ; pLineLinkProjected->GetPointD1D2( ccClass[i].dParE, ICurve::FROM_MINUS, ptE_sfr) ;
|
||||
// scorro tutti i loop della regione di classificazione
|
||||
for ( int j = 0 ; j < int( vCrvSfrLoops.size()) ; ++ j) {
|
||||
// se i punti trovati sono sul loop corrente
|
||||
if ( vCrvSfrLoops[j]->IsPointOn( ptS_sfr, 25 * EPS_SMALL) &&
|
||||
vCrvSfrLoops[j]->IsPointOn( ptE_sfr, 25 * EPS_SMALL)) {
|
||||
// devo capire quale delle due curve (pCrvA, pCrvB) devo seguire sul bordo
|
||||
double dUS ; vCrvSfrLoops[j]->GetParamAtPoint( ptS_sfr, dUS, 25 * EPS_SMALL) ;
|
||||
double dUE ; vCrvSfrLoops[j]->GetParamAtPoint( ptE_sfr, dUE, 25 * EPS_SMALL) ;
|
||||
PtrOwner<ICurveComposite> pCrvA( ConvertCurveToComposite( vCrvSfrLoops[j]->CopyParamRange( dUS, dUE))) ;
|
||||
PtrOwner<ICurveComposite> pCrvB( ConvertCurveToComposite( vCrvSfrLoops[j]->CopyParamRange( dUE, dUS))) ;
|
||||
// tra le due curve (pCrvA, pCrvB) scelgo quella con lunghezza minore
|
||||
double dLenA = INFINITO ; double dLenB = INFINITO ;
|
||||
if ( ! IsNull( pCrvA) && pCrvA->IsValid())
|
||||
pCrvA->GetLength( dLenA) ;
|
||||
if ( ! IsNull( pCrvB) && pCrvB->IsValid()) {
|
||||
// la pCrvB è sempre percorsa in senso opposto
|
||||
pCrvB->Invert() ;
|
||||
pCrvB->GetLength( dLenB) ;
|
||||
}
|
||||
// aggiungo la curva
|
||||
if ( ! pCompoLink->AddCurve( dLenA < dLenB ? Release( pCrvA) : Release( pCrvB), true, 25 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se il link trovato non è valido, ricomincio la ricerca
|
||||
if ( ! pCompoLink->IsValid()) {
|
||||
nCurrRow = 0 ; // azzero il contatore delle righe
|
||||
break ; // interrompo ciclo sulle righe successive di ricerca
|
||||
}
|
||||
|
||||
// porto il link sulla curva attuale di silhouette e lo proietto sulla pStm (sono in locale)
|
||||
double dSfrDistNext = vCrvCompo[nNextRow][nNextCol_path]->GetTempParam( 0) ;
|
||||
pCompoLink->Translate( Z_AX * min( dSfrDistCurr, dSfrDistNext)) ;
|
||||
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _d = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoLink->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _d, LIME) ;
|
||||
#endif
|
||||
|
||||
if ( ! CalcZConstProjectedLink( pCAvTlStm, frXY, frSurf, vtTool, dDepth, ptStartLink, ptEndLink, pCompoLink))
|
||||
return false ;
|
||||
|
||||
#if ENABLE_ZCONST_DEBUG
|
||||
int _e = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoLink->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( _e, RED) ;
|
||||
#endif
|
||||
|
||||
// aggiungo le curve ritrovate al percorso attuale
|
||||
if ( ! vCrvPath.back()->AddCurve( Release( pCompoLink), true, 1500 * EPS_SMALL) ||
|
||||
! vCrvPath.back()->AddCurve( Release( vCrvCompo[nNextRow][nNextCol_path]), true, 1500 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
vCrvPath.back()->GetEndPoint( ptCurrEnd) ; // aggiorno il punto finale del percorso
|
||||
vCrvPath.back()->SetTempProp( nNextRow + 1, 1) ; // salvo come seconda temp prop il piano a cui sono
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se non ho percorsi, non faccio nulla
|
||||
if ( vCrvPath.empty())
|
||||
return true ;
|
||||
// se ho percorsi non validi, errore
|
||||
for ( int i = 0 ; i < int( vCrvPath.size()) ; ++ i) {
|
||||
if ( vCrvPath[i] == nullptr || ! vCrvPath[i]->IsValid())
|
||||
return false ;
|
||||
}
|
||||
// se il link trovato non è valido, passo al successivo
|
||||
if ( ! vCompoLink[nCompo + 1]->IsValid())
|
||||
continue ; // il link rimane inizializzato e non valido ( 0 curve)
|
||||
|
||||
// preso come riferimento il primo percorso, ordino i successivi in base alla vicinanza
|
||||
Point3d ptRef ; vCrvPath.front()->GetEndPoint( ptRef) ;
|
||||
double dSqMaxDist = INFINITO ;
|
||||
for ( int i = 1 ; i < int( vCrvPath.size()) ; ++ i) {
|
||||
int nNextInd = i + 1 ;
|
||||
for ( int j = nNextInd ; j < int( vCrvPath.size()) ; ++ j) {
|
||||
Point3d ptS ; vCrvPath[j]->GetStartPoint( ptS) ;
|
||||
double dCurrSqDist = SqDist( ptS, ptRef) ;
|
||||
if ( dCurrSqDist < dSqMaxDist) {
|
||||
dSqMaxDist = dCurrSqDist ;
|
||||
nNextInd = j ;
|
||||
// porto il link sul piano della curva più in alto tra le due
|
||||
Point3d ptCheck ;
|
||||
vIndependentCurveGroup[nPath][nCompo + 1]->GetStartPoint( ptCheck) ;
|
||||
double dSfrDistNext = DistPointPlane( ptCheck, plProjection) ;
|
||||
vIndependentCurveGroup[nPath][nCompo]->GetStartPoint( ptCheck) ;
|
||||
double dSfrDistCurr = DistPointPlane( ptCheck, plProjection) ;
|
||||
vCompoLink[nCompo + 1]->Translate( Z_AX * min( dSfrDistCurr, dSfrDistNext)) ;
|
||||
// proietto tale Link sulla superficie
|
||||
if ( ! CalcZConstProjectedLink( pCAvTlStm, frXY, frSurf, vtTool, dDepth, ptStartLink, ptEndLink, vCompoLink[nCompo + 1]))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
if ( nNextInd != i + 1)
|
||||
swap( vCrvPath[i], vCrvPath[nNextInd]) ;
|
||||
dSqMaxDist = INFINITO ;
|
||||
|
||||
// calcolo il percorso unendo le curve di bordo con i Link ricavati
|
||||
const double PATH_TOL = 1500. * EPS_SMALL ;
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
int nLay = GDB_ID_NULL ;
|
||||
Color myCol = INVISIBLE ;
|
||||
#endif
|
||||
for ( int nCompo = 0 ; nCompo < int( vIndependentCurveGroup[nPath].size()) - 1 ; ++ nCompo) {
|
||||
if ( IsNull( vCompoLink[nCompo]) || ! vCompoLink[nCompo]->IsValid()) {
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
|
||||
myCol = Color( double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, 1.) ;
|
||||
#endif
|
||||
if ( ! vCrvPath.emplace_back( CreateCurveComposite()))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, CloneCurveComposite( vCompoLink[nCompo])) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
#endif
|
||||
vCrvPath.back()->AddCurve( Release( vCompoLink[nCompo]), true, PATH_TOL) ;
|
||||
}
|
||||
#if ENABLE_ZCONST_PATH_DEBUG
|
||||
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, CloneCurveComposite( vIndependentCurveGroup[nPath][nCompo])) ;
|
||||
m_pGeomDB->SetMaterial( nId, myCol) ;
|
||||
#endif
|
||||
vCrvPath.back()->AddCurve( Release( vIndependentCurveGroup[nPath][nCompo]), true, PATH_TOL) ;
|
||||
}
|
||||
}
|
||||
|
||||
// riporto i percorsi nel frame originale
|
||||
|
||||
Reference in New Issue
Block a user