595421bcdd
- gestone delle eccezioni di vroni - correzioni varie.
180 lines
6.2 KiB
C++
180 lines
6.2 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2013
|
|
//----------------------------------------------------------------------------
|
|
// File : OffsetAux.cpp Data : 23.11.23 Versione : 2.5k5
|
|
// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 23.11.23 SP Creazione modulo spostando alcune funzioni da OffsetCurve.cpp.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "OffsetAux.h"
|
|
#include "CurveArc.h"
|
|
#include "CurveLine.h"
|
|
#include "GeoConst.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
|
{
|
|
// identifico le sottocurve di tipo fillet e assegno loro temp param 1.0 per riconoscerle nella funzione AdjustCurveFillets
|
|
for ( int i = 0 ; i < pCrvCo->GetCurveCount() ; i ++) {
|
|
// recupero la curva
|
|
PtrOwner<ICurve> pCrv( pCrvCo->GetCurve(i)->Clone()) ;
|
|
if ( IsNull( pCrv))
|
|
return false ;
|
|
if ( IsFillet( pCrv, dDist))
|
|
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
|
else
|
|
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
IsFillet( ICurve* pCrv, double dDist)
|
|
{
|
|
// deve essere un arco
|
|
if ( pCrv->GetType() != CRV_ARC)
|
|
return false ;
|
|
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
|
// deve avere raggio uguale alla distanza di offset
|
|
if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL)
|
|
return false ;
|
|
// deve essere CCW se offset a destra e CW se offset a sinistra
|
|
return ( pArc->GetAngCenter() * dDist > 0) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType)
|
|
{
|
|
ICURVEPLIST CrvLst ;
|
|
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
|
while ( ! IsNull( pCrv)) {
|
|
// se identificato come fillet lo trasformo in smusso o estensione
|
|
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
|
CurveComposite ccTemp ;
|
|
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
|
// metto in lista le curve risultanti
|
|
if ( ccTemp.GetCurveCount() > 0) {
|
|
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
|
while ( ! IsNull( pCrv2)) {
|
|
CrvLst.push_back( Release( pCrv2)) ;
|
|
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
|
}
|
|
}
|
|
}
|
|
// altrimenti salvo in lista
|
|
else
|
|
CrvLst.push_back( Release( pCrv)) ;
|
|
// passo alla curva successiva
|
|
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
|
}
|
|
// rimetto le curve nella composita
|
|
for ( auto pCrv : CrvLst) {
|
|
pCrvCo->AddCurve( pCrv) ;
|
|
}
|
|
// unisco tratti allineati
|
|
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux)
|
|
{
|
|
// la curva deve essere un arco
|
|
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
|
if ( pArc == nullptr)
|
|
return false ;
|
|
|
|
// angolo al centro dell'arco
|
|
double dAngDeg = pArc->GetAngCenter() ;
|
|
|
|
// elimino dal tipo le parti estranee all'angolo esterno
|
|
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
|
|
|
|
// se l'angolo esterno supera il retto, offset extend diventa offset chamfer
|
|
if ( nType == ICurve::OFF_EXTEND && abs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
|
|
nType = ICurve::OFF_CHAMFER ;
|
|
|
|
// se angolo esterno molto piccolo, semplifico tutto
|
|
const double SMALL_EXT_ANG = 1.0 ;
|
|
bool bAngSmall = ( abs( dAngDeg) < SMALL_EXT_ANG) ;
|
|
if ( bAngSmall)
|
|
nType = ICurve::OFF_EXTEND ;
|
|
|
|
switch ( nType) {
|
|
case ICurve::OFF_CHAMFER :
|
|
{
|
|
// lunghezza aggiuntiva in tangenza
|
|
double dLen = abs( dDist) * tan( abs( dAngDeg) / 4 * DEGTORAD) ;
|
|
// punti di costruzione smusso
|
|
Point3d ptP1, ptP1a, ptP2a, ptP2 ;
|
|
if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
|
|
return false ;
|
|
Vector3d vtDir1, vtDir2 ;
|
|
if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
|
|
return false ;
|
|
ptP1a = ptP1 + vtDir1 * dLen ;
|
|
ptP2a = ptP2 - vtDir2 * dLen ;
|
|
// aggiungo una nuova linea
|
|
PtrOwner<CurveLine> pLine1( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptP1a))
|
|
return false ;
|
|
if ( ! ccAux.AddCurve( Release( pLine1)))
|
|
return false ;
|
|
// tratto intermedio
|
|
PtrOwner<CurveLine> pLine2( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pLine2) || ! pLine2->Set( ptP1a, ptP2a))
|
|
return false ;
|
|
if ( ! ccAux.AddCurve( Release( pLine2)))
|
|
return false ;
|
|
// aggiungo una nuova linea
|
|
PtrOwner<CurveLine> pLine3( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pLine3) || ! pLine3->Set( ptP2a, ptP2))
|
|
return false ;
|
|
if ( ! ccAux.AddCurve( Release( pLine3)))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
break ;
|
|
case ICurve::OFF_EXTEND :
|
|
{
|
|
// lunghezza aggiuntiva in tangenza
|
|
double dLen = abs( dDist) * tan( abs( dAngDeg) / 2 * DEGTORAD) ;
|
|
// punti di costruzione estensione
|
|
Point3d ptP1, ptPc, ptP2 ;
|
|
if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
|
|
return false ;
|
|
Vector3d vtDir1, vtDir2 ;
|
|
if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
|
|
return false ;
|
|
ptPc = ptP1 + vtDir1 * dLen ;
|
|
// aggiungo una nuova linea
|
|
PtrOwner<CurveLine> pLine1( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptPc))
|
|
return false ;
|
|
if ( ! ccAux.AddCurve( Release( pLine1)))
|
|
return false ;
|
|
// aggiungo una nuova linea
|
|
PtrOwner<CurveLine> pLine2( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pLine2) || ! pLine2->Set( ptPc, ptP2))
|
|
return false ;
|
|
if ( ! ccAux.AddCurve( Release( pLine2)))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
}
|
|
return false ;
|
|
}
|