EgtGeomKernel 1.6b3 :
- aggiunta gestione buchi alle triangolazione di poligoni - creazione suerfici trimesh da regioni con buchi.
This commit is contained in:
+158
-16
@@ -20,16 +20,20 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static bool CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN) ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByContour( const ICurve& Curve, double dLinTol)
|
||||
GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &Curve == nullptr)
|
||||
if ( pCurve == nullptr)
|
||||
return nullptr ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
@@ -41,15 +45,35 @@ GetSurfTriMeshByContour( const ICurve& Curve, double dLinTol)
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByExtrusion( const ICurve& Curve, const Vector3d& vtExtr,
|
||||
GetSurfTriMeshByRegion( const ICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &vpCurve == nullptr || vpCurve.empty())
|
||||
return nullptr ;
|
||||
// calcolo le polilinee che approssimano le curve della regione
|
||||
POLYLINEVECTOR vPL ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
||||
bool bCapEnds, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &Curve == nullptr || &vtExtr == nullptr)
|
||||
if ( pCurve == nullptr || &vtExtr == nullptr)
|
||||
return nullptr ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return nullptr ;
|
||||
// se richiesta chiusura agli estremi
|
||||
bool bDoCapEnds = false ;
|
||||
@@ -62,6 +86,7 @@ GetSurfTriMeshByExtrusion( const ICurve& Curve, const Vector3d& vtExtr,
|
||||
double dOrthoExtr = plPlane.vtN * vtExtr ;
|
||||
if ( ( fabs( dOrthoExtr) > EPS_SMALL)) {
|
||||
bDoCapEnds = true ;
|
||||
// se negativa, inverto il senso del contorno
|
||||
if ( dOrthoExtr < 0)
|
||||
PL.Invert() ;
|
||||
}
|
||||
@@ -95,17 +120,75 @@ GetSurfTriMeshByExtrusion( const ICurve& Curve, const Vector3d& vtExtr,
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByRevolve( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
GetSurfTriMeshByRegionExtrusion( const ICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr)
|
||||
return nullptr ;
|
||||
// se una sola curva, uso la funzione precedente
|
||||
if ( vpCurve.size() == 1 )
|
||||
return GetSurfTriMeshByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
||||
// calcolo le polilinee che approssimano le curve della regione
|
||||
POLYLINEVECTOR vPL ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
return nullptr ;
|
||||
// verifico la direzione di estrusione
|
||||
double dOrthoExtr = vtN * vtExtr ;
|
||||
if ( ( fabs( dOrthoExtr) < EPS_SMALL))
|
||||
return nullptr ;
|
||||
// se componente estrusione negativa, inverto tutti i percorsi
|
||||
if ( dOrthoExtr < 0) {
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
|
||||
vPL[i].Invert() ;
|
||||
}
|
||||
// creo la prima superficie di estremità
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
return nullptr ;
|
||||
// creo la seconda superficie e la unisco alla prima
|
||||
{ // copio la prima superficie
|
||||
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMesh( pSTM->Clone())) ;
|
||||
if ( IsNull( pSTM2))
|
||||
return nullptr ;
|
||||
// inverto la prima superficie
|
||||
pSTM->Invert() ;
|
||||
// traslo la seconda
|
||||
pSTM2->Translate( vtExtr) ;
|
||||
// la unisco alla prima
|
||||
if ( ! pSTM->DoSewing( *pSTM2))
|
||||
return nullptr ;
|
||||
}
|
||||
// creo e unisco le diverse superfici di estrusione
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// estrusione
|
||||
PtrOwner<ISurfTriMesh> pSTM2( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM2) || ! pSTM2->CreateByExtrusion( vPL[i], vtExtr))
|
||||
return nullptr ;
|
||||
// la unisco alla superficie principale
|
||||
if ( ! pSTM->DoSewing( *pSTM2))
|
||||
return nullptr ;
|
||||
}
|
||||
// compatto la superficie
|
||||
if ( ! pSTM->DoCompacting())
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
bool bCapEnds, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &Curve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
return nullptr ;
|
||||
// limite minimo su tolleranza
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return nullptr ;
|
||||
// calcolo lo step di rotazione
|
||||
double dMaxRad = 0 ;
|
||||
@@ -156,17 +239,17 @@ GetSurfTriMeshByRevolve( const ICurve& Curve, const Point3d& ptAx, const Vector3
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByScrewing( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
GetSurfTriMeshByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRotDeg, double dMove, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &Curve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
return nullptr ;
|
||||
// limite minimo su tolleranza
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
|
||||
return nullptr ;
|
||||
// calcolo lo step di rotazione
|
||||
double dMaxRad = 0 ;
|
||||
@@ -189,18 +272,18 @@ GetSurfTriMeshByScrewing( const ICurve& Curve, const Point3d& ptAx, const Vector
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshRuled( const ICurve& Curve1, const ICurve& Curve2, double dLinTol)
|
||||
GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &Curve1 == nullptr || &Curve2 == nullptr)
|
||||
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||
return nullptr ;
|
||||
// calcolo la polilinea che approssima la prima curva
|
||||
PolyLine PL1 ;
|
||||
if ( ! Curve1.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL1))
|
||||
if ( ! pCurve1->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL1))
|
||||
return nullptr ;
|
||||
// calcolo la polilinea che approssima la seconda curva
|
||||
PolyLine PL2 ;
|
||||
if ( ! Curve2.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL2))
|
||||
if ( ! pCurve2->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL2))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
|
||||
@@ -209,3 +292,62 @@ GetSurfTriMeshRuled( const ICurve& Curve1, const ICurve& Curve2, double dLinTol)
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
CalcRegionPolyLines( const ICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||
{
|
||||
// calcolo le polilinee che approssimano le curve
|
||||
POLYLINEVECTOR vPLtmp ;
|
||||
vPLtmp.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, vPLtmp[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
// ne calcolo l'area e genero un ordine in senso decrescente
|
||||
typedef std::pair<int,double> INDAREA ; // coppia indice, area
|
||||
typedef std::vector<INDAREA> INDAREAVECTOR ; // vettore di coppie indice, area
|
||||
INDAREAVECTOR vArea ;
|
||||
vArea.reserve( vPLtmp.size()) ;
|
||||
Vector3d vtN0 ;
|
||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
||||
// verifico chiusura, calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPLtmp[i].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
// imposto la normale del primo contorno come riferimento
|
||||
if ( i == 0)
|
||||
vtN0 = plPlane.vtN ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtN0))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.vtN * vtN0) > 0)
|
||||
vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
sort( vArea.begin(), vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA&b) { return fabs( a.second) > fabs( b.second) ; }) ;
|
||||
// sposto le polilinee nel vettore da restituire secondo l'ordine
|
||||
vPL.clear() ;
|
||||
vPL.resize( vPLtmp.size()) ;
|
||||
bool bCCW = true ;
|
||||
for ( int i = 0 ; i < int( vPLtmp.size()) ; ++ i) {
|
||||
// scambio
|
||||
swap( vPL[i], vPLtmp[vArea[i].first]) ;
|
||||
// verifico senso di rotazione del contorno esterno
|
||||
if ( i == 0)
|
||||
bCCW = ( vArea[i].second > 0) ;
|
||||
// aggiusto gli altri contorni
|
||||
else {
|
||||
if ( ( bCCW && vArea[i].second > 0) || ( ! bCCW && vArea[i].second < 0))
|
||||
vPL[i].Invert() ;
|
||||
}
|
||||
}
|
||||
// restituisco la normale positiva alla regione
|
||||
vtN = ( bCCW ? vtN0 : - vtN0) ;
|
||||
return true ;
|
||||
}
|
||||
Reference in New Issue
Block a user