EgtGeomKernel :
- migliorie MarchingSquares, semplificazione funzioni per CAv.
This commit is contained in:
+60
-331
@@ -305,108 +305,6 @@ ModifyPolyLineToSharped( PNTIVECTOR& vAdvPt, const CAvToolSurfTm& cavTstm, const
|
||||
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
|
||||
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
|
||||
// 5° gruppo, punti minDist A e B e ptMid
|
||||
PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ;
|
||||
/*PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ;
|
||||
myPtA->Set( ptMinDistA) ;
|
||||
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtA))) ;
|
||||
vvCol[4].emplace_back( BROWN) ;
|
||||
@@ -583,7 +481,7 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
||||
PtrOwner<IGeoPoint3d> myPtMid( CreateGeoPoint3d()) ;
|
||||
myPtMid->Set( ptTest) ;
|
||||
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtMid))) ;
|
||||
vvCol[4].emplace_back( BROWN) ;
|
||||
vvCol[4].emplace_back( BROWN) ;*/
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -629,8 +527,7 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
||||
static bool
|
||||
MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep, double dRad,
|
||||
double dOffsR, double dLevel, const CAvToolSurfTm& cavTstm, const Frame3d &frGrid,
|
||||
double dDimZ, double dCalcLevel, bool bSharpedEdges, double dSharpedTol,
|
||||
bool bAvdCorners, bool bWithOffs, POLYLINEVECTOR& vPL)
|
||||
double dDimZ, double dCalcLevel, bool bTool, POLYLINEVECTOR& vPL)
|
||||
{
|
||||
#if ENABLE_PROCESS_SQUARE_DEBUG || ENABLE_BISECTION_DEBUG
|
||||
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) ;
|
||||
#endif
|
||||
|
||||
// definisco un vettore di polyLine temporaneo
|
||||
POLYLINEVECTOR vPL_Tmp ;
|
||||
|
||||
// Recupero i contorni
|
||||
INTVECTOR 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 ;
|
||||
crvCompo.AddLine( ptCurr) ;
|
||||
}
|
||||
// la chiudo se richiesto
|
||||
if ( bWithOffs)
|
||||
crvCompo.Close() ;
|
||||
crvCompo.Close() ;
|
||||
// elimino le parti allineate
|
||||
crvCompo.MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
|
||||
// salto i contorni orari con area inferiore al doppio del quadrato se richiesto
|
||||
if ( bWithOffs) {
|
||||
double dCmpArea ;
|
||||
if ( ! crvCompo.GetAreaXY( dCmpArea) || ( dCmpArea < 0 && abs( dCmpArea) < 2 * dStep * dStep))
|
||||
continue ;
|
||||
}
|
||||
// per test mettere a 1
|
||||
#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
|
||||
// salto i contorni orari con area inferiore al doppio del quadrato
|
||||
double dCmpArea ;
|
||||
if ( ! crvCompo.GetAreaXY( dCmpArea) || ( dCmpArea < 0 && abs( dCmpArea) < 2 * dStep * dStep))
|
||||
continue ;
|
||||
// memorizzo i risultati ottenuti
|
||||
vPL.emplace_back( PolyLine()) ;
|
||||
crvCompo.ApproxWithLines( 0, 0, ICurve::APL_SPECIAL, vPL.back()) ;
|
||||
}
|
||||
|
||||
// se richiesto calcolo degli spigoli vivi
|
||||
if ( bSharpedEdges) {
|
||||
// divido le polyLines aperte dalle chiuse
|
||||
POLYLINEVECTOR vPL_Closed ;
|
||||
POLYLINEVECTOR vPL_Open ;
|
||||
for ( int j = 0 ; j < int( vPL_Tmp.size()) ; ++ j) {
|
||||
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]) ;
|
||||
}
|
||||
// le polyline ricavate, definendo dei contorni di regioni, sono chiuse ; cerco di ricostruire gli spigoli vivi
|
||||
POLYLINEVECTOR vPL_Sharped( vPL.size()) ;
|
||||
for ( int i = 0 ; i < int( vPL_Sharped.size()) ; ++ i)
|
||||
vPL_Sharped[i] = vPL[i] ;
|
||||
if ( TestEdgesClosedPolyLines( vPL_Sharped, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, ANG_TOL_STD_DEG, false))
|
||||
swap( vPL_Sharped, vPL) ;
|
||||
|
||||
// per ogni polyLine ottenuta effettuo Offset di correzione se richiesto
|
||||
if ( bWithOffs) {
|
||||
vPL.clear() ;
|
||||
for ( int i = 0 ; i < int( vPL_Tmp.size()) ; ++ i) {
|
||||
// se non ho impostato un utensile, devo effettuare un contro-offset
|
||||
if ( ! bTool) {
|
||||
POLYLINEVECTOR vPL_Offs ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
CurveComposite crvCompo ;
|
||||
if ( ! crvCompo.FromPolyLine( vPL_Tmp[i]))
|
||||
if ( ! crvCompo.FromPolyLine( vPL[i]))
|
||||
return false ;
|
||||
OffsetCurve offsCompo ;
|
||||
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)) {
|
||||
PolyLine 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()) ;
|
||||
}
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
@@ -1021,7 +890,7 @@ CAvSilhouetteSurfTm( const ISurfTriMesh& Stm, const Plane3d& plPlane, double dTo
|
||||
|
||||
// calcolo della silhouette con il metodo MarchingSquares
|
||||
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 ;
|
||||
// riporto nella corretta posizione le curve trovate
|
||||
for ( auto& PL : vPL)
|
||||
@@ -1060,45 +929,37 @@ CAvParSilhouettesSurfTm::SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& f
|
||||
m_nStepY = 0 ;
|
||||
m_dDimZ = 0 ;
|
||||
m_dLevelOffs = 0 ;
|
||||
m_dCornRad = 0. ;
|
||||
m_dMaxMat = INFINITO ;
|
||||
m_dOffsR = 0. ;
|
||||
m_dSideAng = 0. ;
|
||||
m_dMaxDepth = 0. ;
|
||||
m_bGridOk = false ;
|
||||
m_bTool = false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvParSilhouettesSurfTm::SetDataForRegion( const CISURFTMPVECTOR& vpStm, const ISurfFlatRegion* pSfr, double dSideAng,
|
||||
double dDiam, double dCornRad, double dMaxMat, double dOffsR,
|
||||
double dSampleTol, double dSharpedAngTol)
|
||||
CAvParSilhouettesSurfTm::SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol,
|
||||
double dSideAng, double dDiam, double dCornRad, double dMaxMat, double dOffsR,
|
||||
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_dTol = max( dSampleTol, 100 * EPS_SMALL) ;
|
||||
m_dSharpedTol = dSharpedAngTol ;
|
||||
m_frGrid = frPlanes ;
|
||||
m_dTol = max( dTol, 100 * EPS_SMALL) ;
|
||||
m_nStepX = 0 ;
|
||||
m_nStepY = 0 ;
|
||||
m_dDimZ = 0 ;
|
||||
m_dLevelOffs = 0 ;
|
||||
m_dRad = dDiam / 2. ;
|
||||
m_dCornRad = dCornRad ;
|
||||
m_dMaxMat = dMaxMat ;
|
||||
m_dOffsR = dOffsR ;
|
||||
m_dSideAng = dSideAng ;
|
||||
m_nStepX = 0 ;
|
||||
m_nStepY = 0 ;
|
||||
m_dDimZ = 0 ;
|
||||
m_dLevelOffs = 0 ;
|
||||
m_dMaxDepth = dMaxDepth ;
|
||||
m_bGridOk = false ;
|
||||
|
||||
m_bTool = true ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1117,8 +978,8 @@ CAvParSilhouettesSurfTm::Prepare( void)
|
||||
}
|
||||
|
||||
// calcolo dati della griglia
|
||||
const double EXTRA_XY = 1.5 * m_dTol ;
|
||||
const double EXTRA_Z = 10 * m_dTol ;
|
||||
const double EXTRA_XY = ( m_bTool ? m_dRad + 2 : 1.5 * 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) ;
|
||||
m_nStepX = int( ceil( b3All.GetDimX() / 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
|
||||
if ( m_dSideAng < EPS_ANG_SMALL)
|
||||
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
|
||||
#if ENABLE_COLORED_GRID_DEBUG
|
||||
vector<IGeoObj*> VT_GO ;
|
||||
@@ -1269,7 +1051,6 @@ CAvParSilhouettesSurfTm::PrepareForRegion( void)
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
|
||||
@@ -1282,11 +1063,12 @@ CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
|
||||
return false ;
|
||||
m_bGridOk = true ;
|
||||
|
||||
// calcolo della silhouette con il metodo MarchingSquares
|
||||
dLevel += m_dLevelOffs ;
|
||||
// controllo se ho impostato un utensile, in caso negativo, la silhouette richiede un contro-offset
|
||||
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,
|
||||
m_dDimZ, dCalcLevel, true, m_dSharpedTol, false, true, vPL))
|
||||
m_dDimZ, dCalcLevel, m_bTool, vPL))
|
||||
return false ;
|
||||
|
||||
// riporto nella corretta posizione le curve trovate
|
||||
@@ -1296,57 +1078,4 @@ CAvParSilhouettesSurfTm::GetSilhouette( double dLevel, POLYLINEVECTOR& vPL)
|
||||
PL.ToGlob( m_frGrid) ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
@@ -24,19 +24,16 @@ class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
|
||||
public :
|
||||
// generica
|
||||
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 ;
|
||||
// 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 :
|
||||
CAvParSilhouettesSurfTm( void) ;
|
||||
|
||||
private :
|
||||
bool Prepare( void) ;
|
||||
bool PrepareForRegion( void) ;
|
||||
|
||||
private :
|
||||
CISURFTMPVECTOR m_vpStm ;
|
||||
@@ -53,7 +50,8 @@ class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
|
||||
double m_dOffsR ;
|
||||
double m_dDimZ ;
|
||||
double m_dLevelOffs ;
|
||||
double m_dMaxDepth ;
|
||||
bool m_bGridOk ;
|
||||
bool m_bTool ;
|
||||
DBLVECTOR m_vdGrid ;
|
||||
SurfFlatRegion m_Sfr ;
|
||||
} ;
|
||||
+121
-104
@@ -160,10 +160,10 @@ CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Ve
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, VCT3DVECTOR& vVtN) const
|
||||
CAvToolSurfTm::TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
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,
|
||||
// vVtN è la normale del triangolo che genera collsione ( NB. Nel caso di più triangoli concorrenti,
|
||||
// vengono restituite tutte le normali trovate)
|
||||
@@ -187,77 +187,16 @@ CAvToolSurfTm::TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Ve
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d
|
||||
if ( AreSameFrame( frMove, m_frMove)) {
|
||||
// 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
|
||||
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 ;
|
||||
// Eseguo controllo
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPositionHGAdv( ptCurr, vtDir, vVtN) ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
// Altrimenti eseguo controllo avanzato diretto
|
||||
// scorro tutte le superfici
|
||||
for ( auto pStm : m_vSTM) {
|
||||
Triangle3d Tria ;
|
||||
// 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 ;
|
||||
// Altrimenti eseguo controllo diretto
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPositionAdv( ptCurr, vtDir, vtMove, vVtN) ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -463,16 +402,21 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
if ( lPntM.empty())
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
@@ -489,35 +433,33 @@ CAvToolSurfTm::TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const
|
||||
return false ;
|
||||
}
|
||||
// Determino il numero di punti del path
|
||||
m_nTotPnt = int( lPntM.size()) ;
|
||||
m_nTotPnt = int( vPntM.size()) ;
|
||||
// Recupero il numero massimo di thread concorrenti
|
||||
int nThreadMax = thread::hardware_concurrency() ;
|
||||
bool bOk = true ;
|
||||
// Se un solo thread o pochi punti
|
||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||
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) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
const int MAX_PARTS = 32 ;
|
||||
PNTUVVECTLIST vlPntM[MAX_PARTS] ;
|
||||
// divido la lista in parti
|
||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||
// calcolo le parti del vettore
|
||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||
int nPartDim = m_nTotPnt / nPartCnt ;
|
||||
for ( int i = nPartCnt - 1 ; i > 0 ; -- i) {
|
||||
auto itSplit = prev( lPntM.end(), nPartDim) ;
|
||||
vlPntM[i].splice( vlPntM[i].end(), lPntM, itSplit, lPntM.end()) ;
|
||||
vlPntM[i].push_front( lPntM.back()) ;
|
||||
int nPartDim = m_nTotPnt / nPartCnt + 1 ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
vFstLst[i].first = i * nPartDim ;
|
||||
vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
|
||||
}
|
||||
vlPntM[0].splice( vlPntM[0].end(), lPntM) ;
|
||||
// processo le parti
|
||||
m_nCurrPnt = 0 ;
|
||||
m_bBreak = false ;
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
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
|
||||
int nFin = 0 ;
|
||||
int nNextPE = 0 ;
|
||||
@@ -535,15 +477,8 @@ CAvToolSurfTm::TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const
|
||||
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) ;
|
||||
}
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
@@ -595,21 +530,18 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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é
|
||||
if ( lPntM.empty())
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Ciclo sui punti
|
||||
auto itPntMPrev = lPntM.end() ;
|
||||
auto itPntMCurr = lPntM.begin() ;
|
||||
while ( itPntMCurr != lPntM.end()) {
|
||||
// Ciclo sui punti da verificare
|
||||
for ( int i = nFirst ; i <= nLast ; ++ i) {
|
||||
// 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 ;
|
||||
// passo al successivo
|
||||
itPntMPrev = itPntMCurr ;
|
||||
++ itPntMCurr ;
|
||||
++ m_nCurrPnt ;
|
||||
// se singolo thread
|
||||
if ( nId == -1) {
|
||||
@@ -688,6 +620,34 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector
|
||||
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
|
||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const
|
||||
@@ -739,6 +699,63 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d&
|
||||
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
|
||||
CAvToolSurfTm::PrepareHashGrid( void)
|
||||
|
||||
+9
-4
@@ -48,13 +48,16 @@ class CAvToolSurfTm : public ICAvToolSurfTm
|
||||
}
|
||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
||||
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
||||
|
||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ;
|
||||
bool TestPointAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, VCT3DVECTOR& vVtN) const override ;
|
||||
bool TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, VCT3DVECTOR& vVtN) const 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 TestPointsAdv( PNTUVVECTLIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
|
||||
|
||||
public :
|
||||
CAvToolSurfTm( void) ;
|
||||
@@ -62,10 +65,12 @@ class CAvToolSurfTm : public ICAvToolSurfTm
|
||||
|
||||
private :
|
||||
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 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 MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) 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,
|
||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ;
|
||||
bool PrepareHashGrid( void) ;
|
||||
|
||||
Reference in New Issue
Block a user