From b3d868bcc957a3ee3a6a927c05dca19336950f23 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 10 Dec 2018 07:50:42 +0000 Subject: [PATCH] EgtGeomKernel : - aggiunta HashGrids3d a SurfTm con lazy evaluation - in CAvTool aggiunta verifica utensile ben definito. --- CAvToolSurfTm.cpp | 3 + CAvToolSurfTm.h | 2 +- EgtGeomKernel.vcxproj | 3 - EgtGeomKernel.vcxproj.filters | 9 --- HashGrids2d.cpp | 70 ++++++++++++++++------ HashGrids2d.h | 67 --------------------- HashGrids3d.cpp | 101 ++++++++++++++++++++----------- HashGrids3d.h | 67 --------------------- IntersCrvCompoCrvCompo.cpp | 6 +- IntersLineSurfStd.cpp | 53 +++++++++++++++++ IntersLineSurfStd.h | 4 ++ IntersLineSurfTm.cpp | 45 +++++++++++--- IntersLineSurfTm.h | 32 ---------- IntersPlaneSurfTm.cpp | 4 +- IntersSurfTmSurfTm.cpp | 28 +++------ PointGrid3d.cpp | 20 +++---- SurfTriMesh.cpp | 109 ++++++++++++++++++++++++++++++---- SurfTriMesh.h | 9 ++- Tool.cpp | 9 ++- VolZmapCalculus.cpp | 1 - VolZmapCreation.cpp | 2 +- VolZmapGraphics.cpp | 1 - VolZmapVolume.cpp | 1 - 23 files changed, 349 insertions(+), 297 deletions(-) delete mode 100644 HashGrids2d.h delete mode 100644 HashGrids3d.h delete mode 100644 IntersLineSurfTm.h diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index 50167ae..4864393 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -97,6 +97,9 @@ CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, double& bool CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol) { + // Se utensile non definito, errore + if ( m_Tool.GetType() == Tool::UNDEF) + return false ; // Se lista vuota, non devo fare alcunché if ( lPntM.empty()) return true ; diff --git a/CAvToolSurfTm.h b/CAvToolSurfTm.h index f4caa27..3679795 100644 --- a/CAvToolSurfTm.h +++ b/CAvToolSurfTm.h @@ -13,9 +13,9 @@ #pragma once -#include "HashGrids2d.h" #include "SurfTriMesh.h" #include "Tool.h" +#include "/EgtDev/Include/EGkHashGrids2d.h" #include "/EgtDev/Include/EGkCAvToolSurfTm.h" #include diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 8386eea..6a89a9e 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -513,15 +513,12 @@ copy $(TargetPath) \EgtProg\Dll64 - - - diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index eb7fff8..7f3ff20 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -770,12 +770,6 @@ File di intestazione\Include - - File di intestazione - - - File di intestazione - File di intestazione\Include @@ -800,9 +794,6 @@ File di intestazione\Include - - File di intestazione - File di intestazione diff --git a/HashGrids2d.cpp b/HashGrids2d.cpp index f9053c4..3d1aa15 100644 --- a/HashGrids2d.cpp +++ b/HashGrids2d.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2018 //---------------------------------------------------------------------------- -// File : HashGrids2d.cpp Data : 04.07.15 Versione : 1.6g1 +// File : HashGrids2d.cpp Data : 07.12.18 Versione : 1.9l1 // Contenuto : Funzioni della classe HashGrids2d. // // @@ -13,8 +13,9 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "HashGrids2d.h" #include "DllMain.h" +#include "/EgtDev/Include/EGkHashGrids2d.h" +#include "/EgtDev/Include/EgnStringUtils.h" #include using namespace std ; @@ -24,7 +25,7 @@ const size_t xCellCount = 16 ; const size_t yCellCount = 16 ; const size_t cellVectorSize = 16 ; const size_t occupiedCellsVectorSize = 256 ; -const size_t minimalGridDensity = 8 ; +const size_t minimalGridDensity = 1 ; const size_t gridActivationThreshold = 64 ; const double hierarchyFactor = 2 ; const double MIN_CELL_SIZE = 5.0 ; @@ -86,6 +87,8 @@ class HashGrid2d size_t m_objCount ; // Numero di oggetti presenti in questa griglia int m_stdNeighborOffset[9] ; // Array degli offset standard per le adiacenze + + BBox3d m_b3Grid ; // Box totale degli oggetti inseriti in questa griglia } ; //---------------------------------------------------------------------------- @@ -145,8 +148,10 @@ HashGrid2d::Add( HashGrids2d::ObjData& obj) // ... insert the body into the corresponding cell. Cell* pCell = m_cell + h ; Add( obj, pCell) ; - ++ m_objCount ; + + // Aggiorno box di griglia + m_b3Grid.Add( obj.box) ; } //---------------------------------------------------------------------------- @@ -157,7 +162,6 @@ HashGrid2d::Remove( HashGrids2d::ObjData& obj) // cell from which this body will be removed. Cell* pCell = m_cell + obj.nHash ; Remove( obj, pCell) ; - -- m_objCount ; } @@ -184,25 +188,38 @@ HashGrid2d::Update( HashGrids2d::ObjData& obj) // ... stored in the cell that corresponds to the new hash value. pCell = m_cell + newHash ; Add( obj, pCell) ; + + // Aggiorno box di griglia + m_b3Grid.Add( obj.box) ; } //---------------------------------------------------------------------------- void HashGrid2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) { - // recupero gli estremi del box + // Limito il box a quello di griglia + BBox3d b3Int ; + if ( ! b3Test.FindIntersectionXY( m_b3Grid, b3Int)) + return ; + + // Recupero gli estremi del box Point3d ptMin ; double dXDim, dYDim, dZDim ; - if ( ! b3Test.GetMinDim( ptMin, dXDim, dYDim, dZDim)) + if ( ! b3Int.GetMinDim( ptMin, dXDim, dYDim, dZDim)) return ; - // sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL + // Sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL ptMin -= Vector3d( 1, 1, 0) * ( m_dCellSpan + EPS_SMALL) ; dXDim += m_dCellSpan + 2 * EPS_SMALL ; dYDim += m_dCellSpan + 2 * EPS_SMALL ; - // numero di celle da esplorare sui 3 assi + + // Numero di celle da esplorare sui 3 assi int nXSpan = min( static_cast( ceil( dXDim * m_dInvCellSpan)), int( m_xCellCount)) ; int nYSpan = min( static_cast( ceil( dYDim * m_dInvCellSpan)), int( m_yCellCount)) ; - // verifico se conviene verificare queste celle o direttamente tutte e sole quelle occupate + + //string sOut = "Celle=" + ToString( int( m_xyCellCount)) + " Occupate=" + ToString( int(m_occupiedCells.size())) + " Span=" + ToString( nXSpan * nYSpan) ; + //LOG_INFO( GetEGkLogger(), sOut.c_str()) ; + + // Se conviene verificare queste celle if ( nXSpan * nYSpan < 5 * int( m_occupiedCells.size())) { // cella di base int nX = static_cast( Hash( ptMin)) ; @@ -212,7 +229,7 @@ HashGrid2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) // inserisco in lista gli oggetti della cella if ( m_cell[nY].m_Objs != nullptr) { for ( auto pObj : *( m_cell[nY].m_Objs)) { - if ( b3Test.OverlapsXY( pObj->box)) + if ( b3Int.OverlapsXY( pObj->box)) vnIds.push_back( pObj->nId) ; } } @@ -223,13 +240,15 @@ HashGrid2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) nX += m_cell[nX].m_neighborOffset[5] ; } } + + // altrimenti verifico direttamente tutte e sole quelle occupate else { // ciclo sulle celle occupate for ( auto cell : m_occupiedCells) { // inserisco in lista gli oggetti della cella if ( cell->m_Objs != nullptr) { for ( auto pObj : *(cell->m_Objs)) { - if ( b3Test.OverlapsXY( pObj->box)) + if ( b3Int.OverlapsXY( pObj->box)) vnIds.push_back( pObj->nId) ; } } @@ -247,6 +266,7 @@ HashGrid2d::Clear( void) } m_occupiedCells.clear() ; m_objCount = 0 ; + m_b3Grid.Reset() ; } //---------------------------------------------------------------------------- @@ -509,6 +529,9 @@ HashGrids2d::Add( int nObjId, const BBox3d& box) // bodies stored in 'm_objsToAdd' are finally inserted into the data structure. m_objsToAdd.push_back( &(m_ObjsList.back())) ; + // Aggiorno il box complessivo + m_b3Objs.Add( box) ; + return true ; } catch(...) { @@ -521,7 +544,7 @@ HashGrids2d::Add( int nObjId, const BBox3d& box) bool HashGrids2d::Modify( int nObjId, const BBox3d& box) { - // cerco l'oggetto con l'Id voluto + // Cerco l'oggetto con l'Id voluto auto iIter = m_ObjsMap.find( nObjId) ; if ( iIter == m_ObjsMap.end()) return false ; @@ -529,9 +552,12 @@ HashGrids2d::Modify( int nObjId, const BBox3d& box) if ( pObj == nullptr) return false ; - // modifico il suo box + // Modifico il suo box pObj->box = box ; + // Aggiorno il box complessivo + m_b3Objs.Add( box) ; + return true ; } @@ -635,21 +661,26 @@ HashGrids2d::Update( void) //---------------------------------------------------------------------------- bool -HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) +HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const { // pulisco il risultato vnIds.clear() ; vnIds.reserve( 128) ; + // limito con box globale + BBox3d b3Int ; + if ( ! b3Test.FindIntersectionXY( m_b3Objs, b3Int)) + return false ; + // ricerca nelle griglie if ( m_bGridActive) { for ( auto pGrid : m_GridList) - pGrid->Find( b3Test, vnIds) ; + pGrid->Find( b3Int, vnIds) ; } // ricerca negli oggetti fuori griglia for ( auto pObj : m_nonGridObjs) { - if ( b3Test.OverlapsXY( pObj->box)) + if ( b3Int.OverlapsXY( pObj->box)) vnIds.push_back( pObj->nId) ; } @@ -660,7 +691,6 @@ HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) return ( vnIds.size() > 0) ; } - //---------------------------------------------------------------------------- void HashGrids2d::Clear( void) @@ -675,6 +705,8 @@ HashGrids2d::Clear( void) m_nonGridObjs.clear() ; m_objsToAdd.clear() ; + + m_b3Objs.Reset() ; } //---------------------------------------------------------------------------- diff --git a/HashGrids2d.h b/HashGrids2d.h deleted file mode 100644 index 4e7df0d..0000000 --- a/HashGrids2d.h +++ /dev/null @@ -1,67 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2015 -//---------------------------------------------------------------------------- -// File : HashGrids2d.h Data : 04.07.15 Versione : 1.6g1 -// Contenuto : Dichiarazione della classe HashGrids2d. -// -// -// -// Modifiche : 04.07.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -#pragma once - -#include "EgtDev/Include/EGkBBox3d.h" -#include "EgtDev/Include/EgtNumCollection.h" -#include - -//---------------------------------------------------------------------------- -class HashGrids2d -{ - public : - HashGrids2d( void) ; - ~HashGrids2d( void) ; - void SetActivationGrid( bool bActivate) ; - bool Add( int nObjId, const BBox3d& box) ; - bool Modify( int nObjId, const BBox3d& box) ; - bool Remove( int nObjId) ; - bool Update( void) ; - bool Find( const BBox3d& b3Test, INTVECTOR& vnIds) ; - void Clear( void) ; - - friend class HashGrid2d ; - - private : - struct ObjData { - int nId ; - BBox3d box ; - HashGrid2d* pHGrid ; - size_t nHash ; - size_t nCellId ; - ObjData( void) - : nId( -1), box(), pHGrid( nullptr), nHash( 0), nCellId( 0) {} - ObjData( int nI, const BBox3d& bb, HashGrid2d* pHG, size_t nH, size_t nCI) - : nId( nI), box( bb), pHGrid( pHG), nHash( nH), nCellId( nCI) {} - } ; - typedef std::list ObjList ; - typedef std::vector PtrObjVector ; - typedef std::unordered_map IntPObjUmap ; - - private : - typedef std::list GridList ; // Tipo per lista di hash grid - - private : - void addGrid( ObjData& obj) ; - void addList( ObjData& obj) ; - - private : - ObjList m_ObjsList ; // Lista degli oggetti - IntPObjUmap m_ObjsMap ; // Map da Id a PtrObj - PtrObjVector m_objsToAdd ; // Vettore di puntatori agli oggetti da inserire - PtrObjVector m_nonGridObjs ; // Vettore di puntatori agli oggetti non assegnati alle griglie (per dimensioni o perchè pochi) - GridList m_GridList ; // Lista delle griglie di dimensione fissa ( in ordine crescente di dimensione di cella) - bool m_bActivate ; // Flag che abilita l'attivazione delle griglie - bool m_bGridActive ; // Flag di attivazione delle griglie -} ; diff --git a/HashGrids3d.cpp b/HashGrids3d.cpp index 8bafab2..e4b6279 100644 --- a/HashGrids3d.cpp +++ b/HashGrids3d.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2018 //---------------------------------------------------------------------------- -// File : HashGrids3d.cpp Data : 02.07.15 Versione : 1.6g1 +// File : HashGrids3d.cpp Data : 07.12.18 Versione : 1.9l1 // Contenuto : Funzioni della classe HashGrids3d. // // @@ -13,8 +13,9 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "HashGrids3d.h" #include "DllMain.h" +#include "/EgtDev/Include/EGkHashGrids3d.h" +#include "/EgtDev/Include/EgnStringUtils.h" #include using namespace std ; @@ -25,10 +26,10 @@ const size_t yCellCount = 16 ; const size_t zCellCount = 16 ; const size_t cellVectorSize = 16 ; const size_t occupiedCellsVectorSize = 256 ; -const size_t minimalGridDensity = 8 ; +const size_t minimalGridDensity = 1 ; const size_t gridActivationThreshold = 64 ; const double hierarchyFactor = 2 ; -const double MIN_CELL_SIZE = 25.0 ; +const double MIN_CELL_SIZE = 10.0 ; //---------------------------------------------------------------------------- // HashGrid3d @@ -90,6 +91,8 @@ class HashGrid3d size_t m_objCount ; // Numero di oggetti presenti in questa griglia int m_stdNeighborOffset[27] ; // Array degli offset standard per le adiacenze + + BBox3d m_b3Grid ; // Box totale degli oggetti inseriti in questa griglia } ; //---------------------------------------------------------------------------- @@ -140,31 +143,32 @@ HashGrid3d::~HashGrid3d( void) void HashGrid3d::Add( HashGrids3d::ObjData& obj) { - // If adding the body will cause the total number of bodies assigned to this grid to exceed the - // enlargement threshold, the size of this hash grid must be increased. + // If adding the body will cause the total number of bodies assigned to this grid to exceed the + // enlargement threshold, the size of this hash grid must be increased. if ( m_objCount == m_enlargementThreshold) Enlarge() ; - // Calculate (and store) the hash value (= the body's cell association) and ... + // Calculate (and store) the hash value (= the body's cell association) and ... size_t h = Hash( obj.box.GetMin()) ; obj.nHash = h ; - // ... insert the body into the corresponding cell. + // ... insert the body into the corresponding cell. Cell* pCell = m_cell + h ; Add( obj, pCell) ; - ++ m_objCount ; + + // Aggiorno box di griglia + m_b3Grid.Add( obj.box) ; } //---------------------------------------------------------------------------- void HashGrid3d::Remove( HashGrids3d::ObjData& obj) { - // The stored hash value (= the body's cell association) is used in order to directly access the - // cell from which this body will be removed. + // The stored hash value (= the body's cell association) is used in order to directly access the + // cell from which this body will be removed. Cell* pCell = m_cell + obj.nHash ; Remove( obj, pCell) ; - -- m_objCount ; } @@ -172,46 +176,59 @@ HashGrid3d::Remove( HashGrids3d::ObjData& obj) void HashGrid3d::Update( HashGrids3d::ObjData& obj) { - // The hash value is recomputed based on the body's current spatial location. + // The hash value is recomputed based on the body's current spatial location. size_t newHash = Hash( obj.box.GetMin()) ; size_t oldHash = obj.nHash ; - // If this new hash value is identical to the hash value of the previous time step, the body - // remains assigned to its current grid cell. + // If this new hash value is identical to the hash value of the previous time step, the body + // remains assigned to its current grid cell. if ( newHash == oldHash) return ; - // Only if the hash value changes, the cell association has to be changed, too - meaning, the - // body has to be removed from its currently assigned cell and ... + // Only if the hash value changes, the cell association has to be changed, too - meaning, the + // body has to be removed from its currently assigned cell and ... Cell* pCell = m_cell + oldHash ; Remove( obj, pCell) ; obj.nHash = newHash ; - // ... stored in the cell that corresponds to the new hash value. + // ... stored in the cell that corresponds to the new hash value. pCell = m_cell + newHash ; Add( obj, pCell) ; + + // Aggiorno box di griglia + m_b3Grid.Add( obj.box) ; } //---------------------------------------------------------------------------- void HashGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) { - // recupero gli estremi del box + // Limito il box a quello di griglia + BBox3d b3Int ; + if ( ! b3Test.FindIntersection( m_b3Grid, b3Int)) + return ; + + // Recupero gli estremi del box Point3d ptMin ; double dXDim, dYDim, dZDim ; - if ( ! b3Test.GetMinDim( ptMin, dXDim, dYDim, dZDim)) + if ( ! b3Int.GetMinDim( ptMin, dXDim, dYDim, dZDim)) return ; - // sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL + // Sposto p.to minimo in meno di una cella (oggetti possono occupare 2 celle) e allargo tutto di EPS_SMALL ptMin -= Vector3d( 1, 1, 1) * ( m_dCellSpan + EPS_SMALL) ; dXDim += m_dCellSpan + 2 * EPS_SMALL ; dYDim += m_dCellSpan + 2 * EPS_SMALL ; dZDim += m_dCellSpan + 2 * EPS_SMALL ; - // numero di celle da esplorare sui 3 assi + + // Numero di celle da esplorare sui 3 assi int nXSpan = min( static_cast( ceil( dXDim * m_dInvCellSpan)), int( m_xCellCount)) ; int nYSpan = min( static_cast( ceil( dYDim * m_dInvCellSpan)), int( m_yCellCount)) ; int nZSpan = min( static_cast( ceil( dZDim * m_dInvCellSpan)), int( m_zCellCount)) ; - // verifico se conviene verificare queste celle o direttamente tutte e sole quelle occupate + + //string sOut = "Celle=" + ToString( int( m_xyzCellCount)) + " Occupate=" + ToString( int(m_occupiedCells.size())) + " Span=" + ToString( nXSpan * nYSpan * nZSpan) ; + //LOG_INFO( GetEGkLogger(), sOut.c_str()) ; + + // Se conviene verificare queste celle if ( nXSpan * nYSpan * nZSpan < 5 * int( m_occupiedCells.size())) { // cella di base int nX = static_cast( Hash( ptMin)) ; @@ -223,7 +240,7 @@ HashGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) // inserisco in lista gli oggetti della cella if ( m_cell[nZ].m_Objs != nullptr) { for ( auto pObj : *( m_cell[nZ].m_Objs)) { - if ( b3Test.Overlaps( pObj->box)) + if ( b3Int.Overlaps( pObj->box)) vnIds.push_back( pObj->nId) ; } } @@ -237,13 +254,15 @@ HashGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) nX += m_cell[nX].m_neighborOffset[14] ; } } + + // altrimenti verifico direttamente tutte e sole quelle occupate else { // ciclo sulle celle occupate for ( auto cell : m_occupiedCells) { // inserisco in lista gli oggetti della cella if ( cell->m_Objs != nullptr) { for ( auto pObj : *(cell->m_Objs)) { - if ( b3Test.Overlaps( pObj->box)) + if ( b3Int.Overlaps( pObj->box)) vnIds.push_back( pObj->nId) ; } } @@ -261,6 +280,7 @@ HashGrid3d::Clear( void) } m_occupiedCells.clear() ; m_objCount = 0 ; + m_b3Grid.Reset() ; } //---------------------------------------------------------------------------- @@ -553,6 +573,9 @@ HashGrids3d::Add( int nObjId, const BBox3d& box) // bodies stored in 'm_objsToAdd' are finally inserted into the data structure. m_objsToAdd.push_back( &(m_ObjsList.back())) ; + // Aggiorno il box complessivo + m_b3Objs.Add( box) ; + return true ; } catch(...) { @@ -565,7 +588,7 @@ HashGrids3d::Add( int nObjId, const BBox3d& box) bool HashGrids3d::Modify( int nObjId, const BBox3d& box) { - // cerco l'oggetto con l'Id voluto + // Cerco l'oggetto con l'Id voluto auto iIter = m_ObjsMap.find( nObjId) ; if ( iIter == m_ObjsMap.end()) return false ; @@ -573,8 +596,12 @@ HashGrids3d::Modify( int nObjId, const BBox3d& box) if ( pObj == nullptr) return false ; - // modifico il suo box + // Modifico il suo box pObj->box = box ; + + // Aggiorno il box complessivo + m_b3Objs.Add( box) ; + return true ; } @@ -678,21 +705,26 @@ HashGrids3d::Update( void) //---------------------------------------------------------------------------- bool -HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) +HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const { // pulisco il risultato vnIds.clear() ; vnIds.reserve( 128) ; + // limito con box globale + BBox3d b3Int ; + if ( ! b3Test.FindIntersection( m_b3Objs, b3Int)) + return false ; + // ricerca nelle griglie if ( m_bGridActive) { for ( auto pGrid : m_GridList) - pGrid->Find( b3Test, vnIds) ; + pGrid->Find( b3Int, vnIds) ; } // ricerca negli oggetti fuori griglia for ( auto pObj : m_nonGridObjs) { - if ( b3Test.Overlaps( pObj->box)) + if ( b3Int.Overlaps( pObj->box)) vnIds.push_back( pObj->nId) ; } @@ -718,6 +750,8 @@ HashGrids3d::Clear( void) m_nonGridObjs.clear() ; m_objsToAdd.clear() ; + + m_b3Objs.Reset() ; } //---------------------------------------------------------------------------- @@ -727,7 +761,7 @@ HashGrids3d::addGrid( ObjData& obj) double size = - 1 ; obj.box.GetDiameter( size) ; - // If the body is finite in size, it must be assigned to a grid with suitably sized cells. + // If the body is finite in size, it must be assigned to a grid with suitably sized cells. if ( size > - EPS_ZERO) { size = max( size, MIN_CELL_SIZE) ; @@ -820,6 +854,5 @@ HashGrids3d::addList( ObjData& obj) obj.pHGrid = nullptr ; obj.nHash = m_nonGridObjs.size() ; obj.nCellId = 1 ; - m_nonGridObjs.push_back( &obj) ; + m_nonGridObjs.push_back( &obj) ; } - diff --git a/HashGrids3d.h b/HashGrids3d.h deleted file mode 100644 index 9be10f8..0000000 --- a/HashGrids3d.h +++ /dev/null @@ -1,67 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2015 -//---------------------------------------------------------------------------- -// File : HashGrids3d.h Data : 04.07.15 Versione : 1.6g1 -// Contenuto : Dichiarazione della classe HashGrids3d. -// -// -// -// Modifiche : 02.07.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -#pragma once - -#include "EgtDev/Include/EGkBBox3d.h" -#include "EgtDev/Include/EgtNumCollection.h" -#include - -//---------------------------------------------------------------------------- -class HashGrids3d -{ - public : - HashGrids3d( void) ; - ~HashGrids3d( void) ; - void SetActivationGrid( bool bActivate) ; - bool Add( int nObjId, const BBox3d& box) ; - bool Modify( int nObjId, const BBox3d& box) ; - bool Remove( int nObjId) ; - bool Update( void) ; - bool Find( const BBox3d& b3Test, INTVECTOR& vnIds) ; - void Clear( void) ; - - friend class HashGrid3d ; - - private : - struct ObjData { - int nId ; - BBox3d box ; - HashGrid3d* pHGrid ; - size_t nHash ; - size_t nCellId ; - ObjData( void) - : nId( -1), box(), pHGrid( nullptr), nHash( 0), nCellId( 0) {} - ObjData( int nI, const BBox3d& bb, HashGrid3d* pHG, size_t nH, size_t nCI) - : nId( nI), box( bb), pHGrid( pHG), nHash( nH), nCellId( nCI) {} - } ; - typedef std::list ObjList ; - typedef std::vector PtrObjVector ; - typedef std::unordered_map IntPObjUmap ; - - private : - typedef std::list GridList ; // Tipo per lista di hash grid - - private : - void addGrid( ObjData& obj) ; - void addList( ObjData& obj) ; - - private : - ObjList m_ObjsList ; // Lista degli oggetti - IntPObjUmap m_ObjsMap ; // Map da Id a PtrObj - PtrObjVector m_objsToAdd ; // Vettore di puntatori agli oggetti da inserire - PtrObjVector m_nonGridObjs ; // Vettore di puntatori agli oggetti non assegnati alle griglie (per dimensioni o perchè pochi) - GridList m_GridList ; // Lista delle griglie di dimensione fissa ( in ordine crescente di dimensione di cella) - bool m_bActivate ; // Flag che abilita l'attivazione delle griglie - bool m_bGridActive ; // Flag di attivazione delle griglie -} ; diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp index cce1610..75dfc4d 100644 --- a/IntersCrvCompoCrvCompo.cpp +++ b/IntersCrvCompoCrvCompo.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2014-2014 +// EgalTech 2014-2018 //---------------------------------------------------------------------------- -// File : IntersCrvCompoCrvCompo.cpp Data : 24.06.14 Versione : 1.5f6 +// File : IntersCrvCompoCrvCompo.cpp Data : 09.12.18 Versione : 1.9l1 // Contenuto : Implementazione della classe intersezione curva composita/cc. // // @@ -15,7 +15,7 @@ #include "stdafx.h" #include "IntersCrvCompoCrvCompo.h" #include "CurveAux.h" -#include "HashGrids2d.h" +#include "/EgtDev/Include/EGkHashGrids2d.h" #include using namespace std ; diff --git a/IntersLineSurfStd.cpp b/IntersLineSurfStd.cpp index 0eccf9b..184845e 100644 --- a/IntersLineSurfStd.cpp +++ b/IntersLineSurfStd.cpp @@ -16,9 +16,62 @@ #include "/EgtDev/Include/EGkFrame3d.h" #include "/EgtDev/Include//ENkPolynomialRoots.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include using namespace std ; +//---------------------------------------------------------------------------- +// Punti e vettore devono essere espressi nel medesimo sistema di riferimento. +// Il box è allineato con gli assi di tale sistema di riferimento. +// In dU1, dU2 vengono restituiti i parametri delle intersezioni. +// Viene restituito true in caso di intersezione, false altrimenti. +bool +IntersLineBox( const Point3d& ptP, const Vector3d& vtV, + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) +{ + // Il box è allineato agli assi + dU1 = - INFINITO ; + dU2 = INFINITO ; + + // confronto con piani YZ (perpendicolari ad asse X) + if ( vtV.x > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; + } + else if ( vtV.x < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; + } + else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL) + return false ; + + // confronto con piani ZX (perpendicolari ad asse Y) + if ( vtV.y > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; + } + else if ( vtV.y < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; + } + else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) + return false ; + + // confronto con piani XY (perpendicolari ad asse Z) + if ( vtV.z > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; + } + else if ( vtV.z < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; + } + else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL) + return false ; + + return ( dU2 >= dU1) ; +} + //---------------------------------------------------------------------------- int LineDisc( const Point3d& ptPLine, const Vector3d& vtVLine, diff --git a/IntersLineSurfStd.h b/IntersLineSurfStd.h index 93d3b3c..9e140e5 100644 --- a/IntersLineSurfStd.h +++ b/IntersLineSurfStd.h @@ -34,6 +34,10 @@ // Costanti tipologia di componente lineare enum LinType { Line = 0, Ray = 1, Segment = 2} ; +//---------------------------------------------------------------------------- +bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ; + // Costanti tipologia di intersezioni fra un componente lineare e un disco enum LinCompDiscIntersType { D_ERROR_INT = - 1, D_NO_INTERS = 0, D_BOUNDARY_INT_LINE_NOT_IN_PLANE = 1, diff --git a/IntersLineSurfTm.cpp b/IntersLineSurfTm.cpp index b2c23ef..c09556b 100644 --- a/IntersLineSurfTm.cpp +++ b/IntersLineSurfTm.cpp @@ -14,9 +14,10 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ProjPlane.h" -#include "IntersLineSurfTm.h" +#include "IntersLineSurfStd.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkIntersLineTria.h" +#include "/EgtDev/Include/EGkIntersLineSurfTm.h" using namespace std ; @@ -74,14 +75,40 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS return false ; vInfo.clear() ; + // limito la linea al box dei triangoli della superficie + const BBox3d b3Stm = Stm.GetAllTriaBox() ; + if ( b3Stm.IsEmpty()) + return false ; + double dU1, dU2 ; + if ( ! IntersLineBox( ptL, vtL, b3Stm.GetMin() , b3Stm.GetMax(), dU1, dU2)) + return false ; + if ( bFinite) { + dU1 = max( dU1, 0.) ; + dU2 = min( dU2, dLen) ; + if ( dU2 - dU1 < EPS_SMALL) + return false ; + } + Point3d ptStart = ptL + dU1 * vtL ; + double dLenEff = dU2 - dU1 ; // cerco i triangoli intersecati dalla linea - Triangle3d Tria ; - int nT = Stm.GetFirstTriangle( Tria) ; - while ( nT != SVT_NULL) { - // aggiorno info con intersezione - UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; - // passo al prossimo triangolo - nT = Stm.GetNextTriangle( nT, Tria) ; + const double BOX_STEP = 10 ; + int nStep = int( ceil( dLenEff / BOX_STEP)) ; + Vector3d vtStep = dLenEff / nStep * vtL ; + INTVECTOR vPrevT ; + for ( int i = 0 ; i < nStep ; ++ i) { + BBox3d b3Box( ptL + i * vtStep, ptL + ( i + 1) * vtStep) ; + INTVECTOR vT ; + if ( Stm.GetAllTriaOverlapBox( b3Box, vT)) { + for ( auto nT : vT) { + if ( find( vPrevT.begin(), vPrevT.end(), nT) == vPrevT.end()) { + vPrevT.emplace_back( nT) ; + Triangle3d Tria ; + Stm.GetTriangle( nT, Tria) ; + // aggiorno info con intersezione + UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ; + } + } + } } // ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea @@ -101,7 +128,7 @@ IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfT return ; // creo HashGrid 2d - const int LIM_HG_TRIA = 128 ; + const int LIM_HG_TRIA = 127 ; m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ; // riempio HashGrid diff --git a/IntersLineSurfTm.h b/IntersLineSurfTm.h deleted file mode 100644 index 76d228e..0000000 --- a/IntersLineSurfTm.h +++ /dev/null @@ -1,32 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2016-2016 -//---------------------------------------------------------------------------- -// File : IntersLineSurfTm.h Data : 06.11.16 Versione : 1.6w2 -// Contenuto : Dichiarazioni per intersezioni Linea/SurfTriMesh. -// -// -// -// Modifiche : 06.11.16 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -#pragma once - -#include "HashGrids2d.h" -#include "/EgtDev/Include/EGkIntersLineSurfTm.h" - - -//----------------------------------------------------------------------------- -class IntersParLinesSurfTm -{ - public : - IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm) ; - bool GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vInfo, bool bFinite = true) ; - - private : - bool m_bOk ; - const Frame3d m_frLines ; - const ISurfTriMesh* m_pSTm ; - HashGrids2d m_HGrids ; -} ; diff --git a/IntersPlaneSurfTm.cpp b/IntersPlaneSurfTm.cpp index 6b449b9..2376136 100644 --- a/IntersPlaneSurfTm.cpp +++ b/IntersPlaneSurfTm.cpp @@ -14,13 +14,13 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ProjPlane.h" -#include "IntersLineSurfTm.h" #include "CurveLine.h" #include "DistPointLine.h" -#include "HashGrids3d.h" #include "/EgtDev/Include/EGkIntersPlaneSurfTm.h" #include "/EgtDev/Include/EGkIntersPlaneTria.h" +#include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EGkPointGrid3d.h" +#include "/EgtDev/Include/EGkHashGrids3d.h" #include "/EgtDev/Include/EGkDistPointTria.h" #include diff --git a/IntersSurfTmSurfTm.cpp b/IntersSurfTmSurfTm.cpp index c6c6b77..2fb0ebf 100644 --- a/IntersSurfTmSurfTm.cpp +++ b/IntersSurfTmSurfTm.cpp @@ -13,13 +13,13 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "HashGrids3d.h" #include "DistPointLine.h" #include "IntersLineTria.h" #include "DllMain.h" #include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h" #include "/EgtDev/Include/EGkIntersTriaTria.h" #include "/EgtDev/Include/EGkPointGrid3d.h" +#include "/EgtDev/Include/EGkHashGrids3d.h" #include "/EgtDev/Include/EGkDistPointTria.h" #include "/EgtDev/Include/EgnStringUtils.h" #include @@ -59,29 +59,15 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, int nTriaNbr1 = Stm1.GetTriangleCount() ; int nTriaNbr2 = Stm2.GetTriangleCount() ; bool bHash1 = ( nTriaNbr1 > nTriaNbr2) ; - HashGrids3d HHGrids ; - const int LIM_SRFNBRSQUARED = 4095 ; - HHGrids.SetActivationGrid( long long( nTriaNbr1) * long long(nTriaNbr2) > LIM_SRFNBRSQUARED) ; - Triangle3d TriaH ; - int nT = ( bHash1 ? Stm1.GetFirstTriangle( TriaH) : Stm2.GetFirstTriangle( TriaH)) ; - while ( nT != SVT_NULL) { - BBox3d boxT ; - TriaH.GetLocalBBox( boxT) ; - if ( ! HHGrids.Add( nT, boxT)) - return false ; - nT = ( bHash1 ? Stm1.GetNextTriangle( nT, TriaH) : Stm2.GetNextTriangle( nT, TriaH)) ; - } - if ( ! HHGrids.Update()) - return false ; // cerco i triangoli che si intersecano Triangle3d TriaA ; - int nTA = ( bHash1 ? Stm2.GetFirstTriangle( TriaA) : Stm1.GetFirstTriangle( TriaA)) ; + int nTA = ( bHash1 ? Stm2.GetFirstTriangle( TriaA) : Stm1.GetFirstTriangle( TriaA)) ; while ( nTA != SVT_NULL) { BBox3d boxA ; TriaA.GetLocalBBox( boxA) ; INTVECTOR vnIds ; - if ( HHGrids.Find( boxA, vnIds)) { + if ( bHash1 ? Stm1.GetAllTriaOverlapBox( boxA, vnIds) : Stm2.GetAllTriaOverlapBox( boxA, vnIds)) { for ( int h = 0 ; h < int( vnIds.size()) ; ++ h) { int nB = vnIds[h] ; Triangle3d TriaB ; @@ -112,10 +98,12 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, int nA = vnIds[i] ; const Point3d& ptOth = vBpt[nA].first ; const Point3d& ptOth2 = vBpt[nA].second ; + //if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) && + // AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) || + // ( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) && + // AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) { if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) && - AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) || - ( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) && - AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) { + AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL))) { bFound = true ; break ; } diff --git a/PointGrid3d.cpp b/PointGrid3d.cpp index 7843c90..6b360c9 100644 --- a/PointGrid3d.cpp +++ b/PointGrid3d.cpp @@ -174,7 +174,7 @@ PointGrid3d::RemovePoint( const Point3d& ptP, int nId) //---------------------------------------------------------------------------- bool -PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds) +PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds) const { // pulisco il risultato vnIds.clear() ; @@ -200,7 +200,7 @@ PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds) //---------------------------------------------------------------------------- bool -PointGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) +PointGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const { // pulisco il risultato vnIds.clear() ; @@ -226,7 +226,7 @@ PointGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) //---------------------------------------------------------------------------- bool -PointGrid3d::Find( const Point3d& ptTest, double dTol, int& nId) +PointGrid3d::Find( const Point3d& ptTest, double dTol, int& nId) const { // determino il range di celle sui tre assi IBox iBox ; @@ -252,7 +252,7 @@ PointGrid3d::Find( const Point3d& ptTest, double dTol, int& nId) //---------------------------------------------------------------------------- bool -PointGrid3d::FindNearest( const Point3d& ptTest, INTVECTOR& vnIds) +PointGrid3d::FindNearest( const Point3d& ptTest, INTVECTOR& vnIds) const { const double NEAR_TOL = 100 * EPS_SMALL ; const int SIZE_LIMIT = 1000 ; @@ -356,7 +356,7 @@ PointGrid3d::FindNearest( const Point3d& ptTest, INTVECTOR& vnIds) //---------------------------------------------------------------------------- bool -PointGrid3d::FindNearest( const Point3d& ptTest, double dTol, int& nId) +PointGrid3d::FindNearest( const Point3d& ptTest, double dTol, int& nId) const { // determino il range di celle sui tre assi IBox iBox ; @@ -386,7 +386,7 @@ PointGrid3d::FindNearest( const Point3d& ptTest, double dTol, int& nId) //---------------------------------------------------------------------------- bool -PointGrid3d::First( int& nId) +PointGrid3d::First( int& nId) const { // se vuoto if ( m_MMap.empty()) @@ -398,14 +398,14 @@ PointGrid3d::First( int& nId) //---------------------------------------------------------------------------- int -PointGrid3d::Get1dCellNbr( double dCoord) +PointGrid3d::Get1dCellNbr( double dCoord) const { return static_cast( floor( dCoord * m_dInvCellDim)) ; } //---------------------------------------------------------------------------- bool -PointGrid3d::Get3dRangeNbr( const BBox3d& b3Test, IBox& iBox) +PointGrid3d::Get3dRangeNbr( const BBox3d& b3Test, IBox& iBox) const { // calcolo intersezione tra box BBox3d b3Int ; @@ -423,7 +423,7 @@ PointGrid3d::Get3dRangeNbr( const BBox3d& b3Test, IBox& iBox) //---------------------------------------------------------------------------- bool -PointGrid3d::Get3dRangeNbr( const Point3d& ptTest, double dTol, IBox& iBox) +PointGrid3d::Get3dRangeNbr( const Point3d& ptTest, double dTol, IBox& iBox) const { // calcolo intersezione tra box BBox3d b3Int ; @@ -441,7 +441,7 @@ PointGrid3d::Get3dRangeNbr( const Point3d& ptTest, double dTol, IBox& iBox) //---------------------------------------------------------------------------- int -PointGrid3d::PointHash( int nX, int nY, int nZ) +PointGrid3d::PointHash( int nX, int nY, int nZ) const { return ( nX * 73856093 ^ nY * 19349653 ^ nZ * 83492791) ; } diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index d7e16ac..2cdc31d 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -36,7 +36,7 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ; SurfTriMesh::SurfTriMesh( void) : m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dBoundaryAng( STM_STD_BOUNDARY_ANG), m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false), - m_nTimeStamp( 0), m_nTempProp( 0) + m_nTimeStamp( 0), m_nTempProp( 0), m_pHGrd3d( nullptr) { m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; @@ -45,14 +45,16 @@ SurfTriMesh::SurfTriMesh( void) //---------------------------------------------------------------------------- SurfTriMesh::~SurfTriMesh( void) { + ResetHashGrids3d() ; } //---------------------------------------------------------------------------- bool SurfTriMesh::Init( int nNumVert, int nNumTria, int nNumFacet) { - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // verifico validità parametri if ( nNumVert < 3 || nNumTria < 1) return false ; @@ -80,6 +82,7 @@ SurfTriMesh::AddVertex( const Point3d& ptVert) // imposto ricalcolo m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // inserisco il vertice try { m_vVert.emplace_back( ptVert) ;} catch(...) { return SVT_NULL ;} @@ -94,6 +97,7 @@ SurfTriMesh::SetVertex( int nInd, const StmVert& vV) // imposto ricalcolo m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // recupero la dimensione originale int nPrevSize = int( m_vVert.size()) ; // determino la dimensione necessaria @@ -143,6 +147,7 @@ SurfTriMesh::AddTriangle( const int nIdVert[3]) // imposto ricalcolo m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // inserisco il triangolo try { m_vTria.emplace_back( nIdVert) ;} catch(...) { return SVT_NULL ;} @@ -157,6 +162,7 @@ SurfTriMesh::SetTriangle( int nInd, const StmTria& tT) // imposto ricalcolo m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // recupero la dimensione originale int nPrevSize = int( m_vTria.size()) ; // determino la dimensione necessaria @@ -1040,8 +1046,9 @@ SurfTriMesh::Save( NgeWriter& ngeOut) const bool SurfTriMesh::Load( NgeReader& ngeIn) { - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // leggo la prossima linea ( 2 parametri : dLinTol e dSmoothAng) // tolleranza lineare di costruzione double dLinTol ; @@ -1680,6 +1687,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // verifico se la polilinea è chiusa bool bClosed = PL.IsClosed() ; @@ -1749,6 +1757,7 @@ SurfTriMesh::CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // costruisco la mesh int nVertNbr = 1 + PL.GetPointNbr() ; @@ -1799,7 +1808,8 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2) // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; - + ResetHashGrids3d() ; + // flag di curve chiuse bool bClosed = PL1.IsClosed() && PL2.IsClosed() ; // recupero i parametri delle due polilinee @@ -2091,6 +2101,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // verifico se la polilinea è chiusa bool bClosed = PL.IsClosed() ; @@ -2325,6 +2336,7 @@ SurfTriMesh::DoCompacting( double dTol) // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // definisco un Grid per i vertici della superficie PointGrid3d VertGrid ; @@ -2411,6 +2423,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther) // imposto ricalcolo m_nStatus = ERR ; m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // definisco un Grid per i vertici delle due superfici PointGrid3d VertGrid ; @@ -2538,8 +2551,9 @@ SurfTriMesh::Translate( const Vector3d& vtMove) if ( m_nStatus != OK) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // traslo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2562,8 +2576,9 @@ SurfTriMesh::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, if ( vtAx.IsSmall()) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // ruoto i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2604,8 +2619,9 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double if ( ( bZeroX && bZeroY) || ( bZeroX && bZeroZ) || ( bZeroY && bZeroZ)) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // scalo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2697,8 +2713,9 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) if ( vtNorm.IsSmall()) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // specchio i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) @@ -2729,8 +2746,9 @@ SurfTriMesh::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // eseguo scorrimento dei vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2760,8 +2778,9 @@ SurfTriMesh::ToGlob( const Frame3d& frRef) if ( frRef.GetType() == Frame3d::ERR) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2790,8 +2809,9 @@ SurfTriMesh::ToLoc( const Frame3d& frRef) if ( frRef.GetType() == Frame3d::ERR) return false ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2824,8 +2844,9 @@ SurfTriMesh::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) if ( AreSameFrame( frOri, frDest)) return true ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2854,8 +2875,9 @@ SurfTriMesh::Invert( void) for ( int i = 0 ; i < GetTriangleSize() ; ++ i) InvertTriangle( i) ; - // imposto ricalcolo della grafica + // imposto ricalcolo della grafica e di hashgrids3d m_OGrMgr.Reset() ; + ResetHashGrids3d() ; return true ; } @@ -3069,3 +3091,64 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) return true ; } + +//---------------------------------------------------------------------------- +void +SurfTriMesh::ResetHashGrids3d( void) const +{ + if ( m_pHGrd3d != nullptr) { + delete m_pHGrd3d ; + m_pHGrd3d = nullptr ; + m_b3HGrd3d.Reset() ; + } +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::VerifyHashGrids3d( void) const +{ + // se già calcolato, non devo fare altro + if ( m_pHGrd3d != nullptr) + return true ; + // alloco + m_pHGrd3d = new HashGrids3d ; + if ( m_pHGrd3d == nullptr) + return false ; + // riempio + const int LIM_HG_TRIA = 127 ; + m_pHGrd3d->SetActivationGrid( GetTriangleCount() > LIM_HG_TRIA) ; + Triangle3d TriaH ; + int nT = GetFirstTriangle( TriaH) ; + while ( nT != SVT_NULL) { + BBox3d boxT ; + TriaH.GetLocalBBox( boxT) ; + m_b3HGrd3d.Add( boxT) ; + if ( ! m_pHGrd3d->Add( nT, boxT)) { + ResetHashGrids3d() ; + return false ; + } + nT = GetNextTriangle( nT, TriaH) ; + } + if ( ! m_pHGrd3d->Update()) { + ResetHashGrids3d() ; + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const +{ + if ( ! VerifyHashGrids3d()) + return false ; + return m_pHGrd3d->Find( b3Box, vT) ; +} + +//---------------------------------------------------------------------------- +const BBox3d& +SurfTriMesh::GetAllTriaBox( void) const +{ + VerifyHashGrids3d() ; + return m_b3HGrd3d ; +} diff --git a/SurfTriMesh.h b/SurfTriMesh.h index dfbfa2d..bbbf647 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -17,6 +17,7 @@ #include "DllMain.h" #include "GeoObjRW.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "/EgtDev/Include/EGkHashGrids3d.h" #include #include @@ -181,6 +182,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool GetFacetsContact( int nF1, int nF2, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng) const override ; SurfTriMesh* CloneFacet( int nF) const override ; bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ; + bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ; + const BBox3d& GetAllTriaBox( void) const override ; public : // IGeoObjRW int GetNgeId( void) const override ; @@ -240,6 +243,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool VerifyAdjacTriaFacet( int nT, INTVECTOR& vT) const ; bool MarchAlongFacetLoop( int nF, int nT, int nV, int nTimeStamp, PolyLine& PL) const ; bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ; + void ResetHashGrids3d( void) const ; + bool VerifyHashGrids3d( void) const ; private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto @@ -256,7 +261,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW TRIAVECTOR m_vTria ; // vettore dei triangoli INTVECTOR m_vFacet ; // vettore delle sfaccettature mutable int m_nTimeStamp ; // orologio locale - int m_nTempProp ; // proprietà temporanea + int m_nTempProp ; // proprietà temporanea + mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento + mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d } ; //----------------------------------------------------------------------------- diff --git a/Tool.cpp b/Tool.cpp index 83deedf..4e8e526 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -457,13 +457,16 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, if ( ! bApprox) m_ArcLineApprox.Clear() ; - m_nType = GEN ; - // Il profilo dell'utensile deve stare nel 4° quadrante del piano XY + // Il profilo dell'utensile deve stare nel 1° e 4° quadrante del piano XY BBox3d Bounding ; m_Outline.GetLocalBBox( Bounding) ; - if ( Bounding.GetMin().x < - 10 * EPS_SMALL || Bounding.GetMax().y > 10 * EPS_SMALL) + if ( Bounding.GetMin().x < - 10 * EPS_SMALL) return false ; + + // Assegno il tipo dell'utensile + m_nType = GEN ; + // Assegno le dimensioni dell'utensile m_dHeight = - Bounding.GetMin().y ; m_dRadius = Bounding.GetMax().x ; diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 9307c03..8c30061 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -16,7 +16,6 @@ #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" -#include "IntersLineSurfTm.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkIntersLineTria.h" #include "/EgtDev/Include/EGkIntersLinePlane.h" diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index ab36206..20b11a0 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -17,7 +17,7 @@ #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" -#include "IntersLineSurfTm.h" +#include "/EgtDev/Include/EGkIntersLineSurfTm.h" #include "/EgtDev/Include/EgtNumUtils.h" using namespace std ; diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 264dca7..a28d234 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -16,7 +16,6 @@ #include "CurveLine.h" #include "VolZmap.h" #include "GeoConst.h" -#include "IntersLineSurfTm.h" #include "MC_Tables.h" #include "PolygonPlane.h" #include "/EgtDev/Include/EGkIntervals.h" diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index a4da3a0..e25cccc 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -18,7 +18,6 @@ #include "CurveArc.h" #include "VolZmap.h" #include "GeoConst.h" -#include "IntersLineSurfTm.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkStringUtils3d.h"