Files
EgtGeomKernel/StmFromCurves.cpp
T
Dario Sassi 2dd5001940 EgtGeomKernel 1.6b1 :
- aggiunte funzioni di costruzione superfici Stm da curve
- aggiunta funzione di svuota gruppo
- aggiunta funzione di inverti polilinea.
2015-02-02 08:06:49 +00:00

212 lines
8.0 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : StmFromCurves.cpp Data : 01.02.15 Versione : 1.6b1
// Contenuto : Implementazione di funzioni per creazione di superfici Stm
// a partire da curve, con diversi metodi.
//
//
// Modifiche : 01.02.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <algorithm>
using namespace std ;
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshByContour( const ICurve& Curve, double dLinTol)
{
// verifica parametri
if ( &Curve == nullptr)
return nullptr ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return nullptr ;
// creo e setto la superficie trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByFlatContour( PL))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshByExtrusion( const ICurve& Curve, const Vector3d& vtExtr,
bool bCapEnds, double dLinTol)
{
// verifica parametri
if ( &Curve == nullptr || &vtExtr == nullptr)
return nullptr ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! Curve.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return nullptr ;
// se richiesta chiusura agli estremi
bool bDoCapEnds = false ;
if ( bCapEnds) {
// verifico che la curva sia chiusa e piatta
Plane3d plPlane ;
double dArea ;
if ( PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)) {
// componente dell'estrusione perpendicolare al piano della curva
double dOrthoExtr = plPlane.vtN * vtExtr ;
if ( ( fabs( dOrthoExtr) > EPS_SMALL)) {
bDoCapEnds = true ;
if ( dOrthoExtr < 0)
PL.Invert() ;
}
}
}
// creo e setto la superficie trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByExtrusion( PL, vtExtr))
return nullptr ;
// se da fare, metto i tappi sulle estremità
if ( bDoCapEnds) {
// creo la prima superficie di estremità
PtrOwner<ISurfTriMesh> pSTM1( CreateSurfTriMesh()) ;
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
return nullptr ;
// la copio
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMesh( pSTM1->Clone())) ;
if ( IsNull( pSTM2))
return nullptr ;
// inverto la prima superficie
pSTM1->Invert() ;
// traslo la seconda
pSTM2->Translate( vtExtr) ;
// le unisco alla superficie del fianco
if ( ! pSTM->DoSewing( *pSTM1) || ! pSTM->DoSewing( *pSTM2))
return nullptr ;
}
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshByRevolve( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx,
bool bCapEnds, double dLinTol)
{
// verifica parametri
if ( &Curve == 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))
return nullptr ;
// calcolo lo step di rotazione
double dMaxRad = 0 ;
if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL)
return nullptr ;
double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ;
// se richiesta chiusura degli estremi
if ( bCapEnds && ! PL.IsClosed()) {
Vector3d vtAxN = vtAx ;
vtAxN.Normalize() ;
double dPosIni, dPosFin ;
Point3d ptP ;
// proietto l'ultimo punto sull'asse di rotazione
if ( PL.GetLastPoint( ptP)) {
dPosFin = ( ptP - ptAx) * vtAxN ;
Point3d ptPOnAx = ptAx + dPosFin * vtAxN ;
// se non giace sull'asse, aggiungo il punto proiettato
if ( ! AreSamePointApprox( ptP, ptPOnAx)) {
double dU ;
PL.GetLastU( dU) ;
PL.AddUPoint( ( dU + 1), ptPOnAx) ;
}
}
// inverto la polilinea
PL.Invert() ;
// proietto l'ultimo punto (era il primo) sull'asse di rotazione
if ( PL.GetLastPoint( ptP)) {
dPosIni = ( ptP - ptAx) * vtAxN ;
Point3d ptPOnAx = ptAx + dPosIni * vtAxN ;
// se non giace sull'asse, aggiungo il punto proiettato
if ( ! AreSamePointApprox( ptP, ptPOnAx)) {
double dU ;
PL.GetLastU( dU) ;
PL.AddUPoint( ( dU + 1), ptPOnAx) ;
}
}
// decido se reinvertire la polilinea
if ( dPosFin > dPosIni)
PL.Invert() ;
}
// creo e setto la superficie trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByScrewing( PL, ptAx, vtAx, ANG_FULL, dStepRotDeg, 0))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshByScrewing( const ICurve& Curve, const Point3d& ptAx, const Vector3d& vtAx,
double dAngRotDeg, double dMove, double dLinTol)
{
// verifica parametri
if ( &Curve == 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))
return nullptr ;
// calcolo lo step di rotazione
double dMaxRad = 0 ;
if ( ! PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) || dMaxRad < EPS_SMALL)
return nullptr ;
double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ;
// se superficie rototraslata, necessari limiti sulla lunghezza dei segmenti
if ( fabs( dAngRotDeg) > EPS_ANG_SMALL && fabs( dMove) > EPS_SMALL){
double dLenMax = 2.5 * fabs( dMove * dStepRotDeg / dAngRotDeg) ;
if ( ! PL.AdjustForMaxSegmentLen( dLenMax))
return nullptr ;
}
// creo e setto la superficie trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByScrewing( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg, dMove))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}
//-------------------------------------------------------------------------------
ISurfTriMesh*
GetSurfTriMeshRuled( const ICurve& Curve1, const ICurve& Curve2, double dLinTol)
{
// verifica parametri
if ( &Curve1 == nullptr || &Curve2 == nullptr)
return nullptr ;
// calcolo la polilinea che approssima la prima curva
PolyLine PL1 ;
if ( ! Curve1.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))
return nullptr ;
// creo e setto la superficie trimesh
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( IsNull( pSTM) || ! pSTM->CreateByTwoCurves( PL1, PL2))
return nullptr ;
// restituisco la superficie
return Release( pSTM) ;
}