EgtMachKernel :

- Modifica del calcolo della superficie limite in Sgrossature.
This commit is contained in:
Riccardo Elitropi
2024-10-02 13:16:07 +02:00
parent 06d591cc8f
commit 2a2b0e5d7e
2 changed files with 105 additions and 143 deletions
+99 -140
View File
@@ -78,6 +78,7 @@ using namespace std ;
// 3029 = "Error in SurfRoughing : Error in Classifying border"
// 3029 = "Error in SurfRoughing : Simplify Chunks for SubSteps failed"
// 3030 = "Error in SurfRoughing : Conformal ZigZag not valid at step (xx)"
// 3131 = "Error in SurfRoughing : LeadIn with Mill NoTip in material"
// 3051 = "Warning in SurfRoughing : Skipped entity (xx)"
// 3052 = "Warning in SurfRoughing : No machinable path"
// 3053 = "Warning in SurfRoughing : Tool name changed (xx)"
@@ -1246,6 +1247,15 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
pStmRaw->Translate( - vtTool * 5 * EPS_SMALL) ;
IntersParPlanesSurfTm IPPStm( fr_pCompo, *pStmRaw) ;
// costruisco una superficie di estrusione della curva (devo determinare parte della regione limite)
Vector3d vtLimitExtr = - vtTool * 1.5 * max( b3Raw.GetDimX(), max( b3Raw.GetDimY(), b3Raw.GetDimZ())) ;
PtrOwner<ISurfTriMesh> pStmLimit( GetStmOutSideCompo( pCompo, pStmRaw, vtLimitExtr)) ;
if ( IsNull( pStmLimit))
return false ;
// inizializzo la classe di intersezione tra la superficie trimesh limite e piani paralleli ( quelli di lavoro)
IntersParPlanesSurfTm IPPStm1( fr_pCompo, *pStmLimit) ;
// inizializzo la classe di calcolo delle silhouette nei piani come sopra
SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vSurfId.size()) ;
CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfId.size()) ;
@@ -1381,6 +1391,18 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
else
continue ; // step fuori dal grezzo, passo al successivo
/* ***************** Regione piana esterna a pCompo ****************** */
PtrOwner<ISurfFlatRegion> pSfrOutCompo( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrOutCompo))
return false ;
if ( pStmLimit->IsValid() && pStmLimit->GetTriangleCount() > 0) {
pSfrOutCompo.Set( GetSfrByStmIntersection( IPPStm1, it->dDepth + GetOffsL(), 0)) ;
if ( IsNull( pSfrRaw)) {
m_pMchMgr->SetLastError( 3027, "Error in SurfRoughing : Slicing Raw failed") ;
return false ;
}
}
/* *************************** Silhouette **************************** */
// determino la regione da non lavorare e la sottraggo
POLYLINEVECTOR vPL ;
@@ -1388,7 +1410,6 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
// creo la regione piana dalle PolyLine ricavate dalla Silhouette
SurfFlatRegionByContours SfrMaker ;
for ( auto& PL : vPL) {
@@ -1481,12 +1502,6 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
it->pSfrRemoved = nullptr ;
continue ;
}
// estendo la superficie di riferimento considerando le sottocurve chiuse della
// curva di sgrossatura
if ( ! ModifySurfForOpenCloseEdges( pSfr, vtTool, pCompoPocket)) {
m_pMchMgr->SetLastError( 3026, "Error in SurfRoughing : Detecting open edges failed") ;
return false ;
}
}
// determino i lati aperti ( mediante vicinanza dei tratti di curva al volume progressivo non svuotato)
@@ -1526,10 +1541,21 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
m_pGeomDB->SetMaterial( nNew_SfrPock_Id, GREEN) ;
m_pGeomDB->SetName( nNew_SfrPock_Id, KEY_SURF_POCK + ToString( nPocket)) ;
// nel gruppo temporaneo salvo anche la Shilouette ( per superficie Limite)
// nel gruppo temporaneo salvo anche la superficie Limite)
int nNew_SfrLimit_Id = GDB_ID_NULL ;
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrLimit))
return false ;
if ( ! IsNull( pSfrOutCompo) && pSfrOutCompo->IsValid())
pSfrLimit.Set( pSfrOutCompo) ;
if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) {
nNew_SfrLimit_Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfrSil)) ;
if ( ! IsNull( pSfrLimit) && pSfrLimit->IsValid())
pSfrLimit->Add( *pSfrSil) ;
else
pSfrLimit.Set( pSfrSil) ;
}
if ( ! IsNull( pSfrLimit) && pSfrLimit->IsValid()) {
nNew_SfrLimit_Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfrLimit)) ;
if ( nNew_SfrLimit_Id == GDB_ID_NULL) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
@@ -1614,6 +1640,62 @@ SurfRoughing::GetRaw( void) const
return ( ( pStmRaw->IsValid() && pStmRaw->GetTriangleCount() > 0) ? Release( pStmRaw) : nullptr) ;
}
//----------------------------------------------------------------------------
ISurfTriMesh*
SurfRoughing::GetStmOutSideCompo( ICurveComposite* pCompo, const ISurfTriMesh* pStmRaw, const Vector3d& vtExtr) const
{
// controllo dei parametri
if ( pCompo == nullptr || ! pCompo->IsValid() ||
pStmRaw == nullptr || ! pStmRaw->IsValid())
return nullptr ;
// recupero la PolyLine dalla curva
PolyLine PL ;
pCompo->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ;
// determino la superficie di estrusione
PtrOwner<ISurfTriMesh> pStmExtr( CreateSurfTriMesh()) ;
bool bOk = ( ! IsNull( pStmExtr)) ;
bOk = bOk && pStmExtr->AdjustTopology() ;
bOk = bOk && pStmExtr->CreateByExtrusion( PL, vtExtr) ;
bOk = bOk && ( pStmExtr->IsValid() && pStmExtr->GetTriangleCount() > 0) ;
if ( ! bOk)
return nullptr ;
// aggiungo i caps
PtrOwner<ISurfTriMesh> pStmCap0( CreateSurfTriMesh()) ;
bOk = ( ! IsNull( pStmCap0)) ;
bOk = bOk && pStmCap0->CreateByFlatContour( PL) ;
bOk = bOk && ( pStmCap0->IsValid() && pStmCap0->GetTriangleCount() > 0) ;
if ( ! bOk)
return nullptr ;
Vector3d vtN ; pStmCap0->GetFacetNormal( 0, vtN) ;
Vector3d vtN_ref = vtExtr ; vtN_ref.Normalize() ;
if ( AreOppositeVectorApprox( vtN, vtN_ref))
pStmCap0->Invert() ;
PtrOwner<ISurfTriMesh> pStmCap1( CloneSurfTriMesh( pStmCap0)) ;
bOk = ( ! IsNull( pStmCap1) && pStmCap1->IsValid() && pStmCap1->GetTriangleCount() > 0) ;
bOk = bOk && ( pStmCap1->Translate( vtExtr) && pStmCap1->Invert()) ;
bOk = bOk && pStmExtr->DoSewing( *pStmCap0) ;
bOk = bOk && pStmExtr->DoSewing( *pStmCap1) ;
if ( ! bOk)
return nullptr ;
// la superficie deeve definire un volume
double dVol = 0. ; pStmExtr->GetVolume( dVol) ;
if ( dVol < EPS_ZERO)
pStmExtr->Invert() ;
// sottraggo al grezzo la regione di estrusione
PtrOwner<ISurfTriMesh> pStmLimit( CloneSurfTriMesh( pStmRaw)) ;
bOk = ! IsNull( pStmLimit) ;
bOk = bOk && pStmLimit->IsValid() ;
bOk = bOk && pStmLimit->Subtract( *pStmExtr) ;
if ( ! bOk)
return nullptr ;
return Release( pStmLimit) ;
}
//----------------------------------------------------------------------------
ISurfFlatRegion*
SurfRoughing::GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, double dDist, double dSmallOffs) const
@@ -1857,15 +1939,11 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, const ICRVCOMPOPOVECTOR& v
vStepInfo[nInd].vPaths[i].bOutStart = ( vCrvPaths[i]->GetCurveCount() > 0 &&
vCrvPaths[i]->GetFirstCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ;
// controllo se il punto di ingresso è valido
bool bValidOutLeadIn = true ;
if ( vStepInfo[nInd].vPaths[i].bOutStart) {
if ( ! VerifyLeadInLeadOut( vCrvPaths[i]->GetFirstCurve(), vStepInfo[nInd].pCompo, bValidOutLeadIn))
// se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore
if ( m_TParams.m_nType == TT_MILL_NOTIP && ! vStepInfo[nInd].vPaths[i].bOutStart) {
if ( ! LeadInRawIsOk()) {
m_pMchMgr->SetLastError( 2431, "Error in SurfRoughing : LeadIn with Mill NoTip in material") ;
return false ;
if ( ! bValidOutLeadIn) {
// se non valido, rimuovo il primo tratto
vStepInfo[nInd].vPaths[i].bOutStart = false ;
vCrvPaths[i]->RemoveFirstOrLastCurve( false) ;
}
}
@@ -1873,16 +1951,6 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, const ICRVCOMPOPOVECTOR& v
bool bOutEnd = ( vCrvPaths[i]->GetCurveCount() > 0 &&
vCrvPaths[i]->GetLastCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ;
// controllo se il punto d'uscita va limitato
bool bValidOutLeadOut = true ;
if ( bOutEnd) {
if ( ! VerifyLeadInLeadOut( vCrvPaths[i]->GetLastCurve(), vStepInfo[nInd].pCompo, bValidOutLeadOut))
return false ;
// se non valido, rimuovo l'ultimo tratto
if ( ! bValidOutLeadOut)
vCrvPaths[i]->RemoveFirstOrLastCurve( true) ;
}
// controllo se il percorso è formato da una singola curva seguente il lato chiuso
vStepInfo[nInd].vPaths[i].bSingleCrv = ( vCrvPaths[i]->GetCurveCount() > 0 &&
vCrvPaths[i]->GetTempProp( 0) == TEMP_PROP_SINGLE_CURVE) ;
@@ -2934,62 +3002,6 @@ SurfRoughing::GetRadiusForStartEndElevation( void) const
return ( 0.5 * m_TParams.m_dTDiam + dDeltaRad) ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::AdjustPathForLeadInLeadOut( ICurveComposite* pCrvCompo, int nSubType, const ICurveComposite* pCrvPocket,
bool& bOutStart, bool& bSingleCrv, bool& bOptTrap, bool& bIsZigZagOneWayBorder) const
{
// controllo dei parametri
if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid())
return false ;
// controllo se il percorso ha un ingresso presso un lato aperto
bOutStart = ( pCrvCompo->GetCurveCount() > 0 &&
pCrvCompo->GetFirstCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ;
// controllo se il punto di ingresso è valido
bool bValidOutLeadIn = true ;
if ( bOutStart) {
if ( ! VerifyLeadInLeadOut( pCrvCompo->GetFirstCurve(), pCrvPocket, bValidOutLeadIn))
return false ;
if ( ! bValidOutLeadIn) {
// se non valido, rimuovo il primo tratto
bOutStart = false ;
pCrvCompo->RemoveFirstOrLastCurve( false) ;
}
}
// controllo se il percorso ha un'uscita presso un lato aperto
bool bOutEnd = ( pCrvCompo->GetCurveCount() > 0 &&
pCrvCompo->GetLastCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ;
// controllo se il punto d'uscita va limitata
bool bValidOutLeadOut = true ;
if ( bOutEnd) {
if ( ! VerifyLeadInLeadOut( pCrvCompo->GetLastCurve(), pCrvPocket, bValidOutLeadOut))
return false ;
// se non valido, rimuovo l'ultimo tratto
if ( ! bValidOutLeadOut)
pCrvCompo->RemoveFirstOrLastCurve( true) ;
}
// controllo se il percorso è formato da una singola curva seguente il lato chiuso
bSingleCrv = ( pCrvCompo->GetCurveCount() > 0 &&
pCrvCompo->GetTempProp( 0) == TEMP_PROP_SINGLE_CURVE) ;
// controllo se caso ottimizzato a trapezio
bOptTrap = ( pCrvCompo->GetCurveCount() > 0 &&
pCrvCompo->GetTempProp( 0) == TEMP_PROP_OPT_TRAPEZOID) ;
// controllo se è un percorso a ZigZag/OneWay ( non curva di bordo)
bIsZigZagOneWayBorder = ( pCrvCompo->GetCurveCount() > 0 &&
( nSubType == SURFROU_SUB_ONEWAY || nSubType == SURFROU_SUB_ZIGZAG) &&
pCrvCompo->GetTempProp( 0) == TEMP_PROP_BORDER_CURVE) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::CheckSafetyLinearLink( const Point3d& ptCurr, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool,
@@ -3005,6 +3017,10 @@ SurfRoughing::CheckSafetyLinearLink( const Point3d& ptCurr, const ISurfFlatRegio
if ( ! plProj.Set( ptCurr, vtTool))
return false ;
Point3d ptDestProj = ProjectPointOnPlane( ptDest, plProj) ;
if ( AreSamePointApprox( ptDestProj, ptCurr)) {
bSafe = true ;
return true ;
}
// controllo se la retta che collega ptCurr a ptDesProj è interna o esterna alla regione limite
// devo prima creare un frame Locale XY
@@ -3119,63 +3135,6 @@ SurfRoughing::GetHomogeneousParts( const ICurveComposite* pCrvCompo, ICRVCOMPOPO
}
//----------------------------------------------------------------------------
bool
SurfRoughing::VerifyLeadInLeadOut( const ICurve* pCrv, const ICurveComposite* pCrvPock, bool& bValidLeadIn) const
{
/*
Verifica se il segmento di LeadIn per entrate da fuori sia valido
*/
// controllo dei parametri
if ( pCrv == nullptr || ! pCrv->IsValid() ||
pCrvPock == nullptr || ! pCrvPock->IsValid())
return false ;
// recupero i tratti chiusi della curva di pocketing
ICRVCOMPOPOVECTOR vpCrvs ;
if ( ! GetHomogeneousParts( pCrvPock, vpCrvs))
return false ;
// porto tutto nel piano XY ( la Fat curve di una Linea è ambigua)
Frame3d frLoc ;
Point3d ptFrLoc ; pCrvPock->GetStartPoint( ptFrLoc) ;
double dArea ;
Plane3d plPlane ;
pCrvPock->GetArea( plPlane, dArea) ;
Vector3d vtFrLoc = plPlane.GetVersN() ;
if ( ! frLoc.Set( ptFrLoc, vtFrLoc))
return false ;
// porto la curva in locale
PtrOwner<ICurve> pCrvLoc( pCrv->Clone()) ;
if ( IsNull( pCrvLoc) || ! pCrvLoc->IsValid() || ! pCrvLoc->ToLoc( frLoc))
return false ;
// calcolo la Fat Curve del tratto lineare e la porto in globale
PtrOwner<ISurfFlatRegion> pSfrFat( GetSurfFlatRegionFromFatCurve( pCrvLoc->Clone(), m_TParams.m_dDiam / 2 - 50 * EPS_SMALL, false, false)) ;
if ( IsNull( pSfrFat) || ! pSfrFat->IsValid())
return false ;
bValidLeadIn = true ;
for ( int i = 0 ; i < int( vpCrvs.size()) && bValidLeadIn ; ++ i) {
// se tratto chiuso...
if ( vpCrvs[i]->GetTempProp( 0) == 0) {
// porto nel frame locale
vpCrvs[i]->ToLoc( frLoc) ;
// controllo se interseca la fat curve
CRVCVECTOR ccClass ;
if ( pSfrFat->GetCurveClassification( *vpCrvs[i], EPS_SMALL, ccClass))
bValidLeadIn = ( int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ;
else
bValidLeadIn = false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
// Debug Functions
//----------------------------------------------------------------------------