EgtMachKernel :
- in finiture migliorati i controlli per tipologia Optimal.
This commit is contained in:
+229
-172
@@ -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
@@ -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 ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user