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 ;
|
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 ;
|
|
||||||
}
|
}
|
||||||
@@ -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
@@ -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
@@ -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) ;
|
||||||
|
|||||||
Reference in New Issue
Block a user