52a09392c1
- modifiche e correzioni varie sugli Zmap.
261 lines
8.6 KiB
C++
261 lines
8.6 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2016
|
|
//----------------------------------------------------------------------------
|
|
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
|
|
// Contenuto : Implementazione della classe Volume Zmap (singola griglia)
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 22.01.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "CurveLine.h"
|
|
#include "CurveArc.h"
|
|
#include "VolZmap.h"
|
|
#include "GeoConst.h"
|
|
|
|
using namespace std ;
|
|
|
|
//---------- Tolleranza nell'approssimazione di curve profilo ----------------
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SetTolerances( double dLinTol, double dAngTolDeg)
|
|
{
|
|
m_dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
|
m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR)
|
|
{
|
|
// reset nome
|
|
m_sToolName.clear() ;
|
|
// verifica minime dimensioni globali
|
|
if ( dH < EPS_SMALL || dR < EPS_SMALL)
|
|
return false ;
|
|
// utensile cilindrico
|
|
if ( dCornR < EPS_SMALL) {
|
|
m_nToolType = CylindricalMill ;
|
|
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_nToolType = BullNoseMill ;
|
|
m_dHeight = dH ;
|
|
m_dRadius = dR ;
|
|
m_dTipHeight = dCornR ;
|
|
m_dTipRadius = dR - dCornR ;
|
|
m_dRCorner = dCornR ;
|
|
// come profilo
|
|
m_nToolType = GenericTool ;
|
|
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_ToolOutline.Clear() ;
|
|
CurveLine Line ;
|
|
Line.Set( pt0, pt1) ;
|
|
m_ToolOutline.AddCurve( Line) ;
|
|
m_ToolOutline.AddLine( pt2);
|
|
m_ToolOutline.AddArcTg( pt3) ;
|
|
m_ToolOutline.AddLine( pt4) ;
|
|
return SetGenTool( sToolName, &m_ToolOutline) ;
|
|
}
|
|
// utensile sferico
|
|
else if ( dCornR < dR + EPS_SMALL) {
|
|
m_nToolType = BallEndMill ;
|
|
m_dHeight = dH ;
|
|
m_dRadius = dR ;
|
|
m_dTipHeight = m_dRadius ;
|
|
m_dTipRadius = 0 ;
|
|
m_dRCorner = m_dRadius ;
|
|
}
|
|
// impossibile
|
|
else
|
|
return false ;
|
|
// assegno il nome
|
|
m_sToolName = sToolName ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SetAdvTool( const string& sToolName, double dH, double dR,
|
|
double dTipH, double dTipR, double dCornR)
|
|
{
|
|
// reset nome
|
|
m_sToolName.clear() ;
|
|
// verifica dimensioni globali
|
|
if ( dH < EPS_SMALL || dR < EPS_SMALL)
|
|
return false ;
|
|
// se altezza punta nulla, ricado nel caso standard
|
|
if ( dTipH < EPS_SMALL)
|
|
return SetStdTool( sToolName, dH, dR, dCornR) ;
|
|
// caso avanzato
|
|
if ( abs( dTipR - dR) < EPS_SMALL) {
|
|
m_nToolType = CylindricalMill ;
|
|
m_dHeight = dH ;
|
|
m_dRadius = dR ;
|
|
m_dTipHeight = 0 ;
|
|
m_dTipRadius = m_dRadius ;
|
|
m_dRCorner = 0 ;
|
|
}
|
|
else {
|
|
m_nToolType = ConusMill ;
|
|
m_dHeight = dH ;
|
|
m_dRadius = dR ;
|
|
m_dTipHeight = dTipH ;
|
|
m_dTipRadius = max( dTipR, 0.) ;
|
|
m_dRCorner = dCornR ;
|
|
}
|
|
// assegno il nome
|
|
m_sToolName = sToolName ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline)
|
|
{
|
|
// Aggiorno il nome dell'utensile
|
|
m_sToolName = sToolName ;
|
|
|
|
// Aggiorno il tipo di utensile
|
|
m_nToolType = GenericTool ;
|
|
|
|
// Copio il profilo
|
|
m_ToolOutline.CopyFrom( pToolOutline) ;
|
|
|
|
// Se ci fosse una Bézier la convertiamo in archi e rette
|
|
m_ToolOutline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg) ;
|
|
|
|
// Puntatore a curva costante
|
|
const ICurve* pCurve = m_ToolOutline.GetFirstCurve() ;
|
|
|
|
// Ciclo sulle curve componenti
|
|
while ( pCurve != nullptr) {
|
|
|
|
// Se la curva è un arco valuto approssimarlo
|
|
if ( pCurve->GetType() == CRV_ARC) {
|
|
|
|
// Centro e punti iniziale e finale dell'arco
|
|
Point3d ptStart, ptEnd, ptO ;
|
|
|
|
pCurve->GetStartPoint( ptStart) ;
|
|
pCurve->GetEndPoint( ptEnd) ;
|
|
pCurve->GetCenterPoint( ptO) ;
|
|
|
|
// Vettore congiungente il centro con i punti iniziale e finale
|
|
Vector3d vtStRad = ptStart - ptO ;
|
|
Vector3d vtEnRad = ptEnd - ptO ;
|
|
|
|
// Calcolo del raggio dell'arco
|
|
double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ;
|
|
|
|
// Recupero la curva precedente e quella successiva
|
|
const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ;
|
|
const ICurve* pNext = m_ToolOutline.GetNextCurve() ;
|
|
pNext = m_ToolOutline.GetNextCurve() ;
|
|
|
|
// Valuto la necessità di approssimare l'arco o meno
|
|
|
|
// Punto Iniziale della curva precedente e finale della successiva
|
|
Point3d ptStartPrev, ptEndNext ;
|
|
|
|
// Vettori tangenti alle curve precedente corrente e successiva
|
|
// rispettivamente nei punti finale, iniziale e finale e iniziale
|
|
// e prodotti vettore fra i suddetti
|
|
Vector3d vtPrevEndDir, vtCurrentStartDir, vtCurrentEndDir, vtNextStartDir ;
|
|
Vector3d vtIProd, vtFProd ;
|
|
|
|
Point3d ptTopCurrent = ptO + Y_AX * dRadius ;
|
|
Point3d ptBottomCurrent = ptO - Y_AX * dRadius ;
|
|
|
|
// Valuto le relazioni geometriche fra la
|
|
// curva corrente e quella precedente.
|
|
pPrev->GetStartPoint( ptStartPrev) ;
|
|
pPrev->GetEndDir( vtPrevEndDir) ;
|
|
pCurve->GetStartDir( vtCurrentStartDir) ;
|
|
vtIProd = vtPrevEndDir ^ vtCurrentStartDir ;
|
|
|
|
// Se la curva successiva esiste valuto le
|
|
// medesime relazioni con la quest'ultima
|
|
if ( pNext != nullptr) {
|
|
|
|
pNext->GetEndPoint( ptEndNext) ;
|
|
pCurve->GetEndDir( vtCurrentEndDir) ;
|
|
pNext->GetStartDir( vtNextStartDir) ;
|
|
vtFProd = vtCurrentEndDir ^ vtNextStartDir ;
|
|
}
|
|
|
|
// Se devo approssimare
|
|
if ( ! ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptStartPrev.y > ptTopCurrent.y) &&
|
|
( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) ||
|
|
( pNext != nullptr && vtFProd.z > 0 && ptBottomCurrent.y > ptEndNext.y)))) {
|
|
|
|
// Copio la parte precedente
|
|
const ICurve* pAux = m_ToolOutline.GetFirstCurve() ;
|
|
|
|
while ( pAux != pCurve) {
|
|
|
|
m_ToolArcLineApprox.AddCurve( * pAux, true) ;
|
|
|
|
pAux = m_ToolOutline.GetNextCurve() ;
|
|
}
|
|
|
|
// Creo la polyline approssimante
|
|
PolyLine Polygonal ;
|
|
|
|
pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, 10, Polygonal) ;
|
|
|
|
// Definisco una curva composita a partire dalla polyline
|
|
CurveComposite cvTemp ; cvTemp.FromPolyLine( Polygonal) ;
|
|
|
|
// Aggiungo la parte approssimata
|
|
pAux = cvTemp.GetFirstCurve() ;
|
|
|
|
while ( pAux != nullptr) {
|
|
|
|
m_ToolArcLineApprox.AddCurve( * pAux, true) ;
|
|
|
|
pAux = cvTemp.GetNextCurve() ;
|
|
}
|
|
}
|
|
// Se non deve essere approssimato
|
|
else {
|
|
// Se è già stato definito m_ToolArcLineApprox deve
|
|
// essere completo, aggiungo quindi l'arco corrente
|
|
if ( m_ToolArcLineApprox.GetCurveCount() != 0)
|
|
m_ToolArcLineApprox.AddCurve( * pCurve, true) ;
|
|
}
|
|
}
|
|
// Se è segmento
|
|
else {
|
|
// Se è già stato definito m_ToolArcLineApprox deve
|
|
// essere completo, aggiungo quindi il segmento corrente
|
|
if ( m_ToolArcLineApprox.GetCurveCount() != 0)
|
|
m_ToolArcLineApprox.AddCurve( * pCurve, true) ;
|
|
}
|
|
|
|
pCurve = m_ToolOutline.GetNextCurve() ;
|
|
}
|
|
|
|
// Dimensioni dell'utensile
|
|
BBox3d Bounding ;
|
|
m_ToolOutline.GetLocalBBox( Bounding) ;
|
|
double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ;
|
|
double m_dRadius = Bounding.GetMax().x - Bounding.GetMin().x ;
|
|
|
|
return true ;
|
|
} |