EgtMachKernel :

- in finiture migliorati i controlli per tipologia Optimal.
This commit is contained in:
Riccardo Elitropi
2026-05-29 16:49:28 +02:00
parent 981563b682
commit 1874f6b1f8
2 changed files with 235 additions and 175 deletions
+229 -172
View File
@@ -1670,6 +1670,15 @@ SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d&
pSfrSil->ToGlob( frSurf) ;
double dPockRadOffs = SILH_ARC_TOL ;
pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ;
pSfrSil->Offset( m_TParams.m_dDiam / 2., ICurve::OFF_FILLET) ;
#if DEBUG_SFR
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "FlatRegions MaxDown") ;
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLay, "SfrMaxDow") ;
int nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrSil->Clone()) ;
m_pGeomDB->SetMaterial( nSfr, Color( 1., 0., 0., .5)) ;
#endif
// intersezione tra contorno e regione
if ( ! pSfrCnt->Intersect( *pSfrSil)) {
// ricreo la regione originale
@@ -1965,6 +1974,15 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
dDepth = dInvElev + dToolDepth ;
}
// alla regione di contorno applico un Offset stabilito dal parametro di Overlap
if ( ! pSfrCnt->Offset( m_Params.m_dOverlap, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// se non valida, non faccio nulla
if ( ! pSfrCnt->IsValid())
return true ;
#if DEBUG_SFR
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "FlatRegions") ;
@@ -1987,15 +2005,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId)
return false ;
}
// alla regione di contorno applico un Offset stabilito dal parametro di Overlap
if ( ! pSfrCnt->Offset( m_Params.m_dOverlap, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// se non valida, non faccio nulla
if ( ! pSfrCnt->IsValid())
return true ;
// tengo una copia della regione attuale, nel caso di finitura Optimal
PtrOwner<ISurfFlatRegion> pSfrCntOrig( nullptr) ;
if ( m_Params.m_nSubType == SURFFIN_SUB_OPTIMAL) {
@@ -2623,7 +2632,7 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU
if ( IsNull( pCrvCompo))
return false ;
// recupero le curve semplici e le inserisco nella curva composita
for ( size_t i = 0 ; i < vnInd.size() ; ++ i) {
for ( int i = 0 ; i < ssize( vnInd) ; ++ i) {
int nId = abs( vnInd[i]) - 1 ;
// la aggiungo alla curva composta
if ( ! pCrvCompo->AddCurve( CloneCurveComposite( vCrvCompo.back()[nId]), true, dToler))
@@ -2648,8 +2657,8 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU
}
// controllo la validità di tutte le curve trovate
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
for ( int j = 0 ; j < int( vCrvCompo[i].size()) ; ++ j) {
for ( int i = 0 ; i < ssize( vCrvCompo) ; ++ i) {
for ( int j = 0 ; j < ssize( vCrvCompo[i]) ; ++ j) {
if ( vCrvCompo[i][j] == nullptr || ! vCrvCompo[i][j]->IsValid())
return false ;
}
@@ -5528,13 +5537,161 @@ SurfFinishing::CalcOptimalZigZagCurves( ISURFFRPOVECTOR& vSfrZigZagProj, const F
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcOptimalZigZagSfrByZConstCrv( const ISurfFlatRegion* pSfrLoc, const CISURFTMPVECTOR& vpStm, const Vector3d& vtToolLoc,
double dExtraCollOffs, ICurveComposite* pCompoSil, ISurfFlatRegion* pSfrCollCompoSil) const
{
// verifica dei parametri
if ( pSfrLoc == nullptr || ! pSfrLoc->IsValid() ||
vpStm.empty() ||
pCompoSil == nullptr || ! pCompoSil->IsValid() ||
pSfrCollCompoSil == nullptr)
return false ;
pSfrCollCompoSil->Clear() ;
// definisco il frame della regione piana
Frame3d frSfr ;
Point3d ptC ; pSfrLoc->GetCentroid( ptC) ;
if ( ! frSfr.Set( ptC, pSfrLoc->GetNormVersor()))
return false ;
// definisco il bordo della curva rappresentante la collisione
PtrOwner<ICurveComposite> pCompoColl( CreateCurveComposite()) ;
if ( IsNull( pCompoColl))
return false ;
bool bfirst = true ;
const double TOL_SAFE = Clamp( m_Params.m_dSideStep, 100. * EPS_SMALL, 1.0) ; // tolleranza per pareti verticali e per triangoli misti tra SplitAngle
double dRad = m_TParams.m_dDiam / 2. + TOL_SAFE ;
for ( int nCrv = 0 ; nCrv < pCompoSil->GetCurveCount() ; ++ nCrv) {
const ICurve* pCrv = pCompoSil->GetCurve( nCrv) ;
if ( pCrv == nullptr)
continue ;
// recupero il centro dell'utensile sferico sopra a tale curva
Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ;
Point3d ptSphereCenter = ptEnd + vtToolLoc * dRad ;
// recupero il punto a minima distanza ( quello che ha generato la collisione)
double dMinDist = INFINITO - 1 ;
Point3d ptMinDist = P_INVALID ;
Vector3d vtCollToCenter = V_INVALID ;
for ( int nSurf = 0 ; nSurf < ssize( vpStm) ; ++ nSurf) {
if ( vpStm[nSurf] != nullptr && vpStm[nSurf]->IsValid()) {
DistPointSurfTm distPtSurfTm( ptSphereCenter, *vpStm[nSurf]) ;
double dMyDist = INFINITO - 2 ;
if ( distPtSurfTm.GetDist( dMyDist) && dMyDist < dMinDist) {
dMinDist = dMyDist ;
distPtSurfTm.GetMinDistPoint( ptMinDist) ;
vtCollToCenter = ptSphereCenter - ptMinDist ;
vtCollToCenter.Normalize() ;
}
}
}
if ( ptMinDist.IsValid() && vtCollToCenter.IsValid()) {
Point3d ptColl = ptEnd - OrthoCompo( dRad * vtCollToCenter, vtToolLoc) ;
if ( bfirst) {
pCompoColl->AddPoint( ptColl) ;
bfirst = false ;
}
else
pCompoColl->AddLine( ptColl) ;
}
}
if ( pCompoSil->IsClosed())
pCompoColl->Close() ;
// abballisco le due curve smussandole
SimplifyCurve( pCompoSil, frSfr) ;
SimplifyCurve( pCompoColl, frSfr) ;
#if 0
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoSil->Clone()) ;
m_pGeomDB->SetMaterial( a, FUCHSIA) ;
a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoColl->Clone()) ;
m_pGeomDB->SetMaterial( a, BLUE) ;
#endif
// Se richiesto Offset Extra lo aggiungo alla curva di collisione
if ( abs( dExtraCollOffs) > 10. * EPS_SMALL) {
pCompoColl->SetExtrusion( vtToolLoc) ;
OffsetCurve OffsCrv ;
if ( OffsCrv.Make( pCompoColl, ( ! m_Params.m_bInvert ? dExtraCollOffs : - dExtraCollOffs), ICurve::OFF_FILLET)) {
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid()) {
pCompoColl->Clear() ;
pCompoColl->AddCurve( Release( pCrvOffs)) ;
}
}
}
if ( pCompoSil->IsValid() && pCompoColl->IsValid()) {
if ( pCompoSil->IsClosed()) {
pSfrCollCompoSil->AddExtLoop( Release( pCompoColl)) ;
PtrOwner<ICurveComposite> pCompoIsl( CloneCurveComposite( pCompoSil)) ;
if ( IsNull( pCompoIsl) || ! pCompoIsl->IsValid())
return false ;
pCompoIsl->SetExtrusion( vtToolLoc) ;
double dOffset = ( ! m_Params.m_bInvert ? 1. : -1.) * dRad ;
OffsetCurve OffsCrv ;
OffsCrv.Make( pCompoIsl, dOffset, ICurve::OFF_FILLET) ;
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid())
pSfrCollCompoSil->AddIntLoop( Release( pCrvOffs)) ;
else
pSfrCollCompoSil->AddIntLoop( Release( pCompoIsl)) ;
}
else {
PtrOwner<ICurveComposite> pBorder( CloneCurveComposite( pCompoColl)) ;
if ( IsNull( pBorder) || ! pBorder->IsValid())
return false ;
PtrOwner<ICurve> pNewCrvCompoInv( CloneCurveComposite( pCompoSil)) ;
if ( IsNull( pNewCrvCompoInv) || ! pNewCrvCompoInv->IsValid())
return false ;
pNewCrvCompoInv->SetExtrusion( vtToolLoc) ;
double dOffset = ( ! m_Params.m_bInvert ? 1. : -1.) * dRad ;
OffsetCurve OffsCrv ;
OffsCrv.Make( pNewCrvCompoInv, dOffset, ICurve::OFF_FILLET) ;
PtrOwner<ICurve> pCrvOffs( OffsCrv.GetLongerCurve()) ;
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid())
pNewCrvCompoInv.Set( Release( pCrvOffs)) ;
pNewCrvCompoInv->Invert() ;
Point3d ptCurr ; pBorder->GetEndPoint( ptCurr) ;
Vector3d vtCurr ; pBorder->GetEndDir( vtCurr) ;
Point3d ptEnd ; pNewCrvCompoInv->GetStartPoint( ptEnd) ;
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ; pArc->Set2PVN( ptCurr, ptEnd, vtCurr, vtToolLoc) ;
pBorder->AddCurve( Release( pArc)) ;
pBorder->AddCurve( Release( pNewCrvCompoInv)) ;
pBorder->GetEndPoint( ptCurr) ;
pBorder->GetEndDir( vtCurr) ;
pBorder->GetStartPoint( ptEnd) ;
pArc.Set( CreateCurveArc()) ; pArc->Set2PVN( ptCurr, ptEnd, vtCurr, vtToolLoc) ;
pBorder->AddCurve( Release( pArc)) ;
pSfrCollCompoSil->AddExtLoop( Release( pBorder)) ;
}
}
// per sicurezza oriento a prescindere la normale della superficie come vtToolLoc
if ( pSfrCollCompoSil->IsValid()) {
if ( AreOppositeVectorApprox( pSfrCollCompoSil->GetNormVersor(), vtToolLoc))
pSfrCollCompoSil->Invert() ;
#if 0
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrCollCompoSil->Clone()) ;
m_pGeomDB->SetMaterial( a, Color( 255, 0, 0, 50)) ;
#endif
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const Vector3d& vtTool, double dAngDegSplit, double dAngDegTol, double dDepth,
ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const
ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths, ISurfFlatRegion* pSfrToolColl) const
{
// se la superficie non è valida, non restituisco nulla
if ( pSfrToolColl == nullptr)
return false ;
if ( pSfrLoc == nullptr || ! pSfrLoc->IsValid())
return true ;
@@ -5614,6 +5771,8 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
double dCosUpperBound = cos( ( dAngDegSplit - dAngDegTol) * DEGTORAD + EPS_ANG_SMALL) ;
// --- classificazione punti e PolyLine corrispondenti
enum { VALID = 0, AMBIGUOUS = 1, DISCARD = 2 } ;
// --- offset correttivo per regioni di collisione
const double dExtraOffs = m_TParams.m_dDiam / 2. ;
#if ENABLE_OPTIMAL_DEBUG
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
@@ -5638,9 +5797,9 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
int nLayCrv = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLayCrv, "Curves") ;
m_pGeomDB->SetStatus( nLayCrv, GDB_ST_OFF) ;
int nLaySfrProj = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLaySfrProj, "SfrProj") ;
m_pGeomDB->SetStatus( nLaySfrProj, GDB_ST_OFF) ;
int nLaySfrColl = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLaySfrColl, "SfrColl") ;
m_pGeomDB->SetStatus( nLaySfrColl, GDB_ST_OFF) ;
#endif
// scorro i piani di ZConst ricavati...
@@ -5829,16 +5988,24 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
// se vuota, non faccio nulla
if ( PL.GetPointNbr() < 2)
continue ;
// se PolyLine troppo corta, non la memorizzo ( < 1/4 circonferenza utensile)
// se PolyLine troppo corta, non la memorizzo
double dLen = 0. ; PL.GetLength( dLen) ;
if ( dLen < ( PIGRECO / 2.) * ( m_TParams.m_dDiam / 2.))
if ( dLen < MIN_DIST)
continue ;
// definisco la curva e la abbellisco
PtrOwner<ICurveComposite> pNewCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pNewCrvCompo) || ! pNewCrvCompo->FromPolyLine( PL))
// definisco la curva
PtrOwner<ICurveComposite> pNewCompo( CreateCurveComposite()) ;
if ( IsNull( pNewCompo) || ! pNewCompo->FromPolyLine( PL))
continue ;
SimplifyCurve( pNewCrvCompo, frSfr) ;
vvCrvCompo[i].emplace_back( Release( pNewCrvCompo)) ;
// aggiorno la regione per il calcolo dello ZigZag ( la funzione abbellisce le curve)
PtrOwner<ISurfFlatRegion> pSfrColl( CreateSurfFlatRegion()) ;
CalcOptimalZigZagSfrByZConstCrv( pSfrLoc, vpStm, vtAxL, - dExtraOffs, pNewCompo, pSfrColl) ;
if ( ! IsNull( pSfrColl) && pSfrColl->IsValid()) {
if ( ! pSfrToolColl->IsValid())
pSfrToolColl->CopyFrom( pSfrColl) ;
else
pSfrToolColl->Add( *pSfrColl) ;
}
vvCrvCompo[i].emplace_back( Release( pNewCompo)) ;
// memorizzo come primo TempParam la distanza della superficie ( per coerenza)
vvCrvCompo[i].back()->SetTempParam( dSfrDist, 0) ;
#if ENABLE_OPTIMAL_DEBUG
@@ -5848,6 +6015,17 @@ SurfFinishing::CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SU
}
}
// la superficie complessiva di collisione viene limitata al bordo
if ( pSfrToolColl->IsValid()) {
pSfrToolColl->Offset( - dExtraOffs, ICurve::OFF_FILLET) ;
if ( pSfrToolColl->IsValid())
pSfrToolColl->Intersect( *pSfrLoc) ;
#if ENABLE_OPTIMAL_DEBUG
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLaySfrColl, pSfrToolColl->Clone()) ;
m_pGeomDB->SetMaterial( a, Color( 255, 0, 255, 50)) ;
#endif
}
// collego tra loro le curve trovate definendo quindi un percorso
ICRVCOMPOPOVECTOR vCrv ;
if ( ! CreateZConstPaths( pCAvTlStm, frSurf, vvCrvCompo, vtTool, pMySfrZConst, dDepth, vCrv)) {
@@ -5947,156 +6125,37 @@ SurfFinishing::AreSameSfrChunkEpsilon( const ISurfFlatRegion* pSfrChunkA, const
//----------------------------------------------------------------------------
bool
SurfFinishing::CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const Vector3d& vtToolLoc, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const
SurfFinishing::CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const ISurfFlatRegion* pSfrZLevelColl,
const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const Vector3d& vtToolLoc, double dDepth,
double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const
{
// verifico validità dei parametri
if ( pSfrCntLoc == nullptr || ! pSfrCntLoc->IsValid())
return false ;
vpSfrZigZagProj.clear() ;
const double COS_SPLIT_ANG = cos( dSplitAngDeg * DEGTORAD) ;
// se non esiste una regione di ZLevelColl, quindi non esistono curve di Zlevel, tutta la superficie deve
// essere lavorata in ZigZag
if ( pSfrZLevelColl == nullptr || ! pSfrZLevelColl->IsValid())
return ( vpSfrZigZagProj.emplace_back( CloneSurfFlatRegion( pSfrCntLoc))) ;
// scorro tutte le facce delle superfici presenti
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSrfLoc.size()) ;
for ( const SurfLocal& SurfL : vSrfLoc) {
// recupero la superficie
const ISurf* pSurf = GetSurf( SurfL.Get()) ;
if ( pSurf == nullptr || ! pSurf->IsValid())
continue ;
int nType = pSurf->GetType() ;
// se TriMesh
if ( nType == SRF_TRIMESH) {
const ISurfTriMesh* pStm = GetSurfTriMesh( pSurf) ;
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
vpStm.emplace_back( pStm) ;
}
// se Bezier
else if ( nType == SRF_BEZIER) {
const ISurfBezier* pSBz = GetSurfBezier( pSurf) ;
if ( pSBz != nullptr && pSBz->IsValid()) {
double dOldTol = GetSurfBezierAuxSurfRefinedTol() ;
SetSurfBezierAuxSurfRefinedTol( 5. * EPS_SMALL) ;
const ISurfTriMesh* pStm = pSBz->GetAuxSurfRefined() ;
SetSurfBezierAuxSurfRefinedTol( dOldTol) ;
if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0)
vpStm.emplace_back( pStm) ;
}
}
}
// Definisco una Zuppa di Triangoli per le facce entro la tolleranza
#if ENABLE_OPTIMAL_DEBUG
int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
m_pGeomDB->SetName( nGrp, "SplitAngleSurf") ;
m_pGeomDB->SetStatus( nGrp, GDB_ST_OFF) ;
int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ;
m_pGeomDB->SetName( nLay, "SplitAngleSurf") ;
#endif
StmFromTriangleSoup StmSoup ;
StmSoup.Start() ;
for ( const ISurfTriMesh* pStm : vpStm) {
if ( pStm == nullptr || ! pStm->IsValid())
continue ;
// scorro le faccie della superficie e controllo l'angolo presente
for ( int nF = 0 ; nF < pStm->GetFacetCount() ; ++ nF) {
Vector3d vtFaceN ; pStm->GetFacetNormal( nF, vtFaceN) ;
#if ENABLE_OPTIMAL_DEBUG
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pStm->CloneFacet( nF)) ;
#endif
if ( vtFaceN * vtToolLoc > COS_SPLIT_ANG) {
#if ENABLE_OPTIMAL_DEBUG
m_pGeomDB->SetMaterial( nId, LIME) ;
#endif
INTVECTOR vnTria ; pStm->GetAllTriaInFacet( nF, vnTria) ;
for ( const int& nT : vnTria) {
Triangle3d Tria ; pStm->GetTriangle( nT, Tria) ;
StmSoup.AddTriangle( Tria) ;
}
}
else {
#if ENABLE_OPTIMAL_DEBUG
m_pGeomDB->SetMaterial( nId, BLACK) ;
#endif
}
}
}
StmSoup.End() ;
// recupero i parametri per il calcolo delle regioni piane a ZigZag
Point3d ptTop ; pSfrCntLoc->GetCentroid( ptTop) ;
Frame3d frPlanes ;
if ( ! frPlanes.Set( ptTop, vtToolLoc))
// separo ogni Chunk della regione a ZigZag (ognuno di essi verrà lavorato singolarmanete)
PtrOwner<ISurfFlatRegion> pSfrZigZag( CloneSurfFlatRegion( pSfrCntLoc)) ;
if ( IsNull( pSfrZigZag) || ! pSfrZigZag->IsValid())
return false ;
const double TOL_SIL = 1.0 ;
INTDBLVECTOR vSfrDistInd ;
// Recupero le Superfici TriMesh
PtrOwner<ISurfTriMesh> pStmZigZag( StmSoup.GetSurf()) ;
while ( ! IsNull( pStmZigZag)) {
if ( pStmZigZag->IsValid() && pStmZigZag->GetTriangleCount() > 0) {
// ogni Part della TriMesh a ZigZag diventa una FlatRegion
for ( int nP = 0 ; nP < pStmZigZag->GetPartCount() ; ++ nP) {
PtrOwner<ISurfTriMesh> pStmZigZagPart( pStmZigZag->ClonePart( nP)) ;
if ( ! IsNull( pStmZigZagPart) && pStmZigZagPart->IsValid()) {
// recupero il Box della Parte corrente e determino la quota media ( controllo basilare, migliorabile)
BBox3d BBoxPart ;
pStmZigZagPart->GetLocalBBox( BBoxPart) ;
Point3d ptMid ; BBoxPart.GetCenter( ptMid) ;
// recupero le PolyLine di proiezione per la definizione del bordo
PtrOwner<ICAvParSilhouettesSurfTm> pCavParSilh( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( {pStmZigZagPart}, frPlanes, TOL_SIL))
return false ;
POLYLINEVECTOR vPL ;
if ( ! pCavParSilh->GetSilhouette( - dDepth, vPL))
return false ;
// inizializzo classe di calcolo per regione piana corrente mediante le PolyLine ricavate
SurfFlatRegionByContours SfrByC ;
for ( const PolyLine& PL : vPL) {
PtrOwner<ICurveComposite> pCompoPL( CreateCurveComposite()) ;
if ( IsNull( pCompoPL) || ! pCompoPL->FromPolyLine( PL) || ! SfrByC.AddCurve( pCompoPL->Clone()))
return false ;
}
// Recupero le superfici piane e le memorizzo
PtrOwner<ISurfFlatRegion> pSfrProj( SfrByC.GetSurf()) ;
while ( ! IsNull( pSfrProj)) {
if ( pSfrProj->IsValid()) {
// porto la superficie in Globale
if ( AreOppositeVectorEpsilon( pSfrProj->GetNormVersor(), vtToolLoc, 20. * EPS_SMALL))
pSfrProj->Invert() ;
// limito questa regione all'intersezione con la superficie di Contorno
if ( ! pSfrProj->Intersect( *pSfrCntLoc))
return false ;
if ( pSfrProj->IsValid()) {
// verifico che non ci siano delle superfici duplicate
bool bDuplicate = false ;
for ( int i = 0 ; ! bDuplicate && i < ssize( vpSfrZigZagProj) ; ++ i)
bDuplicate = AreSameSfrChunkEpsilon( pSfrProj, vpSfrZigZagProj[i], m_TParams.m_dDiam / 4.) ;
if ( ! bDuplicate) {
vpSfrZigZagProj.emplace_back( Release( pSfrProj)) ;
vSfrDistInd.emplace_back( make_pair( ssize( vpSfrZigZagProj) - 1, abs( ( ptMid - ptTop) * vtToolLoc))) ;
}
}
}
pSfrProj.Set( SfrByC.GetSurf()) ;
}
}
if ( ! pSfrZigZag->Subtract( *pSfrZLevelColl))
return false ;
if ( pSfrZigZag->IsValid()) {
for ( int nC = 0 ; nC < pSfrZigZag->GetChunkCount() ; ++ nC) {
PtrOwner<ISurfFlatRegion> pSfrZigZagChunk( pSfrZigZag->CloneChunk( nC)) ;
if ( ! IsNull( pSfrZigZagChunk) && pSfrZigZagChunk->IsValid()) {
// verifico che il Chunk non sia troppo "snello"
double dMaxOffs = 0. ;
pSfrZigZagChunk->GetMaxOffset( dMaxOffs) ;
if ( dMaxOffs > m_TParams.m_dDiam / 2. - 2. * EPS_SMALL)
vpSfrZigZagProj.emplace_back( Release( pSfrZigZagChunk)) ;
}
}
pStmZigZag.Set( StmSoup.GetSurf()) ;
}
if ( ssize( vpSfrZigZagProj) < 2)
return true ;
// ordino le superfici ottenute in base alla distanza con la Superficie di contorno ( riferita alla Part di TriMesh)
ranges::sort( vSfrDistInd, {}, &pair<int, double>::second) ;
for ( int i = 0 ; i < ssize( vSfrDistInd) ; ++ i) {
int nCurrI = i ;
while ( vSfrDistInd[nCurrI].first != nCurrI) {
int nNextI = vSfrDistInd[nCurrI].first ;
swap( vpSfrZigZagProj[nCurrI], vpSfrZigZagProj[nNextI]) ;
swap( vSfrDistInd[nCurrI], vSfrDistInd[nNextI]) ;
}
}
return true ;
@@ -6108,9 +6167,6 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
const ISurfFlatRegion* pSfrCnt, const ISurfFlatRegion* pSfrCntExt,
const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs)
{
// vettore dei percorsi da calcolare
VECTORPATHS vPaths ;
// se entrambe le regioni non sono valide, non faccio nulla
if ( ( pSfrCnt == nullptr || ! pSfrCnt->IsValid()) && ( pSfrCntExt == nullptr || ! pSfrCntExt->IsValid()))
return false ;
@@ -6125,18 +6181,21 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
return false ;
// --- [1°] calcolo delle curve ZLevel e [2°] definizione della regione di proiezione per Zlevel ---
PtrOwner<ISurfFlatRegion> pSfrCntZLevel( pSfrCntLoc->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + EPS_SMALL, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrCntZLevel))
PtrOwner<ISurfFlatRegion> pSfrCntLimit( pSfrCntLoc->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + EPS_SMALL, ICurve::OFF_FILLET)) ;
if ( IsNull( pSfrCntLimit))
return false ;
// calcolo tutte le curve a ZLevel e determino la regione rimossa da queste curve
if ( ! CalcOptimalZConstCurves( pSfrCntZLevel, vSrfLoc, frSurf, vtTool, dAngDegSplit, dAngDegTol, dDepth, pCAvTlStm, vPaths)) {
VECTORPATHS vPaths ;
PtrOwner<ISurfFlatRegion> pSfrZLevelColl( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrZLevelColl) ||
! CalcOptimalZConstCurves( pSfrCntLimit, vSrfLoc, frSurf, vtTool, dAngDegSplit, dAngDegTol, dDepth, pCAvTlStm, vPaths, pSfrZLevelColl)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
// [3°] calcolo della regione di proiezione ZigZag ---
ISURFFRPOVECTOR vSfrZigZagProj ;
if ( ! CalcOptimalZigZagRegion( pSfrCntZLevel, vSrfLoc, frSurf, GetToLoc( vtTool, frSurf), dDepth, dAngDegSplit, vSfrZigZagProj)) {
if ( ! CalcOptimalZigZagRegion( pSfrCntLimit, pSfrZLevelColl, vSrfLoc, frSurf, GetToLoc( vtTool, frSurf), dDepth, dAngDegSplit, vSfrZigZagProj)) {
m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ;
return false ;
}
@@ -6148,8 +6207,6 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr
return false ;
}
}
// se non ho percorsi, non faccio nulla
if ( vPaths.empty())
return true ;
+6 -3
View File
@@ -178,7 +178,10 @@ class SurfFinishing : public Machining
double dFrontTriaTolerAng, double& dMaxFrontTriaRad) const ;
bool CalcOptimalZConstCurves( const ISurfFlatRegion* pSfrLoc, const SURFLOCALVECTOR& vSrfLoc,
const Frame3d& frSurf, const Vector3d& vtTool, double dAngDegSplit,
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths) const ;
double dAngDegTol, double dDepth, ICAvToolSurfTm* pCAvTlStm, VECTORPATHS& vPaths,
ISurfFlatRegion* pSfrToolColl) const ;
bool CalcOptimalZigZagSfrByZConstCrv( const ISurfFlatRegion* pSfrLoc, const CISURFTMPVECTOR& vpStm, const Vector3d& vtToolLoc,
double dExtraCollOffs, ICurveComposite* pCompoSil, ISurfFlatRegion* pSfrZigZag) const ;
bool CalcOptimalZigZagCurves( ISURFFRPOVECTOR& vSfrZigZagProj, 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,
@@ -215,8 +218,8 @@ class SurfFinishing : public Machining
double dLimInfClippingAng, double dLimSupClippingAng, const Vector3d& vtAxL, const Vector3d& vtMoveL, ICAvToolSurfTm* pCAvTlStm,
ICRVCOMPOPOVECTOR& vCrvCompo) const ;
bool AreSameSfrChunkEpsilon( const ISurfFlatRegion* pSfrChunkA, const ISurfFlatRegion* pSfrChunkB, double dMaxDist) const ;
bool CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const Vector3d& vtTool, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const ;
bool CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const ISurfFlatRegion* pSfrZLevelColl, const SURFLOCALVECTOR& vSrfLoc,
const Frame3d& frSurf, const Vector3d& vtTool, double dDepth, double dSplitAngDeg, ISURFFRPOVECTOR& vpSfrZigZagProj) const ;
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
double GetRadiusForStartEndElevation( void) const ;