EgtGeomKernel :

- migliorie MarchingSquares, semplificazione funzioni per CAv.
This commit is contained in:
Riccardo Elitropi
2025-03-11 11:17:30 +01:00
parent 5bc7036e98
commit a2825b2b6d
4 changed files with 195 additions and 446 deletions
+60 -331
View File
@@ -305,108 +305,6 @@ ModifyPolyLineToSharped( PNTIVECTOR& vAdvPt, const CAvToolSurfTm& cavTstm, const
return true ; return true ;
} }
//----------------------------------------------------------------------------
static bool
TestEdgesOpenPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int nStepX, int nStepY,
const Frame3d& frGrid, double dDimZ, double dLevel, double dStep, double dAngTol,
bool bAdvCorners)
{
// se non ho polylinee, allora esco
if ( vPL.empty())
return true ;
dAngTol = max( dAngTol, ANG_TOL_STD_DEG / 5.) ;
double dSegLen = 50 * dStep ;
// scorro le polyLinee aperte
for ( int nPol = 0 ; nPol < int( vPL.size()) ; ++ nPol) {
// essendo aperte, se presenti meno di 3 punti, non faccio nulla
int nPts = vPL[nPol].GetPointNbr() ;
if ( nPts < 3)
continue ;
// creo un vettore contenente tutti i punti
PNTVECTOR vPt ; vPt.reserve( nPts) ;
Point3d myPt ;
if ( ! vPL[nPol].GetFirstPoint( myPt))
return false ;
vPt.emplace_back( myPt) ;
while ( vPL[nPol].GetNextPoint( myPt))
vPt.emplace_back( myPt) ;
// creazione vettore di punti avanzati ( tutti validi)
PNTIVECTOR vAdvPt ; vAdvPt.reserve( nPts) ;
vPL[nPol].GetFirstPoint( myPt) ;
vAdvPt.emplace_back( make_pair( myPt, PointType::VALID)) ;
while ( vPL[nPol].GetNextPoint( myPt))
vAdvPt.emplace_back( make_pair( myPt, PointType::VALID)) ;
// modifico la posizione dei punti
if ( ! ModifyPolyLineToSharped( vAdvPt, cavTstm, frGrid, dAngTol, dStep, dSegLen))
return false ;
// ricostrusico la polyLine
vPL[nPol].Clear() ;
double dPar = -1 ;
for ( int j = 0 ; j < int( vAdvPt.size()) ; ++ j) {
// se punto valido o sharped di angolo interno, lo aggiungo
if ( j == 0 || j == int( vAdvPt.size() - 1) ||
vAdvPt[j].second == PointType::VALID || vAdvPt[j].second == PointType::SHARPED_INT)
vPL[nPol].AddUPoint( ++ dPar, vAdvPt[j].first) ;
// se è un punto sharped di un angolo esterno
else if ( vAdvPt[j].second == PointType::SHARPED_EXT) {
// se non richiesto il calcolo avanzato del punto a minima distanza dallo spigolo, aggiungo il punto
if ( ! bAdvCorners)
vPL[nPol].AddUPoint( ++ dPar, vAdvPt[j].first) ;
else {
// ricavo il punto a minima distanza dal materiale mediante metodo di bisezione
Vector3d vtPrev = ( vAdvPt[j-1].first - vAdvPt[j].first) ;
vtPrev.Normalize() ;
Vector3d vtAfter = ( vAdvPt[j+1].first - vAdvPt[j].first) ;
vtAfter.Normalize() ;
Vector3d vtMove = ( vtPrev + vtAfter) ;
vtMove.Normalize() ;
Point3d ptTest = vAdvPt[j].first + ( 2 * dStep * vtMove) ; // doppio dello step griglia
const int MAX_ITER = 20 ;
int nCount = 0 ;
while ( nCount < MAX_ITER) {
double dMove ;
ptTest.z += cavTstm.GetToolHeight() ;
ptTest.ToGlob( frGrid) ;
cavTstm.TestPosition( ptTest, frGrid.VersZ(), frGrid.VersZ(), dMove) ;
ptTest.ToLoc( frGrid) ;
ptTest.z -= cavTstm.GetToolHeight() ;
if ( dMove > EPS_SMALL)
ptTest = Media( ptTest, vAdvPt[j].first) ;
else
break ;
++ nCount ;
}
// ricavo i punti a minima distanza tra i due segmenti
Point3d ptMinDistA, ptMinDistB ;
DistPointLine distPtLPrev( ptTest, vAdvPt[j-1].first, vAdvPt[j].first) ;
DistPointLine distPtLSucc( ptTest, vAdvPt[j].first, vAdvPt[j+1].first) ;
distPtLPrev.GetMinDistPoint( ptMinDistA) ;
distPtLSucc.GetMinDistPoint( ptMinDistB) ;
vPL[nPol].AddUPoint( ++ dPar, ptMinDistA) ;
vPL[nPol].AddUPoint( ++ dPar, ptTest) ;
vPL[nPol].AddUPoint( ++ dPar, ptMinDistB) ;
}
}
}
// se la polyLinea si autointerseca, allora non la modifico ( essendo a distanza R dalla
// trimesh rischio di evere Chunk distinti uniti in un unico Chunk
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo))
return false ;
pCompo->FromPolyLine( vPL[nPol]) ;
SelfIntersCurve SIC( *pCompo) ;
if ( SIC.GetCrossOrOverlapIntersCount() > 0)
continue ;
}
return true ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool static bool
TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int nStepX, int nStepY, TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int nStepX, int nStepY,
@@ -572,7 +470,7 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
#if ENABLE_SHARPED_EDGES_DEBUG #if ENABLE_SHARPED_EDGES_DEBUG
// 5° gruppo, punti minDist A e B e ptMid // 5° gruppo, punti minDist A e B e ptMid
PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ; /*PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ;
myPtA->Set( ptMinDistA) ; myPtA->Set( ptMinDistA) ;
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtA))) ; vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtA))) ;
vvCol[4].emplace_back( BROWN) ; vvCol[4].emplace_back( BROWN) ;
@@ -583,7 +481,7 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
PtrOwner<IGeoPoint3d> myPtMid( CreateGeoPoint3d()) ; PtrOwner<IGeoPoint3d> myPtMid( CreateGeoPoint3d()) ;
myPtMid->Set( ptTest) ; myPtMid->Set( ptTest) ;
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtMid))) ; vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtMid))) ;
vvCol[4].emplace_back( BROWN) ; vvCol[4].emplace_back( BROWN) ;*/
#endif #endif
} }
} }
@@ -629,8 +527,7 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
static bool static bool
MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep, double dRad, MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep, double dRad,
double dOffsR, double dLevel, const CAvToolSurfTm& cavTstm, const Frame3d &frGrid, double dOffsR, double dLevel, const CAvToolSurfTm& cavTstm, const Frame3d &frGrid,
double dDimZ, double dCalcLevel, bool bSharpedEdges, double dSharpedTol, double dDimZ, double dCalcLevel, bool bTool, POLYLINEVECTOR& vPL)
bool bAvdCorners, bool bWithOffs, POLYLINEVECTOR& vPL)
{ {
#if ENABLE_PROCESS_SQUARE_DEBUG || ENABLE_BISECTION_DEBUG #if ENABLE_PROCESS_SQUARE_DEBUG || ENABLE_BISECTION_DEBUG
vector<IGeoObj*> VT_GO ; vector<IGeoObj*> VT_GO ;
@@ -859,9 +756,6 @@ MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep,
SaveGeoObj( VT_GO, VT_CO, Bisection_Debug_File_Name) ; SaveGeoObj( VT_GO, VT_CO, Bisection_Debug_File_Name) ;
#endif #endif
// definisco un vettore di polyLine temporaneo
POLYLINEVECTOR vPL_Tmp ;
// Recupero i contorni // Recupero i contorni
INTVECTOR vnId ; INTVECTOR vnId ;
while ( chainC.GetChainFromNear( ORIG, false, vnId)) { while ( chainC.GetChainFromNear( ORIG, false, vnId)) {
@@ -872,68 +766,31 @@ MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep,
Point3d ptCurr = vBiPnt[vnId[i]-1].second ; Point3d ptCurr = vBiPnt[vnId[i]-1].second ;
crvCompo.AddLine( ptCurr) ; crvCompo.AddLine( ptCurr) ;
} }
// la chiudo se richiesto crvCompo.Close() ;
if ( bWithOffs)
crvCompo.Close() ;
// elimino le parti allineate // elimino le parti allineate
crvCompo.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ; crvCompo.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
// salto i contorni orari con area inferiore al doppio del quadrato se richiesto // salto i contorni orari con area inferiore al doppio del quadrato
if ( bWithOffs) { double dCmpArea ;
double dCmpArea ; if ( ! crvCompo.GetAreaXY( dCmpArea) || ( dCmpArea < 0 && abs( dCmpArea) < 2 * dStep * dStep))
if ( ! crvCompo.GetAreaXY( dCmpArea) || ( dCmpArea < 0 && abs( dCmpArea) < 2 * dStep * dStep)) continue ;
continue ; // memorizzo i risultati ottenuti
} vPL.emplace_back( PolyLine()) ;
// per test mettere a 1 crvCompo.ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL.back()) ;
#if 1
vPL_Tmp.emplace_back( PolyLine()) ;
crvCompo.ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL_Tmp.back()) ;
#else
// eseguo offset a sinistra pari allo step
OffsetCurve offsCompo ;
offsCompo.Make( &crvCompo, -( dRad - 2 * EPS_SMALL), ICurve::OFF_CHAMFER) ;
PtrOwner<ICurve> pCrvOffset( offsCompo.GetLongerCurve()) ;
if ( ! IsNull( pCrvOffset)) {
vPL_Tmp.emplace_back( PolyLine()) ;
pCrvOffset->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL.back()) ;
}
#endif
} }
// se richiesto calcolo degli spigoli vivi // le polyline ricavate, definendo dei contorni di regioni, sono chiuse ; cerco di ricostruire gli spigoli vivi
if ( bSharpedEdges) { POLYLINEVECTOR vPL_Sharped( vPL.size()) ;
// divido le polyLines aperte dalle chiuse for ( int i = 0 ; i < int( vPL_Sharped.size()) ; ++ i)
POLYLINEVECTOR vPL_Closed ; vPL_Sharped[i] = vPL[i] ;
POLYLINEVECTOR vPL_Open ; if ( TestEdgesClosedPolyLines( vPL_Sharped, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, ANG_TOL_STD_DEG, false))
for ( int j = 0 ; j < int( vPL_Tmp.size()) ; ++ j) { swap( vPL_Sharped, vPL) ;
if ( vPL_Tmp[j].IsClosed())
vPL_Closed.emplace_back( vPL_Tmp[j]) ;
else
vPL_Open.emplace_back( vPL_Tmp[j]) ;
}
// ricostruisco gli spigoli vivi delle chiuse e delle aperte
POLYLINEVECTOR vPL_copy_Closed( vPL_Closed.size()) ;
for ( int j = 0 ; j < int( vPL_Closed.size()) ; ++ j)
vPL_copy_Closed[j] = vPL_Closed[j] ;
if ( TestEdgesClosedPolyLines( vPL_copy_Closed, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, dSharpedTol, bAvdCorners))
swap( vPL_copy_Closed, vPL_Closed) ;
POLYLINEVECTOR vPL_copy_Open( vPL_Open.size()) ;
for ( int j = 0 ; j < int( vPL_Open.size()) ; ++ j)
vPL_copy_Open[j] = vPL_Open[j] ;
if ( TestEdgesOpenPolyLines( vPL_copy_Open, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, dSharpedTol, bAvdCorners))
swap( vPL_copy_Open, vPL_Open) ;
vPL_Tmp.clear() ;
for ( int j = 0 ; j < int( vPL_Closed.size()) ; ++ j)
vPL_Tmp.emplace_back( vPL_Closed[j]) ;
for ( int j = 0 ; j < int( vPL_Open.size()) ; ++ j)
vPL_Tmp.emplace_back( vPL_Open[j]) ;
}
// per ogni polyLine ottenuta effettuo Offset di correzione se richiesto // se non ho impostato un utensile, devo effettuare un contro-offset
if ( bWithOffs) { if ( ! bTool) {
vPL.clear() ; POLYLINEVECTOR vPL_Offs ;
for ( int i = 0 ; i < int( vPL_Tmp.size()) ; ++ i) { for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
CurveComposite crvCompo ; CurveComposite crvCompo ;
if ( ! crvCompo.FromPolyLine( vPL_Tmp[i])) if ( ! crvCompo.FromPolyLine( vPL[i]))
return false ; return false ;
OffsetCurve offsCompo ; OffsetCurve offsCompo ;
offsCompo.Make( &crvCompo, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND) ; offsCompo.Make( &crvCompo, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND) ;
@@ -941,13 +798,25 @@ MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep,
while ( ! IsNull( pCrvOffset)) { while ( ! IsNull( pCrvOffset)) {
PolyLine myPolyLine ; PolyLine myPolyLine ;
pCrvOffset->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, myPolyLine) ; pCrvOffset->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, myPolyLine) ;
vPL.emplace_back( myPolyLine) ; vPL_Offs.emplace_back( myPolyLine) ;
pCrvOffset.Set( offsCompo.GetLongerCurve()) ; pCrvOffset.Set( offsCompo.GetLongerCurve()) ;
} }
} }
swap( vPL_Offs, vPL) ;
} }
else
swap( vPL_Tmp, vPL) ; #if ENABLE_BISECTION_DEBUG
VT_GO.emplace_back( static_cast<IGeoObj*>( cavTstm.GetvStm()[0]->Clone())) ;
VT_GO.back()->ToLoc( frGrid) ;
VT_CO.emplace_back( GRAY) ;
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
pCompo->FromPolyLine( vPL[i]) ;
VT_GO.emplace_back( static_cast<IGeoObj*>( pCompo->Clone())) ;
VT_CO.emplace_back( WHITE) ;
}
SaveGeoObj( VT_GO, VT_CO, Bisection_Debug_File_Name) ;
#endif
return true ; return true ;
} }
@@ -1021,7 +890,7 @@ CAvSilhouetteSurfTm( const ISurfTriMesh& Stm, const Plane3d& plPlane, double dTo
// calcolo della silhouette con il metodo MarchingSquares // calcolo della silhouette con il metodo MarchingSquares
double dLevel = dLevelOffs ; double dLevel = dLevelOffs ;
if ( ! MarchingSquares( vdGrid, nStepX, nStepY, dTol, dRad, 0., dLevel, cavTstm, frGrid, -1., -1., false, 0., false, true, vPL)) if ( ! MarchingSquares( vdGrid, nStepX, nStepY, dTol, dRad, 0., dLevel, cavTstm, frGrid, -1., -1., false, vPL))
return false ; return false ;
// riporto nella corretta posizione le curve trovate // riporto nella corretta posizione le curve trovate
for ( auto& PL : vPL) for ( auto& PL : vPL)
@@ -1060,45 +929,37 @@ CAvParSilhouettesSurfTm::SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& f
m_nStepY = 0 ; m_nStepY = 0 ;
m_dDimZ = 0 ; m_dDimZ = 0 ;
m_dLevelOffs = 0 ; m_dLevelOffs = 0 ;
m_dCornRad = 0. ;
m_dMaxMat = INFINITO ;
m_dOffsR = 0. ;
m_dSideAng = 0. ;
m_dMaxDepth = 0. ;
m_bGridOk = false ; m_bGridOk = false ;
m_bTool = false ;
return true ; return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvParSilhouettesSurfTm::SetDataForRegion( const CISURFTMPVECTOR& vpStm, const ISurfFlatRegion* pSfr, double dSideAng, CAvParSilhouettesSurfTm::SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol,
double dDiam, double dCornRad, double dMaxMat, double dOffsR, double dSideAng, double dDiam, double dCornRad, double dMaxMat, double dOffsR,
double dSampleTol, double dSharpedAngTol) double dMaxDepth)
{ {
// controllo validità della regione piana
if ( pSfr == nullptr || ! pSfr->IsValid())
return false ;
// recupero la FlatRegion
if ( ! m_Sfr.CopyFrom( pSfr) || ! m_Sfr.IsValid())
return false ;
// definisco il frame intrinseco alla regione piana
Frame3d frSfr ;
Point3d ptCenter ; m_Sfr.GetCentroid( ptCenter) ;
if ( ! frSfr.Set( ptCenter, m_Sfr.GetNormVersor()))
return false ;
m_frGrid = frSfr ;
m_vpStm = vpStm ; m_vpStm = vpStm ;
m_dTol = max( dSampleTol, 100 * EPS_SMALL) ; m_frGrid = frPlanes ;
m_dSharpedTol = dSharpedAngTol ; m_dTol = max( dTol, 100 * EPS_SMALL) ;
m_nStepX = 0 ;
m_nStepY = 0 ;
m_dDimZ = 0 ;
m_dLevelOffs = 0 ;
m_dRad = dDiam / 2. ; m_dRad = dDiam / 2. ;
m_dCornRad = dCornRad ; m_dCornRad = dCornRad ;
m_dMaxMat = dMaxMat ; m_dMaxMat = dMaxMat ;
m_dOffsR = dOffsR ; m_dOffsR = dOffsR ;
m_dSideAng = dSideAng ; m_dSideAng = dSideAng ;
m_nStepX = 0 ; m_dMaxDepth = dMaxDepth ;
m_nStepY = 0 ;
m_dDimZ = 0 ;
m_dLevelOffs = 0 ;
m_bGridOk = false ; m_bGridOk = false ;
m_bTool = true ;
return true ; return true ;
} }
@@ -1117,8 +978,8 @@ CAvParSilhouettesSurfTm::Prepare( void)
} }
// calcolo dati della griglia // calcolo dati della griglia
const double EXTRA_XY = 1.5 * m_dTol ; const double EXTRA_XY = ( m_bTool ? m_dRad + 2 : 1.5 * m_dTol) ;
const double EXTRA_Z = 10 * m_dTol ; const double EXTRA_Z = 10 * m_dTol + ( m_dMaxDepth > EPS_SMALL ? max( 0., m_dMaxDepth - b3All.GetDimZ()) : 0) ;
b3All.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ; b3All.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ;
m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ; m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ;
m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ; m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ;
@@ -1136,84 +997,6 @@ CAvParSilhouettesSurfTm::Prepare( void)
} }
} }
// esecuzione della verifica
if ( ! m_cavTstm.SetStdTool( m_dDimZ, m_dRad, 0))
return false ;
if ( m_vpStm.empty() || ! m_cavTstm.SetSurfTm( *( m_vpStm[0])))
return false ;
for ( int k = 1 ; k < int( m_vpStm.size()) ; ++ k)
m_cavTstm.AddSurfTm( *( m_vpStm[k])) ;
if ( ! m_cavTstm.TestSeries( vPntM, m_frGrid.VersZ(), m_frGrid.VersZ(), -1))
return false ;
// griglia degli spostamenti
m_vdGrid.clear() ;
m_vdGrid.resize( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
int nInd = i + j * ( m_nStepX + 1) ;
m_vdGrid[nInd] = vPntM[nInd].second ;
}
}
// disegno la griglia colorando i punti in base alle altezze trovate
#if ENABLE_COLORED_GRID_DEBUG
vector<IGeoObj*> VT_GO ;
vector<Color> VT_CO ;
for ( int i = 0 ; i < int( vPntM.size()) ; ++ i) {
PtrOwner<IGeoPoint3d> myPt( CreateGeoPoint3d()) ;
myPt->Set( vPntM[i].first) ;
double myAngle = 240 + 120 * ( vPntM[i].second / m_dDimZ) ;
VT_GO.emplace_back( static_cast<IGeoObj*>( Release( myPt))) ;
VT_CO.emplace_back( Color( GetColorFromHSV( HSV( myAngle, 1., 1.)))) ;
}
SaveGeoObj( VT_GO, VT_CO, Colored_Grid_Debug_File_Name) ;
#endif
return true ;
}
//----------------------------------------------------------------------------
bool
CAvParSilhouettesSurfTm::PrepareForRegion( void)
{
// se la regione piana non è valida, allora esco
if ( ! m_Sfr.IsValid())
return false ;
// se la regione piana ha normale diversa dalla griglia, allora errore
if ( ! AreSameVectorApprox( m_Sfr.GetNormVersor(), m_frGrid.VersZ()))
return false ;
// ingombro delle superfici nel riferimento dei piani
BBox3d b3All ;
Frame3d frInv = GetInvert( m_frGrid) ;
for ( auto pStm : m_vpStm) {
BBox3d b3Surf ;
if ( ! pStm->GetBBox( frInv, b3Surf, BBF_STANDARD))
return false ;
b3All.Add( b3Surf) ;
}
// calcolo dati della griglia
const double EXTRA_XY = m_dRad + 2 ; // per maggiore sicurezza aggiungo 2
const double EXTRA_Z = 10 * m_dTol ;
b3All.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ;
m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ;
m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ;
m_frGrid.ChangeOrig( GetToGlob( b3All.GetMin(), m_frGrid)) ;
m_dDimZ = b3All.GetDimZ() ;
m_dLevelOffs = - b3All.GetMin().z ;
// calcolo dei punti della griglia (sul top dell'utensile)
PNTUVECTOR vPntM( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
int nInd = i + j * ( m_nStepX + 1) ;
Point3d ptP = GetToGlob( Point3d( i * m_dTol, j * m_dTol, m_dDimZ), m_frGrid) ;
vPntM[nInd] = { ptP, 0.} ;
}
}
// esecuzione della verifica // esecuzione della verifica
if ( m_dSideAng < EPS_ANG_SMALL) if ( m_dSideAng < EPS_ANG_SMALL)
m_cavTstm.SetStdTool( m_dDimZ + m_dOffsR, m_dRad + m_dOffsR, m_dCornRad + m_dOffsR) ; m_cavTstm.SetStdTool( m_dDimZ + m_dOffsR, m_dRad + m_dOffsR, m_dCornRad + m_dOffsR) ;
@@ -1251,7 +1034,6 @@ CAvParSilhouettesSurfTm::PrepareForRegion( void)
} }
} }
// disegno la griglia colorando i punti in base alle altezze trovate // disegno la griglia colorando i punti in base alle altezze trovate
#if ENABLE_COLORED_GRID_DEBUG #if ENABLE_COLORED_GRID_DEBUG
vector<IGeoObj*> VT_GO ; vector<IGeoObj*> VT_GO ;
@@ -1269,7 +1051,6 @@ CAvParSilhouettesSurfTm::PrepareForRegion( void)
return true ; return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL) CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
@@ -1282,11 +1063,12 @@ CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
return false ; return false ;
m_bGridOk = true ; m_bGridOk = true ;
// calcolo della silhouette con il metodo MarchingSquares
dLevel += m_dLevelOffs ; dLevel += m_dLevelOffs ;
// controllo se ho impostato un utensile, in caso negativo, la silhouette richiede un contro-offset
double dCalcLevel = max( dLevel, 0.) ; double dCalcLevel = max( dLevel, 0.) ;
// calcolo della silhouette con il metodo MarchingSquare
if ( ! MarchingSquares( m_vdGrid, m_nStepX, m_nStepY, m_dTol, m_dRad, m_dOffsR, dCalcLevel, m_cavTstm, m_frGrid, if ( ! MarchingSquares( m_vdGrid, m_nStepX, m_nStepY, m_dTol, m_dRad, m_dOffsR, dCalcLevel, m_cavTstm, m_frGrid,
m_dDimZ, dCalcLevel, true, m_dSharpedTol, false, true, vPL)) m_dDimZ, dCalcLevel, m_bTool, vPL))
return false ; return false ;
// riporto nella corretta posizione le curve trovate // riporto nella corretta posizione le curve trovate
@@ -1296,57 +1078,4 @@ CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
PL.ToGlob( m_frGrid) ; PL.ToGlob( m_frGrid) ;
} }
return true ; return true ;
}
//----------------------------------------------------------------------------
bool
CAvParSilhouettesSurfTm::GetSilhouetteInsideRegion( double dLevel, POLYLINEVECTOR& vPL)
{
// reset risultato
vPL.clear() ;
// se necessario eseguo i calcoli preparatori
if ( ! m_bGridOk && ! PrepareForRegion())
return false ;
m_bGridOk = true ;
// calcolo della silhouette con il metodo MarchingSquares
dLevel += m_dLevelOffs ;
double dCalcLevel = max( dLevel, 0.) ;
if ( ! MarchingSquares( m_vdGrid, m_nStepX, m_nStepY, m_dTol, m_dRad, m_dOffsR, dCalcLevel, m_cavTstm, m_frGrid,
m_dDimZ, dCalcLevel, true, m_dSharpedTol, false, false, vPL))
return false ;
// taglio le regioni ottenute con la superficie piana
if ( m_Sfr.IsValid()) {
POLYLINEVECTOR vPL_InsideSfr ;
for ( auto& PL : vPL) {
// riporto nella corretta posizione le curve trovate
if ( dLevel < dCalcLevel - EPS_SMALL)
PL.Translate( Vector3d{ 0, 0, dLevel - dCalcLevel}) ;
PL.ToGlob( m_frGrid) ;
// definisco una curva composita a partire dalla polyline
CurveComposite curveCompo ;
curveCompo.FromPolyLine( PL) ;
// classifico la curva con la superficie piana di riferimento
CRVCVECTOR ccClass ;
if ( ! m_Sfr.GetCurveClassification( curveCompo, EPS_SMALL, ccClass))
return false ;
for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) {
// tengo tutti i tratti classfificati come "non fuori"
if ( ccClass[i].nClass != CRVC_OUT) {
PtrOwner<ICurveComposite> pCrvCompoPartIn( ConvertCurveToComposite( curveCompo.CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ;
if ( ! IsNull( pCrvCompoPartIn) && pCrvCompoPartIn->IsValid()) {
vPL_InsideSfr.emplace_back( PolyLine()) ;
pCrvCompoPartIn->ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL_InsideSfr.back()) ;
}
}
}
}
swap( vPL, vPL_InsideSfr) ;
}
else
return false ;
return true ;
} }
+5 -7
View File
@@ -24,19 +24,16 @@ class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
public : public :
// generica // generica
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol) override ; bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol) override ;
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol,
double dSideAng, double dDiam, double dCornRad, double dMaxMat, double dOffsR,
double dMaxDepth) override ;
bool GetSilhouette( double dLevel, POLYLINEVECTOR& vPL) override ; bool GetSilhouette( double dLevel, POLYLINEVECTOR& vPL) override ;
// con regione piana
bool SetDataForRegion( const CISURFTMPVECTOR& vpStm, const ISurfFlatRegion* pSfr, double dSideAng,
double dDiam, double dCornRad, double dMaxMat, double dOffsR,
double dSampleTol = 10 * EPS_SMALL, double dSharpedAngTol = 15.) override ;
bool GetSilhouetteInsideRegion( double dLevel, POLYLINEVECTOR& vPL) override ;
public : public :
CAvParSilhouettesSurfTm( void) ; CAvParSilhouettesSurfTm( void) ;
private : private :
bool Prepare( void) ; bool Prepare( void) ;
bool PrepareForRegion( void) ;
private : private :
CISURFTMPVECTOR m_vpStm ; CISURFTMPVECTOR m_vpStm ;
@@ -53,7 +50,8 @@ class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
double m_dOffsR ; double m_dOffsR ;
double m_dDimZ ; double m_dDimZ ;
double m_dLevelOffs ; double m_dLevelOffs ;
double m_dMaxDepth ;
bool m_bGridOk ; bool m_bGridOk ;
bool m_bTool ;
DBLVECTOR m_vdGrid ; DBLVECTOR m_vdGrid ;
SurfFlatRegion m_Sfr ;
} ; } ;
+121 -104
View File
@@ -160,10 +160,10 @@ CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Ve
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvToolSurfTm::TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, CAvToolSurfTm::TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
double& dTotDist, VCT3DVECTOR& vVtN) const double& dTotDist, VCT3DVECTOR& vVtN) const
{ {
// Funzione per calcolo collisione tra utensile e superfici; // Funzione per calcolo collisione tra utensile e superfici ;
// dToTDist è la distanza di traslazione del punto ptT lungo vtDir per evitare la collisione, // dToTDist è la distanza di traslazione del punto ptT lungo vtDir per evitare la collisione,
// vVtN è la normale del triangolo che genera collsione ( NB. Nel caso di più triangoli concorrenti, // vVtN è la normale del triangolo che genera collsione ( NB. Nel caso di più triangoli concorrenti,
// vengono restituite tutte le normali trovate) // vengono restituite tutte le normali trovate)
@@ -187,77 +187,16 @@ CAvToolSurfTm::TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Ve
frMove.Set( ORIG, vtMove) ; frMove.Set( ORIG, vtMove) ;
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d // Se riferimenti di movimento uguali, sfrutto HashGrid 2d
if ( AreSameFrame( frMove, m_frMove)) { if ( AreSameFrame( frMove, m_frMove)) {
// calcolo box utensile nel riferimento di movimento // Eseguo controllo
BBox3d b3Tool ; Point3d ptCurr = ptT ;
Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ; dTotDist = MyTestPositionHGAdv( ptCurr, vtDir, vVtN) ;
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ; return ( dTotDist > - EPS_SMALL) ;
b3Tool.Add( ptTL) ;
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
if ( vtDirL.IsX())
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
else if ( vtDirL.IsY())
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
else if ( vtDirL.IsZ())
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
else {
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDirL.y * vtDirL.y) ;
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// ciclo sui triangoli che intersecano box in 2d
INTVECTOR vnIds ;
if ( m_HGrids.Find( b3Tool, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
// recupero la superficie
int nInd = vnIds[i] ;
int nSurf = GetSurfInd( nInd) ;
if ( nSurf == -1)
return false ;
// recupero il triangolo
int nT = nInd - m_vBaseInd[nSurf] ;
Triangle3d Tria ;
if ( ! m_vSTM[nSurf]->GetTriangle( nT, Tria))
return false ;
// calcolo della collisione
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
if ( dDist < - EPS_SMALL)
return false ;
// se nuova distanza circa uguale a quella massima
if ( dDist > EPS_ZERO && abs( dDist - dTotDist) < 10 * EPS_SMALL)
vVtN.push_back( Tria.GetN()) ;
else if ( dDist > dTotDist + 10 * EPS_SMALL) {
dTotDist = dDist ;
vVtN.clear() ;
vVtN.push_back( Tria.GetN()) ;
}
}
}
return true ;
} }
} }
// Altrimenti eseguo controllo avanzato diretto // Altrimenti eseguo controllo diretto
// scorro tutte le superfici Point3d ptCurr = ptT ;
for ( auto pStm : m_vSTM) { dTotDist = MyTestPositionAdv( ptCurr, vtDir, vtMove, vVtN) ;
Triangle3d Tria ; return ( dTotDist > - EPS_SMALL) ;
// scorro tutti i trinagoli
for ( int nTria = pStm->GetFirstTriangle( Tria) ; nTria != SVT_NULL ; nTria = pStm->GetNextTriangle( nTria, Tria)) {
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
if ( dDist < - EPS_SMALL)
return false ;
// se nuova distanza maggiore della massima ...
if ( dDist > dTotDist) {
dTotDist = dDist ;
vVtN.clear() ;
vVtN.push_back( Tria.GetN()) ;
}
// se distanza circa uguale alla massima corrente...
else if ( dDist > EPS_SMALL && dDist > dTotDist - EPS_SMALL)
vVtN.push_back( Tria.GetN()) ;
}
}
return true ;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -463,16 +402,21 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvToolSurfTm::TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff) CAvToolSurfTm::TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff)
{ {
// NB. la posizione del punto non viene modificata :
// get<0> vPntM[i] è il punto su cui viene posizionata la testa dell'utensile ( const)
// get<1> vPntM[i] è il parametro di traslazione del punto lungo vtDir per evitare collisioni con i triangoli
// get<2> vPntM[i] è un vettore di Vector3d contenente tutte le normali di tangenza ( a meno di 10 * EPS_SMALL)
// Se utensile non definito, errore // Se utensile non definito, errore
if ( m_Tool.GetType() == Tool::UNDEF) if ( m_Tool.GetType() == Tool::UNDEF)
return false ; return false ;
// Se direzioni non definite, errore // Se direzioni non definite, errore
if ( vtDir.IsSmall() || vtMove.IsSmall()) if ( vtDir.IsSmall() || vtMove.IsSmall())
return false ; return false ;
// Se lista vuota, non devo fare alcunché // Se vettore vuoto, non devo fare alcunché
if ( lPntM.empty()) if ( vPntM.empty())
return true ; return true ;
// Calcolo nuovo riferimento di movimento // Calcolo nuovo riferimento di movimento
Frame3d frMove ; Frame3d frMove ;
@@ -489,35 +433,33 @@ CAvToolSurfTm::TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const
return false ; return false ;
} }
// Determino il numero di punti del path // Determino il numero di punti del path
m_nTotPnt = int( lPntM.size()) ; m_nTotPnt = int( vPntM.size()) ;
// Recupero il numero massimo di thread concorrenti // Recupero il numero massimo di thread concorrenti
int nThreadMax = thread::hardware_concurrency() ; int nThreadMax = thread::hardware_concurrency() ;
bool bOk = true ; bool bOk = true ;
// Se un solo thread o pochi punti // Se un solo thread o pochi punti
if ( nThreadMax <= 1 || m_nTotPnt < 500) { if ( nThreadMax <= 1 || m_nTotPnt < 500) {
m_nCurrPnt = 0 ; m_nCurrPnt = 0 ;
bOk = TestSubPointsAdv( -1, lPntM, vtDir, vtMove, dProgCoeff) ; bOk = TestSubSeriesAdv( -1, vPntM, vtDir, 0, m_nTotPnt - 1, dProgCoeff) ;
ProcessEvents( int( 100 * dProgCoeff), 0) ; ProcessEvents( int( 100 * dProgCoeff), 0) ;
} }
// altrimenti // altrimenti
else { else {
const int MAX_PARTS = 32 ; const int MAX_PARTS = 32 ;
PNTUVVECTLIST vlPntM[MAX_PARTS] ; INTINTVECTOR vFstLst( MAX_PARTS) ;
// divido la lista in parti // calcolo le parti del vettore
int nPartCnt = min( nThreadMax, MAX_PARTS) ; int nPartCnt = min( nThreadMax, MAX_PARTS) ;
int nPartDim = m_nTotPnt / nPartCnt ; int nPartDim = m_nTotPnt / nPartCnt + 1 ;
for ( int i = nPartCnt - 1 ; i > 0 ; -- i) { for ( int i = 0 ; i < nPartCnt ; ++ i) {
auto itSplit = prev( lPntM.end(), nPartDim) ; vFstLst[i].first = i * nPartDim ;
vlPntM[i].splice( vlPntM[i].end(), lPntM, itSplit, lPntM.end()) ; vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
vlPntM[i].push_front( lPntM.back()) ;
} }
vlPntM[0].splice( vlPntM[0].end(), lPntM) ;
// processo le parti // processo le parti
m_nCurrPnt = 0 ; m_nCurrPnt = 0 ;
m_bBreak = false ; m_bBreak = false ;
future<bool> vRes[MAX_PARTS] ; future<bool> vRes[MAX_PARTS] ;
for ( int i = 0 ; i < nPartCnt ; ++ i) for ( int i = 0 ; i < nPartCnt ; ++ i)
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPointsAdv, this, i, ref( vlPntM[i]), cref( vtDir), cref( vtMove), dProgCoeff) ; vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubSeriesAdv, this, i, ref( vPntM), cref( vtDir), vFstLst[i].first, vFstLst[i].second, dProgCoeff) ;
// attendo i risultati // attendo i risultati
int nFin = 0 ; int nFin = 0 ;
int nNextPE = 0 ; int nNextPE = 0 ;
@@ -535,15 +477,8 @@ CAvToolSurfTm::TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const
m_bBreak = true ; m_bBreak = true ;
} }
} }
// unisco le liste risultati
for ( int i = 0 ; i < nPartCnt ; ++ i) {
if ( i > 0)
lPntM.pop_back() ;
lPntM.splice( lPntM.end(), vlPntM[i]) ;
}
ProcessEvents( int( 100 * dProgCoeff), 0) ; ProcessEvents( int( 100 * dProgCoeff), 0) ;
} }
return bOk ; return bOk ;
} }
@@ -595,21 +530,18 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvToolSurfTm::TestSubPointsAdv( int nId, PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff) CAvToolSurfTm::TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff)
{ {
// Se lista vuota, non devo fare alcunché // Se vettore vuoto, non devo fare alcunché
if ( lPntM.empty()) if ( vPntM.empty())
return true ; return true ;
// Ciclo sui punti // Ciclo sui punti da verificare
auto itPntMPrev = lPntM.end() ; for ( int i = nFirst ; i <= nLast ; ++ i) {
auto itPntMCurr = lPntM.begin() ;
while ( itPntMCurr != lPntM.end()) {
// verifico il punto // verifico il punto
if ( ! TestPointAdv( get<0>( *itPntMCurr), vtDir, vtMove, get<1>( *itPntMCurr), get<2>( *itPntMCurr))) Point3d ptCurr = get<0>( vPntM[i]) ;
get<1>( vPntM[i]) = MyTestPositionHGAdv( ptCurr, vtDir, get<2>( vPntM[i])) ;
if ( get<1>( vPntM[i]) < - EPS_SMALL)
return false ; return false ;
// passo al successivo
itPntMPrev = itPntMCurr ;
++ itPntMCurr ;
++ m_nCurrPnt ; ++ m_nCurrPnt ;
// se singolo thread // se singolo thread
if ( nId == -1) { if ( nId == -1) {
@@ -688,6 +620,34 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector
return dTotDist ; return dTotDist ;
} }
//----------------------------------------------------------------------------
double
CAvToolSurfTm::MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const
{
double dTotDist = 0 ;
vVtTriaN.clear() ;
for ( auto pStm : m_vSTM) {
Triangle3d Tria ;
for ( int nTria = pStm->GetFirstTriangle( Tria) ;
nTria != SVT_NULL ;
nTria = pStm->GetNextTriangle( nTria, Tria)) {
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
if ( dDist < - EPS_SMALL)
return -1 ;
// se devo traslare il punto, c'è collisione
if ( dDist > EPS_SMALL) {
if ( dDist > 10 * EPS_SMALL) {
vVtTriaN.clear() ;
dTotDist += dDist ;
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
}
vVtTriaN.push_back( Tria.GetN()) ;
}
}
}
return dTotDist ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
double double
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const
@@ -739,6 +699,63 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d&
return dTotDist ; return dTotDist ;
} }
//----------------------------------------------------------------------------
double
CAvToolSurfTm::MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const
{
// calcolo box utensile nel riferimento di movimento
BBox3d b3Tool ;
Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ;
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
b3Tool.Add( ptTL) ;
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
if ( vtDirL.IsX())
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
else if ( vtDirL.IsY())
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
else if ( vtDirL.IsZ())
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
else {
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDirL.y * vtDirL.y) ;
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// ciclo sui triangoli che intersecano box in 2d
double dTotDist = 0. ;
INTVECTOR vnIds ;
if ( m_HGrids.Find( b3Tool, vnIds)) {
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
// recupero la superficie
int nInd = vnIds[i] ;
int nSurf = GetSurfInd( nInd) ;
if ( nSurf == -1)
return -1 ;
// recupero il triangolo
int nT = nInd - m_vBaseInd[nSurf] ;
Triangle3d Tria ;
if ( ! m_vSTM[nSurf]->GetTriangle( nT, Tria))
return -1 ;
// calcolo della collisione
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
if ( dDist < - EPS_SMALL)
return -1 ;
// se devo traslare il punto, c'è collisione
if ( dDist > EPS_SMALL) {
if ( dDist > 10 * EPS_SMALL) {
vVtTriaN.clear() ;
dTotDist += dDist ;
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
}
vVtTriaN.push_back( Tria.GetN()) ;
}
}
}
return dTotDist ;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
CAvToolSurfTm::PrepareHashGrid( void) CAvToolSurfTm::PrepareHashGrid( void)
+9 -4
View File
@@ -48,13 +48,16 @@ class CAvToolSurfTm : public ICAvToolSurfTm
} }
const ICurveComposite& GetToolOutline( bool bApprox = false) const override const ICurveComposite& GetToolOutline( bool bApprox = false) const override
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;} { return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ; double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ;
bool TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, bool TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
double& dTotDist, VCT3DVECTOR& vVtN) const override ; double& dTotDist, VCT3DVECTOR& vVtN) const override ;
bool TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ; bool TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
bool TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff = 1) override ; bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff = 1) override ;
bool TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
public : public :
CAvToolSurfTm( void) ; CAvToolSurfTm( void) ;
@@ -62,10 +65,12 @@ class CAvToolSurfTm : public ICAvToolSurfTm
private : private :
bool TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ; bool TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
bool TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff) ; bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff) ;
bool TestSubPointsAdv( int nId, PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff) ;
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const ; double MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const ;
double MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const ;
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const ; double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const ;
double MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const ;
bool MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr, bool MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ; const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ;
bool PrepareHashGrid( void) ; bool PrepareHashGrid( void) ;