Files
EgtGeomKernel/Tool.cpp
T
Dario Sassi f6bb62dc7e EgtGeomKernel :
- modifiche a Zmap per utensili generici e per features.
2018-01-29 07:53:08 +00:00

359 lines
11 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2016
//----------------------------------------------------------------------------
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
// 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 <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
Tool::Tool( void)
: m_dLinTol( 2 * 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_dMrtChsWidth( 0), m_dMrtChsThickness( 0)
{
}
//----------------------------------------------------------------------------
Tool::~Tool( void)
{
}
//---------- 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, int nToolNum)
{
// assegno il nome
m_sName = sToolName ;
// Aggiorno il numero dell'utensile corrente
m_nCurrentNum = nToolNum ;
// Imposto il tipo di utensile a indefinito
m_nType = UNDEF ;
// verifica sulle minime dimensioni globali
if ( dH < EPS_SMALL || dR < 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 ;
}
// utensile naso di toro
else if ( dCornR < dR - EPS_SMALL) {
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = dCornR ;
m_dTipRadius = dR - dCornR ;
m_dRCorner = dCornR ;
// come 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.Clear() ;
CurveLine Line ;
Line.Set( pt0, pt1) ;
m_Outline.AddCurve( Line) ;
m_Outline.AddLine( pt2);
m_Outline.AddArcTg( pt3) ;
m_Outline.AddLine( pt4) ;
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 ;
}
// impossibile
else
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetAdvTool( const string& sToolName, double dH, double dR,
double dTipH, double dTipR, double dCornR, int nToolNum)
{
// Setto il nome
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
m_nType = UNDEF ;
// Verifica dimensioni globali
if ( dH < EPS_SMALL || dR < 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, nToolNum) ;
// Caso avanzato
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = dTipH ;
m_dTipRadius = max( dTipR, 0.) ;
// Se raggio corner nullo, allora utensile conico
if ( dCornR < EPS_SMALL) {
m_nType = CONUSMILL ;
m_dRCorner = 0 ;
return true ;
}
// Altrimenti utensile generico.
m_dRCorner = dCornR ;
m_Outline.Clear() ;
// Definisco il profilo
Point3d pt0( 0, 0, 0) ;
Point3d pt1( m_dRadius, 0, 0) ;
Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ;
if ( m_dTipRadius < m_dRadius) {
CurveLine LineSt ;
LineSt.Set( pt0, pt1) ;
Point3d ptInt( dTipR, - dH, 0) ;
Point3d ptLast( 0, - dH, 0) ;
CurveLine cLine1 ;
cLine1.Set( pt2, ptInt) ;
CurveLine cLine2 ;
cLine2.Set( ptInt, ptLast) ;
Point3d ptIn1 = ptInt + Y_AX * dCornR ;
Point3d ptIn2 = ptInt - X_AX * dCornR ;
double dTrim1, dTrim2 ;
PtrOwner< ICurveArc> pArc( CreateFillet( cLine1, ptIn1, cLine2, ptIn2, Z_AX, dCornR, dTrim1, dTrim2)) ;
if ( IsNull( pArc))
return false ;
cLine1.TrimEndAtParam( abs( dTrim1)) ;
cLine2.TrimStartAtParam( abs( dTrim2)) ;
Point3d pt3, pt4 ;
cLine1.GetEndPoint( pt3) ;
cLine2.GetStartPoint( pt4) ;
Point3d ptC = pArc->GetCenter() ;
CurveArc cvArc ;
cvArc.SetC2P( ptC, pt3, pt4) ;
m_Outline.AddCurve( LineSt) ;
m_Outline.AddLine( pt2);
m_Outline.AddLine( pt3);
m_Outline.AddCurve( cvArc) ;
m_Outline.AddLine( ptLast) ;
}
else {
if ( m_dTipRadius < m_dRCorner)
return false ;
CurveLine LineSt ;
LineSt.Set( pt0, pt1) ;
Point3d ptC( dTipR - dCornR, - dH + dCornR, 0) ;
CurveArc cvCirc ;
cvCirc.SetXY( ptC, dCornR) ;
Point3d ptNear( ptC.x + dCornR, ptC.y + dCornR, 0) ;
PtrOwner<ICurveLine> pLine( GetLinePointTgCurve( pt2, cvCirc, ptNear)) ;
if ( IsNull( pLine))
return false ;
Point3d pt3 ;
pLine->GetEndPoint( pt3) ;
Point3d pt4( ptC.x, - dH, 0) ;
CurveArc cvArc ;
cvArc.SetC2P( ptC, pt3, pt4) ;
Point3d pt5( 0, - dH, 0) ;
m_Outline.AddCurve( LineSt) ;
m_Outline.AddLine( pt2);
m_Outline.AddLine( pt3);
m_Outline.AddCurve( cvArc) ;
m_Outline.AddLine( pt5) ;
}
return SetGenTool( sToolName, &m_Outline, nToolNum) ;
}
//----------------------------------------------------------------------------
bool
Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, int nToolNum)
{
// Assegno nome, tipo e id dell'utensile
m_sName = sToolName ;
m_nType = UNDEF ;
m_nCurrentNum = nToolNum ;
// 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 ;
// Flag di avvenuta approssimazione
bool bApprox = false ;
// Ciclo sulle curve componenti
const ICurve* pCurve = m_Outline.GetFirstCurve() ;
while ( pCurve != nullptr) {
// Se la curva è un arco verifico se approssimarlo
if ( 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() ; ++ 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 ;
plyApprox.GetFirstPoint( ptEnd) ;
while ( plyApprox.GetNextPoint( ptEnd)) {
m_ArcLineApprox.AddLine( ptEnd) ;
}
bApprox = true ;
}
// altrimenti lo aggiungo semplicemente
else
m_ArcLineApprox.AddCurve( *pCurve, true) ;
}
// altrimenti è segmento e lo aggiungo semplicemente
else
m_ArcLineApprox.AddCurve( *pCurve, true) ;
pCurve = m_Outline.GetNextCurve() ;
}
// Se non ci sono state approssimazioni, cancello la curva approssimante
if ( ! bApprox)
m_ArcLineApprox.Clear() ;
m_nType = GEN ;
// Il profilo dell'utensile deve stare nel 4° quadrante del piano XY
BBox3d Bounding ;
m_Outline.GetLocalBBox( Bounding) ;
if ( Bounding.GetMin().x < - 10 * EPS_SMALL || Bounding.GetMax().y > 10 * EPS_SMALL)
return false ;
// Assegno le dimensioni dell'utensile
m_dHeight = - Bounding.GetMin().y ;
m_dRadius = Bounding.GetMax().x ;
return true ;
}
//----------------------------------------------------------------------------
bool
Tool::SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum)
{
// Setto il nome e il numero dell'utensile
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
// Imposto a indefinito il tipo
m_nType = UNDEF ;
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)
{
// Setto il nome e il numero dell'utensile
m_sName = sToolName ;
m_nCurrentNum = nToolNum ;
// Imposto a indefinito il tipo
m_nType = UNDEF ;
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 ;
}