2dd5001940
- aggiunte funzioni di costruzione superfici Stm da curve - aggiunta funzione di svuota gruppo - aggiunta funzione di inverti polilinea.
212 lines
8.0 KiB
C++
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) ;
|
|
}
|