EgtGeomKernel :
- aggiunte funzioni per calcolo di Zmap e TriMesh di Offset Fillet Thickening.
This commit is contained in:
+45
-8
@@ -1,12 +1,14 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2022
|
||||
// EgalTech 2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMeshOffset.cpp Data : 10.06.25 Versione : 2.7e4
|
||||
// Contenuto : Implementazione funzione per Offset di Superfici TriMesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 10.06.25 RE Creazione modulo.
|
||||
// Modifiche : 10.06.25 RE - Creazione modulo.
|
||||
// 10.06.25 RE - Offset di superfici chiuse. ( ver. 2.7e4)
|
||||
// 04.07.25 RE - Thickening Offset di superfici generiche. ( ver. 2.7g1)
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -44,17 +46,25 @@ SumStm( const CISURFTMPVECTOR& vStm)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che crea l'Offset di una superficie TriMesh chiusa */
|
||||
/* Funzione che crea l'Offset di una superficie TriMesh */
|
||||
ISurfTriMesh*
|
||||
CreateSurfTriMeshOffset( const ISurfTriMesh* pStm, double dOffs, double dLinTol)
|
||||
CreateSurfTriMeshOffset( const ISurfTriMesh* pStm, double dOffs, double dLinTol, int nType)
|
||||
{
|
||||
return CreateSurfTriMeshesOffset( { pStm}, dOffs, dLinTol) ;
|
||||
return ( CreateSurfTriMeshesOffset( { pStm}, dOffs, dLinTol, nType)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che crea il Fat Offset di una superficie TriMesh */
|
||||
ISurfTriMesh*
|
||||
CreateSurfTriMeshThickeningOffset( const ISurfTriMesh* pStm, double dOffs, double dLinTol, int nType)
|
||||
{
|
||||
return ( CreateSurfTriMeshesThickeningOffset( { pStm}, dOffs, dLinTol, nType)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che crea l'Offset di un insieme di superfici */
|
||||
ISurfTriMesh*
|
||||
CreateSurfTriMeshesOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dLinTol)
|
||||
CreateSurfTriMeshesOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dLinTol, int nType)
|
||||
{
|
||||
// se vettore delle superfici vuoto, non faccio nulla
|
||||
if ( vStm.empty())
|
||||
@@ -66,10 +76,37 @@ CreateSurfTriMeshesOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dLi
|
||||
// ( questo valore serve per rimanere coerente con l'Offset delle curve)
|
||||
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||
return SumStm( vStm) ;
|
||||
// --- NB. Per la creazione dello Zmap è necessario che le superfici siano chiuse
|
||||
|
||||
// creo lo Zmap associato alle superfici TriMesh
|
||||
PtrOwner<IVolZmap> pVolZmap( CreateVolZmap()) ;
|
||||
if ( IsNull( pVolZmap) || ! pVolZmap->CreateFromTriMeshOffset( vStm, dOffs, dMyLinTol))
|
||||
if ( IsNull( pVolZmap) || ! pVolZmap->CreateFromTriMeshOffset( vStm, dOffs, dMyLinTol, nType))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie TriMesh
|
||||
return ( pVolZmap->GetSurfTriMesh()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione che crea il Fat Offset di un insieme di superfici */
|
||||
ISurfTriMesh*
|
||||
CreateSurfTriMeshesThickeningOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dLinTol, int nType)
|
||||
{
|
||||
// se vettore delle superfici vuoto, non faccio nulla
|
||||
if ( vStm.empty())
|
||||
return nullptr ;
|
||||
// controllo sul valore di tolleranza lineare
|
||||
double dMyLinTol = max( dLinTol, 10 * EPS_SMALL) ;
|
||||
// --- NB. ( Il valore di Offset deve essere maggiore di 10 * EPS_SMALL in valore assoluto)
|
||||
// Nel caso sia minore, restituisco semplicemente la somma delle superfici
|
||||
// ( questo valore serve per rimanere coerente con l'Offset delle curve)
|
||||
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||
return SumStm( vStm) ;
|
||||
|
||||
// creo lo Zmap associato alle superfici TriMesh
|
||||
PtrOwner<IVolZmap> pVolZmap( CreateVolZmap()) ;
|
||||
if ( IsNull( pVolZmap) || ! pVolZmap->CreateFromTriMeshThickeningOffset( vStm, dOffs, dMyLinTol, nType))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie TriMesh
|
||||
return ( pVolZmap->GetSurfTriMesh()) ;
|
||||
}
|
||||
@@ -82,7 +82,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
|
||||
bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ;
|
||||
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox = 0.) override ;
|
||||
bool CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) override ;
|
||||
bool CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = ISurfTriMesh::OFF_FILLET) override ;
|
||||
bool CreateFromTriMeshThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = ISurfTriMesh::OFF_FILLET) override ;
|
||||
int GetBlockCount( void) const override ;
|
||||
int GetBlockUpdatingCounter( int nBlock) const override ;
|
||||
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
|
||||
@@ -439,8 +440,13 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
bool SubtractMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||
// Funzioni per Offset di superfici
|
||||
bool CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid) ;
|
||||
bool CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid) ;
|
||||
bool InitVolZMapOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||
bool InitVolZMapThickeningOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||
bool UpdateVolZMapByOpenSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||
bool UpdateVolZMapByClosedSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||
bool UpdateVolZMapBySurfThickeningFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||
bool CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid, int nVertexType = 0) ;
|
||||
bool CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid, int nVertexType = 0) ;
|
||||
bool SubtractIntervalsForOffset( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
int nToolNum, bool bSkipSwap = false) ;
|
||||
|
||||
+346
-100
@@ -23,9 +23,8 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per aggiungere intervalli lungo un Dexel per l'offset di una superficie TriMesh */
|
||||
/* Funzione per sottrarre intervalli lungo un Dexel per l'offset di una superficie TriMesh */
|
||||
bool
|
||||
VolZmap::SubtractIntervalsForOffset( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
@@ -50,7 +49,7 @@ VolZmap::AddIntervalsForOffset( int nGrid, int nI, int nJ,
|
||||
/* Funzione per la creazione di una sfera di Offset centrata sul vertice di una TriMesh con cui
|
||||
aggiungere o sottrarre intervalli lungo i Dexel coinvolti */
|
||||
bool
|
||||
VolZmap::CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid)
|
||||
VolZmap::CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid, int nTool)
|
||||
{
|
||||
// determino il Box della sfera posizionata su tale vertice
|
||||
BBox3d BBoxSphere( ptV - dOffs * Vector3d( 1., 1., 1.),
|
||||
@@ -76,9 +75,9 @@ VolZmap::CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid)
|
||||
Vector3d vtNmax = Point3d( dX, dY, dMax) - ptV ;
|
||||
vtNmax.Normalize() ;
|
||||
if ( dOffs > 0.)
|
||||
AddIntervalsForOffset( nGrid, i, j, dMin, dMax, vtNmin, vtNmax, 0) ;
|
||||
AddIntervalsForOffset( nGrid, i, j, dMin, dMax, vtNmin, vtNmax, nTool) ;
|
||||
else
|
||||
SubtractIntervalsForOffset( nGrid, i, j, dMin, dMax, -vtNmin, -vtNmax, 0) ;
|
||||
SubtractIntervalsForOffset( nGrid, i, j, dMin, dMax, -vtNmin, -vtNmax, nTool) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +89,8 @@ VolZmap::CreateOffsSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid)
|
||||
/* Funzione per la creazione di un cilindro di Offset sul vertice di una TriMesh con cui
|
||||
aggiungere o sottrarre intervalli lungo i Dexel coinvolti */
|
||||
bool
|
||||
VolZmap::CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid)
|
||||
VolZmap::CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid,
|
||||
int nTool)
|
||||
{
|
||||
// determino la lunghezza dello spigolo corrente
|
||||
double dH = Dist( ptP1, ptP2) ;
|
||||
@@ -129,9 +129,9 @@ VolZmap::CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, dou
|
||||
if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dH, abs( dOffs), true, true,
|
||||
ptInt1, vtN1, ptInt2, vtN2)) {
|
||||
if ( dOffs > 0.)
|
||||
AddIntervalsForOffset( nGrid, i, j, ptInt1.z, ptInt2.z, -vtN1, -vtN2, 0) ;
|
||||
AddIntervalsForOffset( nGrid, i, j, ptInt1.z, ptInt2.z, -vtN1, -vtN2, nTool) ;
|
||||
else
|
||||
SubtractIntervalsForOffset( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, 0) ;
|
||||
SubtractIntervalsForOffset( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, nTool) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,44 +140,53 @@ VolZmap::CreateOffsCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, dou
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per la creazine di uno Zmap di Offset (positivo o negativo) a partire da una
|
||||
superficie TriMesh */
|
||||
/* Funzione per inizializzare lo ZMap a partire da un vettore di superfici TriMesh */
|
||||
/* L'idea è quella di creare uno ZMap a partire dal Box complessivo delle superfici TriMesh :
|
||||
* - le superfici chiuse possono già inserire i rispettivi spilloni
|
||||
* - le superfici aperte non danno contributo */
|
||||
bool
|
||||
VolZmap::CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol)
|
||||
VolZmap::InitVolZMapOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol)
|
||||
{
|
||||
// se non ho superfici, non faccio nulla
|
||||
if ( vSurf.empty())
|
||||
return true ;
|
||||
// controllo delle superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
if ( Surf == nullptr)
|
||||
return false ;
|
||||
}
|
||||
// verifica sul parametro di Offset ( coerente con Curve e FlatRegion)
|
||||
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||
return true ;
|
||||
// se non ho superfici, non faccio nulla
|
||||
if ( vSurf.empty())
|
||||
return true ;
|
||||
|
||||
// definisco lo Zmap di partenza a partire dalle superfici
|
||||
// se una sola superficie
|
||||
// definisco la tolleranza di espansione del Box per la creazione dellop ZMap
|
||||
double dBoxExpansion = ( abs( dOffs) + 1.5 * dTol) + 10 * EPS_SMALL ;
|
||||
|
||||
// --- se una sola superficie
|
||||
if ( int( vSurf.size()) == 1) {
|
||||
// controllo la validità della superficie
|
||||
if ( ! vSurf[0]->IsValid() || vSurf[0]->GetTriangleCount() == 0)
|
||||
return true ;
|
||||
// definisco lo Zamp a partire dall'espansione del Box della superficie
|
||||
if ( ! CreateFromTriMesh( *vSurf[0], dTol, true, dBoxExpansion))
|
||||
// --- se superficie chiusa posso direttamente creare lo Zmap iniziale
|
||||
if ( vSurf[0]->IsClosed()) {
|
||||
// definisco lo Zamp a partire dall'espansione del Box della superficie
|
||||
if ( ! CreateFromTriMesh( *vSurf[0], dTol, true, dBoxExpansion))
|
||||
return false ;
|
||||
}
|
||||
// --- se superficie aperta, lo creo inizialmente vuoto a partire dal suo Box
|
||||
BBox3d BBoxSurf ;
|
||||
vSurf[0]->GetLocalBBox( BBoxSurf) ;
|
||||
BBoxSurf.Expand( dBoxExpansion) ;
|
||||
if ( ! CreateEmpty( BBoxSurf.GetMin(), BBoxSurf.GetDimX(), BBoxSurf.GetDimY(), BBoxSurf.GetDimZ(), dTol, true))
|
||||
return false ;
|
||||
}
|
||||
// se più superfici
|
||||
// --- se più superfici
|
||||
else {
|
||||
// calcolo il Box complessivo delle superfici TriMesh
|
||||
// calcolo il Box complessivo
|
||||
BBox3d BBoxGlob ;
|
||||
for ( int i = 0 ; i < int( vSurf.size()) ; ++ i) {
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
// controllo la validità della superficie
|
||||
if ( ! vSurf[i]->IsValid() || vSurf[i]->GetTriangleCount() == 0)
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
continue ;
|
||||
// calcolo il Box della superficie
|
||||
BBox3d BBoxSurf ; vSurf[i]->GetLocalBBox( BBoxSurf) ;
|
||||
BBox3d BBoxSurf ; Surf->GetLocalBBox( BBoxSurf) ;
|
||||
// aggiungo il Box a quello complessivo
|
||||
BBoxGlob.Add( BBoxSurf) ;
|
||||
}
|
||||
@@ -185,20 +194,80 @@ VolZmap::CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, do
|
||||
BBoxGlob.Expand( dBoxExpansion) ;
|
||||
if ( ! CreateEmpty( BBoxGlob.GetMin(), BBoxGlob.GetDimX(), BBoxGlob.GetDimY(), BBoxGlob.GetDimZ(), dTol, true))
|
||||
return false ;
|
||||
// aggiungo tutte le superfici chiuse
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0 || ! Surf->IsClosed())
|
||||
continue ;
|
||||
if ( ! AddSurfTm( Surf))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per inizializzare lo ZMap a partire da un vettore di superfici TriMesh */
|
||||
/* L'idea è quella di creare uno ZMap vuoto a partire dal Box complessivo delle superfici TriMesh */
|
||||
bool
|
||||
VolZmap::InitVolZMapThickeningOffs( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol)
|
||||
{
|
||||
// se non ho superfici, non faccio nulla
|
||||
if ( vSurf.empty())
|
||||
return true ;
|
||||
// controllo delle superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
if ( Surf == nullptr)
|
||||
return false ;
|
||||
}
|
||||
|
||||
// definisco la tolleranza di espansione del Box per la creazione dellop ZMap
|
||||
double dBoxExpansion = ( abs( dOffs) + 1.5 * dTol) + 10 * EPS_SMALL ;
|
||||
|
||||
// calcolo il Box complessivo
|
||||
BBox3d BBoxGlob ;
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
// controllo la validità della superficie
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
continue ;
|
||||
// calcolo il Box della superficie
|
||||
BBox3d BBoxSurf ; Surf->GetLocalBBox( BBoxSurf) ;
|
||||
// aggiungo il Box a quello complessivo
|
||||
BBoxGlob.Add( BBoxSurf) ;
|
||||
}
|
||||
// definisco uno Zmap vuoto a partire dal Box
|
||||
BBoxGlob.Expand( dBoxExpansion) ;
|
||||
return ( CreateEmpty( BBoxGlob.GetMin(), BBoxGlob.GetDimX(), BBoxGlob.GetDimY(), BBoxGlob.GetDimZ(), dTol, true)) ;
|
||||
}
|
||||
|
||||
/* [Fillet] Funzione per aggiornare mediante Sfere, Cilindri e Facce di estrusione lo ZMap corrente
|
||||
mediante una superficie chiusa */
|
||||
bool
|
||||
VolZmap::UpdateVolZMapByOpenSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol)
|
||||
{
|
||||
// da studiare...
|
||||
return false ;
|
||||
}
|
||||
|
||||
/* [Fillet] Funzione per aggiornare mediante Sfere, Cilindri e Facce di estrusione lo ZMap corrente
|
||||
mediante una superficie chiusa */
|
||||
bool
|
||||
VolZmap::UpdateVolZMapByClosedSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol)
|
||||
{
|
||||
// controlli sulla superficie
|
||||
if ( Surf == nullptr || ! Surf->IsClosed())
|
||||
return false ;
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
return true ;
|
||||
|
||||
/* Assunzioni :
|
||||
- Idea Generale di Offset
|
||||
- Su ogni vertice viene definita una sfera ( con raggio pari al valore di Offset e
|
||||
centro il vertice corrente)
|
||||
- Su ogni lato viene definito un cilindro ( con raggio di pase pari al valore di Offset
|
||||
e asse definito dall'edge stesso)
|
||||
- Su ogni faccia viene definita una superficie di estrusione ( dove le due basi sono
|
||||
definite dalla traslazione sia in positivo che in negativo della faccia lungo la sua normale)
|
||||
- Su ogni lato viene definito un cilindro ( con raggio di base pari al valore di Offset
|
||||
e asse definito dall'edge stesso)
|
||||
- Su ogni faccia viene definita una superficie di estrusione ( dove le due basi sono
|
||||
definite dalla traslazione sia in positivo che in negativo della faccia lungo la sua normale)
|
||||
|
||||
- Segno dell'Offset :
|
||||
- Positivo ( si sommano gli intervalli corrisipondenti alle entità create)
|
||||
@@ -218,74 +287,57 @@ VolZmap::CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, do
|
||||
vFrGrid[2].Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ;
|
||||
vFrGrid[3].Set( m_MapFrame.Orig(), m_MapFrame.VersZ(), m_MapFrame.VersX(), m_MapFrame.VersY()) ;
|
||||
|
||||
// scorro le superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
// se superficie non valida, passo alla successiva
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
// definisco una mappa dei vertici, in modo da sapere su quali sono state già create le sfere
|
||||
BOOLVECTOR vbVert( Surf->GetVertexCount(), false) ;
|
||||
// ----------------------- Cilindri e Sfere -----------------------
|
||||
// scorro gli Edge della superficie
|
||||
for ( int nE = 0 ; nE < Surf->GetEdgeCount() ; ++ nE) {
|
||||
// recupero lo spigolo
|
||||
int nV1, nV2, nF1, nF2 ; double dAng ;
|
||||
Surf->GetEdge( nE, nV1, nV2, nF1, nF2, dAng) ;
|
||||
// controllo se il cilindro serve
|
||||
// NB. la mancata creazione del cilindro comporta la mancata creazione delle sfere sui suoi vertici
|
||||
// durante questa iterazione; non significa che questa sfera non verrà mai creata...
|
||||
// Non esiste la sfera sul vertive V <=> non esiste alcun cilindro su tutti gli edge concorrenti
|
||||
if ( dAng * dOffs < 0)
|
||||
continue ;
|
||||
// definisco una mappa dei vertici, in modo da sapere su quali sono state già create le sfere
|
||||
BOOLVECTOR vbVert( Surf->GetVertexCount(), false) ;
|
||||
// ----------------------- Cilindri e Sfere -----------------------
|
||||
// scorro gli Edge della superficie
|
||||
for ( int nE = 0 ; nE < Surf->GetEdgeCount() ; ++ nE) {
|
||||
// recupero lo spigolo
|
||||
int nV1, nV2, nF1, nF2 ; double dAng ;
|
||||
Surf->GetEdge( nE, nV1, nV2, nF1, nF2, dAng) ;
|
||||
// controllo se il cilindro serve
|
||||
// NB. la mancata creazione del cilindro comporta la mancata creazione delle sfere sui suoi vertici
|
||||
// durante questa iterazione; non significa che questa sfera non verrà mai creata...
|
||||
// Non esiste la sfera sul vertive V <=> non esiste alcun cilindro su tutti gli edge concorrenti
|
||||
if ( dAng * dOffs < 0)
|
||||
continue ;
|
||||
// recupero le coordinate dei vertici
|
||||
Point3d ptP1 ; Surf->GetVertex( nV1, ptP1) ;
|
||||
Point3d ptP2 ; Surf->GetVertex( nV2, ptP2) ;
|
||||
// ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < 3 ; ++ nGrid) {
|
||||
// esprimo gli estremi nel riferimento della griglia
|
||||
ptP1.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
ptP2.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dal cilindro
|
||||
if ( ! CreateOffsCylinderOnEdge( ptP1, ptP2, dOffs, nGrid))
|
||||
// recupero le coordinate dei vertici
|
||||
Point3d ptP1 ; Surf->GetVertex( nV1, ptP1) ;
|
||||
Point3d ptP2 ; Surf->GetVertex( nV2, ptP2) ;
|
||||
// ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < 3 ; ++ nGrid) {
|
||||
// esprimo gli estremi nel riferimento della griglia
|
||||
ptP1.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
ptP2.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dal cilindro
|
||||
if ( ! CreateOffsCylinderOnEdge( ptP1, ptP2, dOffs, nGrid))
|
||||
return false ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dalla sfera
|
||||
if ( ! vbVert[nV1]) {
|
||||
if ( ! CreateOffsSphereOnVertex( ptP1, dOffs, nGrid))
|
||||
return false ;
|
||||
}
|
||||
if ( ! vbVert[nV2]) {
|
||||
if ( ! CreateOffsSphereOnVertex( ptP2, dOffs, nGrid))
|
||||
return false ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dalla sfera
|
||||
if ( ! vbVert[nV1]) {
|
||||
vbVert[nV1] = ( nGrid == 2) ;
|
||||
if ( ! CreateOffsSphereOnVertex( ptP1, dOffs, nGrid))
|
||||
return false ;
|
||||
}
|
||||
if ( ! vbVert[nV2]) {
|
||||
vbVert[nV2] = ( nGrid == 2) ;
|
||||
if ( ! CreateOffsSphereOnVertex( ptP2, dOffs, nGrid))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----------------------- Facce -----------------------
|
||||
// scorro tutte le facce definendo una superficie di estrusione
|
||||
for ( int nF = 0 ; nF < Surf->GetFacetCount() ; ++ nF) {
|
||||
// recupero lo faccia
|
||||
POLYLINEVECTOR vPL ; Surf->GetFacetLoops( nF, vPL) ;
|
||||
// recupero la normale della faccia
|
||||
Vector3d vtN ; Surf->GetFacetNormal( nF, vtN) ;
|
||||
// definisco la superficie di estrusione
|
||||
CICURVEPVECTOR vpCrvs ; vpCrvs.reserve( vPL.size()) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vPL[i].Translate( - abs( dOffs) * vtN) ;
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[i])) {
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
vpCrvs.emplace_back( Release( pCrvCompo)) ;
|
||||
}
|
||||
// recupero la TriMesh di estrusione
|
||||
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByRegionExtrusion( vpCrvs, 2 * abs( dOffs) * vtN)) ;
|
||||
if ( IsNull( pStmExtr) || ! pStmExtr->IsValid() || pStmExtr->GetTriangleCount() == 0) {
|
||||
vbVert[nV1] = true ;
|
||||
vbVert[nV2] = true ;
|
||||
}
|
||||
// ----------------------- Facce -----------------------
|
||||
// scorro tutte le facce definendo una superficie di estrusione
|
||||
for ( int nF = 0 ; nF < Surf->GetFacetCount() ; ++ nF) {
|
||||
// recupero lo faccia
|
||||
POLYLINEVECTOR vPL ; Surf->GetFacetLoops( nF, vPL) ;
|
||||
// recupero la normale della faccia
|
||||
Vector3d vtN ; Surf->GetFacetNormal( nF, vtN) ;
|
||||
// definisco la superficie di estrusione
|
||||
CICURVEPVECTOR vpCrvs ; vpCrvs.reserve( vPL.size()) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vPL[i].Translate( - abs( dOffs) * vtN) ;
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[i])) {
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
@@ -293,22 +345,216 @@ VolZmap::CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, do
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// aggiorno gli spilloni
|
||||
if ( dOffs > 0.)
|
||||
AddSurfTm( pStmExtr) ;
|
||||
else
|
||||
SubtractSurfTm( pStmExtr) ;
|
||||
vpCrvs.emplace_back( Release( pCrvCompo)) ;
|
||||
}
|
||||
// recupero la TriMesh di estrusione
|
||||
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByRegionExtrusion( vpCrvs, 2 * abs( dOffs) * vtN)) ;
|
||||
if ( IsNull( pStmExtr) || ! pStmExtr->IsValid() || pStmExtr->GetTriangleCount() == 0) {
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// aggiorno gli spilloni
|
||||
if ( dOffs > 0.)
|
||||
AddSurfTm( pStmExtr) ;
|
||||
else
|
||||
SubtractSurfTm( pStmExtr) ;
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
}
|
||||
m_nShape = OFFSET ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
/* [Fillet Thickening] Funzione per aggiornare mediante Sfere, Cilindri e Facce di estrusione lo ZMap corrente
|
||||
mediante una superficie generica (aperta o chiusa) */
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::UpdateVolZMapBySurfThickeningFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol)
|
||||
{
|
||||
// controlli sulla superficie
|
||||
if ( Surf == nullptr)
|
||||
return false ;
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
return true ;
|
||||
|
||||
// non inizializzo lo Zmap, semplicemente lavoro con facce, spigoli e vertici
|
||||
|
||||
// definisco vettore di frame Locali alle 3 griglie
|
||||
FRAME3DVECTOR vFrGrid( 4) ;
|
||||
vFrGrid[0].Set( ORIG, X_AX, Y_AX, Z_AX) ;
|
||||
vFrGrid[1].Set( m_MapFrame.Orig(), m_MapFrame.VersX(), m_MapFrame.VersY(), m_MapFrame.VersZ()) ;
|
||||
vFrGrid[2].Set( m_MapFrame.Orig(), m_MapFrame.VersY(), m_MapFrame.VersZ(), m_MapFrame.VersX()) ;
|
||||
vFrGrid[3].Set( m_MapFrame.Orig(), m_MapFrame.VersZ(), m_MapFrame.VersX(), m_MapFrame.VersY()) ;
|
||||
|
||||
// definisco una mappa dei vertici, in modo da sapere su quali sono state già create le sfere
|
||||
BOOLVECTOR vbVert( Surf->GetVertexCount(), false) ;
|
||||
// ----------------------- Cilindri e Sfere -----------------------
|
||||
// scorro gli Edge della superficie
|
||||
for ( int nE = 0 ; nE < Surf->GetEdgeCount() ; ++ nE) {
|
||||
// recupero lo spigolo
|
||||
int nV1, nV2, nF1, nF2 ; double dAng ;
|
||||
Surf->GetEdge( nE, nV1, nV2, nF1, nF2, dAng) ;
|
||||
// recupero le coordinate dei vertici
|
||||
Point3d ptP1 ; Surf->GetVertex( nV1, ptP1) ;
|
||||
Point3d ptP2 ; Surf->GetVertex( nV2, ptP2) ;
|
||||
// ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < 3 ; ++ nGrid) {
|
||||
// esprimo gli estremi nel riferimento della griglia
|
||||
ptP1.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
ptP2.LocToLoc( vFrGrid[nGrid], vFrGrid[nGrid + 1]) ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dal cilindro
|
||||
if ( ! CreateOffsCylinderOnEdge( ptP1, ptP2, abs( dOffs), nGrid))
|
||||
return false ;
|
||||
// aggiungo/sottraggo gli intervalli definiti dalla sfera
|
||||
if ( ! vbVert[nV1]) {
|
||||
if ( ! CreateOffsSphereOnVertex( ptP1, abs( dOffs), nGrid))
|
||||
return false ;
|
||||
}
|
||||
if ( ! vbVert[nV2]) {
|
||||
if ( ! CreateOffsSphereOnVertex( ptP2, abs( dOffs), nGrid))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
vbVert[nV1] = true ;
|
||||
vbVert[nV2] = true ;
|
||||
}
|
||||
// ----------------------- Facce -----------------------
|
||||
// scorro tutte le facce definendo una superficie di estrusione
|
||||
for ( int nF = 0 ; nF < Surf->GetFacetCount() ; ++ nF) {
|
||||
// recupero lo faccia
|
||||
POLYLINEVECTOR vPL ; Surf->GetFacetLoops( nF, vPL) ;
|
||||
// recupero la normale della faccia
|
||||
Vector3d vtN ; Surf->GetFacetNormal( nF, vtN) ;
|
||||
// definisco la superficie di estrusione
|
||||
CICURVEPVECTOR vpCrvs ; vpCrvs.reserve( vPL.size()) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vPL[i].Translate( - abs( dOffs) * vtN) ;
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[i])) {
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
vpCrvs.emplace_back( Release( pCrvCompo)) ;
|
||||
}
|
||||
// recupero la TriMesh di estrusione
|
||||
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByRegionExtrusion( vpCrvs, 2 * abs( dOffs) * vtN)) ;
|
||||
if ( IsNull( pStmExtr) || ! pStmExtr->IsValid() || pStmExtr->GetTriangleCount() == 0) {
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
// aggiorno gli spilloni
|
||||
AddSurfTm( pStmExtr) ;
|
||||
// dealloco le curve
|
||||
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
|
||||
delete ( vpCrvs[i]) ;
|
||||
vpCrvs[i] = nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per la creazine di uno Zmap di Offset (positivo o negativo) a partire da un
|
||||
vettore di superfici TriMesh (aperte o chiuse) */
|
||||
/*
|
||||
Definizione :
|
||||
- Lo Zmap di Offset ( positivo o negativo) di una superficie chiusa è automaticamente l'Offset stesso
|
||||
- Lo Zmap di Offset ( positivo o negativo) di una superficie aperta è ????? ( da capire...)
|
||||
*/
|
||||
bool
|
||||
VolZmap::CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType)
|
||||
{
|
||||
// controllo delle superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
if ( Surf == nullptr)
|
||||
return false ;
|
||||
}
|
||||
// verifica sul parametro di Offset ( coerente con Curve e FlatRegion)
|
||||
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||
return true ;
|
||||
// se non ho superfici, non faccio nulla
|
||||
if ( vSurf.empty())
|
||||
return true ;
|
||||
|
||||
// inizializzo lo Zmap di Offset a partire dalle superfici
|
||||
if ( ! InitVolZMapOffs( vSurf, dOffs, dTol))
|
||||
return false ;
|
||||
|
||||
// scorro le superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
// se superficie non valida, passo alla successiva
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
continue ;
|
||||
// aggiorno lo ZMap
|
||||
if ( Surf->IsClosed()) {
|
||||
if ( nType == ISurfTriMesh::OFF_FILLET) {
|
||||
if ( ! UpdateVolZMapByClosedSurfFilletOffset( Surf, dOffs, dTol))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// --- LE SUPERFICI APERTE SONO PER ORA DISABILITATE ---
|
||||
}
|
||||
}
|
||||
|
||||
m_nShape = OFFSET ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/* Funzione per la creazine di uno Zmap di Fat Offset a partire da un
|
||||
vettore di superfici TriMesh (aperte o chiuse) */
|
||||
bool
|
||||
VolZmap::CreateFromTriMeshThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType)
|
||||
{
|
||||
// controllo delle superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
if ( Surf == nullptr)
|
||||
return false ;
|
||||
}
|
||||
// verifica sul parametro di Offset ( coerente con Curve e FlatRegion)
|
||||
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||
return true ;
|
||||
// se non ho superfici, non faccio nulla
|
||||
if ( vSurf.empty())
|
||||
return true ;
|
||||
|
||||
// inizializzo lo Zmap di Offset a partire dalle superfici
|
||||
if ( ! InitVolZMapThickeningOffs( vSurf, dOffs, dTol))
|
||||
return false ;
|
||||
|
||||
// scorro le superfici
|
||||
for ( const ISurfTriMesh* Surf : vSurf) {
|
||||
// se superficie non valida, passo alla successiva
|
||||
if ( ! Surf->IsValid() || Surf->GetTriangleCount() == 0)
|
||||
continue ;
|
||||
|
||||
// aggiorno lo Zmap
|
||||
if ( nType == ISurfTriMesh::OFF_FILLET) {
|
||||
if ( ! UpdateVolZMapBySurfThickeningFilletOffset( Surf, dOffs, dTol))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
m_nShape = OFFSET ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user