Files
EgtGeomKernel/VolZmapTool.cpp
T
Dario Sassi 17425bc753 EgtGeomKernel 1.8f1 :
- modifiche a Zmap per salvataggio/lettura e altro con nuova struttura a blocchi.
2017-06-05 07:20:45 +00:00

354 lines
11 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2016
//----------------------------------------------------------------------------
// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
// Contenuto : Implementazione della classe Volume Zmap (utensili)
//
//
//
// Modifiche : 22.01.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveLine.h"
#include "CurveArc.h"
#include "VolZmap.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGKLinePntTgCurve.h"
#include "/EgtDev/Include/EGKFilletChamfer.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 ;
// Aggiorno il numero dell'utensile corrente
m_nCurrentToolNum = 0 ;
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 || abs( dTipR - dR) < EPS_SMALL)
return SetStdTool( sToolName, dH, dR, dCornR) ;
// caso avanzato
else {
m_dHeight = dH ;
m_dRadius = dR ;
m_dTipHeight = dTipH ;
m_dTipRadius = max( dTipR, 0.) ;
if ( dCornR < EPS_SMALL) {
m_nToolType = ConusMill ;
m_dRCorner = 0 ;
}
// Se il raggio corner è non nullo
// l'utensile viene descritto da
// come utensile generico.
else {
m_dRCorner = dCornR ;
m_nToolType = GenericTool ;
// 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) ;
if ( m_dTipRadius < m_dRadius) {
Point3d ptInt( dTipR, - dH, 0) ;
Point3d ptLast( 0, - dH, 0) ;
CurveLine cLine1 ; cLine1.Set( pt2, ptInt) ;
CurveLine cLine2 ; cLine2.Set( ptInt, ptLast) ;
double dTrim1, dTrim2 ;
Point3d ptIn1 = ptInt + Y_AX * dCornR ;
Point3d ptIn2 = ptInt - X_AX * dCornR ;
ICurveArc* pArc = CreateFillet( cLine1, ptIn1, cLine2, ptIn2, Z_AX, dCornR, dTrim1, dTrim2) ;
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_ToolOutline.Clear() ;
CurveLine LineSt ; LineSt.Set( pt0, pt1) ;
m_ToolOutline.AddCurve( LineSt) ;
m_ToolOutline.AddLine( pt2);
m_ToolOutline.AddLine( pt3);
m_ToolOutline.AddCurve( cvArc) ;
m_ToolOutline.AddLine( ptLast) ;
}
else {
if ( dTipR - dCornR < 0)
return false ;
Point3d ptC( dTipR - dCornR, - dH + dCornR, 0) ;
CurveArc cvCirc ; cvCirc.SetXY( ptC, dCornR) ;
Point3d ptNear( ptC.x + dCornR, ptC.y + dCornR, 0) ;
ICurveLine* pLine = GetLinePointTgCurve( pt2, cvCirc, ptNear) ;
Point3d pt3 ;
pLine -> GetEndPoint( pt3) ;
Point3d pt4( ptC.x, - dH, 0) ;
CurveArc cvArc ; cvArc.SetC2P( ptC, pt3, pt4) ;
Point3d pt5( 0, - dH, 0) ;
m_ToolOutline.Clear() ;
CurveLine Line ; Line.Set( pt0, pt1) ;
m_ToolOutline.AddCurve( Line) ;
m_ToolOutline.AddLine( pt2);
m_ToolOutline.AddLine( pt3);
m_ToolOutline.AddCurve( cvArc) ;
m_ToolOutline.AddLine( pt5) ;
}
return SetGenTool( sToolName, &m_ToolOutline) ;
}
}
// assegno il nome
m_sToolName = sToolName ;
// Aggiorno il numero dell'utensile corrente
m_nCurrentToolNum = 0 ;
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 ;
// Aggiorno il numero dell'utensile corrente
m_nCurrentToolNum = 0 ;
// 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 se 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 ;
}