Merge commit '3d31988979706c38178e8b31bf5cb52ef9576861'

This commit is contained in:
Dario Sassi
2025-07-02 17:23:10 +02:00
3 changed files with 286 additions and 222 deletions
+253 -215
View File
@@ -2537,7 +2537,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons
bool
SurfFinishing::GetZConstQuotesInsideSfrParallelToTool( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfr, const Vector3d& vtTool,
set<double>& setZAmbiguos)
set<double>& setZAmbiguos) const
{
// controllo dei parametri
setZAmbiguos.clear() ;
@@ -2660,7 +2660,7 @@ SurfFinishing::GetSfrSilhouette( const SURFLOCALVECTOR& vSrfLoc, const Frame3d&
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfrClass, const Vector3d& vtTool, double dDepth, vector<ICRVCOMPOPOVECTOR>& vCrvCompo)
const ISurfFlatRegion* pSfrClass, const Vector3d& vtTool, double dDepth, vector<ICRVCOMPOPOVECTOR>& vCrvCompo) const
{
/* funzione per calcolare le curve singole di finitura mediante Silhouette e le regioni da non rovinare */
@@ -2818,7 +2818,7 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU
bool
SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
vector<ICRVCOMPOPOVECTOR>& vCrvCompo, const Vector3d& vtTool, const ISurfFlatRegion* pSfr,
double dDepth, ICRVCOMPOPOVECTOR& vCrvPath)
double dDepth, ICRVCOMPOPOVECTOR& vCrvPath) const
{
/* funzione per collegare le curve trovate creando quindi i percorsi di lavoro */
// NB. La prima tempProp della curva è il piano in cui iniziale e la seconda tempProp è
@@ -3106,7 +3106,7 @@ bool
SurfFinishing::CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
const Point3d ptStart_forced, const Point3d ptEnd_forced,
ICurveComposite* pCrv)
ICurveComposite* pCrv) const
{
// funzione per proiettare una curva su una supericie trimesh passando per la silhouette
// controllo dei parametri
@@ -4037,21 +4037,21 @@ SurfFinishing::ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQp
// C0 - E0 - C1
static int LineTable[16][4] = { { 0, -1, -1, -1}, // ( 0)
{ 2, 0, 5, 3}, // ( 1)
{ 2, 1, 4, 0}, // ( 2)
{ 1, 1, 3, -1}, // ( 3)
{ 2, 2, 5, 1}, // ( 4)
{ -1, -1, -1, -1}, // ( 5) -> ambiguo
{ 1, 2, 0, -1}, // ( 6)
{ 2, 2, 4, 3}, // ( 7)
{ 2, 3, 4, 2}, // ( 8)
{ 1, 0, 2, -1}, // ( 9)
{ -1, -1, -1, -1}, // ( 10) -> ambiguo
{ 2, 1, 5, 2}, // ( 11)
{ 1, 3, 1, -1}, // ( 12)
{ 2, 0, 4, 1}, // ( 13)
{ 2, 3, 5, 0}, // ( 14)
{ 0, -1, -1, -1} } ; // ( 15)
{ 2, 0, 5, 3}, // ( 1)
{ 2, 1, 4, 0}, // ( 2)
{ 1, 1, 3, -1}, // ( 3)
{ 2, 2, 5, 1}, // ( 4)
{ -1, -1, -1, -1}, // ( 5) -> ambiguo
{ 1, 2, 0, -1}, // ( 6)
{ 2, 2, 4, 3}, // ( 7)
{ 2, 3, 4, 2}, // ( 8)
{ 1, 0, 2, -1}, // ( 9)
{ -1, -1, -1, -1}, // ( 10) -> ambiguo
{ 2, 1, 5, 2}, // ( 11)
{ 1, 3, 1, -1}, // ( 12)
{ 2, 0, 4, 1}, // ( 13)
{ 2, 3, 5, 0}, // ( 14)
{ 0, -1, -1, -1} } ; // ( 15)
static int LineTableAmbiguos[4][5] = { { 2, 2, 1, 0, 3}, // ( 5-split)
{ 2, 2, 3, 0, 1}, // ( 5-stick)
{ 2, 1, 0, 3, 2}, // ( 10-split)
@@ -4124,7 +4124,7 @@ SurfFinishing::TestSubEdges( unordered_map<int, Point3d>& umEdgePnt, const INTVE
vtAxL, vtMoveL, dCosSplitAng, pCAvTlStm, _nInd_debug) ;
if ( ! ptQ.IsValid())
return false ;
umEdgePnt[ nKey] = ptQ ;
umEdgePnt[nKey] = ptQ ;
}
return true ;
}
@@ -4182,28 +4182,28 @@ SurfFinishing::MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, d
if ( bUp0 != bUp1) {
int nKey = 4 * nInd0 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
if ( bUp3 != bUp2) {
int nKey = 4 * nInd3 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
if ( bUp0 != bUp3) {
int nKey = 4 * nInd0 + 1 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
if ( bUp1 != bUp2) {
int nKey = 4 * nInd1 + 1 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
@@ -4216,14 +4216,14 @@ SurfFinishing::MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, d
if ( bUp1 != bUp3) {
int nKey = 4 * nInd0 + 2 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
if ( bUp0 != bUp2) {
int nKey = 4 * nInd0 + 3 ;
if ( umEdgePnt.find( nKey) == umEdgePnt.end()) {
umEdgePnt[ nKey] = P_INVALID ;
umEdgePnt[nKey] = P_INVALID ;
vEdgeInd.emplace_back( nKey) ;
}
}
@@ -4351,14 +4351,23 @@ SurfFinishing::MarchingSquares( const VECTORCOLLISIONSFR& vPntM, bool bSpiral, d
const double SILH_ARC_TOL = 0.1 ;
const double SILH_ARC_FEA_MAX = 100. ;
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
#if ENABLE_OPTIMAL_DEBUG
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _nInd_debug, vCrvCompo[i]->Clone()) ;
m_pGeomDB->SetMaterial( a, WHITE) ;
#endif
PolyArc PA ;
if ( vCrvCompo[i]->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) {
PtrOwner<ICurveComposite> pTempCrv( CreateCurveComposite()) ;
if ( ! IsNull( pTempCrv) &&
pTempCrv->FromPolyArc( PA) &&
pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) &&
pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG))
pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG)) {
vCrvCompo[i].Set( pTempCrv) ;
#if ENABLE_OPTIMAL_DEBUG
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, _nInd_debug, vCrvCompo[i]->Clone()) ;
m_pGeomDB->SetMaterial( a, PURPLE) ;
#endif
}
}
}
@@ -4392,8 +4401,25 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR&
double dCosClipping = cos( dSplitAngle * DEGTORAD) ;
// costanti
const double TOL_SAMPLE = 2. ; // Tolleranza di campionamento per collisioni
const double EXTRA_XY = 2.5 * TOL_SAMPLE ; // Espansione del Box in X e Y per griglia di campionamento
const double TOL_SAMPLE = 2. ;
double dExtraXY = 0. ;
if ( m_TParams.m_dSideAng < EPS_ANG_SMALL)
dExtraXY += m_TParams.m_dDiam / 2. ;
else {
double dDeltaRad ;
double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ;
if ( m_TParams.m_dSideAng > 0) {
if ( m_TParams.m_dCornRad < EPS_SMALL)
dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ;
else
dDeltaRad = ( m_TParams.m_dCornRad * cos( dSideAngRad) +
( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad)) ;
}
else
dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ;
dExtraXY += m_TParams.m_dDiam / 2. + dDeltaRad ;
}
const double EXTRA_XY = dExtraXY + 2.5 * TOL_SAMPLE ;
// frame pianoXY
Frame3d frXY ;
@@ -4468,6 +4494,7 @@ SurfFinishing::GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR&
}
get<2>( vCollision[nInd].CollisionInfo).push_back( get<2>( vPntM[nInd])[nV]) ;
}
#if ENABLE_OPTIMAL_DEBUG
PtrOwner<IGeoPoint3d> pt( CreateGeoPoint3d()) ;
pt->Set( get<0>( vCollision[nInd].CollisionInfo)) ;
@@ -4573,7 +4600,7 @@ SurfFinishing::OrderAndConnectPencilCurves( ICRVCOMPOPOVECTOR& vCrvCompo, double
}
}
// se ho meno di 2 curve da ordinare, non faccio nulla
if ( int( vCrvCompo.size() < 2))
if ( int( vCrvCompo.size()) < 2)
return true ;
// vettore dei quadrati delle distanze
@@ -5356,6 +5383,192 @@ SurfFinishing::AddPencil( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcOptimalSpiralCurves( const ISurfFlatRegion* pSfrSpiral, const ISurfFlatRegion* pSfrCnt,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const
{
// se la superficie non è valida, non restituisco nulla
if ( pSfrSpiral == nullptr || ! pSfrSpiral->IsValid())
return true ;
// le curve di finitura spiral devono stare sul bordo della regione trovata
PtrOwner<ISurfFlatRegion> pMySfrSpiral( pSfrSpiral->CreateOffsetSurf( m_Params.m_dSideStep, ICurve::OFF_FILLET)) ;
if ( IsNull( pMySfrSpiral))
return false ;
// mi assicuro di non uscire dalla superficie originale
double dOffs = - m_TParams.m_dDiam / 2. - GetOffsR() + m_Params.m_dOverlap + 5 * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrClass( pSfrCnt->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrClass))
return false ;
if ( pSfrClass->IsValid()) {
pSfrClass->ToLoc( frSurf) ;
pMySfrSpiral->Intersect( *pSfrClass) ;
}
else
pMySfrSpiral->Clear() ;
// se regione risultante non valida, non faccio nulla
if ( ! pMySfrSpiral->IsValid())
return true ;
// imposto i lati chiusi
for ( int nC = 0 ; nC < pMySfrSpiral->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pMySfrSpiral->GetLoopCount( nC) ; ++ nL) {
for ( int nU = 0 ; nU < pMySfrSpiral->GetLoopCurveCount( nC, nL) ; ++ nU)
pMySfrSpiral->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
}
}
// eseguo calcolo delle lavorazioni come SpiralIN
ICRVCOMPOPOVECTOR vpCrvs ;
if ( ! CalcPocketing( pMySfrSpiral, 0., 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
POCKET_SPIRALIN, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
m_Params.m_dLiTang, GetLeadInType(), vpCrvs)) {
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
return false ;
}
// ciclo sui percorsi ricavati risultanti
double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ;
for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) {
// definisco un nuovo percorso (in locale)
vPaths.resize( vPaths.size() + 1) ;
vPaths.back().pCrvPath.Set( Release( vpCrvs[k])) ;
vPaths.back().nType = SURFFIN_SUB_SPIRALIN ;
// li correggo per non interferire con le superfici
if ( pCAvTlStm != nullptr) {
// approssimo la curva con una polilinea
PolyLine PL ;
if ( ! vPaths.back().pCrvPath->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return false ;
// eventuale aggiunta di punti per garantire max distanza
const double MIN_DIST = 1. ;
const double MAX_DIST = 50. ;
double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ;
if ( ! PL.AdjustForMaxSegmentLen( dDist))
return false ;
// porto i dati geometrici in locale alle superfici
Vector3d vtAxL = vtTool ;
vtAxL.ToLoc( frSurf) ;
Vector3d vtMoveL = vtAxL ;
// traslo della lunghezza utensile diminuita dell'affondamento
PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ;
// eseguo CAv
if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff))
return false ;
// contro-traslo della lunghezza utensile
PL.Translate( - vtAxL * m_TParams.m_dLen) ;
// elimino i punti allineati
PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ;
// creo una curva composita a partire dalla polilinea
PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL))
return false ;
// sostituisco la vecchia curva con la nuova
vPaths.back().pCrvPath.Set( pCompo) ;
}
}
// porto tutti i percorsi nel frame globale
for ( int i = 0 ; i < int( vPaths.size()) ; ++ i)
vPaths[i].pCrvPath->ToGlob( frSurf) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrZConst, const ISurfFlatRegion* pSfrCnt,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
const SURFLOCALVECTOR& vSrfLoc, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const
{
// se la superficie non è valida, non restituisco nulla
if ( pSfrZConst == nullptr || ! pSfrZConst->IsValid())
return true ;
// mi assicuro di non uscire dalla superficie originale
PtrOwner<ISurfFlatRegion> pMySfrZConst( pSfrZConst->CreateOffsetSurf( m_Params.m_dSideStep, ICurve::OFF_FILLET)) ;
if ( IsNull( pMySfrZConst))
return false ;
double dOffs = - m_TParams.m_dDiam / 2. - GetOffsR() + m_Params.m_dOverlap + 5 * EPS_SMALL ;
PtrOwner<ISurfFlatRegion> pSfrClass( pSfrCnt->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrClass))
return false ;
if ( pSfrClass->IsValid()) {
pSfrClass->ToLoc( frSurf) ;
pMySfrZConst->Intersect( *pSfrClass) ;
}
else
pMySfrZConst->Clear() ;
// se regione risultante non valida, non faccio nulla
if ( ! pMySfrZConst->IsValid())
return true ;
// imposto i lati chiusi
for ( int nC = 0 ; nC < pMySfrZConst->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pMySfrZConst->GetLoopCount( nC) ; ++ nL) {
for ( int nU = 0 ; nU < pMySfrZConst->GetLoopCurveCount( nC, nL) ; ++ nU)
pMySfrZConst->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
}
}
// inizializzo la classe di calcolo delle silhouette
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSrfLoc.size()) ;
// scorro le superfici
for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) {
// recupero la superficie TriMesh e se valida la memorizzo
const ISurfTriMesh* pStm = GetSurfTriMesh( vSrfLoc[i].Get()) ;
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
vpStm.emplace_back( pStm) ;
}
// definisco il frame della regione piana
Frame3d frSfr ;
Point3d ptC ; pSfrZConst->GetCentroid( ptC) ;
if ( ! frSfr.Set( ptC, pSfrZConst->GetNormVersor()))
return false ;
// inizializzo classe di calcolo per le curve a ZConst
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCavParSilh) ||
! pCavParSilh->SetData( vpStm, frSfr, SILH_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam,
m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), dDepth))
return false ;
// recupero le curve singole definite dal bordo della Silhouette
vector<ICRVCOMPOPOVECTOR> vCrvCompo ;
if ( ! CalcZConstSilCrv( pCavParSilh, vSrfLoc, frSurf, pMySfrZConst, vtTool, dDepth, vCrvCompo)) {
m_pMchMgr->SetLastError( 3126, "Error in SurfFinishing : Computing ZConst Curves failed") ;
return false ;
}
// se non ho ricato curve, non faccio nulla
if ( vCrvCompo.empty())
return true ;
// collego tra loro le curve trovate
ICRVCOMPOPOVECTOR vCrv ;
if ( ! CreateZConstPaths( pCAvTlStm, frSurf, vCrvCompo, vtTool, pMySfrZConst, dDepth, vCrv)) {
m_pMchMgr->SetLastError( 3127, "Error in SurfFinishing : Computing ZConst Paths failed") ;
return false ;
}
// aggiungo i percorsi trovati
for ( int i = 0 ; i < int( vCrv.size()) ; ++ i) {
vPaths.resize( vPaths.size() + 1) ;
vPaths.back().pCrvPath.Set( Release( vCrv[i])) ;
vPaths.back().nType = SURFFIN_SUB_Z_CONST ;
// in globale
vPaths.back().pCrvPath->ToGlob( frSurf) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr,
@@ -5389,204 +5602,29 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
return false ;
}
// ----------------------- Lavorazione Spiral -------------------------------
if ( ! IsNull( pSfrSpiral) && pSfrSpiral->IsValid()) {
// se richiesto parametro SkipMaxDown, devo limitare questa superficie alla vera Silhouette
bool bSkipMaxDown = true ;
GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ;
PtrOwner<ISurfFlatRegion> pSfrSil_real( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrSil_real))
return false ;
if ( bSkipMaxDown) {
Frame3d frSfr ;
Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ;
if ( ! frSfr.Set( ptCenter, pSfr->GetNormVersor()))
return false ;
Frame3d frLvl0 = GetToLoc( frSfr, frSurf) ;
// riduco la regione sulla Silhouette corretta
pSfrSil_real.Set( GetSfrSilhouette( vSrfLoc, frLvl0, - dDepth)) ;
if ( IsNull( pSfrSil_real) || ! pSfrSil_real->IsValid()) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// intersezione
pSfrSil_real->Offset( - m_Params.m_dSideStep + 10 * EPS_SMALL, ICurve::OFF_FILLET) ;
if ( ! IsNull( pSfrSil_real) && pSfrSil_real->IsValid()) {
pSfrSil_real->Translate( dDepth * frLvl0.VersZ()) ;
if ( ! pSfrSpiral->Intersect( *pSfrSil_real))
return false ;
}
}
// le curve di finitura spiral devono stare sul bordo della regione trovata
pSfrSpiral->Offset( m_Params.m_dSideStep, ICurve::OFF_FILLET) ;
// mi assicuro di non uscire dalla superficie originale
PtrOwner<ISurfFlatRegion> pSfrOverlap( pSfr->CreateOffsetSurf( m_Params.m_dOverlap, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrOverlap))
return false ;
if ( ! IsNull( pSfrOverlap) && pSfrOverlap->IsValid()) {
pSfrOverlap->ToLoc( frSurf) ;
pSfrSpiral->Intersect( *pSfrOverlap) ;
}
else
pSfrSpiral->Clear() ;
if ( ! IsNull( pSfrSpiral) && pSfrSpiral->IsValid()) {
// imposto i lati chiusi
for ( int nCC = 0 ; nCC < pSfrSpiral->GetChunkCount() ; ++ nCC) {
for ( int nL = 0 ; nL < pSfrSpiral->GetLoopCount( nCC) ; ++ nL) {
for ( int nU = 0 ; nU < pSfrSpiral->GetLoopCurveCount( nCC, nL) ; ++ nU)
pSfrSpiral->SetCurveTempProp( nCC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
}
}
// lavorazione Spiral
ICRVCOMPOPOVECTOR vpCrvs ;
if ( ! CalcPocketing( pSfrSpiral, m_Params.m_dSideStep, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle, 5.,
POCKET_SPIRALIN, false, false, true, false, false, P_INVALID, nullptr, true, m_Params.m_dSideStep,
m_Params.m_dLiTang, GetLeadInType(), vpCrvs)) {
m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ;
return false ;
}
// ciclo sui percorsi ricavati risultanti
double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ;
for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) {
// definisco un nuovo percorso (in locale)
vPaths.resize( vPaths.size() + 1) ;
vPaths.back().pCrvPath.Set( Release( vpCrvs[k])) ;
vPaths.back().nType = SURFFIN_SUB_SPIRALIN ;
// li correggo per non interferire con le superfici
if ( pCAvTlStm != nullptr) {
// approssimo la curva con una polilinea
PolyLine PL ;
if ( ! vPaths.back().pCrvPath->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
return false ;
// eventuale aggiunta di punti per garantire max distanza
const double MIN_DIST = 1. ;
const double MAX_DIST = 50. ;
double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ;
if ( ! PL.AdjustForMaxSegmentLen( dDist))
return false ;
// porto i dati geometrici in locale alle superfici
Vector3d vtAxL = vtTool ;
vtAxL.ToLoc( frSurf) ;
Vector3d vtMoveL = vtAxL ;
// traslo della lunghezza utensile diminuita dell'affondamento
PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ;
// eseguo CAv
if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff))
return false ;
// contro-traslo della lunghezza utensile
PL.Translate( - vtAxL * m_TParams.m_dLen) ;
// elimino i punti allineati
PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ;
// creo una curva composita a partire dalla polilinea
PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL))
return false ;
// sostituisco la vecchia curva con la nuova
vPaths.back().pCrvPath.Set( pCompo) ;
}
}
}
// porto tutti i percorsi nel frame globale
for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) {
#if ENABLE_OPTIMAL_SOFT_DEBUG
int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ;
m_pGeomDB->SetMaterial( _n, RED) ;
#endif
vPaths[i].pCrvPath->ToGlob( frSurf) ;
}
// recupero le curve dalla regione Spiral
if ( ! CalcOptimalSpiralCurves( pSfrSpiral, pSfr, frSurf, vtTool, dDepth, pCAvTlStm, vPaths)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// aggiorno la ProgressBar al 60%
ExeProcessEvents( 60, 0) ;
#if ENABLE_OPTIMAL_SOFT_DEBUG
// disegno i percorsi per controllo
int ___a = int( vPaths.size()) ;
for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) {
int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ;
m_pGeomDB->SetMaterial( _n, RED) ;
}
#endif
// ----------------------- Lavorazione Zconst -------------------------------
if ( ! IsNull( pSfrZConst) && pSfrZConst->IsValid()) {
// mi assicuro di non uscire dalla superficie originale
PtrOwner<ISurfFlatRegion> pSfrOverlap( pSfr->CreateOffsetSurf( m_Params.m_dOverlap + GetOffsR(), ICurve::OFF_FILLET)) ;
if ( ! IsNull( pSfrOverlap) && pSfrOverlap->IsValid()) {
if ( ! pSfrOverlap->ToLoc( frSurf) || ! pSfrZConst->Intersect( *pSfrOverlap))
return false ;
// imposto i lati chiusi
for ( int nC = 0 ; nC < pSfrZConst->GetChunkCount() ; ++ nC) {
for ( int nL = 0 ; nL < pSfrZConst->GetLoopCount( nC) ; ++ nL) {
for ( int nU = 0 ; nU < pSfrZConst->GetLoopCurveCount( nC, nL) ; ++ nU)
pSfrZConst->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ;
}
}
// inizializzo la classe di calcolo delle silhouette
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSrfLoc.size()) ;
// scorro le superfici
for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) {
// recupero la superficie TriMesh e se valida la memorizzo
const ISurfTriMesh* pStm = GetSurfTriMesh( vSrfLoc[i].Get()) ;
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
vpStm.emplace_back( pStm) ;
}
// definisco il frame della regione piana
Frame3d frSfr ;
Point3d ptC ; pSfrZConst->GetCentroid( ptC) ;
if ( ! frSfr.Set( ptC, pSfrZConst->GetNormVersor()))
return false ;
// inizializzo classe di calcolo per le curve a ZConst
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCavParSilh) ||
! pCavParSilh->SetData( vpStm, frSfr, SILH_SAMPLING, m_TParams.m_dSideAng, m_TParams.m_dDiam,
m_TParams.m_dCornRad, m_TParams.m_dMaxMat, GetOffsR(), dDepth))
return false ;
// recupero le curve singole definite dal bordo della Silhouette
vector<ICRVCOMPOPOVECTOR> vCrvCompo ;
if ( ! CalcZConstSilCrv( pCavParSilh, vSrfLoc, frSurf, pSfrZConst, vtTool, dDepth, vCrvCompo)) {
m_pMchMgr->SetLastError( 3126, "Error in SurfFinishing : Computing ZConst Curves failed") ;
return false ;
}
// se ho delle curve, allora unisco i percorsi trovati
if ( ! vCrvCompo.empty()) {
// collego tra loro le curve trovate
ICRVCOMPOPOVECTOR vCrv ;
if ( ! CreateZConstPaths( pCAvTlStm, frSurf, vCrvCompo, vtTool, pSfrZConst, dDepth, vCrv)) {
m_pMchMgr->SetLastError( 3127, "Error in SurfFinishing : Computing ZConst Paths failed") ;
return false ;
}
// aggiungo i percorsi trovati
for ( int i = 0 ; i < int( vCrv.size()) ; ++ i) {
#if ENABLE_OPTIMAL_SOFT_DEBUG
int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrv[i]->Clone()) ;
m_pGeomDB->SetMaterial( _n, GREEN) ;
#endif
vPaths.resize( vPaths.size() + 1) ;
vPaths.back().pCrvPath.Set( Release( vCrv[i])) ;
vPaths.back().nType = SURFFIN_SUB_ZIGZAG ;
// in globale
vPaths.back().pCrvPath->ToGlob( frSurf) ;
}
}
}
// recupero le curve dalla regione ZConst
if ( ! CalcOptimalZConstCurves( pSfrZConst, pSfr, frSurf, vtTool, dDepth, vSrfLoc, pCAvTlStm, vPaths)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// aggiorno la ProgressBar all' 80%
ExeProcessEvents( 80, 0) ;
#if ENABLE_OPTIMAL_SOFT_DEBUG
// disegno i percorsi per controllo
for ( int i = ___a ; i < int( vPaths.size()) ; ++ i) {
int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ;
m_pGeomDB->SetMaterial( _n, GREEN) ;
}
#endif
// ordino i percorsi in base alla Zlocale
if ( ! OrderOptimalPathsByZLoc( pSfr, vPaths))
return false ;
// aggiorno la ProgressBar all' 80%
// aggiorno la ProgressBar al 90%
ExeProcessEvents( 90, 0) ;
// aggiusto la regione a seconda dei parametri
+9 -4
View File
@@ -121,7 +121,7 @@ class SurfFinishing : public Machining
bool CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
const Point3d ptStart_forced, const Point3d ptEnd_forced,
ICurveComposite* pCrv) ;
ICurveComposite* pCrv) const ;
// lavorazioni per superfici
bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ;
@@ -160,18 +160,23 @@ class SurfFinishing : public Machining
const Vector3d& vtTool, double dDepth, double dClippingAngle, double dTolerAngle,
ISURFTMPOVECTOR& vpStm1, ISURFTMPOVECTOR& vpStm2, double& dMaxFrontTriaRad) const ;
bool GetZConstQuotesInsideSfrParallelToTool( const SURFLOCALVECTOR&, const Frame3d& frSurf, const ISurfFlatRegion* pSfr,
const Vector3d& vtTool, std::set<double>& setZAmbiguos) ;
const Vector3d& vtTool, std::set<double>& setZAmbiguos) const ;
ISurfFlatRegion* GetSfrSilhouette( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frLvl0, double dDepth) const ;
ISurfFlatRegion* GetSfrProjectedStmLoops( const ISURFTMPOVECTOR& vStm, const ISurfFlatRegion* pSfrContour,
const DBLVECTOR& vdLinFeaTol, const DBLVECTOR& vdAngTol, const DBLVECTOR& vdMaxLinTol) const ;
ISurfTriMesh* SplitStmTriaUnderClippingAngle( const SurfLocal SrfLoc, const Vector3d& vtTest, double dClippingAngle,
double dFrontTriaTolerAng, double& dMaxFrontTriaRad) const ;
bool CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrZConst, const ISurfFlatRegion* pSfrCnt,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth,
const SURFLOCALVECTOR& vSrfLoc, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
bool CalcOptimalSpiralCurves( const ISurfFlatRegion* pSfrSpiral, const ISurfFlatRegion* pSfrCnt, const Frame3d& frSurf,
const Vector3d& vtTool, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
bool GetOptimalSfr( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfrLoc, const Vector3d& vtTool,
double dDepth, double dElev, ISurfFlatRegion* pSfrSpiral, ISurfFlatRegion* pSfrZConst) const ;
bool CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfrClass, const Vector3d& vtTool, double dDepth, std::vector<ICRVCOMPOPOVECTOR>& vCrvCompo) ;
const ISurfFlatRegion* pSfrClass, const Vector3d& vtTool, double dDepth, std::vector<ICRVCOMPOPOVECTOR>& vCrvCompo) const ;
bool CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, std::vector<ICRVCOMPOPOVECTOR>& vCrvCompo, const Vector3d& vtTool,
const ISurfFlatRegion* pSfr, double dDepth, ICRVCOMPOPOVECTOR& vCrvPath) ;
const ISurfFlatRegion* pSfr, double dDepth, ICRVCOMPOPOVECTOR& vCrvPath) const ;
bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
+24 -3
View File
@@ -2105,10 +2105,13 @@ SurfRoughing::GetStmOutSideSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh*
pStmRaw == nullptr || ! pStmRaw->IsValid())
return nullptr ;
double dTol = 100 * EPS_SMALL ;
// creo una copia della pSfr mediante un piccolo offset correttivo (per problemi con archi)
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfr->CreateOffsetSurf( 100 * EPS_SMALL, ICurve::OFF_FILLET)) ;
PtrOwner<ISurfFlatRegion> pSfrOffs( pSfr->CreateOffsetSurf( dTol, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid())
return nullptr ;
pSfrOffs->Translate( dTol * pSfr->GetNormVersor()) ;
// definisco il vettore delle curve dei bordi della regione
CICURVEPVECTOR vpCrv ;
@@ -2126,13 +2129,31 @@ SurfRoughing::GetStmOutSideSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh*
}
}
// definisco la TrimMesh limite
// definisco la TrimMesh limite ( inizialmente come copia del grezzo)
PtrOwner<ISurfTriMesh> pStmLimit( CloneSurfTriMesh( pStmRaw)) ;
bOk = bOk && ( ! IsNull( pStmLimit) && pStmLimit->IsValid()) ;
// tengo solo le parti di superficie che sono effettivamente vicine alla regione di sgrossatura
// box della superficie piana
BBox3d BBoxSfr ;
bOk = bOk && pSfrOffs->GetLocalBBox( BBoxSfr) ;
BBoxSfr.Expand( 0., 0., vtExtr.Len()) ;
// scorro le parts
for ( int nPart = 0 ; nPart < pStmLimit->GetPartCount() && bOk ; ++ nPart) {
// calcolo il box della part corrente
BBox3d BBoxPart ;
bOk = bOk && pStmLimit->GetPartLocalBBox( nPart, BBoxPart) ;
// se non c'è intersezione con i Box, elimino la parte corrente
BBox3d BBoxInt ;
if ( BBoxSfr.FindIntersection( BBoxPart, BBoxInt)) {
bOk = pStmLimit->RemovePart( nPart) ;
-- nPart ;
}
}
// definisco la superficie di estrusione
if ( bOk) {
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByRegionExtrusion( vpCrv, vtExtr)) ;
PtrOwner<ISurfTriMesh> pStmExtr( GetSurfTriMeshByRegionExtrusion( vpCrv, ( 1 + 2. * dTol) * vtExtr)) ;
bOk = ( ! IsNull( pStmExtr) && pStmExtr->IsValid()) ;
// la superficie deve definire un volume
double dVol = 0. ;