diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 01bf4f7..6077566 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -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 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 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 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 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 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 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 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 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 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 //---------------------------------------------------------------------------- diff --git a/SurfRoughing.h b/SurfRoughing.h index d7b536e..ee7f6b5 100644 --- a/SurfRoughing.h +++ b/SurfRoughing.h @@ -112,19 +112,17 @@ class SurfRoughing : public Machining bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtTool, const ICurveComposite* pCrvPath, Point3d& ptP1) const ; - bool VerifyLeadInLeadOut( const ICurve* pCrv, const ICurveComposite* pCrvPock, bool& bSkip) const ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, const ISurfFlatRegion* pSfr, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced, bool bSkipControl) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, Point3d& ptP1) ; ISurfTriMesh* GetRaw( void) const ; + ISurfTriMesh* GetStmOutSideCompo( ICurveComposite* pCompo, const ISurfTriMesh* pStmRaw, const Vector3d& vtExtr) const ; ISurfFlatRegion* GetSfrByStmIntersection( const IntersParPlanesSurfTm& IPPStm, double dDist, double dSmallOffs = 0) const ; bool GetActiveSurfaces( INTVECTOR& vSurfId) const ; double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRadiusForStartEndElevation( void) const ; - bool AdjustPathForLeadInLeadOut( ICurveComposite* pCrvCompo, int nSubType, const ICurveComposite* pCrvPocket, bool& bOutStart, - bool& bSingleCrv, bool& bOptTrap, bool& bIsZigZagOneWayBorder) const ; bool AssignOpenEdgesForPocketCrvCompo( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSfr) const ; bool ResetCurveAllTempProp( ICurve* pCurve) const ; bool RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr) const ; @@ -165,6 +163,11 @@ class SurfRoughing : public Machining if ( m_Params.m_nLeadInType != SURFROU_LI_GLIDE && m_Params.m_dLiElev < 10 * EPS_SMALL) return SURFROU_LI_NONE ; return m_Params.m_nLeadInType ; } + bool LeadInRawIsOk( void) const + { if ( m_TParams.m_nType != TT_MILL_NOTIP) + return true ; + return (( GetLeadInType() == SURFROU_LI_ZIGZAG || GetLeadInType() == SURFROU_LI_HELIX) && + m_Params.m_dLiTang >= 0.9 * m_TParams.m_dDiam && m_Params.m_dLiElev <= 2) ; } int GetLeadOutType( void) const { if ( m_Params.m_dLoTang < std::min( 0.1 * m_TParams.m_dDiam, 1.0)) return SURFROU_LO_NONE ;