diff --git a/Operation.cpp b/Operation.cpp index 9059a0a..d0812db 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -737,15 +737,15 @@ Operation::GetSignedDistFromStmRaw( int nPhase, const Point3d ptP, const Vector3 dDist = dCurrDist ; double dTmpCurrDist = 0 ; - for ( int i = 0 ; i < ( int)vSrfRawPart.size() ; ++ i) { + for ( int i = 0 ; i < int( vSrfRawPart.size()) ; ++ i) { ILSIVECTOR vInfo ; // info Triangle3d Tria ; // triangolo della trimesh intersecato // recupero la distanza tra il punto e la parte p-esima if ( IntersLineSurfTm( ptP, vtDir, RAY_LEN, *vSrfRawPart[i], vInfo)) { - - if (( int)vInfo.size() == 0) + + if ( vInfo.empty()) continue ; DistPointSurfTm distPtStm( ptP, *vSrfRawPart[i]) ; diff --git a/Pocketing.cpp b/Pocketing.cpp index c86e63e..0f726a4 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -122,6 +122,91 @@ static double SAFE_Z_RET = 5. ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), Pocketing) ; +//---------------------------------------------------------------------------- +//************************ Debug utilities *********************************** +void +Pocketing::DrawLoopsSurf( const ISurfFlatRegion* pSfr, bool bWithSurf, Color Col, bool bAlphaCoverage) { + if ( bWithSurf) + DrawSimpleSurf( pSfr) ; + + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++ l) { + PtrOwner pCrvCompo( GetCurveComposite( pSfr->GetLoop( c, l))) ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ; + int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ; + m_pGeomDB->SetMaterial( nInd, nProp0 == 0 ? ! bAlphaCoverage ? BLUE : AQUA : ! bAlphaCoverage ? RED : ORANGE) ; + } + } + } + return ; +} + +void +Pocketing::DrawSimpleSurf( const ISurfFlatRegion* pSfr, Color Col) +{ + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfr->Clone()) ; + m_pGeomDB->SetMaterial( nInd, Col) ; + return ; +} + +void +Pocketing::DrawVectorCurves( const ICRVCOMPOPOVECTOR& vCrv) +{ + for ( int l = 0 ; l < int( vCrv.size()) ; ++ l) { + for ( int u = 0 ; u < vCrv[l]->GetCurveCount() ; ++ u) { + int nProp0 ; vCrv[l]->GetCurveTempProp( u, nProp0, 0) ; + int nProp1 ; vCrv[l]->GetCurveTempProp( u, nProp1, 1) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrv[l]->GetCurve( u)->Clone()) ; + m_pGeomDB->SetMaterial( nInd, nProp0 == 0 ? BLUE : RED) ; + } + } + return ; +} + +void +Pocketing::DrawSimpleCurve( const ICurveComposite* pCrv, bool bUniform) +{ + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) { + int nProp0 ; pCrv->GetCurveTempProp( u, nProp0, 0) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->GetCurve( u)->Clone()) ; + m_pGeomDB->SetMaterial( nInd, ! bUniform ? nProp0 == 0 ? BLUE : nProp0 == 1 ? RED : WHITE : WHITE) ; + } + return ; +} + +void +Pocketing::DrawSimpleTriMesh( const ISurfTriMesh* pStm, Color Col) +{ + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm->Clone()) ; + m_pGeomDB->SetMaterial( nInd, Col) ; + return ; +} + +void +Pocketing::DrawSimplePoint( const Point3d& pT, Color Col) +{ + PtrOwner ptGeo( CreateGeoPoint3d()) ; + ptGeo->Set( pT) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ptGeo->Clone()) ; + m_pGeomDB->SetMaterial( nInd, Col) ; + return ; +} + +void +Pocketing::DrawSimpleVector( const Vector3d& vT, Point3d ptPos, Color Col) +{ + PtrOwner vtGeo( CreateGeoVector3d()) ; + vtGeo->Set( vT) ; + vtGeo->Translate( ptPos - ORIG) ; + int nInd = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vtGeo->Clone()) ; + m_pGeomDB->SetMaterial( nInd, Col) ; + return ; +} + +// *************************************************************************** + //---------------------------------------------------------------------------- const string& Pocketing::GetClassName( void) const @@ -298,7 +383,7 @@ Pocketing::Pocketing( void) m_dOffsetR_Prec = 0. ; m_dSideStep_Prec = 0. ; m_dLen_Prec = 0. ; - m_bOrderStepZ = true ; + m_bOrderStepZ = false ; m_bPocketPlane = false ; m_dOpenEdgeRad = 0. ; } @@ -1501,10 +1586,14 @@ Pocketing::Chain( int nGrpDestId) if ( ! vCrvCompo[u]->GetCentroid( ptInside)) return false ; vPts.push_back( ptInside) ; + // campiono la curva ( potrebbero esserci archi) for ( int uu = 0 ; uu < vCrvCompo[u]->GetCurveCount() ; ++ uu) { - if ( ! vCrvCompo[u]->GetCurve( uu)->GetMidPoint( ptInside)) - return false ; - vPts.push_back( ptInside) ; + for ( int p = 0 ; p < 8 ; ++ p) { + Point3d ptInside ; + if ( ! vCrvCompo[u]->GetPointD1D2( 1. * uu + 1. * p / 8, ICurve::FROM_MINUS, ptInside)) + return false ; + vPts.push_back( ptInside) ; + } } } @@ -1639,7 +1728,7 @@ bool Pocketing::CreateStmForIntersection( ISurfTriMesh* pStm, ICRVCOMPOPOVECTOR& vCrvCompo, const Vector3d& vtN) { // se non ho entità esco - if ( int( vCrvCompo.size()) == 0) + if ( vCrvCompo.empty()) return true ; // creo un frame centrato sulla prima curva con Z orientata come m_vtTool @@ -1767,9 +1856,11 @@ Pocketing::CalcOffsExtensionsForCurves( const ICurveComposite* pCrvCompo, const return false ; vPts.push_back( ptC) ; for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { - if ( ! pCrvCompo->GetCurve( u)->GetStartPoint( ptC)) - return false ; - vPts.push_back( ptC) ; + for ( int p = 0 ; p < 8 ; ++ p) { + if ( ! pCrvCompo->GetPointD1D2( 1. * u + 1. * p / 8, ICurve::FROM_MINUS, ptC)) + return false ; + vPts.push_back( ptC) ; + } } // creo un frame coerente con la curva e la direzione di svuotatura @@ -2248,8 +2339,21 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) // eventuale imposizione massima elevazione da note utente double dMaxElev = 0. ; - if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) - dElev = dMaxElev ; + if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) { + dElev = dMaxElev ; // aggiorno l'elevazione + // aggiorno il volume di svuotatura, tagliandolo alla quota MaxElev + frElevation.Set( ptC + vtTool * dZ_min, vtTool) ; + if ( ! frElevation.IsValid()) + return false ; + pStm_PartVolume->ToLoc( frElevation) ; + Plane3d plMaxElev ; plMaxElev.Set( ORIG + dElev * Z_AX, Z_AX) ; + if ( ! plMaxElev.IsValid() || + ! pStm_PartVolume->Cut( plMaxElev, false) || + ! pStm_PartVolume->IsValid() || + //! SewingMissingFacesOnPlanes( pStm_PartVolume, plMaxElev) || // manca il grezzo dinamico... + ! pStm_PartVolume->ToGlob( frElevation)) + return false ; + } // verifico che lo step dell'utensile sia sensato double dOkStep = ( m_Params.m_dStep > EPS_SMALL ? m_Params.m_dStep + EPS_SMALL : 0) ; @@ -2403,7 +2507,7 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) // creo i parametri utili per la svuotatura ISURFFRPOVECTOR vSrfSliced ; // vettore delle superficie ricavate ( per ogni step) - vector vCrvOEWithFlags; // vettore delle relative curve originali ( per ogni step) + vector vCrvOEWithFlags ; // vettore delle relative curve originali ( per ogni step) BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature ISURFFRPOVECTOR vSrfLimit ; // vettore delle superfici limite @@ -2574,12 +2678,14 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa m_pMchMgr->SetLastError( 2437, "Error in Pocketing : Slicing volume failed") ; return false ; } + // tolgo/aggiungo eventuali proiezioni - if ( ! ProjectVolume( pStmVol, pStm_Part, vVtTrasl[j-1], j == 1 ? V_INVALID : vVtTrasl[j-2], pSfrLimit, + if ( ! ProjectVolume( pStmVol, pStm_Part, vVtTrasl[j-1], j == 1 ? V_INVALID : vVtTrasl[j-2], bIsExtraStep, pSfrLimit, pSfrCurr, int( vVtTrasl.size()) == 1, dExtraLenInOut)) { m_pMchMgr->SetLastError( 2438, "Error in Pocketing : Projecting volume failed") ; return false ; } + // ricavo le proprietà di lato aperto/chiuso if ( ! ChooseCloseOrOpenEdge( pSfrCurr, ( bIsExtraStep && ! m_bPocketPlane) ? vStmES_Edges_OC[j-1] : pStm_Part, bIsExtraStep && ! m_bPocketPlane)) { @@ -2594,6 +2700,7 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa // salvo le curve originali per casi ottimizzati if ( ! GetCurvesForOptimizedPocketing( pSfrCurr, vCrvOEWithFlags[j-1])) return false ; + // modifico la supericie in base alle proprietà di lato aperto/chiuso PtrOwner pSfrNoExtension( CloneSurfFlatRegion( pSfrCurr)) ; if ( IsNull( pSfrNoExtension) || @@ -2601,12 +2708,14 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; return false ; } + // controllo se la superficie deriva da una lavorazione precedente if ( ! GetNewSfrByAnotherPocketing( pSfrCurr, pSfrNoExtension, pStmVol, pStm_Part, pSfrLimit)) { m_pMchMgr->SetLastError( 2440, "Error in Pocketing : Computing second pocket failed") ; return false ; } // inserisco la superficie nel vettore + pSfrCurr->SetTempProp( bIsExtraStep ? 1 : 0, 0) ; // salvo nella superficie se è riferita ad uno step Extra o no vSrfSliced[j-1].Set( Release( pSfrCurr)) ; // inserisco la superficie limite nel vettore vSfrLimit[j-1].Set( Release( pSfrLimit)) ; @@ -3007,7 +3116,7 @@ Pocketing::SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlan // recupero tutti i Loop ( se presenti) POLYLINEVECTOR vPL ; pStm->GetLoops( vPL) ; - for ( int p = 0 ; p < ( int)vPL.size() ; ++ p) { + for ( int p = 0 ; p < int( vPL.size()) ; ++ p) { // controllo la PolyLine è contenuta nel piano dove svuoto, altrimenti non la considero Plane3d plCheck ; double dArea ; Point3d ptCheck ; if ( vPL[p].IsClosedAndFlat( plCheck, dArea)) { @@ -3043,11 +3152,11 @@ Pocketing::SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlan //---------------------------------------------------------------------------- bool -Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, +Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol_, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, const bool bIsExtraStep, ISurfFlatRegion* pSfrResult) { // controllo dei parametri - if ( pStmVol == nullptr || ! pStmVol->IsValid() || + if ( pStmVol_ == nullptr || ! pStmVol_->IsValid() || pStm_Part == nullptr || ! pStm_Part->IsValid()) return false ; pSfrResult->Clear() ; @@ -3063,6 +3172,24 @@ Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pS SurfFlatRegionByContours SfrBC_final ; // vettore di PolyLines dalle quali construirò la superficie piana da svuotare POLYLINEVECTOR vPL ; + // Volume + PtrOwner pStmVol( CloneSurfTriMesh( pStmVol_)) ; + if ( IsNull( pStmVol) || ! pStmVol->IsValid()) + return false ; + + + // come prima cosa controllo che il volume sia ben definito e la TriMesh chiusa + if ( ! pStmVol->IsClosed()) { // ad esempio se ho una MaxElev dai parametri di lavorazione + POLYLINEVECTOR vPL_tmp ; + if ( ! pStmVol->GetLoops( vPL_tmp)) + return false ; + for ( int i = 0 ; i < int( vPL_tmp.size()) ; ++ i) { + Plane3d plTmp ; double dArea ; + if ( ! vPL_tmp[i].IsClosedAndFlat( plTmp, dArea) || + ! SewingMissingFacesOnPlanes( pStmVol, plTmp)) + return false ; + } + } // se si tratta di uno step extra e non devo svuotare tutto sul piano di pocketing... if ( bIsExtraStep && ! m_bPocketPlane) { @@ -3139,7 +3266,7 @@ Pocketing::CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pS bool Pocketing::CheckSideAngleForVolume( const ISurfTriMesh* pStmVol_Above, const ISurfTriMesh* pStm_Part, ISurfFlatRegion* pSfr_Projection, double& dExtraLenInOut, - ISurfFlatRegion* pSfr, ISurfFlatRegion* pSfrExtension) + ISurfFlatRegion* pSfr) { // NB. Questa funzione è chimata solo in caso ci sia uno Step e il tool non sia cilindrico @@ -3152,6 +3279,9 @@ Pocketing::CheckSideAngleForVolume( const ISurfTriMesh* pStmVol_Above, const ISu if ( ! pStmVol_Above->IsValid()) return true ; + // pulisco la superficie di proiezione + pSfr_Projection->Clear() ; + // chiudo il volume con il piano a Z minima ( quindi posso vedere semplicemente i Loop presenti) POLYLINEVECTOR vPL_tmp ; Point3d ptC_tmp ; @@ -3375,7 +3505,7 @@ Pocketing::GetDangerSfrForSideStep( const ISurfFlatRegion* pSfr, const ISurfTriM //---------------------------------------------------------------------------- bool Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, - const Vector3d& vtTrasl1, ISurfFlatRegion* pSfrLimit, ISurfFlatRegion* pSfr, + const Vector3d& vtTrasl1, const bool bIsExtraStep, ISurfFlatRegion* pSfrLimit, ISurfFlatRegion* pSfr, const bool bOneStep, double& dExtraLenInOut) { // controllo dei parametri @@ -3453,55 +3583,59 @@ Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_ if ( ! pStmAbove_Near->IsValid() || pStmBetween_Planes->GetTriangleCount() == 0) return true ; - // -------------------------------------------------------------------------------------------------- + // Ricavo la Proiezioni ( dei Chiusi C e degli aperti A ) + // ------------------------------------------------------------------------------------------------- - // per la superficie tra i due piani ricavo gli indici dei triangoli delle facce C ( tutti questi triangoli andranno - // rimossi lasciando quindi solo le facce A) - // NB. sul piano Far la TriMesh non presenta facce, bisogna riaggiungerle - //if ( ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plFar) || - // ! SewingMissingFacesOnPlanes( pStmBetween_Planes, plNear)) - // return false ; - - INTVECTOR vAllTria_C_between ; - for ( int f = 0 ; f < pStmBetween_Planes->GetFacetCount() ; ++ f) { - // ricavo i parametri della faccia - Point3d ptC_f ; Vector3d vtN_f ; - if ( ! pStmBetween_Planes->GetFacetCenter( f, ptC_f, vtN_f)) - return false ; - // controllo se si tratta di una faccia interna alla Part - DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ; - if ( distPtStm.IsPointInside()) { - // se faccia interna, prendo tutti i suoi tringoli ... - INTVECTOR vT ; - if ( ! pStmBetween_Planes->GetAllTriaInFacet( f, vT)) - return false ; - // ... e aggiungo i loro indici al vettore - for ( int t = 0 ; t < int( vT.size()) ; ++ t) - vAllTria_C_between.push_back( vT[t]) ; - } - } - // dalla superficie tra i due piani rimouovo i triangoli ottenuti - for ( int t = 0 ; t < int( vAllTria_C_between.size()) ; ++ t) - if ( ! pStmBetween_Planes->RemoveTriangle( vAllTria_C_between[t])) - return false ; - pStmBetween_Planes->DoCompacting() ; - - // se non ho ricavato nulla, allora significa che tutte le facce del volume di svuotatura comprese tra plNear e - // plFar sono chiuse, quindi non ho nulla da proiettare + // se si tratta di uno Step Extra, allora non considero la superficie di estensione + // ... rischio di svuotare anche tutto un possibile contorno esterno di + // spessore molto stretto... ( cambiando del tutto la geometria voluta ) PtrOwner pSfr_ExtendProjection( CreateSurfFlatRegion()) ; if ( IsNull( pSfr_ExtendProjection)) return false ; - if ( pStmBetween_Planes->IsValid() || pStmBetween_Planes->GetTriangleCount() > 0) { - // tutta questa superficie contiene solo facce A, le proietto sul piano plNear - if ( ! ProjectStmOnPlane( pStmBetween_Planes, plNear, pSfr_ExtendProjection)) - return false ; - // controllo ( per estrema sicurezza) la coerenza con le normali - if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfr_ExtendProjection->GetNormVersor())) - pSfr_ExtendProjection->Invert() ; - // NB. Questa superficie esce dal volume definito, devo stare attento a non rovinare parti di grezzo - if ( pSfrLimit->IsValid() && pSfr_ExtendProjection->IsValid()) { - if ( ! pSfr_ExtendProjection->Subtract( *pSfrLimit)) + + if ( ! bIsExtraStep) { + INTVECTOR vAllTria_C_between ; + for ( int f = 0 ; f < pStmBetween_Planes->GetFacetCount() ; ++ f) { + // ricavo i parametri della faccia + Point3d ptC_f ; Vector3d vtN_f ; + if ( ! pStmBetween_Planes->GetFacetCenter( f, ptC_f, vtN_f)) return false ; + // controllo se si tratta di una faccia interna alla Part + DistPointSurfTm distPtStm( ptC_f, *pStm_Part) ; + if ( distPtStm.IsPointInside()) { + // se faccia interna, prendo tutti i suoi tringoli ... + INTVECTOR vT ; + if ( ! pStmBetween_Planes->GetAllTriaInFacet( f, vT)) + return false ; + // ... e aggiungo i loro indici al vettore + for ( int t = 0 ; t < int( vT.size()) ; ++ t) + vAllTria_C_between.push_back( vT[t]) ; + } + } + // dalla superficie tra i due piani rimouovo i triangoli ottenuti + for ( int t = 0 ; t < int( vAllTria_C_between.size()) ; ++ t) + if ( ! pStmBetween_Planes->RemoveTriangle( vAllTria_C_between[t])) + return false ; + pStmBetween_Planes->DoCompacting() ; + + // se non ho ricavato nulla, allora significa che tutte le facce del volume di svuotatura comprese tra plNear e + // plFar sono chiuse, quindi non ho nulla da proiettare + if ( pStmBetween_Planes->IsValid() || pStmBetween_Planes->GetTriangleCount() > 0) { + // tutta questa superficie contiene solo facce A, le proietto sul piano plNear + if ( ! ProjectStmOnPlane( pStmBetween_Planes, plNear, pSfr_ExtendProjection)) + return false ; + // controllo ( per estrema sicurezza) la coerenza con le normali + if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfr_ExtendProjection->GetNormVersor())) + pSfr_ExtendProjection->Invert() ; + // se valida, la estendo leggermente ( evito intersezioni con Archi simili ) + if ( pSfr_ExtendProjection->IsValid()) + if ( ! pSfr_ExtendProjection->Offset( 5 * EPS_SMALL, ICurve::OFF_FILLET)) + return false ; + // NB. Questa superficie esce dal volume definito, devo stare attento a non rovinare parti di grezzo + if ( pSfrLimit->IsValid() && pSfr_ExtendProjection->IsValid()) { + if ( ! pSfr_ExtendProjection->Subtract( *pSfrLimit)) + return false ; + } } } @@ -3514,8 +3648,7 @@ Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_ return false ; if ( m_TParams.m_dSideAng != 0 && bOneStep) { - if ( ! CheckSideAngleForVolume( pStmAbove_Near, pStm_Part, pSfrProjection, dExtraLenInOut, - pSfr, pSfr_ExtendProjection)) + if ( ! CheckSideAngleForVolume( pStmAbove_Near, pStm_Part, pSfrProjection, dExtraLenInOut, pSfr)) return false ; } else { @@ -3550,11 +3683,16 @@ Pocketing::ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_ // tutta questa superficie contiene solo facce C, le proietto sul piano plNear if ( ! ProjectStmOnPlane( pStmAbove_Near, plNear, pSfrProjection)) return false ; + // se valida, la estendo leggermente ( evito intersezioni con Archi simili ) + if ( pSfrProjection->IsValid()) + if ( ! pSfrProjection->Offset( 50 * EPS_SMALL, ICurve::OFF_FILLET)) + return false ; // controllo ( per estrema sicurezza) la coerenza con le normali if ( AreOppositeVectorApprox( pSfr->GetNormVersor(), pSfrProjection->GetNormVersor())) pSfrProjection->Invert() ; } } + // ------------------------------------------------------------------------------------------------- // 1) La superficie con le facce A tra i due piani plNear e plFar indentificano una proeizione che estende la @@ -3694,7 +3832,7 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* // precedente ( l'attuale infatti svuoterà quello che rimane da svuotare proprio da questa lavorazione) // Vedi GetNewSfrByAnotherPocketing() - // creo la superifcie da restituire... ( questa superficie sarà estesa presso i lati aperti) + // creo la superficie da restituire... ( questa superficie sarà estesa presso i lati aperti) PtrOwner pSrfFinal( CreateSurfFlatRegion()) ; if ( IsNull( pSrfFinal)) return false ; @@ -3739,35 +3877,41 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* bIsChunkModified = true ; // la curva è stata modificata } - // 4) Controllo i bordi delle isole ottenute e modifico quelli in cui sono presenti lati aperti - for ( int i = 0 ; i < ( int)vCrvIsl.size() ; ++ i) { - bSomeOpen = false ; - nProp0 = -1 ; + // 4) Controllo i bordi delle isole ottenute + // NB. L'isola può essere tutta aperta o tutta chiusa ( se non uniforme, passo a tutta chiusa ) + // La definizione di isola con proprietà non uniformi non è definita... + for ( int i = 0 ; i < int( vCrvIsl.size()) ; ++ i) { + // controllo uniformità + int nCurrTmpProp = -1 ; + int nPrecTmpProp = -1 ; + bool bIsMixed = false ; PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ; - for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bSomeOpen ; ++ u) { - if ( pCrvIsl->GetCurveTempProp( u, nProp0, 0) && nProp0 == 1) - bSomeOpen = true ; + if ( IsNull( pCrvIsl) || ! pCrvIsl->IsValid()) + return false ; + for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bIsMixed ; ++ u) { + pCrvIsl->GetCurveTempProp( u, nCurrTmpProp, 0) ; + bIsMixed = ( u != 0 && nCurrTmpProp != nPrecTmpProp) ; + nPrecTmpProp = nCurrTmpProp ; } - if ( bSomeOpen) { // se trovo dei lati aperti ... - // 4.1) se l'isola è tutta aperta e "trascurabile" la tolgo + // se proprità non uniformi -> tutta chiusa + if ( bIsMixed) { + for ( int u = 0 ; u < pCrvIsl->GetCurveCount() ; ++ u) + pCrvIsl->SetTempProp( u, 0) ; + nCurrTmpProp = 0 ; // aggiorno il Flag + bIsChunkModified = true ; // la curva è stata modificata + } + // se curva tutta aperta, controllo se l'isola può essere trascurata + if ( nCurrTmpProp == 1) { bool bRemove = false ; if ( ! CheckForRemovingIsland( pCrvIsl, m_dDiam_Prec > 0 ? m_dDiam_Prec + m_dOffsetR_Prec : m_TParams.m_dDiam, bRemove)) return false ; - if ( bRemove) // se si può trascurare passo alla successiva + if ( bRemove) continue ; - // 4.2) sistemo la superificie - ICRVCOMPOPOVECTOR vCrvNULL ; - if ( ! AdjustContourWithOpenEdges( pCrvIsl, vCrvNULL, m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam, - m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), - m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), - pSfrLimit)) { - m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; - return false ; - } - bIsChunkModified = true ; // la curva è stata modificata } - vCrvToTIsland.emplace_back( pCrvIsl->Clone()) ; + for ( int u = 0 ; u < pCrvIsl->GetCurveCount() ; ++ u) + pCrvIsl->SetCurveTempProp( u, 0, 0) ; // lascio tutto chiuso, ho già esteso + vCrvToTIsland.emplace_back( pCrvIsl->Clone()) ; // entra nelle curve della regione da svuotare } // 6) Se c'è stata almeno una modifica di lato aperto al chunk (c-esimo), devo ricreare il Chunk @@ -6630,8 +6774,11 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& // modifico il punto di destinazione a seconda del tipo di attacco per tangenza Vector3d vtEnd = vtStart ; if ( ! vbOut[i]) { - if ( ! SetLeadInPointStart( ptCurr, vtTool, !m_Params.m_bInvert, vtStart, ptDest)) - return false ; + // controllo se sono in uno Step dove devo salire ( extraStep senza ordine in Z) + if ( vSfr[j-1]->GetTempProp( 0) == 0 && ! m_bOrderStepZ) { + if ( ! SetLeadInPointStart( ptCurr, vtTool, !m_Params.m_bInvert, vtStart, ptDest)) + return false ; + } } // calcolo il percorso di ritorno del percorso attuale if ( IsNull( pRCrv) || @@ -6793,9 +6940,7 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl // pCrvStepLink -> curva di collegamento tra Chunks o Steps diversi // controllo dei parametri - if ( ! ptS.IsValid() || ! ptE.IsValid() || - pSfr == nullptr || ! pSfr->IsValid() || - pCrvStepLink == nullptr) + if ( ! ptS.IsValid() || ! ptE.IsValid() || pSfr == nullptr || ! pSfr->IsValid() || pCrvStepLink == nullptr) return false ; pCrvStepLink->Clear() ; @@ -6805,7 +6950,11 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl if ( ! frCurr.IsValid()) return false ; // ricavo il punto finale proiettato sul piano Z = 0 ( quello di svuotatura attuale) - Point3d ptEProj = ptE ; ptEProj.ToLoc( frCurr) ; ptEProj.z = 0 ; + Point3d ptEProj = ptE ; ptEProj.ToLoc( frCurr) ; + double dDistZ = 0. ; // distanza in Z ( sarebbe lo Step ) ( extra... ?) + if ( ptEProj.z > 0) + dDistZ = ptEProj.z ; + ptEProj.z = 0 ; // Se il punto proiettato coincide con l'ORIG ( ptS) allora ho già finito ( il collegamento non serve) if ( AreSamePointEpsilon( ORIG, ptEProj, 200 * EPS_SMALL)) @@ -6913,7 +7062,7 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl return pCrvStepLink->AddPoint( ORIG) && pCrvStepLink->AddLine( ORIG + ( SAFE_Z_RET + dMAxElev) * Z_AX) && pCrvStepLink->AddLine( ptEProj + ( SAFE_Z_RET + dMAxElev) * Z_AX) && - ( dMAxElev - SAFE_Z_RET > 0 ? pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) : true) && + ( dMAxElev - SAFE_Z_RET > 0 ? pCrvStepLink->AddLine( ptEProj + ( dDistZ + SAFE_Z_RET) * Z_AX) : true) && pCrvStepLink->IsValid() && pCrvStepLink->ToGlob( frCurr) ; @@ -8017,9 +8166,6 @@ Pocketing::CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& if ( ! vOffs[i]->GetStartPoint( ptS)) return false ; - // ricavo l'iterazione corrente - int nCurrIter = int( vOffs[i]->GetTempParam( 0)) ; - int nNextInd = -1 ; // indice della curva successiva double dMinDist = INFINITO ; // distanza tra questa curva e la successiva Point3d ptStartNext ; // punto iniziale della curva successiva @@ -9546,7 +9692,7 @@ Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const if ( IsNull( pCompo) ) return false ; if ( ! pCompo->LocToLoc( GLOB_FRM, frLoc) ) - return false; + return false ; PtrOwner pCompoHelp( pLine->Clone()) ; if ( IsNull( pCompoHelp)) @@ -9555,7 +9701,7 @@ Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const return false ; // scorro il vettore degli indici degli offset delle isole intersecati - for ( int i = 0 ; i < int( vOffIslands.size()) ; i++) { + for ( int i = 0 ; i < int( vOffIslands.size()) ; i++) { CRVCVECTOR ccClass ; IntersCurveCurve intCC( *pCompo, *vOffIslands[i]) ; intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; @@ -9644,12 +9790,12 @@ Pocketing::CalcBoundedSmootedLink( const Point3d& ptStart, const Vector3d& vtSta bOk = IsPointInsidePolyLine( ptS_shift, PL, EPS_SMALL) || IsPointInsidePolyLine( ptE_shift, PL, EPS_SMALL) ; } - if ( ! CalcBoundedLink( bOk ? ptS_shift : ptStart, bOk ? ptE_shift : ptEnd, vOffIslands, pCrvLink)) - return false ; - pCrvLink->AddLine( ptStart, false) ; - pCrvLink->AddLine( ptEnd, true) ; - ModifyCurveToSmoothed( pCrvLink, 2.5, 2.5, false) ; - return true ; + if ( CalcBoundedLink( bOk ? ptS_shift : ptStart, bOk ? ptE_shift : ptEnd, vOffIslands, pCrvLink)) { + pCrvLink->AddLine( ptStart, false) ; + pCrvLink->AddLine( ptEnd, true) ; + ModifyCurveToSmoothed( pCrvLink, 2.5, 2.5, false) ; + return true ; + } } // se BiArco troppo grande allora lo modifico @@ -9969,9 +10115,10 @@ Pocketing::GetSignedDistFromRealDirection( const Point3d ptP, const Vector3d vtD if ( dDist > INFINITO - 1) { if ( ! GetSignedDistFromStmRaw( m_nPhase, ptP, -vtDir, dDist, vtNorm)) return false ; - // se ancora infinita, errore + // se ancora infinita, allora sono fuori completamente dal grezzo ( la dimensione della svuotatura + // è minore del raggio ) else if ( dDist > INFINITO - 1) - return false ; + dDist = 0 ; } return true ; @@ -10947,6 +11094,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVE ICRVCOMPOPOVECTOR vpCrvs ; if ( ! GetHomogeneousParts( pCrvCompo, vpCrvs)) return false ; + // NB. Il primo tratto è la prima metà del tratto aperto più lungo ( se esiste ) // Offset esterno per CurveJ double dDiamJ = 1.05 * ( dDiam) + 2 * dOffR ; @@ -10970,7 +11118,16 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVE double dParE = dParS + 1. * vpCrvs[i]->GetCurveCount() ; // se aperta if ( nCurrTmpProp == 1) { - if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, dRad, dDiamJ, pSfrLimit, vpCrvs[i])) + // ricavo la tangenze dei lati chiusi agli estremi di questa curva + Vector3d vtTanS = V_INVALID ; + Vector3d vtTanE = V_INVALID ; + if ( i != 0) { + if ( ! vpCrvs[i-1]->GetEndDir( vtTanS) || // tangente finale del chiuso precedente + ! vpCrvs[( i + 1) % int( vpCrvs.size())]->GetStartDir( vtTanE)) // tangente iniziale del chiuso successivo... + return false ; + vtTanE.Invert() ; // invertita + } + if ( ! AdjustOpenEdge( pCrvCompo, vCrvIsl, dParS, dParE, vtTanS, vtTanE, dRad, dDiamJ, pSfrLimit, vpCrvs[i])) return false ; } // assegno le proprietà di lato Aperto/Chiuso per la curva corrente @@ -10978,6 +11135,7 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVE vpCrvs[i]->SetCurveTempProp( u, nCurrTmpProp, 0) ; // aggiungo la curva ricavata ( se chiusa -> la copio, se aperta -> copio l'estesa) if ( ! pCrvCompo_final->AddCurve( vpCrvs[i]->Clone())) { + // per sicurezza, se gli estremi non coincidono, creo un piccolo raccordo lineare Point3d ptH ; vpCrvs[i]->GetStartPoint( ptH) ; if ( ! pCrvCompo_final->AddLine( ptH) || ! pCrvCompo_final->SetCurveTempProp( pCrvCompo_final->GetCurveCount() - 1, 1, 0) || @@ -10999,7 +11157,8 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVE //---------------------------------------------------------------------------- bool Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvIsland, - const double dParS, const double dParE, const double dRad, const double dDiamJ, + const double dParS, const double dParE, const Vector3d& vtTanS, + const Vector3d& vtTanE, const double dRad, const double dDiamJ, const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvBorder) { /* parametri : @@ -11008,6 +11167,8 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE pCrvOpenOffs -> tratto aperto corrente già Offsettato verso l'esterno dParS -> parametro sulla pCrvCompo per l'inizio del tratto aperto dParE -> parametro sulla pCrvCompo per la fine del tratto aperto + vtTanS -> vettore di tangenza finale tratto chiuso precedente + vtTanE -> vettore di tangenza iniziale ( invertito ) del tratto chiuso successivo dRad -> raggio di Offset per la regione di incidenza dDiamJ -> ampiezza delle curve a fagiolo per estendere la regione di incidenza pCrvRes -> curva da restituire ( inizialmente è il tratto aperto sulla pCrvCompo ; @@ -11026,12 +11187,12 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE // definisco la regione di incidenza PtrOwner pSfrInc( CreateSurfFlatRegion()) ; if ( IsNull( pSfrInc) || - ! CreateSurfFrIncidence( pCrvBorder, dRad, pSfrInc)) + ! CreateSurfFrIncidence( pCrvBorder, vtTanS, vtTanE, dRad + 75 * EPS_SMALL, pSfrInc)) return false ; // creo un vettore con tutte le curve che potrebbero cadere, in parte, nella regione di incidenza ICRVCOMPOPOVECTOR vCrvToCheck ; - for ( int i = 0 ; i < ( int)vCrvIsland.size() ; ++ i) + for ( int i = 0 ; i < int( vCrvIsland.size()) ; ++ i) vCrvToCheck.emplace_back( vCrvIsland[i]->Clone()) ; // aggiungo le isole // se la curva originale non è tutta Aperta -> devo aggiungere anche essa nelle curve da controllare bool bIsAllOpen = abs( abs( dParE - dParS) - pCrvCompo->GetCurveCount()) < EPS_SMALL ; @@ -11043,6 +11204,13 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE vCrvToCheck.emplace_back( Release( pCompoOther)) ; // aggiungo il bordo } + // controllo se la curva è un'isola ( normale del piano -Z_AX) + bool bIsIsland = false ; + double dArea ; Plane3d plCheck ; + if ( ! pCrvCompo->GetArea( plCheck, dArea)) + return false ; + bIsIsland = AreSameVectorEpsilon( plCheck.GetVersN(), - Z_AX, 10 * EPS_SMALL) ; + // scorro il vettore creato... for ( int c = 0 ; c < int( vCrvToCheck.size()) ; ++ c) { // 1) recupero la curva corrente @@ -11059,7 +11227,7 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE continue ; // 4) effettuo l'Offset della curva di metà dDiamJ OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5, ICurve::OFF_FILLET)) { + if ( ! OffsCrv.Make( vpCrvs[cl], - dDiamJ * 0.5 - 20 * EPS_SMALL, ICurve::OFF_FILLET)) { m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; return false ; } @@ -11093,6 +11261,7 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE // lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di // esso ! if ( pSfrLimit->IsValid()) { + pSfrInc->Offset( 50 * EPS_SMALL, ICurve::OFF_FILLET) ; if ( ! pSfrInc->Subtract( *pSfrLimit)) return false ; // può capitare che la regione Limite mi crei più Chunk sulla pSfrInc @@ -11115,26 +11284,19 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE // se estremi in comune, la curva cercata è la seguente if ( pCrvEL->IsPointOn( ptS, 300 * EPS_SMALL) && pCrvEL->IsPointOn( ptE, 300 * EPS_SMALL)) { if ( ! pNewSfrInc->IsValid()) // se la nuova regione di incidenza è vuota... - pNewSfrInc.Set( pSfrInc->CloneChunk( i)) ; // aggiorno.... + pNewSfrInc.Set( pSfrInc->CloneChunk( i)) ; // aggiorno... else // se la nuova regione di incidenza non è vuota... if ( ! pNewSfrInc->Add( * pSfrInc->CloneChunk( i))) // aggiungo... return false ; } } - // definisco quinfi la nuova regione di incidenza + // definisco quindi la nuova regione di incidenza if ( ! pNewSfrInc->IsValid()) return false ; pSfrInc.Set( Release( pNewSfrInc)) ; } } - // controllo se la curva è un'isola ( dall'area ) - bool bIsIsland = false ; - double dArea ; Plane3d plCheck ; - if ( ! pCrvCompo->GetArea( plCheck, dArea)) - return false ; - bIsIsland = AreSameVectorEpsilon( plCheck.GetVersN(), - Z_AX, 10 * EPS_SMALL) ; - // dalla regione di incidenza devo estrarre il tratto di bordo che ha per estremi i lati chiusi // ( stando al di fuori, quindi estendendomi all'esterno, della regione da svuotare ) PtrOwner pCrvNewBorder( ConvertCurveToComposite( pSfrInc->GetLoop( 0, 0))) ; @@ -11164,8 +11326,8 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE Point3d ptStart ; pCrvBorder->GetStartPoint( ptStart) ; Point3d ptEnd ; pCrvBorder->GetEndPoint( ptEnd) ; double dUTrimS, dUTrimE ; - pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 6000 * EPS_SMALL) ; - pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 6000 * EPS_SMALL) ; + pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 10000 * EPS_SMALL) ; + pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 10000 * EPS_SMALL) ; // pulisco la curva originale pCrvBorder->Clear() ; @@ -11181,7 +11343,8 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE //--------------------------------------------------------------------------- bool -Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, ISurfFlatRegion* pSfrInc) +Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, const Vector3d& vtTanE_, + const double dRad, ISurfFlatRegion* pSfrInc) { // controllo dei parametri if ( pCrv == nullptr || ! pCrv->IsValid()) @@ -11200,14 +11363,23 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ; } + // 1) *** // La regione di incidenza non deve avere un bordo distante dRad dagli estremi del tratto aperto // per questo motivo, creo due FlatRegion a rettangolo che andrò a sottrarre alla pSfrInc_tmp // ( tolgo i semi-dischi agli estremi ) + // 2) *** + // La regione di incidenza deve seguire seguire in tangenza il percorso agli estremi del tratto + // aperto corrente, creo due FlatRegion a rettangolo, orientate come le tangenza dei chiusi che andrò + // a sottrarre alla pSfrInc_tmp + + + // 1) *** + // Rettangolo all'inizio Vector3d vtTanS ; pCrv->GetStartDir( vtTanS) ; Point3d ptS ; pCrv->GetStartPoint( ptS) ; - Vector3d vtOut = vtTanS ; vtOut.Rotate( Z_AX, -90) ; + Vector3d vtOut = vtTanS ; vtOut.Rotate( Z_AX, - 90) ; PtrOwner pCrvRectSBorder( CreateCurveComposite()) ; if ( IsNull( pCrvRectSBorder)) return false ; @@ -11216,6 +11388,7 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad pCrvRectSBorder->AddLine( ptS - ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ; pCrvRectSBorder->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut - vtTanS * ( dRad + 500 * EPS_SMALL)) ; pCrvRectSBorder->Close() ; + //DrawSimpleCurve( pCrvRectSBorder) ; PtrOwner pSfrRectStart( CreateSurfFlatRegion()) ; if ( IsNull( pSfrRectStart) || ! pSfrRectStart->AddExtLoop( Release( pCrvRectSBorder)) || @@ -11227,7 +11400,7 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad // Rettangolo alla fine Vector3d vtTanE ; pCrv->GetEndDir( vtTanE) ; Point3d ptE ; pCrv->GetEndPoint( ptE) ; - vtOut = vtTanE ; vtOut.Rotate( Z_AX, -90) ; + vtOut = vtTanE ; vtOut.Rotate( Z_AX, - 90) ; PtrOwner pCrvRectEBorder( CreateCurveComposite()) ; if ( IsNull( pCrvRectEBorder)) return false ; @@ -11236,6 +11409,7 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad pCrvRectEBorder->AddLine( ptE - ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ; pCrvRectEBorder->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut + vtTanE * ( dRad + 500 * EPS_SMALL)) ; pCrvRectEBorder->Close() ; + //DrawSimpleCurve( pCrvRectEBorder) ; PtrOwner pSfrRectEnd( CreateSurfFlatRegion()) ; if ( IsNull( pSfrRectEnd) || ! pSfrRectEnd->AddExtLoop( Release( pCrvRectEBorder)) || @@ -11244,11 +11418,59 @@ Pocketing::CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectEnd->GetNormVersor())) pSfrRectEnd->Invert() ; + // 2) *** + + // Rettangolo all'inizio + Vector3d vtTanCS = vtTanS_ ; + Vector3d vtTanCE = vtTanE_ ; + PtrOwner pCrvRect_TanCLS_Border( CreateCurveComposite()) ; + if ( IsNull( pCrvRect_TanCLS_Border)) + return false ; + pCrvRect_TanCLS_Border->AddPoint( ptS) ; + pCrvRect_TanCLS_Border->AddLine( ptS + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCS) ; + vtOut = vtTanCS ; vtOut.Rotate( Z_AX, - 90) ; + pCrvRect_TanCLS_Border->AddLine( ptS + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCS + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRect_TanCLS_Border->AddLine( ptS + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRect_TanCLS_Border->Close() ; + //DrawSimpleCurve( pCrvRect_TanCLS_Border) ; + PtrOwner pSfrRectCLStart( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrRectCLStart) || + ! pSfrRectCLStart->AddExtLoop( Release( pCrvRect_TanCLS_Border)) || + ! pSfrRectCLStart->IsValid()) + return false ; + if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectCLStart->GetNormVersor())) + pSfrRectCLStart->Invert() ; + + // Rettangolo alla fine + PtrOwner pCrvRect_TanCLE_Border( CreateCurveComposite()) ; + if ( IsNull( pCrvRect_TanCLE_Border)) + return false ; + pCrvRect_TanCLE_Border->AddPoint( ptE) ; + pCrvRect_TanCLE_Border->AddLine( ptE + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCE) ; + vtOut = vtTanCE ; vtOut.Rotate( Z_AX, 90) ; + pCrvRect_TanCLE_Border->AddLine( ptE + ( 1.5 * dRad + 500 * EPS_SMALL) * vtTanCE + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRect_TanCLE_Border->AddLine( ptE + ( dRad + 500 * EPS_SMALL) * vtOut) ; + pCrvRect_TanCLE_Border->Close() ; + //DrawSimpleCurve( pCrvRect_TanCLE_Border) ; + PtrOwner pSfrRectCLEEnd( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrRectCLEEnd) || + ! pSfrRectCLEEnd->AddExtLoop( Release( pCrvRect_TanCLE_Border)) || + ! pSfrRectCLEEnd->IsValid()) + return false ; + if ( AreOppositeVectorApprox( pSfrInc->GetNormVersor(), pSfrRectCLStart->GetNormVersor())) + pSfrRectCLStart->Invert() ; + // alla superficie di incidenza, sottraggo i due rettangoli ricavati if ( ! pSfrInc->Subtract( *pSfrRectStart) || ! pSfrInc->Subtract( *pSfrRectEnd)) return false ; + // tolgo ora i rettangoli per le tangenze ai chiusi + pSfrInc->Subtract( *pSfrRectCLStart) ; + pSfrInc->Subtract( *pSfrRectCLEEnd) ; + + //DrawSimpleSurf( pSfrInc) ; + return pSfrInc->IsValid() && pSfrInc->GetChunkCount() > 0 ; } @@ -11934,9 +12156,10 @@ Pocketing::SetBetterPtStartForSubChunks( ICurveComposite* pCrvOffsAct, const ISu if ( nInd != -1) pCrv->ChangeStartPoint( nInd) ; // la prima curva non è un "raccordo" di Offset + for ( int i = 1 ; i < pCrv->GetCurveCount() ; ++ i) { double dLen = 0. ; - if ( pCrv->GetCurve( i)->GetLength( dLen) && dLen < 0.5 * m_TParams.m_dDiam) + if ( pCrv->GetCurve( i)->GetLength( dLen) && dLen < 0.025 * m_TParams.m_dDiam) pCrv->SetCurveTempProp( i, 0, 0) ; else { int nTmpProp0, nTmpProp1 ; @@ -11945,7 +12168,7 @@ Pocketing::SetBetterPtStartForSubChunks( ICurveComposite* pCrvOffsAct, const ISu // copio la temp prop della curva precedente pCrv->SetCurveTempProp( i, pCrv->GetCurve( i-1)->GetTempProp(), 0) ; // se troppo corta, allora chiusa - if ( pCrv->GetCurve( i)->GetLength( dLen) && dLen < 0.2 * m_TParams.m_dDiam) + if ( pCrv->GetCurve( i)->GetLength( dLen) && dLen < 0.01 * m_TParams.m_dDiam) pCrv->SetCurveTempProp( i, 0, 0) ; } } @@ -13784,7 +14007,8 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V // recupero info sui lati aperti int nPropOpen = pCompo->GetTempProp( 0) ; bool bEdgeOpen = (( nPropOpen & ( bLeadIn ? 8 : 2)) > 0) ; - bool bBaseOpen = (( nPropOpen & 1) > 0) ; + bool bBase0Open = (( nPropOpen & 1) > 0) ; + bool bBase1Open = (( nPropOpen & 4) > 0) ; // recupero info per capire se sto considerando un lato aggiuntivo per pulire angoli int nIdCrv = ( bLeadIn ? 0 : pCompo->GetCurveCount() - 1) ; @@ -13840,9 +14064,9 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V } // tento con attacco ruotato di 90° se non sto considerando un tratto aggiuntivo per pulire angoli - if ( bBaseOpen && ! bIsOutsideRaw && nExtraEdge == 0) { + if (( bBase0Open || bBase1Open) && ! bIsOutsideRaw && nExtraEdge == 0) { - Vector3d vtDirO = vtDir ; + Vector3d vtDirO = bBase0Open ? vtDir : - vtDir ; vtDirO.Rotate( vtExtr, ( m_Params.m_bInvert ? -90 : 90)) ; // calcolo distanza dal bordo del grezzo lungo vtDirO double dDist ; diff --git a/Pocketing.h b/Pocketing.h index ea7d9a8..943a1e3 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -69,6 +69,17 @@ class Pocketing : public Machining Pocketing( void) ; private : + // Debug functions ---- + void DrawLoopsSurf( const ISurfFlatRegion* pSfr, bool bWithSurf = true, Color Col = Color( 0., 0., 1., 0.45), + bool bAlphaCoverage = false) ; + void DrawSimpleSurf( const ISurfFlatRegion* pSrf, Color Col = Color( 0., 0., 1., 0.45)) ; + void DrawVectorCurves( const ICRVCOMPOPOVECTOR& vCrv) ; + void DrawSimpleCurve( const ICurveComposite* pCrv, bool bUniform = false) ; + void DrawSimpleTriMesh( const ISurfTriMesh* pStm, Color Col = Color( 0., 0., 0., 1.)) ; + void DrawSimplePoint( const Point3d& pT, Color Col = WHITE) ; + void DrawSimpleVector( const Vector3d& vt, Point3d ptPos = ORIG, Color Col = WHITE) ; + // -------------------- + bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; bool GetCurvesAndPartialVolume( SelData Id, ICURVEPLIST& lstPC, ISurfTriMesh* pStmTmp, Vector3d& vtN) ; bool GetForcedClosed( void) ; @@ -110,11 +121,10 @@ class Pocketing : public Machining bool CutVolumeByPlane( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, const bool bIsExtraStep, ISurfFlatRegion* pSfrResult) ; bool CheckSideAngleForVolume( const ISurfTriMesh* pStmVol_Sliced, const ISurfTriMesh* pStm_Part, - ISurfFlatRegion* pSfr_Projection, double& dExtraLenInOut, - ISurfFlatRegion* pSfr, ISurfFlatRegion* pSfrExtension) ; + ISurfFlatRegion* pSfr_Projection, double& dExtraLenInOut, ISurfFlatRegion* pSfr) ; bool ProjectVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const Vector3d& vtTrasl, - const Vector3d& vtTraslPrec, ISurfFlatRegion* pSfrOpenProjPrec, ISurfFlatRegion* pSfr, - const bool bOneStep, double& dExtraLenInOut) ; + const Vector3d& vtTraslPrec, const bool bIsExtraStep, ISurfFlatRegion* pSfrOpenProjPrec, + ISurfFlatRegion* pSfr, const bool bOneStep, double& dExtraLenInOut) ; bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm, const bool bOnIsClosed = false) ; bool SimplifySfrLoops( ISurfFlatRegion* pSfr) ; bool GetCurvesForOptimizedPocketing( ISurfFlatRegion* pSfr, ICRVCOMPOPOVECTOR& vCrvOEWithFlags) ; @@ -122,11 +132,13 @@ class Pocketing : public Machining bool AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvIsl, const double dDiam, const double dOffR, const double dStep, const ISurfFlatRegion* pSfrLimit) ; bool AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvIsland, - const double dParS, const double dParE, const double dRad, const double dDiamJ, + const double dParS, const double dParE, const Vector3d& vtTanS, + const Vector3d& vtTanE, const double dRad, const double dDiamJ, const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvBorder) ; bool GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStm, const ISurfTriMesh* pStmVol, const Vector3d& vtTrasl, ISurfFlatRegion* pSfrProj) ; - bool CreateSurfFrIncidence( const ICurveComposite* pCrv, const double dRad, ISurfFlatRegion* pSfrInc) ; + bool CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS, const Vector3d& vtTaneE, + const double dRad, ISurfFlatRegion* pSfrInc) ; bool GetNewSfrByAnotherPocketing( ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrNoExtendedByOpenEdges, const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, const ISurfFlatRegion* pSfrLimit) ;