aa9c46cbb5
- aggiunte la surfBz SweptInPlane e Swept3D.
1407 lines
56 KiB
C++
1407 lines
56 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 20024
|
|
//----------------------------------------------------------------------------
|
|
// File : SbzFromCurves.cpp Data : 07.05.24 Versione : 2.6e2
|
|
// Contenuto : Implementazione di funzioni per creazione di superfici Sbz
|
|
// a partire da curve, con diversi metodi.
|
|
//
|
|
//
|
|
// Modifiche : 07.05.24 DB Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GeoConst.h"
|
|
#include "CurveLine.h"
|
|
#include "CurveArc.h"
|
|
#include "CurveComposite.h"
|
|
#include "SurfTriMesh.h"
|
|
#include "SurfBezier.h"
|
|
#include "Voronoi.h"
|
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
|
|
#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
|
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
|
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include <future>
|
|
|
|
using namespace std ;
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierByFlatContour( const ICurve* pCurve, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
if ( pCurve == nullptr)
|
|
return nullptr ;
|
|
// calcolo la polilinea che approssima la curva
|
|
PolyLine PL ;
|
|
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
return nullptr ;
|
|
// creo e setto la superficie trimesh
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByFlatContour( PL))
|
|
return nullptr ;
|
|
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
if ( &vpCurve == nullptr || vpCurve.empty())
|
|
return nullptr ;
|
|
// calcolo le polilinee che approssimano le curve della regione
|
|
POLYLINEVECTOR vPL ;
|
|
vPL.resize( vpCurve.size()) ;
|
|
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
|
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
|
return nullptr ;
|
|
}
|
|
Vector3d vtN ;
|
|
INTMATRIX vnPLIndMat ;
|
|
BOOLVECTOR vbInvert ;
|
|
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat,vbInvert))
|
|
return nullptr ;
|
|
POLYLINEVECTOR vPLOrd ;
|
|
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) {
|
|
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++j){
|
|
vPLOrd.push_back(vPL[vnPLIndMat[i][j]]) ;
|
|
if( vbInvert[vnPLIndMat[i][j]])
|
|
vPLOrd.back().Invert() ;
|
|
}
|
|
}
|
|
// creo e setto la superficie di bezier
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByRegion( vPLOrd))
|
|
return nullptr ;
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
|
bool bCapEnds, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
if ( pCurve == nullptr || &vtExtr == nullptr)
|
|
return nullptr ;
|
|
// calcolo la polilinea che approssima la curva
|
|
PolyLine PL ;
|
|
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, 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.GetVersN() * vtExtr ;
|
|
// if ( ( abs( dOrthoExtr) > EPS_SMALL)) {
|
|
// bDoCapEnds = true ;
|
|
// // se negativa, inverto il senso del contorno
|
|
// if ( dOrthoExtr < 0)
|
|
// PL.Invert() ;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
PtrOwner<const ICurve> pBezierForm( CurveToBezierCurve( pCurve)) ;
|
|
// creo e setto la superficie trimesh
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
|
|
return nullptr ;
|
|
|
|
//// se da fare, metto i tappi sulle estremità
|
|
//if ( bDoCapEnds) {
|
|
// // 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( vtExtr) ;
|
|
|
|
// ////// SurfCompo?
|
|
// //// le unisco alla superficie del fianco
|
|
// //if ( ! pSbz->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
|
|
// // return nullptr ;
|
|
//}
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
////-------------------------------------------------------------------------------
|
|
//ISurfCompo*
|
|
//GetSurfBezierByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol) ///// RICHIEDE LE SURF COMPO/////////////////
|
|
//{
|
|
// // verifica parametri
|
|
// if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr)
|
|
// return nullptr ;
|
|
// // se una sola curva, uso la funzione precedente
|
|
// if ( vpCurve.size() == 1 )
|
|
// return GetSurfBezierByExtrusion( 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 ( ( abs( 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<SurfBezier> pSbz1( CreateBasicSurfBezier()) ;
|
|
// if ( IsNull( pSbz1) || ! pSbz1->CreateByRegion( vPL))
|
|
// return nullptr ;
|
|
// // creo la seconda superficie come copia della prima e poi inverto la prima
|
|
// PtrOwner<ISurfBezier> pSbz2( pSbz1->Clone()) ;
|
|
// pSbz1->Invert() ;
|
|
//
|
|
// // creo e unisco le diverse superfici di estrusione
|
|
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
|
// // estrusione
|
|
// SurfBezier SbzLat ;
|
|
// if ( ! SbzLat.CreateByExtrusion( vPL[i], vtExtr)) // qui mi serve la curva e non la polyline della curva. vuol dire che dalla CalcRegionPolyLines devo farmi restituire anche le curve ordinate
|
|
// return nullptr ;
|
|
// }
|
|
// // restituisco la superficie
|
|
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
|
|
//}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
|
bool bCapEnds, double dLinTol) // con l'aggiunta delle SURFCOMPO posso gestire anche i cap e curve che attraversano l'asse
|
|
{
|
|
// verifica parametri
|
|
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 ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
// return nullptr ;
|
|
|
|
//// se richiesta chiusura degli estremi
|
|
//if ( bCapEnds && ! PL.IsClosed()) { // serve la SURFCOMPO
|
|
// Vector3d vtAxN = vtAx ;
|
|
// vtAxN.Normalize() ;
|
|
// double dPosIni = 0, dPosFin = 0 ;
|
|
// 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<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, ANG_FULL, 0))
|
|
return nullptr ;
|
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
double dVol ;
|
|
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
|
pSbz->Invert() ;
|
|
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
|
double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
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 ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
return nullptr ;
|
|
|
|
// creo e setto la superficie bezier
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove))
|
|
return nullptr ;
|
|
//// se richiesti caps /// richiede la SurfCompo
|
|
//if ( bCapEnds) {
|
|
// // determino se la sezione è chiusa e piatta
|
|
// Plane3d plPlane ; double dArea ;
|
|
// bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
|
|
// // determino non sia una semplice rivoluzione
|
|
// bool bRevolved = ( abs( abs( dAngRotDeg) - ANG_FULL) < EPS_ANG_SMALL && abs( dMove) < EPS_SMALL) ;
|
|
// // se sezione chiusa e piatta e non rivoluzione, posso aggiungere i tappi
|
|
// if ( bSectClosedFlat && ! bRevolved) {
|
|
// // aggiungo il cap sull'inizio
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
|
// return nullptr ;
|
|
// pSTM->DoSewing( *pSci) ;
|
|
// // aggiungo il cap sulla fine
|
|
// Vector3d vtMove = vtAx ;
|
|
// vtMove.Normalize() ;
|
|
// vtMove *= dMove ;
|
|
// PL.Translate( vtMove) ;
|
|
// PL.Rotate( ptAx, vtAx, dAngRotDeg) ;
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
|
// return nullptr ;
|
|
// pSce->Invert() ;
|
|
// pSTM->DoSewing( *pSce) ;
|
|
// }
|
|
//}
|
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
double dVol ;
|
|
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
|
pSbz->Invert() ;
|
|
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
//
|
|
////-------------------------------------------------------------------------------
|
|
//static ISurfBezier*
|
|
//GetSurfBezierSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // verifico che la linea guida sia piana
|
|
// Plane3d plGuide ;
|
|
// if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// Vector3d vtNorm = plGuide.GetVersN() ;
|
|
// // determino se la guida è chiusa
|
|
// bool bGuideClosed = pGuide->IsClosed() ;
|
|
// // curve di offset
|
|
// OffsetCurve OffsCrvR ;
|
|
// if ( ! OffsCrvR.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0)
|
|
// return nullptr ;
|
|
// PtrOwner<ICurve> pCrvR( OffsCrvR.GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvR))
|
|
// return nullptr ;
|
|
// OffsetCurve OffsCrvL ;
|
|
// if ( ! OffsCrvL.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0)
|
|
// return nullptr ;
|
|
// PtrOwner<ICurve> pCrvL( OffsCrvL.GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvL))
|
|
// return nullptr ;
|
|
// // costruisco le parti di superficie
|
|
// PtrOwner<ISurfTriMesh> pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
// if ( IsNull( pSrfTop))
|
|
// return nullptr ;
|
|
// PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
|
// if ( IsNull( pSrfBot))
|
|
// return nullptr ;
|
|
// pSrfBot->Translate( -dDimV * vtNorm) ;
|
|
// pSrfBot->Invert() ;
|
|
// PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
|
|
// if ( IsNull( pSrfRgt))
|
|
// return nullptr ;
|
|
// pSrfRgt->Invert() ;
|
|
// PtrOwner<ISurfTriMesh> pSrfLft( GetSurfTriMeshByExtrusion( pCrvL, -dDimV * vtNorm, false, dLinTol)) ;
|
|
// if ( IsNull( pSrfLft))
|
|
// return nullptr ;
|
|
// // unisco le parti
|
|
// PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
|
// pSTM->DoSewing( *pSrfRgt) ;
|
|
// pSTM->DoSewing( *pSrfLft) ;
|
|
// pSTM->DoSewing( *pSrfBot) ;
|
|
// // salvo tolleranza lineare usata e imposto angolo per smooth
|
|
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
// pSTM->SetSmoothAngle( 20) ;
|
|
// // se guida aperta e tappi piatti
|
|
// if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
|
// // verifico che le due estremità siano chiuse e piatte
|
|
// POLYLINEVECTOR vPL ;
|
|
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
|
// return nullptr ;
|
|
// Plane3d plEnds ; double dArea ;
|
|
// if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// // aggiungo il cap sull'inizio
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
|
// return nullptr ;
|
|
// pSci->Invert() ;
|
|
// pSTM->DoSewing( *pSci) ;
|
|
// // aggiungo il cap sulla fine
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
|
// return nullptr ;
|
|
// pSce->Invert() ;
|
|
// pSTM->DoSewing( *pSce) ;
|
|
// }
|
|
// // se altrimenti guida aperta e tappi arrotondati
|
|
// if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
|
// // step di rotazione per rispettare la tolleranza
|
|
// double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
|
// // aggiungo il cap sull'inizio
|
|
// Point3d ptStart ;
|
|
// pGuide->GetStartPoint( ptStart) ;
|
|
// Vector3d vtStart ;
|
|
// pGuide->GetStartDir( vtStart) ;
|
|
// vtStart.Rotate( vtNorm, 0, 1) ;
|
|
// PolyLine PLStart ;
|
|
// PLStart.AddUPoint( 0, ptStart) ;
|
|
// PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ;
|
|
// PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ;
|
|
// PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ;
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
// return nullptr ;
|
|
// pSci->Invert() ;
|
|
// pSTM->DoSewing( *pSci) ;
|
|
// // aggiungo il cap sulla fine
|
|
// Point3d ptEnd ;
|
|
// pGuide->GetEndPoint( ptEnd) ;
|
|
// Vector3d vtEnd ;
|
|
// pGuide->GetEndDir( vtEnd) ;
|
|
// vtEnd.Rotate( vtNorm, 0, -1) ;
|
|
// PolyLine PLEnd ;
|
|
// PLEnd.AddUPoint( 0, ptEnd) ;
|
|
// PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ;
|
|
// PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ;
|
|
// PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ;
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
// return nullptr ;
|
|
// pSce->Invert() ;
|
|
// pSTM->DoSewing( *pSce) ;
|
|
// }
|
|
// // restituisco la superficie
|
|
// return Release( pSTM) ;
|
|
//}
|
|
//
|
|
////-------------------------------------------------------------------------------
|
|
//static ISurfBezier*
|
|
//GetSurfBezierBeveledRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // metodo di calcolo impostato da USE_VORONOI
|
|
//
|
|
// // verifico che la linea guida sia piana
|
|
// Plane3d plGuide ;
|
|
// if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// // assegno la normale del piano
|
|
// Vector3d vtNorm = plGuide.GetVersN() ;
|
|
// // determino il punto centrale della sezione
|
|
// Point3d ptCen ;
|
|
// pGuide->GetStartPoint( ptCen) ;
|
|
// ptCen -= dDimV / 2 * vtNorm ;
|
|
// // determino se la guida è chiusa
|
|
// bool bGuideClosed = pGuide->IsClosed() ;
|
|
// // curve di offset
|
|
// const int NUM_OFFS = 4 ;
|
|
// OffsetCurve vOffsCrv[NUM_OFFS] ;
|
|
// double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ;
|
|
// bool bOk = true ;
|
|
// if ( ! USE_VORONOI) {
|
|
// future<bool> vRes[NUM_OFFS] ;
|
|
// for ( int i = 0 ; i < NUM_OFFS ; ++ i)
|
|
// vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
|
// bool bOk = true ;
|
|
// int nFin = 0 ;
|
|
// while ( nFin < NUM_OFFS) {
|
|
// for ( int i = 0 ; i < NUM_OFFS ; ++ i) {
|
|
// if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
|
// bOk = vRes[i].get() && bOk ;
|
|
// ++ nFin ;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// else {
|
|
// // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
|
|
// for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
|
// bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
|
// }
|
|
//
|
|
// if ( ! bOk ||
|
|
// vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
|
// vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
|
// return nullptr ;
|
|
// PtrOwner<ICurve> pCrvR( vOffsCrv[0].GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvR))
|
|
// return nullptr ;
|
|
// PtrOwner<ICurve> pCrvL( vOffsCrv[1].GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvL))
|
|
// return nullptr ;
|
|
// PtrOwner<ICurve> pCrvRb( vOffsCrv[2].GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvRb))
|
|
// return nullptr ;
|
|
// pCrvRb->Translate( - dBevelV * vtNorm) ;
|
|
// PtrOwner<ICurve> pCrvLb( vOffsCrv[3].GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvLb))
|
|
// return nullptr ;
|
|
// pCrvLb->Translate( - dBevelV * vtNorm) ;
|
|
// // costruisco le parti di superficie
|
|
// PtrOwner<ISurfTriMesh> pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
// if ( IsNull( pSrfTop))
|
|
// return nullptr ;
|
|
// PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
|
// if ( IsNull( pSrfBot))
|
|
// return nullptr ;
|
|
// pSrfBot->Translate( -dDimV * vtNorm) ;
|
|
// pSrfBot->Invert() ;
|
|
// PtrOwner<ISurfTriMesh> pSrfTopR( GetSurfTriMeshRuled( pCrvRb, pCrvR, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
// if ( IsNull( pSrfTopR))
|
|
// return nullptr ;
|
|
// PtrOwner<ISurfTriMesh> pSrfBotR( pSrfTopR->Clone()) ;
|
|
// if ( IsNull( pSrfBotR))
|
|
// return nullptr ;
|
|
// pSrfBotR->Mirror( ptCen, vtNorm) ;
|
|
// PtrOwner<ISurfTriMesh> pSrfTopL( GetSurfTriMeshRuled( pCrvL, pCrvLb, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
// if ( IsNull( pSrfTopL))
|
|
// return nullptr ;
|
|
// PtrOwner<ISurfTriMesh> pSrfBotL( pSrfTopL->Clone()) ;
|
|
// if ( IsNull( pSrfBotL))
|
|
// return nullptr ;
|
|
// pSrfBotL->Mirror( ptCen, vtNorm) ;
|
|
// PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvRb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ;
|
|
// if ( IsNull( pSrfRgt))
|
|
// return nullptr ;
|
|
// pSrfRgt->Invert() ;
|
|
// PtrOwner<ISurfTriMesh> pSrfLft( GetSurfTriMeshByExtrusion( pCrvLb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ;
|
|
// if ( IsNull( pSrfLft))
|
|
// return nullptr ;
|
|
// // unisco le parti
|
|
// int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
|
// StmFromTriangleSoup stmSoup ;
|
|
// if ( ! stmSoup.Start( nBuckets))
|
|
// return nullptr ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfTopR) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfTopL) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfBotR) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfBotL) ;
|
|
// stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
|
// PtrOwner<ISurfTriMesh> pSTM ;
|
|
// // se guida aperta e tappi piatti
|
|
// if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
|
// // completo unione e recupero la superficie risultante
|
|
// if ( ! stmSoup.End())
|
|
// return nullptr ;
|
|
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
// // preparo seconda zuppa di triangoli per inserire i tappi
|
|
// StmFromTriangleSoup stmCapSoup ;
|
|
// if ( ! stmCapSoup.Start( nBuckets))
|
|
// return nullptr ;
|
|
// // verifico che le due estremità siano chiuse e piatte
|
|
// POLYLINEVECTOR vPL ;
|
|
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
|
// return nullptr ;
|
|
// Plane3d plEnds ; double dArea ;
|
|
// if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
|
// return nullptr ;
|
|
// // calcolo il cap sull'inizio
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
|
// return nullptr ;
|
|
// pSci->Invert() ;
|
|
// // calcolo il cap sulla fine
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
|
// return nullptr ;
|
|
// pSce->Invert() ;
|
|
// // cucio i tappi all'estrusione
|
|
// if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
|
|
// return nullptr ;
|
|
// }
|
|
// // se altrimenti guida aperta e tappi arrotondati
|
|
// else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
|
// // step di rotazione per rispettare il tipo o la tolleranza
|
|
// double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
|
// // aggiungo il cap sull'inizio
|
|
// Point3d ptStart ;
|
|
// pGuide->GetStartPoint( ptStart) ;
|
|
// Vector3d vtStart ;
|
|
// pGuide->GetStartDir( vtStart) ;
|
|
// vtStart.Rotate( vtNorm, 0, 1) ;
|
|
// PolyLine PLStart ;
|
|
// PLStart.AddUPoint( 0, ptStart) ;
|
|
// PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ;
|
|
// PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ;
|
|
// PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ;
|
|
// PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ;
|
|
// PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ;
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
// return nullptr ;
|
|
// pSci->Invert() ;
|
|
// stmSoup.AddSurfTriMesh( *pSci) ;
|
|
// // aggiungo il cap sulla fine
|
|
// Point3d ptEnd ;
|
|
// pGuide->GetEndPoint( ptEnd) ;
|
|
// Vector3d vtEnd ;
|
|
// pGuide->GetEndDir( vtEnd) ;
|
|
// vtEnd.Rotate( vtNorm, 0, -1) ;
|
|
// PolyLine PLEnd ;
|
|
// PLEnd.AddUPoint( 0, ptEnd) ;
|
|
// PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ;
|
|
// PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ;
|
|
// PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ;
|
|
// PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ;
|
|
// PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ;
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
// return nullptr ;
|
|
// pSce->Invert() ;
|
|
// stmSoup.AddSurfTriMesh( *pSce) ;
|
|
// // completo unione e recupero la superficie risultante
|
|
// if ( ! stmSoup.End())
|
|
// return nullptr ;
|
|
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
// }
|
|
// else {
|
|
// // completo unione e recupero la superficie risultante
|
|
// if ( ! stmSoup.End())
|
|
// return nullptr ;
|
|
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
// }
|
|
// // salvo tolleranza lineare usata e imposto angolo per smooth
|
|
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
// pSTM->SetSmoothAngle( 20) ;
|
|
// // restituisco la superficie
|
|
// return Release( pSTM) ;
|
|
//}
|
|
//
|
|
////-------------------------------------------------------------------------------
|
|
//ISurfBezier*
|
|
//GetSurfBezierRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // verifica parametri
|
|
// if ( pGuide == nullptr || dBevelH > 0.4 * dDimH || dBevelV > 0.4 * dDimV)
|
|
// return nullptr ;
|
|
// // determino se sezione squadrata o con smusso
|
|
// bool bSharp = ( dBevelH < 100 * EPS_SMALL || dBevelV < 100 * EPS_SMALL) ;
|
|
// // eseguo
|
|
// if ( bSharp)
|
|
// return GetSurfBezierSharpRectSwept( dDimH, dDimV, pGuide, nCapType, dLinTol) ;
|
|
// else
|
|
// return GetSurfBezierBeveledRectSwept( dDimH, dDimV, dBevelH, dBevelV, pGuide, nCapType, dLinTol) ;
|
|
//}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
|
|
{
|
|
//// determino se la sezione è chiusa
|
|
//bool bSectClosed = pSect->IsClosed() ;
|
|
//// determino se la guida è chiusa
|
|
//bool bGuideClosed = pGuide->IsClosed() ;
|
|
|
|
// riferimento all'inizio della linea guida
|
|
Frame3d frStart ;
|
|
Point3d ptStart ;
|
|
pGuide->GetStartPoint( ptStart) ;
|
|
Vector3d vtStart ;
|
|
pGuide->GetStartDir( vtStart) ;
|
|
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
|
|
// capisco se la guida è una linea spezzata o una curva
|
|
bool bGuideIsPolyLine = false ;
|
|
switch( pGuide->GetType()) {
|
|
case CRV_COMPO : {
|
|
bGuideIsPolyLine = true ;
|
|
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
|
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
|
const ICurve* pCrv = pCC->GetCurve( i) ;
|
|
if( pCrv->GetType() != CRV_LINE) {
|
|
if ( pCrv->GetType() == CRV_BEZIER) {
|
|
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
|
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
}
|
|
else
|
|
bGuideIsPolyLine = false ;
|
|
}
|
|
}
|
|
break ;
|
|
}
|
|
case CRV_LINE :
|
|
bGuideIsPolyLine = true ;
|
|
break ;
|
|
case CRV_BEZIER : {
|
|
// controllo se i punti di controllo sono allineati
|
|
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
|
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
break ;
|
|
}
|
|
default :
|
|
break ;
|
|
}
|
|
|
|
bool bRat = false ;
|
|
int nSpanV = 0 ;
|
|
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
if ( bGuideIsPolyLine ) {
|
|
if( pGuide->GetType() == CRV_LINE)
|
|
nSpanV = 1 ;
|
|
else if ( pGuide->GetType() == CRV_COMPO)
|
|
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
|
}
|
|
else {
|
|
//converto in bezier la guida ( grado 3, non razionale)
|
|
if ( pGuide->GetType() != CRV_BEZIER)
|
|
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
|
else {
|
|
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
|
if( ! pGuideBez->IsRational())
|
|
pCrvV->AddCurve( pGuide->Clone()) ;
|
|
else
|
|
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
|
}
|
|
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
|
return nullptr ;
|
|
nSpanV = pCrvV->GetCurveCount() ;
|
|
}
|
|
|
|
// converto in bezier la sezione ( grado 3, non razionale)
|
|
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
|
if ( pSect->GetType() != CRV_BEZIER)
|
|
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
|
else {
|
|
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
|
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
|
}
|
|
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
|
return nullptr ;
|
|
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
|
|
|
int nDegV = 3 ;
|
|
if ( bGuideIsPolyLine)
|
|
nDegV = 1 ;
|
|
|
|
int nDegU = 3 ;
|
|
// superficie swept
|
|
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
|
if ( bGuideIsPolyLine) {
|
|
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
pCrvU->ToLoc( frStart) ;
|
|
// la guida è una linea spezzata, quindi posso lavorare con gli offset
|
|
ICRVCOMPOPOVECTOR vCC ;
|
|
INTMATRIX mRep ; mRep.resize( nSpanU * nDegU + 1) ;
|
|
int nMaxSpanV = nSpanV ;
|
|
for( int i = 0 ; i < nSpanU ; ++i) {
|
|
const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
|
for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
|
// faccio l'offset della guida nel punto di controllo della sezione
|
|
OffsetCurve OffsCrv ;
|
|
if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
|
return nullptr ;
|
|
vCC.emplace_back() ;
|
|
vCC.back()->AddCurve(OffsCrv.GetLongerCurve()) ;
|
|
if ( IsNull( pCrvV))
|
|
return nullptr ;
|
|
vCC.back()->Translate( ptCtrl.y * frStart.VersY()) ;
|
|
//mRep[ i * nDegU + j].resize(vCC.back()->GetCurveCount()) ;
|
|
nMaxSpanV = max ( nMaxSpanV, vCC.back()->GetCurveCount()) ;
|
|
}
|
|
}
|
|
|
|
// devo capire quante span in V devo creare e a quale span appartengono i tratti degli offset
|
|
for ( int k = 0 ; k < int( vCC.size()) ; ++k) {
|
|
const ICurveComposite* pCC = vCC[k] ;
|
|
mRep[k].resize( nMaxSpanV) ;
|
|
for ( int z = 0 ; z < int( mRep[k].size()) ; ++z) {
|
|
int nProp = - 1 ; pCC->GetCurveTempProp( z, nProp) ;
|
|
if ( nProp == 0) {
|
|
// ho trovato almeno una curva di offset che ha un tratto non derivante direttamente dalla curva originale
|
|
// tutte le altre curve che hanno curve di offeset che non hanno questo tratto bonus dovranno ripetere il punto di controllo
|
|
for ( int w = 0 ; w < int( vCC.size()) ; ++w) {
|
|
const ICurveComposite* pCCOther = vCC[w] ;
|
|
int nPropCheck = -1 ; pCCOther->GetCurveTempProp( z, nPropCheck) ;
|
|
if( nPropCheck != 0)
|
|
mRep[w][z] = 1 ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// conto in quante colonne di mRep la somma degli elementi è != 0
|
|
// questo numero va aggiunto all'attuale nSpanV
|
|
int nSpanPlus = 0 ;
|
|
for( int z = 0 ; z < nMaxSpanV ; ++z) {
|
|
int nPosTot = 0 ;
|
|
for ( int k = 0 ; k < int( mRep.size()) ; ++k )
|
|
nPosTot += mRep[k][z] ;
|
|
if( nPosTot != 0)
|
|
nSpanPlus += 1 ;
|
|
}
|
|
nMaxSpanV = max( nMaxSpanV, nSpanV + nSpanPlus) ;
|
|
nSpanV = nMaxSpanV ;
|
|
|
|
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
|
//// aggiungo i punti di controllo alla superficie
|
|
//for( int i = 0 ; i < nSpanU ; ++i) {
|
|
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
// const ICurveComposite* pOffsetCrv = vCC[i*nDegU + j] ;
|
|
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
|
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
|
// if( pCL == nullptr)
|
|
// return nullptr ;
|
|
// if( z == 0) {
|
|
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
|
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
|
// }
|
|
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
|
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//// aggiungo i punti di controllo alla superficie /// DA CORREGGERE L'AGGIUNTA DEI PUNTI DI CONTROLLO
|
|
//for( int i = 0 ; i < int( vCC.size()) ; ++i) {
|
|
// const ICurveComposite* pOffsetCrv = vCC[i] ;
|
|
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
|
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
|
// if( pCL == nullptr)
|
|
// return nullptr ;
|
|
// if( z == 0) {
|
|
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
|
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
|
// }
|
|
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
|
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
|
// }
|
|
//}
|
|
|
|
}
|
|
else {
|
|
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
|
|
|
// VERSIONE con le copie della sezione ( superficie skinned)
|
|
|
|
// creo delle copie della curva e faccio la skinned
|
|
// per ogni sottocurva della guida ( che sarà composta da curve di bezier di grado 3)
|
|
// posiziono una copia della curva di sezione per ogni punto di controllo
|
|
frStart.Set( ptStart, vtStart) ;
|
|
pCrvU->ToLoc( frStart) ;
|
|
ICURVEPOVECTOR vCrvSet ;
|
|
CICURVEPVECTOR vpCrv ;
|
|
RotationMinimizingFrame rmfGuide ; rmfGuide.Set( pCrvV, frStart) ;
|
|
//double dStep = 0.25 ;
|
|
FRAME3DVECTOR vFrame ;
|
|
int nSpanV = pCrvV->GetCurveCount() ;
|
|
int nSplit = 8 * nSpanV ;
|
|
rmfGuide.GetFramesBySplit( nSplit, vFrame) ;
|
|
|
|
for ( int i = 0 ; i < nSpanV ; ++i) {
|
|
for ( int j = i==0 ? 0 : 1 ; j < nSplit + 1 ; ++j) {
|
|
ICurve* pNewSect = pCrvU->Clone() ;
|
|
pNewSect->ToGlob( vFrame[j]) ; // da sistemare se ho più curve ( la pGuide è una compo) e in base allo step di divisione!!!!!!!!! ///////
|
|
vpCrv.push_back( pNewSect) ;
|
|
vCrvSet.emplace_back( pNewSect) ;
|
|
}
|
|
}
|
|
|
|
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
|
|
|
|
|
|
|
//////VERSIONE con l'offset dei punti di controllo // richiede l'interpolazione dei punti
|
|
//
|
|
//// faccio l'offset della guida e poi riconverto i risultati in curve di bezier tramite interpolazione
|
|
//
|
|
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
|
//// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
//pCrvU->ToLoc( frStart) ;
|
|
//for( int i = 0 ; i < nSpanU ; ++i) {
|
|
// const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
|
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
|
// Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
|
// // faccio l'offset della guida nel punto di controllo della sezione
|
|
// OffsetCurve OffsCrv ;
|
|
// if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
|
// return nullptr ;
|
|
// PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
// pCrvV->AddCurve( OffsCrv.GetLongerCurve()) ;
|
|
// if ( IsNull( pCrvV))
|
|
// return nullptr ;
|
|
// pCrvV->Translate( ptCtrl.y * frStart.VersY()) ;
|
|
// PNTVECTOR vPnt ;
|
|
// int nOffCrvs = pCrvV->GetCurveCount() ;
|
|
// for ( int z = 0 ; z < nOffCrvs ; ++z) {
|
|
// Point3d ptCtrl ;
|
|
// if ( z == 0) {
|
|
// pCrvV->GetCurve(z)->GetStartPoint( ptCtrl) ;
|
|
// vPnt.push_back( ptCtrl) ;
|
|
// }
|
|
// pCrvV->GetCurve(z)->GetEndPoint( ptCtrl) ;
|
|
// vPnt.push_back( ptCtrl) ;
|
|
// }
|
|
// pCrvV.Set( CreateCurveComposite()) ;
|
|
// pCrvV->AddCurve( InterpolatePointSetWithBezier( vPnt, dLinTol)) ;
|
|
//
|
|
//
|
|
// nSpanV = pCrvV->GetCurveCount() ;
|
|
// pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ; /// NON POSSO REINIZIALIZZARE LA SURF QUI!
|
|
// /// QUANDO INIZIO A INSERIRE I PUNTI DI CONTROLLO DEVO AVER DEFINITO nSpanV
|
|
//
|
|
//
|
|
// // aggiungo i punti di controllo alla superficie
|
|
// for ( int z = 0 ; z < nSpanV ; ++z) {
|
|
// const ICurveBezier* pCrvBez = GetCurveBezier( pCrvV->GetCurve( z)) ;
|
|
// if( pCrvBez == nullptr)
|
|
// return nullptr ;
|
|
// for ( int k = z == 0 ? 0 : 1 ; k < nDegV ; ++k) {
|
|
// Point3d ptCtrl = pCrvBez->GetControlPoint( k) ;
|
|
// pSurfBez->SetControlPoint( i * nDegU + j, z * nDegV + k, ptCtrl) ;
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
}
|
|
|
|
|
|
|
|
|
|
////// se richiesti caps e sezione chiusa e guida aperta /// in attesa della SurfCompo, al momento viene fatto nell'executor
|
|
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
// // verifico che le due estremità siano chiuse e piatte
|
|
|
|
//}
|
|
|
|
// restituisco la superficie
|
|
return Release( pSurfBez) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
{
|
|
//// determino se la sezione è chiusa
|
|
//bool bSectClosed = pSect->IsClosed() ;
|
|
//// determino se la guida è chiusa
|
|
//bool bGuideClosed = pGuide->IsClosed() ;
|
|
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
|
|
bool bRMF = vtAx.IsSmall() ;
|
|
|
|
// riferimento all'inizio della linea guida
|
|
Point3d ptStart ;
|
|
pGuide->GetStartPoint( ptStart) ;
|
|
Vector3d vtStart ;
|
|
pGuide->GetStartDir( vtStart) ;
|
|
Frame3d frStart ;
|
|
if ( bRMF) {
|
|
if ( ! frStart.Set( ptStart, vtStart))
|
|
return nullptr ;
|
|
}
|
|
else {
|
|
Vector3d vtAxX = vtAx ^ vtStart ;
|
|
if ( vtAxX.IsSmall()) {
|
|
vtAxX = FromUprightOrtho( vtAx) ;
|
|
vtAxX.Rotate( vtAx, 0, 1) ;
|
|
}
|
|
if ( ! frStart.Set( ptStart, vtStart, vtAxX))
|
|
return nullptr ;
|
|
}
|
|
|
|
// capisco se la guida è una linea spezzata o una curva
|
|
bool bGuideIsPolyLine = false ;
|
|
switch( pGuide->GetType()) {
|
|
case CRV_COMPO : {
|
|
bGuideIsPolyLine = true ;
|
|
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
|
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
|
const ICurve* pCrv = pCC->GetCurve( i) ;
|
|
if( pCrv->GetType() != CRV_LINE) {
|
|
if ( pCrv->GetType() == CRV_BEZIER) {
|
|
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
|
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
}
|
|
else
|
|
bGuideIsPolyLine = false ;
|
|
}
|
|
}
|
|
break ;
|
|
}
|
|
case CRV_LINE :
|
|
bGuideIsPolyLine = true ;
|
|
break ;
|
|
case CRV_BEZIER : {
|
|
// controllo se i punti di controllo sono allineati
|
|
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
|
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
|
break ;
|
|
}
|
|
default :
|
|
break ;
|
|
}
|
|
|
|
bool bRat = false ;
|
|
int nSpanV = 0 ;
|
|
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
|
if ( bGuideIsPolyLine) {
|
|
if( pGuide->GetType() == CRV_LINE)
|
|
nSpanV = 1 ;
|
|
else if ( pGuide->GetType() == CRV_COMPO)
|
|
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
|
}
|
|
else {
|
|
//converto in bezier la guida ( grado 3, non razionale)
|
|
if ( pGuide->GetType() != CRV_BEZIER)
|
|
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
|
else {
|
|
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
|
if( ! pGuideBez->IsRational())
|
|
pCrvV->AddCurve( pGuide->Clone()) ;
|
|
else
|
|
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
|
}
|
|
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
|
return nullptr ;
|
|
nSpanV = pCrvV->GetCurveCount() ;
|
|
}
|
|
|
|
// converto in bezier la sezione ( grado 3, non razionale)
|
|
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
|
if ( pSect->GetType() != CRV_BEZIER)
|
|
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
|
else {
|
|
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
|
if( ! pSectBez->IsRational())
|
|
pCrvU->AddCurve( pSect->Clone()) ; ///// questa curva potrebbe non essere di grado 3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
else
|
|
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
|
}
|
|
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
|
return nullptr ;
|
|
|
|
// calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
|
|
FRAME3DVECTOR vFrames ;
|
|
if ( bRMF) {
|
|
RotationMinimizingFrame RMF ;
|
|
if( bGuideIsPolyLine) {
|
|
if ( ! RMF.Set( pGuide, frStart) ||
|
|
! RMF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
|
return nullptr ;
|
|
}
|
|
else {
|
|
if ( ! RMF.Set( pGuide, frStart) ||
|
|
! RMF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
|
return nullptr ;
|
|
}
|
|
}
|
|
else {
|
|
RotationXplaneFrame RXF ;
|
|
if( bGuideIsPolyLine) {
|
|
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
|
! RXF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
|
return nullptr ;
|
|
}
|
|
else {
|
|
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
|
! RXF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
//// per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
|
|
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
|
int nDegU = 9 ; // debug
|
|
|
|
|
|
int nDegV = 3 ;
|
|
if ( bGuideIsPolyLine){
|
|
nDegV = 1 ;
|
|
// superficie swept
|
|
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
|
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
|
pCrvU->ToLoc( frStart) ;
|
|
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
|
PtrOwner<ICurveComposite> pNewSect( pCrvU->Clone()) ;
|
|
pNewSect->ToGlob( vFrames[f]) ;
|
|
for ( int i = 0 ; i < nSpanU ; ++i) {
|
|
const ICurveBezier* pSubCrvBez = GetCurveBezier( pNewSect->GetCurve( i)) ;
|
|
for ( int j = 0 ; j < nDegU + 1 ; ++j) {
|
|
Point3d ptCtrl = pSubCrvBez->GetControlPoint( j) ;
|
|
pSurfBez->SetControlPoint( i * nDegU + j, f, ptCtrl) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Release( pSurfBez) ;
|
|
}
|
|
else {
|
|
// porto la sezione nel sistema di riferimento del piano in cui giace
|
|
pCrvU->ToLoc( frStart) ;
|
|
ICURVEPOVECTOR vCrvSet ;
|
|
CICURVEPVECTOR vpCrv ;
|
|
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
|
ICurve* pNewSect = pCrvU->Clone() ;
|
|
// porto la curva nel frame corrente
|
|
pNewSect->ToGlob( vFrames[f]) ;
|
|
vpCrv.push_back( pNewSect) ;
|
|
vCrvSet.emplace_back( pNewSect) ;
|
|
}
|
|
|
|
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
|
}
|
|
|
|
//// se richiesti caps e sezione chiusa e guida aperta
|
|
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
|
|
// // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
|
// return nullptr ;
|
|
// pSci->ToGlob( vFrames.front()) ;
|
|
// // aggiungo
|
|
// StmFts.AddSurfTriMesh( *pSci) ;
|
|
|
|
// // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
|
// return nullptr ;
|
|
// pSce->ToGlob( vFrames.back()) ;
|
|
// // inverto
|
|
// pSce->Invert() ;
|
|
// // aggiungo
|
|
// StmFts.AddSurfTriMesh( *pSce) ;
|
|
//}
|
|
|
|
//// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
//double dVol ;
|
|
//if ( pSTM->GetVolume( dVol) && dVol < 0)
|
|
// pSTM->Invert() ;
|
|
|
|
// restituisco la superficie
|
|
return nullptr ;
|
|
}
|
|
|
|
////-------------------------------------------------------------------------------
|
|
//ISurfBezier*
|
|
//GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx,
|
|
// bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // verifica parametri
|
|
// if ( pSect == nullptr || pGuide == nullptr)
|
|
// return nullptr ;
|
|
//
|
|
// bool bIsLine = false ;
|
|
// if ( pGuide->GetType() == CRV_LINE)
|
|
// bIsLine = true ;
|
|
// else {
|
|
// const CurveComposite* pCompo = GetBasicCurveComposite( pGuide) ;
|
|
// Point3d ptStart, ptEnd ;
|
|
// if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
|
|
// bIsLine = true ;
|
|
// }
|
|
// // se la guida è piana
|
|
// Plane3d plGuide ;
|
|
// if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL))
|
|
// return GetSurfBezierSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ;
|
|
//
|
|
// // altrimenti swept 3d
|
|
// return GetSurfBezierSwept3d( pSect, pGuide, vtAx, bCapEnds, dLinTol) ;
|
|
//}
|
|
//
|
|
////-------------------------------------------------------------------------------
|
|
//ISurfBezier*
|
|
//GetSurfBezierSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, const Vector3d& vtAx,
|
|
// bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // verifica dei parametri
|
|
// if ( pSfrSect == nullptr || pGuide == nullptr)
|
|
// return nullptr ;
|
|
//
|
|
// // predispongo collettore superfici componenti
|
|
// StmFromTriangleSoup StmSoup ;
|
|
// StmSoup.Start() ;
|
|
//
|
|
// // per ogni loop della superficie, creo una Swept
|
|
// for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
|
|
// for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
|
|
// // recupero il loop
|
|
// PtrOwner<ICurve> pCrvLoop( pSfrSect->GetLoop( nC, nL)) ;
|
|
// if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
|
|
// return nullptr ;
|
|
// // creo la Trimesh Swept
|
|
// PtrOwner<ISurfTriMesh> pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, vtAx, false, dLinTol)) ;
|
|
// if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid())
|
|
// return nullptr ;
|
|
// // aggiungo la Swept ricavata al risultato finale ( come triangoli )
|
|
// StmSoup.AddSurfTriMesh( *pStmLoopSwept) ;
|
|
// }
|
|
// }
|
|
//
|
|
// // Recupero la superficie
|
|
// if ( ! StmSoup.End())
|
|
// return nullptr ;
|
|
// PtrOwner<ISurfTriMesh> pStmSwept( StmSoup.GetSurf()) ;
|
|
// if ( IsNull( pStmSwept))
|
|
// return nullptr ;
|
|
//
|
|
// // se rischiesta chiusura...
|
|
// // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa
|
|
// if ( bCapEnds && ! pGuide->IsClosed()) {
|
|
// // recupero i loop all'inizio (dalla regione e apportunamente approssimati)
|
|
// POLYLINEVECTOR vPLi ;
|
|
// for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
|
|
// for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
|
|
// vPLi.emplace_back() ;
|
|
// if ( ! pSfrSect->ApproxLoopWithLines( nC, nL, dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLi.back()))
|
|
// return nullptr ;
|
|
// }
|
|
// }
|
|
// // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
|
|
// PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
|
|
// if ( ! pSci->CreateByRegion( vPLi))
|
|
// return nullptr ;
|
|
// pStmSwept->DoSewing( *pSci) ;
|
|
// // recupero i loops alla fine
|
|
// POLYLINEVECTOR vPLe ;
|
|
// if ( ! pStmSwept->GetLoops( vPLe))
|
|
// return nullptr ;
|
|
// // creo la superficie alla fine e la attacco
|
|
// PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
|
// if ( ! pSce->CreateByRegion( vPLe))
|
|
// return nullptr ;
|
|
// // attacco la superficie finale alla swept
|
|
// pSce->Invert() ;
|
|
// pStmSwept->DoSewing( *pSce) ;
|
|
// }
|
|
// // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
// double dVol ;
|
|
// if ( pStmSwept->GetVolume( dVol) && dVol < 0)
|
|
// pStmSwept->Invert() ;
|
|
//
|
|
// return Release( pStmSwept) ;
|
|
//}
|
|
//
|
|
////-------------------------------------------------------------------------------
|
|
//ISurfBezier*
|
|
//GetSurfBezierTransSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
//{
|
|
// // verifica parametri
|
|
// if ( pSect == nullptr || pGuide == nullptr)
|
|
// return nullptr ;
|
|
// // determino se la sezione è chiusa
|
|
// bool bSectClosed = pSect->IsClosed() ;
|
|
// // punto iniziale della sezione e vettore a inizio guida
|
|
// Point3d ptStart ;
|
|
// if ( ! pSect->GetStartPoint( ptStart))
|
|
// return nullptr ;
|
|
// Point3d ptGuide ;
|
|
// if ( ! pGuide->GetStartPoint( ptGuide))
|
|
// return nullptr ;
|
|
// Vector3d vtDelta = ptStart - ptGuide ;
|
|
// // calcolo la polilinea che approssima la guida
|
|
// PolyLine PLG ;
|
|
// if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG))
|
|
// return nullptr ;
|
|
// // determino se la guida è chiusa
|
|
// bool bGuideClosed = PLG.IsClosed() ;
|
|
// // calcolo la superficie
|
|
// PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSTM))
|
|
// return nullptr ;
|
|
// // salvo tolleranza lineare usata
|
|
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
// // superficie swept
|
|
// PtrOwner<ICurve> pPrevCrv ;
|
|
// Point3d ptP ;
|
|
// bool bPoint = PLG.GetFirstPoint( ptP) ;
|
|
// while ( bPoint) {
|
|
// // nuova curva
|
|
// PtrOwner<ICurve> pCurrCrv( pSect->Clone()) ;
|
|
// if ( IsNull( pCurrCrv))
|
|
// return nullptr ;
|
|
// pCurrCrv->Translate( ptP - ptStart + vtDelta) ;
|
|
// // se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
|
|
// if ( ! IsNull( pPrevCrv)) {
|
|
// PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_ISOPAR, dLinTol)) ;
|
|
// if ( IsNull( pSr))
|
|
// return nullptr ;
|
|
// pSTM->DoSewing( *pSr) ;
|
|
// }
|
|
// // salvo la curva come prossima precedente
|
|
// pPrevCrv.Set( pCurrCrv) ;
|
|
// // prossimo punto
|
|
// bPoint = PLG.GetNextPoint( ptP) ;
|
|
// }
|
|
// // se richiesti caps e sezione chiusa e guida aperta
|
|
// if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
// // calcolo la polilinea che approssima la sezione
|
|
// PolyLine PLS ;
|
|
// if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLS))
|
|
// return nullptr ;
|
|
// // verifico che la sezione sia chiusa e piatta
|
|
// Plane3d plSect ; double dArea ;
|
|
// if ( PLS.IsClosedAndFlat( plSect, dArea, 100 * EPS_SMALL)) {
|
|
// // aggiungo il cap sull'inizio
|
|
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PLS))
|
|
// return nullptr ;
|
|
// pSci->Invert() ;
|
|
// Point3d ptGi ; PLG.GetFirstPoint( ptGi) ;
|
|
// pSci->Translate( ptGi - ptStart + vtDelta) ;
|
|
// pSTM->DoSewing( *pSci) ;
|
|
// // aggiungo il cap sulla fine
|
|
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PLS))
|
|
// return nullptr ;
|
|
// Point3d ptGe ; PLG.GetLastPoint( ptGe) ;
|
|
// pSce->Translate( ptGe - ptStart + vtDelta) ;
|
|
// pSTM->DoSewing( *pSce) ;
|
|
// }
|
|
// }
|
|
// // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
// double dVol ;
|
|
// if ( pSTM->GetVolume( dVol) && dVol < 0)
|
|
// pSTM->Invert() ;
|
|
// // restituisco la superficie
|
|
// return Release( pSTM) ;
|
|
//}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
if ( &ptP == nullptr || pCurve == nullptr)
|
|
return nullptr ;
|
|
//// calcolo la polilinea che approssima la curva
|
|
//PolyLine PL ;
|
|
//if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
// return nullptr ;
|
|
// creo e setto la superficie trimesh
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve))
|
|
return nullptr ;
|
|
//// salvo tolleranza lineare usata
|
|
//pSbz->SetLinearTolerance( dLinTol) ;
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, double dLinTol)
|
|
{
|
|
// verifica parametri
|
|
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
|
return nullptr ;
|
|
|
|
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
|
if ( pCurve1->GetType() != CRV_BEZIER)
|
|
pCC1->AddCurve( CurveToBezierCurve( pCurve1, true, false)) ;
|
|
else
|
|
pCC1->AddCurve( pCurve1->Clone()) ;
|
|
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
|
return nullptr ;
|
|
|
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
|
if ( pCurve2->GetType() != CRV_BEZIER)
|
|
pCC2->AddCurve( CurveToBezierCurve( pCurve2, true, false)) ;
|
|
else
|
|
pCC2->AddCurve( pCurve2->Clone()) ;
|
|
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
|
return nullptr ;
|
|
|
|
// creo e setto la superficie trimesh
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType))
|
|
return nullptr ;
|
|
//// salvo tolleranza lineare usata
|
|
//pSbz->SetLinearTolerance( dLinTol) ;
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
ISurfBezier*
|
|
GetSurfBezierSkinned( const CICURVEPVECTOR& vCrv, double dLinTol)
|
|
{
|
|
// verifico che le curve siano valide
|
|
for ( int i = 0 ; i < int( vCrv.size()) ; ++i) {
|
|
if( vCrv[i] == nullptr || ! vCrv[i]->IsValid())
|
|
return nullptr ;
|
|
}
|
|
|
|
// se ho solo due curve allora faccio la rigata
|
|
if( vCrv.size() == 2)
|
|
return GetSurfBezierRuled( vCrv[0], vCrv[1], ISurfBezier::RLT_B_MINDIST_PLUS, dLinTol) ;
|
|
|
|
//trasformo le curve in curve di bezier, pareggio il numero di sottocurve e il grado
|
|
|
|
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
|
ICURVEPOVECTOR vCrvBez ;
|
|
for( int c = 0 ; c < int( vCrv.size()) ; ++c){
|
|
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
|
|
if ( vCrv[c]->GetType() != CRV_BEZIER )
|
|
pCC->AddCurve( CurveToBezierCurve( vCrv[c])) ;
|
|
else
|
|
pCC->AddCurve( vCrv[c]->Clone()) ;
|
|
if ( IsNull( pCC) || ! pCC->IsValid())
|
|
return nullptr ;
|
|
vCrvBez.emplace_back( Release( pCC)) ;
|
|
}
|
|
|
|
// creo e setto la superficie trimesh
|
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
|
if ( IsNull( pSbz) || ! pSbz->CreateBySetOfCurves( vCrvBez, true))
|
|
return nullptr ;
|
|
// restituisco la superficie
|
|
return Release( pSbz) ;
|
|
} |