Files
EgtGeomKernel/StmStandard.cpp
T
DarioS 4410a83631 EgtGeomKernel :
- piccole modifiche per nuovo Set di PtrOwner.
2023-03-27 18:41:16 +02:00

264 lines
9.6 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : StmStandard.cpp Data : 31.03.15 Versione : 1.6c7
// Contenuto : Implementazione di funzioni per creazione di superfici Stm
// standard : Box, Pyramid, Cylinder, Sphere, Cone.
//
//
// Modifiche : 31.03.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveArc.h"
#include "SurfTriMesh.h"
#include "/EgtDev/Include/EGkStmStandard.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EGkPolygon3d.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//-------------------------------------------------------------------------------
static SurfTriMesh*
GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
{
// creo la polilinea del contorno della base
PolyLine PL ;
int nU = 0 ;
PL.AddUPoint( nU, Point3d( 0, 0, 0)) ;
PL.AddUPoint( ++ nU, Point3d( dDimX, 0, 0)) ;
PL.AddUPoint( ++ nU, Point3d( dDimX, dDimY, 0)) ;
PL.AddUPoint( ++ nU, Point3d( 0, dDimY, 0)) ;
PL.AddUPoint( ++ nU, Point3d( 0, 0, 0)) ;
if ( dHeight < 0)
PL.Invert() ;
// vettore altezza (estrusione)
Vector3d vtExtr( 0, 0, dHeight) ;
// creo e setto la superficie trimesh laterale
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
return nullptr ;
// creo la prima superficie di estremità
SurfTriMesh STM1 ;
if ( ! STM1.CreateByFlatContour( PL))
return nullptr ;
// la copio
SurfTriMesh STM2 = STM1 ;
// inverto la prima superficie
STM1.Invert() ;
// traslo la seconda
STM2.Translate( Vector3d( 0, 0, dHeight)) ;
// le unisco alla superficie del fianco
if ( ! pSTM->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
static SurfTriMesh*
GetRegularSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
{
// i triangoli devono essere quasi equilateri pertanto calcolo come dividere le varie parti
double dMaxStep = INFINITO ;
double dMin1 = min( dDimX, dDimY) ;
double dMin2 = min( max( dDimX, dDimY), abs( dHeight)) ;
dMaxStep = min( max( dMin1, dMin2), 2 * min( dMin1, dMin2)) ;
dMaxStep = max( dMaxStep, 1.) ;
int nStepX = max( int( dDimX / dMaxStep + 0.9), 1) ;
double dStepX = dDimX / nStepX ;
int nStepY = max( int( dDimY / dMaxStep + 0.9), 1) ;
double dStepY = dDimY / nStepY ;
int nStepZ = max( int( abs( dHeight) / dMaxStep + 0.9), 1) ;
double dStepZ = dHeight / nStepZ ;
// creo la polilinea del contorno della base
PolyLine PL1 ;
int nU1 = 0 ;
PL1.AddUPoint( nU1, ORIG) ;
for ( int i = 1 ; i <= nStepX ; ++i)
PL1.AddUPoint( ++ nU1, Point3d( i * dStepX, 0, 0)) ;
for ( int j = 1 ; j <= nStepY ; ++j)
PL1.AddUPoint( ++ nU1, Point3d( dDimX, j * dStepY, 0)) ;
for ( int i = 1 ; i <= nStepX ; ++i)
PL1.AddUPoint( ++ nU1, Point3d( dDimX - i * dStepX, dDimY, 0)) ;
for ( int j = 1 ; j <= nStepY ; ++j)
PL1.AddUPoint( ++ nU1, Point3d( 0, dDimY - j * dStepY, 0)) ;
if ( dHeight < 0)
PL1.Invert() ;
// vettore altezza (estrusione)
Vector3d vtExtr1( 0, 0, dStepZ) ;
// creo e unisco le superfici trimesh laterali
PtrOwner<SurfTriMesh> pSTM1 ;
for ( int k = 0 ; k < nStepZ ; ++ k) {
SurfTriMesh STMz ;
if ( ! STMz.CreateByExtrusion( PL1, vtExtr1))
return nullptr ;
STMz.Translate( Vector3d( 0, 0, k * dStepZ)) ;
if ( IsNull( pSTM1))
pSTM1.Set( STMz.Clone()) ;
else if ( ! pSTM1->DoSewing( STMz))
return nullptr ;
}
// creo la polilinea del lato sinistro della superficie inferiore
PolyLine PL2 ;
int nU2 = 0 ;
PL2.AddUPoint( nU2, ORIG) ;
for ( int j = 1 ; j <= nStepY ; ++j)
PL2.AddUPoint( ++ nU2, Point3d( 0, j * dStepY, 0)) ;
// vettore estrusione
Vector3d vtExtr2( dStepX, 0, 0) ;
// creo e unisco le superfici trimesh inferiori
SurfTriMesh STM2 ;
for ( int i = 0 ; i < nStepX ; ++ i) {
SurfTriMesh STMx ;
if ( ! STMx.CreateByExtrusion( PL2, vtExtr2))
return nullptr ;
STMx.Translate( Vector3d( i * dStepX, 0, 0)) ;
if ( STM2.IsEmpty())
STM2 = STMx ;
else if ( ! STM2.DoSewing( STMx))
return nullptr ;
}
// la copio
SurfTriMesh STM3 = STM2 ;
// inverto e traslo la superficie superiore
STM3.Invert() ;
STM3.Translate( Vector3d( 0, 0, dHeight)) ;
// le unisco alla superficie del fianco
if ( ! pSTM1->DoSewing( STM2) || ! pSTM1->DoSewing( STM3))
return nullptr ;
// restituisco la superficie
return Release( pSTM1) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshBox( double dDimX, double dDimY, double dHeight, bool bRegular)
{
// le dimensioni devono essere significative
if ( dDimX < EPS_SMALL || dDimY < EPS_SMALL || abs( dHeight) < EPS_SMALL)
return nullptr ;
// se trimesh standard
if ( ! bRegular)
return GetStandardSurfTriMeshBox( dDimX, dDimY, dHeight) ;
// altrimenti regolarizzata
else
return GetRegularSurfTriMeshBox( dDimX, dDimY, dHeight) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshPyramid( double dDimX, double dDimY, double dHeight)
{
// le dimensioni devono essere significative
if ( dDimX < EPS_SMALL || dDimY < EPS_SMALL || abs( dHeight) < EPS_SMALL)
return nullptr ;
// creo la polilinea del contorno della base
PolyLine PL ;
PL.AddUPoint( 0, ORIG) ;
PL.AddUPoint( 1, Point3d( dDimX, 0, 0)) ;
PL.AddUPoint( 2, Point3d( dDimX, dDimY, 0)) ;
PL.AddUPoint( 3, Point3d( 0, dDimY, 0)) ;
PL.AddUPoint( 4, ORIG) ;
if ( dHeight < 0)
PL.Invert() ;
// punto di vertice
Point3d ptTip( 0.5 * dDimX, 0.5 * dDimY, dHeight) ;
// creo e setto la superficie trimesh laterale
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByPointCurve( ptTip, PL))
return nullptr ;
// creo la superficie di base e ne inverto la normale
SurfTriMesh STM1 ;
if ( ! STM1.CreateByFlatContour( PL))
return nullptr ;
STM1.Invert() ;
// la unisco alla superficie del fianco
if ( ! pSTM->DoSewing( STM1))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshCylinder( double dRadius, double dHeight, double dLinTol)
{
// le dimensioni devono essere significative
if ( dRadius < EPS_SMALL || abs( dHeight) < EPS_SMALL)
return nullptr ;
// creo la circonferenza di base
CurveArc cArc ;
cArc.Set( ORIG, Z_AX, dRadius) ;
// vettore altezza (estrusione)
Vector3d vtExtr( 0, 0, dHeight) ;
// creo il cilindro
return GetSurfTriMeshByExtrusion( &cArc, vtExtr, true, dLinTol) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshCone( double dRadius, double dHeight, double dLinTol)
{
// le dimensioni devono essere significative
if ( dRadius < EPS_SMALL || abs( dHeight) < EPS_SMALL)
return nullptr ;
// creo la circonferenza di base
CurveArc cArc ;
cArc.Set( ORIG, Z_AX, dRadius) ;
if ( dHeight < 0)
cArc.Invert() ;
// punto di vertice
Point3d ptTip( 0, 0, dHeight) ;
// creo la superficie laterale del cono
PtrOwner<ISurfTriMesh> pSTM( GetSurfTriMeshRuled( ptTip, &cArc, dLinTol)) ;
if ( IsNull( pSTM))
return nullptr ;
// creo la superficie di base e la inverto
PtrOwner<ISurfTriMesh> pSTM1( GetSurfTriMeshByFlatContour( &cArc, dLinTol)) ;
if ( IsNull( pSTM1))
return nullptr ;
pSTM1->Invert() ;
// la unisco alla superficie del fianco
if ( ! pSTM->DoSewing( *pSTM1))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshSphere( double dRadius, double dLinTol)
{
// le dimensioni devono essere significative
if ( dRadius < EPS_SMALL)
return nullptr ;
// creo la semicirconferenza di riferimento
CurveArc cArc ;
cArc.Set( ORIG, Y_AX, dRadius, Z_AX, ANG_STRAIGHT, 0) ;
// creo la sfera
return GetSurfTriMeshByRevolve( &cArc, ORIG, Z_AX, true, dLinTol) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshPlaneInBox( const Plane3d& plPlane, const BBox3d& b3Box, bool bOnEq, bool bOnCt)
{
// verifico la definizione del piano
if ( ! plPlane.IsValid())
return nullptr ;
// creo il poligono corrispondente alla parte di piano limitata dal box
Polygon3d Polyg ;
if ( ! Polyg.FromPlaneTrimmedWithBox( plPlane, b3Box.GetMin(), b3Box.GetMax(), bOnEq, bOnCt))
return nullptr ;
// creo la trimesh con questo contorno
PtrOwner<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( IsNull( pStm) || ! pStm->CreateByFlatContour( Polyg.GetPolyLine()))
return nullptr ;
// restituisco la superficie
return Release( pStm) ;
}