ff6307fcca
- prime sistemazioni per offset superfici trimesh tramite Zmap.
569 lines
24 KiB
C++
569 lines
24 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2025-2025
|
|
//----------------------------------------------------------------------------
|
|
// File : OffsetSurfTm.cpp Data : 09.06.25 Versione : 2.7e3
|
|
// Contenuto : Dichiarazione della funzione per calcolare l'offset di superfici TriMesh
|
|
// mediante Zmap
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 09.06.25 RE Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "VolZmap.h"
|
|
#include "CurveLine.h"
|
|
#include "GeoConst.h"
|
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
|
#include <future>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 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,
|
|
int nToolNum, bool bSkipSwap)
|
|
{
|
|
// TODO -- Aggiustare eventuali tolleranze
|
|
return SubtractIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, bSkipSwap) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Funzione per aggiungere intervalli lungo un Dexel per l'offset di una superficie TriMesh
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::AddIntervalsForOffset( int nGrid, int nI, int nJ,
|
|
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
|
int nToolNum, bool bSkipSwap)
|
|
{
|
|
// TODO -- Aggiustare eventuali tolleranze
|
|
return AddIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, bSkipSwap) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 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, int nTool)
|
|
{
|
|
// determino il Box della sfera posizionata su tale vertice
|
|
BBox3d BBoxSphere( ptV - dOffs * Vector3d( 1., 1., 1.),
|
|
ptV + dOffs * Vector3d( 1., 1., 1.)) ;
|
|
// determino gli intervalli di interesse mediante intersezione con Box della sfera
|
|
int nStartI = max( 0, int( BBoxSphere.GetMin().x / m_dStep)) ;
|
|
int nEndI = min( m_nNx[nGrid] - 1, int( BBoxSphere.GetMax().x / m_dStep)) ;
|
|
int nStartJ = max( 0, int( BBoxSphere.GetMin().y / m_dStep)) ;
|
|
int nEndJ = min( m_nNy[nGrid] - 1, int( BBoxSphere.GetMax().y / m_dStep)) ;
|
|
// aggiorno gli spilloni interessati
|
|
double dSqRad = dOffs * dOffs ;
|
|
for ( int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
double dX = ( i + 0.5) * m_dStep ;
|
|
double dY = ( j + 0.5) * m_dStep ;
|
|
Point3d ptC( dX, dY, 0.) ;
|
|
double dStSqDXY = SqDistXY( ptC, ptV) ;
|
|
if ( dStSqDXY < dSqRad) {
|
|
double dMin = ptV.z - sqrt( dSqRad - dStSqDXY) ;
|
|
Vector3d vtNmin = Point3d( dX, dY, dMin) - ptV ;
|
|
vtNmin.Normalize() ;
|
|
double dMax = ptV.z + sqrt( dSqRad - dStSqDXY) ;
|
|
Vector3d vtNmax = Point3d( dX, dY, dMax) - ptV ;
|
|
vtNmax.Normalize() ;
|
|
if ( dOffs > 0.)
|
|
AddIntervalsForOffset( nGrid, i, j, dMin, dMax, vtNmin, vtNmax, nTool) ;
|
|
else
|
|
SubtractIntervalsForOffset( nGrid, i, j, dMin, dMax, -vtNmin, -vtNmax, nTool) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 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,
|
|
int nTool)
|
|
{
|
|
// determino la lunghezza dello spigolo corrente
|
|
double dH = Dist( ptP1, ptP2) ;
|
|
// asse del cilindro
|
|
Vector3d vtV = ptP2 - ptP1 ; vtV.Normalize() ;
|
|
// calcolo box del cilindro
|
|
BBox3d BBoxCylinder ;
|
|
BBoxCylinder.Add( ptP1) ;
|
|
BBoxCylinder.Add( ptP2) ;
|
|
if ( AreSameOrOppositeVectorApprox( vtV, X_AX))
|
|
BBoxCylinder.Expand( 0., abs( dOffs), abs( dOffs)) ;
|
|
else if ( AreSameOrOppositeVectorApprox( vtV, Y_AX))
|
|
BBoxCylinder.Expand( abs( dOffs), 0., abs( dOffs)) ;
|
|
else if ( AreSameOrOppositeVectorApprox( vtV, Z_AX))
|
|
BBoxCylinder.Expand( abs( dOffs), abs( dOffs), 0.) ;
|
|
else {
|
|
double dExpandX = abs( dOffs) * sqrt( 1 - vtV.x * vtV.x) ;
|
|
double dExpandY = abs( dOffs) * sqrt( 1 - vtV.y * vtV.y) ;
|
|
double dExpandZ = abs( dOffs) * sqrt( 1 - vtV.z * vtV.z) ;
|
|
BBoxCylinder.Expand( dExpandX, dExpandY, dExpandZ) ;
|
|
}
|
|
// determino gli intervalli di interesse mediante intersezione
|
|
int nStartI = max( 0, int( BBoxCylinder.GetMin().x / m_dStep)) ;
|
|
int nEndI = min( m_nNx[nGrid] - 1, int( BBoxCylinder.GetMax().x / m_dStep)) ;
|
|
int nStartJ = max( 0, int( BBoxCylinder.GetMin().y / m_dStep)) ;
|
|
int nEndJ = min( m_nNy[nGrid] - 1, int( BBoxCylinder.GetMax().y / m_dStep)) ;
|
|
// aggiorno gli spilloni interessati
|
|
Frame3d CylFrame ;
|
|
if ( ! CylFrame.Set( ptP1, vtV))
|
|
return false ;
|
|
for ( int i = nStartI ; i <= nEndI ; ++ i) {
|
|
for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
|
|
Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ;
|
|
Point3d ptInt1, ptInt2 ;
|
|
Vector3d vtN1, vtN2 ;
|
|
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, nTool) ;
|
|
else
|
|
SubtractIntervalsForOffset( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2, nTool) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// 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::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 ;
|
|
}
|
|
|
|
// 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 ;
|
|
// --- 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
|
|
else {
|
|
// 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) ;
|
|
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 aperta
|
|
//----------------------------------------------------------------------------
|
|
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 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)
|
|
// - Negativo ( si sottraggono gli intervalli corrispondenti alle enetità create)
|
|
//
|
|
// - Semplificazione entità :
|
|
// La creazione di Sfere e Cilindri potrebbe essere resa più "corretta" definitendo solo
|
|
// "spicchi 3d" di sfera e "spicchi 3d" di cilindri. Dato che le operazioni di somma, sottrazioni e
|
|
// calcolo delle normali per gli spilloni sono elementari su queste figure, si rischia di appesantire
|
|
// troppo i conti introducendo variabili angolari che non sommando tutte le parti.
|
|
//
|
|
|
|
// 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) ;
|
|
// 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))
|
|
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 ;
|
|
}
|
|
}
|
|
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
|
|
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 ;
|
|
}
|
|
}
|
|
|
|
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 == STMOFF_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 == STMOFF_FILLET) {
|
|
if ( ! UpdateVolZMapBySurfThickeningFilletOffset( Surf, dOffs, dTol))
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
m_nShape = OFFSET ;
|
|
return true ;
|
|
}
|