Files
EgtGeomKernel/Tool.cpp
T
2022-01-05 15:46:40 +01:00

748 lines
27 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2018
//----------------------------------------------------------------------------
// File : Tool.cpp Data : 04.07.18 Versione : 1.9g1
// Contenuto : Implementazione della classe Tool
//
//
//
// Modifiche : 22.01.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveLine.h"
#include "CurveArc.h"
#include "Tool.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
#include "/EgtDev/Include/EGkFilletChamfer.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkIntersCurves.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
Tool::Tool( bool bApproxWithLines)
: m_bApproxWithLines( bApproxWithLines), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG),
m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), m_dTipHeight( 0), m_dRadius( 0), m_dRCorner( 0),
m_dTipRadius( 0), m_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0)/*,
m_bAllPartCut( true)*/
{
}
//----------------------------------------------------------------------------
Tool::~Tool( void)
{
}
//----------------------------------------------------------------------------
bool
Tool::Clear( void)
{
m_dLinTol = LIN_TOL_STD ;
m_dAngTolDeg = ANG_TOL_APPROX_DEG ;
m_nType = UNDEF ;
m_nCurrentNum = 0 ;
m_dHeight = 0 ;
m_dTipHeight = 0 ;
m_dRadius = 0 ;
m_dRCorner = 0 ;
m_dTipRadius = 0 ;
m_dRefRadius = 0 ;
m_dMrtChsWidth = 0 ;
m_dMrtChsThickness = 0 ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
return true ;
}
//---------- Tolleranza nell'approssimazione di curve profilo ----------------
//----------------------------------------------------------------------------
bool
Tool::SetTolerances( double dLinTol, double dAngTolDeg)
{
m_dLinTol = max( dLinTol, LIN_TOL_MIN) ;
m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, double dCutterH, int nToolNum)
{
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// Per test additivi //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//return SetAdditiveTool( sToolName, dH, dR, dCornR, nToolNum) ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
m_dCutterHeight = dCutterH ;
// verifica sulle minime dimensioni globali
if ( dH < EPS_SMALL || dR < EPS_SMALL || dCornR < - EPS_SMALL)
return false ;
// utensile cilindrico
if ( dCornR < EPS_SMALL) {
m_nType = CYLMILL ;
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = 0 ;
m_dTipRadius = m_dRadius ;
m_dRCorner = 0 ;
m_dRefRadius = m_dRadius ;
// profilo
Point3d pt0( 0, 0, 0) ;
Point3d pt1( m_dRadius, 0, 0) ;
Point3d pt3( m_dRadius, - m_dHeight, 0) ;
Point3d pt4( 0, - m_dHeight, 0) ;
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt4) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// utensile naso di toro
else if ( dCornR < dR - EPS_SMALL) {
m_nType = BULLNOSEMILL ;
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = dCornR ;
m_dTipRadius = dR - dCornR ;
m_dRCorner = dCornR ;
m_dRefRadius = m_dRadius ;
// profilo
Point3d pt0( 0, 0, 0) ;
Point3d pt1( m_dRadius, 0, 0) ;
Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ;
Point3d pt3( m_dTipRadius, - m_dHeight, 0) ;
Point3d pt4( 0, - m_dHeight, 0) ;
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddArcTg( pt3) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddLine( pt4) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
// se da approosimare
if ( m_bApproxWithLines)
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
// utensile sferico
else if ( dCornR < dR + EPS_SMALL) {
m_nType = BALLMILL ;
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = m_dRadius ;
m_dTipRadius = 0 ;
m_dRCorner = m_dRadius ;
m_dRefRadius = m_dRadius ;
// profilo
Point3d pt0( 0, 0, 0) ;
Point3d pt1( m_dRadius, 0, 0) ;
Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ;
Point3d pt4( 0, - m_dHeight, 0) ;
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddArcTg( pt4) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// impossibile
else
return false ;
// eventuali sistemazioni per altezza tagliente
if ( ModifyForCutterHeight())
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
else
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetAdvTool( const string& sToolName, double dH, double dR,
double dTipH, double dTipR, double dCornR, double dCutterH, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
m_dCutterHeight = dCutterH ;
// Verifica dimensioni globali
if ( dH < EPS_SMALL || dR < EPS_SMALL || dTipH < - EPS_SMALL || dTipR < - EPS_SMALL || dCornR < - EPS_SMALL)
return false ;
// Se altezza punta nulla, ricado nel caso standard
if ( dTipH < EPS_SMALL || abs( dTipR - dR) < EPS_SMALL)
return SetStdTool( sToolName, dH, dR, dCornR, dCutterH, nToolNum) ;
// Caso avanzato
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = min( max( dTipH, 0.), m_dHeight) ;
m_dTipRadius = max( dTipR, 0.) ;
m_dRCorner = dCornR ;
// Definisco il profilo
Point3d pt0( 0, 0, 0) ;
Point3d pt1( m_dRadius, 0, 0) ;
Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ;
Point3d pt5( 0, - m_dHeight, 0) ;
// Se raggio corner nullo, allora utensile conico
if ( m_dRCorner < EPS_SMALL) {
m_nType = CONEMILL ;
m_dRCorner = 0 ;
// Assegno il raggio di riferimento
m_dRefRadius = m_dRadius * min( 1., m_dRadius / m_dTipHeight) ;
// profilo
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( m_dTipRadius, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
// eventuali sistemazioni per altezza tagliente
if ( ModifyForCutterHeight())
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
else
return true ;
}
// Altrimenti utensile generico
// se Tip a punta ( TipRadius raggio teorico della parte finale dell'utensile senza raccordo)
if ( m_dTipRadius < m_dRadius) {
// se punta a sfera
if ( m_dTipRadius < EPS_SMALL) {
// Assegno il raggio di riferimento
m_dRefRadius = m_dRCorner ;
// circonferenza del corner
Point3d ptC( 0, - m_dHeight + m_dRCorner, 0) ;
CurveArc cvCirc ;
cvCirc.SetXY( ptC, m_dRCorner) ;
// segmento tangente al corner da sopra o intersezione del gambo con il corner
Point3d pt3 ;
Point3d ptNear( ptC.x + m_dRCorner, ptC.y + m_dRCorner, 0) ;
PtrOwner<ICurveLine> pLine( GetLinePointTgCurve( pt2, cvCirc, ptNear)) ;
if ( ! IsNull( pLine))
pLine->GetEndPoint( pt3) ;
else {
double dSqDelta = m_dRCorner * m_dRCorner - m_dRadius * m_dRadius ;
double dDelta = ( dSqDelta > DBL_EPSILON ? sqrt( dSqDelta) : 0.) ;
pt2 = Point3d( m_dRadius, - m_dHeight + m_dRCorner + dDelta, 0) ;
pt3 = pt2 ;
}
// creazione del corner
Point3d pt4( 0, - m_dHeight, 0) ;
CurveArc cvArc ;
cvArc.SetC2P( ptC, pt3, pt4) ;
// creazione curva composita
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// altrimenti punta a naso di toro
else {
// Assegno il raggio di riferimento
m_dRefRadius = m_dTipRadius ;
// punto da smussare con corner
Point3d ptInt( m_dTipRadius, - m_dHeight, 0) ;
// linea sopra il corner
CurveLine cLine1 ;
cLine1.Set( pt2, ptInt) ;
// linea sotto il corner
CurveLine cLine2 ;
cLine2.Set( ptInt, pt5) ;
// calcolo del corner
Point3d ptIn1 = Media( pt2, ptInt, 0.5) ;
Point3d ptIn2 = Media( ptInt, pt5, 0.5) ;
double dTrim1, dTrim2 ;
PtrOwner< ICurveArc> pArc( CreateFillet( cLine1, ptIn1, cLine2, ptIn2, Z_AX, m_dRCorner, dTrim1, dTrim2)) ;
if ( IsNull( pArc))
return false ;
Point3d pt3 ;
pArc->GetStartPoint( pt3) ;
// creazione curva composita
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddCurve( Release( pArc)) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
}
// altrimenti Tip a coda di rondine ( TipRadius raggio misurabile della parte finale dell'utensile)
else {
// il raggio della punta non pu essere inferiore al raggio corner
if ( m_dTipRadius < m_dRCorner)
return false ;
// Assegno il raggio di riferimento
m_dRefRadius = m_dTipRadius ;
// circonferenza del corner
Point3d ptC( m_dTipRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0) ;
CurveArc cvCirc ;
cvCirc.SetXY( ptC, m_dRCorner) ;
// segmento tangente al corner da sopra
Point3d ptNear( ptC.x + m_dRCorner, ptC.y + m_dRCorner, 0) ;
PtrOwner<ICurveLine> pLine( GetLinePointTgCurve( pt2, cvCirc, ptNear)) ;
if ( IsNull( pLine))
return false ;
// creazione del corner
Point3d pt3 ;
pLine->GetEndPoint( pt3) ;
Point3d pt4( ptC.x, - m_dHeight, 0) ;
CurveArc cvArc ;
cvArc.SetC2P( ptC, pt3, pt4) ;
if ( cvArc.GetAngCenter() > 0)
cvArc.ToExplementary() ;
// creazione curva composita
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// eventuali sistemazioni per altezza tagliente
ModifyForCutterHeight() ;
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
//----------------------------------------------------------------------------
bool
Tool::ModifyForCutterHeight( void)
{
// Se altezza tagliente non definita o superiore alla altezza utensile non devo fare alcunch
if ( m_dCutterHeight < EPS_SMALL || m_dCutterHeight > m_dHeight - EPS_SMALL)
return false ;
// quota di taglio
double dYtrim = -m_dHeight + m_dCutterHeight ;
// linea di taglio
const double LEN_EXTRA = 10 ;
CurveLine clTrim ;
clTrim.SetPDL( Point3d( -LEN_EXTRA, dYtrim, 0), 0, max( m_dRadius, m_dTipRadius) + LEN_EXTRA) ;
// intersezione con il profilo
IntersCurveCurve intCC( m_Outline, clTrim) ;
int nInters = intCC.GetIntersCount() ;
if ( nInters > 0) {
IntCrvCrvInfo aInfo ;
intCC.GetIntCrvCrvInfo( nInters - 1, aInfo) ;
double dU = ( aInfo.bOverlap ? aInfo.IciA[1].dU : aInfo.IciA[0].dU) ;
m_Outline.TrimStartAtParam( dU) ;
m_Outline.AddLine( Point3d( 0, dYtrim, 0), false) ;
m_Outline.AddLine( ORIG, false) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
Tool::SetSawTool( const string& sToolName, double dH, double dR,
double dThick, double dStemR, double dCornR, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nType = UNDEF ;
m_nCurrentNum = nToolNum ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// Verifica dimensioni globali
if ( dH < EPS_SMALL || dR < EPS_SMALL || dThick < EPS_SMALL || dStemR < - EPS_SMALL || dCornR < - EPS_SMALL)
return false ;
// Con gambo
if ( dH > dThick) {
// punti notevoli
Point3d pt0( 0, 0, 0) ;
Point3d pt1( dStemR, 0, 0) ;
Point3d pt2( dStemR, - dH + dThick, 0) ;
Point3d pt3( dR, - dH + dThick, 0) ;
Point3d pt4( dR, - dH, 0) ;
Point3d pt5( 0, - dH, 0) ;
// senza raggio corner
if ( dCornR < EPS_SMALL) {
// creazione profilo
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddLine( pt4) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// altrimenti con raggio corner
else {
// creazione profilo
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt1) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt2) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( pt3 - X_AX * dCornR) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.AddLine( pt4 + Y_AX * dCornR) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddArcTg( pt4 - X_AX * dCornR) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 5, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
}
// altrimenti senza gambo
else {
// punti notevoli
Point3d pt0( 0, - dH + dThick, 0) ;
Point3d pt3( dR, - dH + dThick, 0) ;
Point3d pt4( dR, - dH, 0) ;
Point3d pt5( 0, - dH, 0) ;
// senza raggio corner
if ( dCornR < EPS_SMALL) {
// creazione profilo
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt3) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt4) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// altrimenti con raggio corner
else {
// creazione profilo
m_Outline.AddPoint( pt0) ;
m_Outline.AddLine( pt3 - X_AX * dCornR) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt4 + Y_AX * dCornR) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddArcTg( pt4 - X_AX * dCornR) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( pt5) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
}
// Assegno il raggio di riferimento
m_dRefRadius = dThick ;
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
//----------------------------------------------------------------------------
bool
Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nType = UNDEF ;
m_nCurrentNum = nToolNum ;
if ( pToolOutline != &m_Outline)
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// Copio il profilo e garantisco sia di soli archi e rette (converto eventuali curve di Bezier)
if ( ! m_Outline.CopyFrom( pToolOutline) ||
! m_Outline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg))
return false ;
// Valuto se tutte le curve tagliano
m_ArcLineApprox.SetTempProp( 1, 1) ;
const ICurve* pCurve = m_Outline.GetFirstCurve() ;
while ( pCurve != nullptr && m_ArcLineApprox.GetTempProp( 1) == 1) {
int nCutTempProp = pCurve->GetTempProp( 1) ;
if ( nCutTempProp == 0) {
m_ArcLineApprox.SetTempProp( 0, 1) ;
}
pCurve = m_Outline.GetNextCurve() ;
}
// Ciclo sulle curve componenti
pCurve = m_Outline.GetFirstCurve() ;
while ( pCurve != nullptr) {
int nCutTempProp = pCurve->GetTempProp( 1) ;
// Se la curva un arco ed richiesto la verifica per l'approssimazione,
// verifico se approssimarlo
if ( m_bApproxWithLines && pCurve->GetType() == CRV_ARC) {
// Centro e raggio dell'arco
Point3d ptO = GetBasicCurveArc( pCurve)->GetCenter() ;
double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ;
// Se il centro fuori dall'asse devo approssimare
bool bCurrApprox = ( abs( ptO.x) > EPS_SMALL) ;
// Se una delle altre curve dista dal centro meno del raggio, devo approssimare
for ( int nI = 0 ; ! bCurrApprox && nI < m_Outline.GetCurveCount() && m_ArcLineApprox.GetTempProp( 1) == 1 ; ++ nI) {
const ICurve* pOtherCrv = m_Outline.GetCurve( nI) ;
if ( pOtherCrv != pCurve) {
DistPointCurve CalcDist( ptO, *pOtherCrv) ;
double dCurrDist ;
if ( CalcDist.GetDist( dCurrDist) && dCurrDist < dRadius - EPS_SMALL)
bCurrApprox = true ;
}
}
// Se devo approssimare
if ( bCurrApprox) {
// Creo la polyline approssimante
PolyLine plyApprox ;
if ( ! pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, ICurve::APL_SPECIAL, plyApprox))
return false ;
// Aggiungo i segmenti di retta alla approssimazione
Point3d ptEnd, ptTmp ;
plyApprox.GetFirstPoint( ptEnd) ;
double dEndU ;
pCurve->GetParamAtPoint( ptEnd, dEndU) ;
Vector3d vtTanArc, vtExtN ;
pCurve->GetPointTang( dEndU, ICurve::FROM_MINUS, ptTmp, vtTanArc) ;
vtExtN = - vtTanArc ^ Z_AX ;
vtExtN.Normalize() ;
m_vArcNormals.emplace_back( vtExtN) ;
while ( plyApprox.GetNextPoint( ptEnd)) {
m_ArcLineApprox.AddLine( ptEnd) ;
pCurve->GetParamAtPoint( ptEnd, dEndU) ;
pCurve->GetPointTang( dEndU, ICurve::FROM_MINUS, ptTmp, vtTanArc) ;
vtExtN = - vtTanArc ^ Z_AX ;
vtExtN.Normalize() ;
m_vArcNormals.emplace_back( vtExtN) ;
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, int( m_vArcNormals.size()) - 1) ;
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
}
}
// altrimenti lo aggiungo semplicemente
else {
m_ArcLineApprox.AddCurve( *pCurve, true) ;
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, - 1) ;
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
}
}
// altrimenti segmento e lo aggiungo semplicemente
else {
m_ArcLineApprox.AddCurve( *pCurve, true) ;
int nCvCount = m_ArcLineApprox.GetCurveCount() ;
m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ;
}
pCurve = m_Outline.GetNextCurve() ;
}
// Il profilo dell'utensile deve stare nel 1 e 4 quadrante del piano XY
BBox3d Bounding ;
m_Outline.GetLocalBBox( Bounding) ;
if ( Bounding.GetMin().x < - 10 * EPS_SMALL)
return false ;
// Assegno il tipo dell'utensile
m_nType = GEN ;
// Assegno le dimensioni dell'utensile
m_dHeight = - Bounding.GetMin().y ;
m_dRadius = Bounding.GetMax().x ;
// Assegno il raggio di riferimento se non gi assegnato
if ( m_dRefRadius < EPS_SMALL)
m_dRefRadius = 0.25 * m_dRadius ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetMortiserTool( const string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// Verifica dimensioni globali
if ( dH < EPS_SMALL || dW < EPS_SMALL ||
dTh < EPS_SMALL || dRc < 0 || dW - 2 * dRc < 0)
return false ;
m_dHeight = dH ;
m_dRCorner = dRc ;
m_dMrtChsWidth = dW ;
m_dMrtChsThickness = dTh ;
// Imposto il tipo
m_nType = MORTISER ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// Verifica dimensioni globali
if ( dH < EPS_SMALL || dW < EPS_SMALL || dTh < 0)
return false ;
m_dHeight = dH ;
m_dMrtChsWidth = dW ;
m_dMrtChsThickness = dTh ;
// Imposto il tipo
m_nType = CHISEL ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum)
{
// Impostazioni generali
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
m_Outline.Clear() ;
m_ArcLineApprox.Clear() ;
// verifica sulle minime dimensioni globali
if ( dH < EPS_SMALL || dR < EPS_SMALL || dRC < - EPS_SMALL)
return false ;
m_nType = ADDITIVE ;
m_dHeight = dH ;
m_dRadius = dR ;
m_dRCorner = dRC ;
m_dTipHeight = 0 ;
m_dTipRadius = 0 ;
m_dRefRadius = 0 ;
m_dCutterHeight = dH ;
double dSquareCornerRadProj = m_dRCorner * m_dRCorner - 0.25 * m_dHeight * m_dHeight ;
// Utensile sfiancato
if ( dSquareCornerRadProj > 0) {
double dCenX = m_dRadius - m_dRCorner ;
double dCylRad = dCenX + sqrt( dSquareCornerRadProj) ;
// Utensile mal definito
if ( dCylRad < 0)
return false ;
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
CurveArc cvArc ;
cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
// Utensile cilindrico con eventuale raggio corner
else {
// Utensile mal definito
if ( m_dRadius - m_dRCorner < EPS_SMALL)
return false ;
// Raggio corner nullo
if ( m_dRadius < EPS_SMALL) {
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( m_dRadius, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
}
else {
// Profilo
m_Outline.AddPoint( Point3d( 0, 0, 0)) ;
m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)) ;
m_Outline.SetCurveTempProp( 0, 1, 1) ;
CurveArc cvArc ;
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, - m_dRCorner, 0)) ;
m_Outline.SetCurveTempProp( 1, 1, 1) ;
m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0)) ;
m_Outline.SetCurveTempProp( 2, 1, 1) ;
cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, - m_dHeight, 0)) ;
m_Outline.AddCurve( cvArc) ;
m_Outline.SetCurveTempProp( 3, 1, 1) ;
m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ;
m_Outline.SetCurveTempProp( 4, 1, 1) ;
m_Outline.SetTempProp( 1, 1) ;
}
}
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
}