EgtMachKernel :

- migliorata gestione Archi
- migliorata gestioni lati aperti e gestione delle operazioni booleane tra regioni piane
- migliorie varie.
This commit is contained in:
Riccardo Elitropi
2024-03-01 17:51:23 +01:00
parent 0980e10c33
commit caee6ccb83
3 changed files with 374 additions and 138 deletions
+3 -3
View File
@@ -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]) ;
+353 -129
View File
@@ -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<ICurveComposite> 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<IGeoPoint3d> 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<IGeoVector3d> 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<ICRVCOMPOPOVECTOR> vCrvOEWithFlags; // vettore delle relative curve originali ( per ogni step)
vector<ICRVCOMPOPOVECTOR> 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<ISurfFlatRegion> 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<ISurfTriMesh> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ICRVCOMPOPOVECTOR>&
// 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ISurfFlatRegion> 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 ;
+18 -6
View File
@@ -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) ;