EgtMachKernel :

- finti lati aperti.
This commit is contained in:
Riccardo Elitropi
2023-07-17 13:42:53 +02:00
parent 1fef9786ac
commit 2a3a9fefe3
2 changed files with 376 additions and 88 deletions
+368 -84
View File
@@ -51,6 +51,7 @@
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
#include "/EgtDev/Include/EGkStmFromCurves.h"
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
#include <algorithm>
using namespace std ;
@@ -4411,7 +4412,7 @@ Pocketing::AddSpiralIn( const ISurfFlatRegion* pSrfPock, const Vector3d& vtTool,
nStep, vtTool, dElev, dDepth, dStep))
return false ;
return false ;
//return false ;
Point3d ptP1 ; // per LeadIn
// ciclo su tutti gli step
@@ -9051,7 +9052,7 @@ Pocketing::AdjustPathOutsideRawForOpenEdges( const ICurveComposite* pCompo, cons
if ( pStmRaw != nullptr) {
bool bIsChanged ;
if ( m_bIntersRaw)
IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false) ;
IntersSurfWithRaw( pSfrInc, pStmRaw, 1.01 * vtTrasl, bIsChanged, 1500 * EPS_SMALL, bInVsOut, false, false) ;
}
if ( bInVsOut) {
@@ -9409,7 +9410,7 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl
return false ;
if ( pSrf->GetChunkCount() == 0 || ! pSrf->IsValid())
return true ;
/*PtrOwner<ISurfFlatRegion> pSrf_toDraw( CloneSurfFlatRegion( pSrf)) ;
PtrOwner<ISurfFlatRegion> pSrf_toDraw( CloneSurfFlatRegion( pSrf)) ;
pSrf_toDraw->Translate( vtTrasl) ;
int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ;
m_pGeomDB->SetMaterial( a, AQUA) ;
@@ -9418,12 +9419,17 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl
const ICurveComposite* pCrvCompo( GetCurveComposite( pSrf_toDraw->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 aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ;
m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
if ( nProp1 != -99)
m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ;
else
m_pGeomDB->SetMaterial( aaa, Color( 1.0, 0.5, 0.0)) ;
}
}
}*/
}
}
// 2) PROIEZIONE CON GREZZO
if ( m_bProjectRaw) {
// recupero la Trimesh di partenza
@@ -9482,71 +9488,230 @@ Pocketing::AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const doubl
//----------------------------------------------------------------------------
bool
Pocketing::AdjustFakeOpenEdges( ISurfFlatRegion* pSrf, const ISurfFlatRegion* pSrfOrig, const Vector3d vtTrasl)
Pocketing::AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSfrOrig, const ISurfTriMesh* pStmRaw,
const Vector3d vtTrasl)
{
// controllo dei parametri
if ( pSrf == nullptr || ! pSrf->IsValid() || pSrf->GetChunkCount() == 0 ||
pSrfOrig == nullptr || ! pSrfOrig->IsValid() || pSrfOrig->GetChunkCount() == 0 ||
vtTrasl.IsSmall())
if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0)
return false ;
if ( pStmRaw == nullptr) // se non c'è grezzo...
return true ;
// creo un frame Locale
Frame3d frPock ;
Vector3d vtN = pSrf->GetNormVersor() ;
Point3d ptC ;
if ( ! pSrf->GetCentroid( ptC))
if ( ! pSrf->GetLoop( 0, 0)->GetStartPoint( ptC))
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->Clone()) ;
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrOrig->Clone()) ;
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRaw->Clone()) ;
// recupero le tmpProp, vettore estrusione e spessore
int nTmpProp0 = pCrvCompo->GetTempProp() ;
int nTmpProp1 = pCrvCompo->GetTempProp( 1) ;
Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ;
double dThick ; pCrvCompo->GetThickness( dThick) ;
// -------------------- TAGLIO IL GREZZO CON IL PIANO DEFINITO ALLO STEP ATTUALE -------------
// 1) CREAZIONE DEL PIANO
Plane3d plProj ;
Point3d ptCen ;
if ( ! pCrvCompo->GetCentroid( ptCen)) // punto
if ( ! pCrvCompo->GetStartPoint( ptCen))
return false ;
frPock.Set( ptC, vtN) ;
if ( ! frPock.IsValid())
Vector3d vtNorm = pSfrOrig->GetNormVersor() ; // normale
if ( vtNorm.IsSmall())
return false ;
// clono le superifici
PtrOwner<ISurfFlatRegion> pSrfAct( CloneSurfFlatRegion( pSrf)) ;
PtrOwner<ISurfFlatRegion> pSrfOrig_c( CloneSurfFlatRegion( pSrfOrig)) ;
if ( IsNull( pSrfAct) || ! pSrfAct->IsValid() || pSrfAct->GetChunkCount() == 0 ||
IsNull( pSrfOrig_c) || ! pSrfOrig_c->IsValid() || pSrfOrig_c->GetChunkCount() == 0)
plProj.Set( ptCen + vtTrasl, -vtNorm) ; // così taglio tutto cià che sta nel semipiano negativo dello step attuale
if ( ! plProj.IsValid())
return false ;
// 2) TAGLIO DEL GREZZO
PtrOwner<ISurfTriMesh> pSrfRaw_clone( CloneSurfTriMesh( pStmRaw)) ;
if ( IsNull( pSrfRaw_clone))
return false ;
if ( ! pSrfRaw_clone->Cut( plProj, true))
return false ;
if ( ! pSrfRaw_clone->IsValid() || pSrfRaw_clone->GetTriangleCount() == 0)
return true ;
// -------------------------------------------------------------------------------------------
// traslo la superificie da svuotare in modo da sovrapporla con la superificie originale
pSrfAct->Translate( - vtTrasl) ;
// ------- PROIEZIONE DELLE CURVE DI OGNI FACCIA DEL GREZZO RICAVATO SUL PIANO DELLA SVUOTATURA --------------
// Proietto ora le curve, delle facce della superificie ottenuta, sul piano della svuotatura
ICRVCOMPOPVECTOR vCrvExtProj ;
PtrOwner<ICurveComposite> pCrvCompo_Clone_Trasl( CloneCurveComposite( pCrvCompo)) ;
if ( IsNull( pCrvCompo_Clone_Trasl) || ! pCrvCompo_Clone_Trasl->IsValid())
return false ;
pCrvCompo_Clone_Trasl->Translate( vtTrasl) ;
vCrvExtProj.emplace_back( CloneCurveComposite( pCrvCompo_Clone_Trasl)) ; // come indice 0
// porto le due superifici nel frame locale
pSrfAct->ToLoc( frPock) ;
pSrfOrig_c->ToLoc( frPock) ;
// per ogni chunk c...
for ( int c = 0 ; c < pSrfAct->GetChunkCount() ; ++ c) {
// per ogni loop l...
for ( int l = 0 ; l < pSrfAct->GetLoopCount( c) ; ++ l) {
// ricavo la curva composita del loop
PtrOwner<ICurveComposite> pCrvCompo( GetCurveComposite( pSrfAct->GetLoop( c, l ))) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0)
for ( int f = 0 ; f < pSrfRaw_clone->GetFacetCount() ; ++ f) {
// controllo se la faccia è quasi perpendicolare, nel caso la salto
Vector3d vtN_check ; pSrfRaw_clone->GetFacetNormal( f, vtN_check) ;
if ( abs( vtN_check * vtNorm) < EPS_ZERO)
continue ;
POLYLINEVECTOR vPL ;
pSrfRaw_clone->GetFacetLoops( f, vPL) ;
// per ogni Loop l della faccia f
for ( int l = 0 ; l < ( int) vPL.size() ; ++ l) {
PtrOwner<ICurveComposite> pCrvBorder( CreateCurveComposite()) ;
if ( IsNull( pCrvBorder) || ! pCrvBorder->FromPolyLine( vPL[l]))
return false ;
// per ogni sottocurva della composita
for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
PtrOwner<ICurve> pCrv_u( pCrvCompo->GetCurve( u)->Clone()) ;
if ( IsNull( pCrv_u) || ! pCrv_u->IsValid())
return false ;
// ricavo la temp prop
int nTmpProp ; pCrv_u->GetTempProp( 0) ;
if ( nTmpProp == 0) {
// se si tratta di un lato aperto...
// 1) clono il lato
PtrOwner<ICurve> pCrv_uOpen_clone( pCrv_u->Clone()) ;
if ( IsNull( pCrv_uOpen_clone) || ! pCrv_uOpen_clone->IsValid())
return false ;
// 2) effettuo l'Offset
OffsetCurve OffsCrv ;
}
}
PtrOwner<ICurve> pCrvProjFacef( ProjectCurveOnPlane( *pCrvBorder, plProj)) ;
if ( IsNull( pCrvProjFacef) || ! pCrvProjFacef->IsValid())
return false ;
// controllo validità della curva ( che sia chiusa e non degenere)
double dArea = EPS_SMALL ;
Plane3d plCheck ;
if ( ! pCrvProjFacef->IsClosed() || ! pCrvProjFacef->GetArea( plCheck, dArea) || dArea <= EPS_SMALL)
continue ;
// creo la curva composita associata
PtrOwner<ICurveComposite> pCrvBorderProj_f( CreateCurveComposite()) ;
pCrvBorderProj_f->AddCurve( Release( pCrvProjFacef)) ;
vCrvExtProj.emplace_back( Release( pCrvBorderProj_f)) ;
}
}
//for ( int i = 0 ; i < vCrvExtProj.size() ; ++ i)
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvExtProj[i]->Clone()) ;
//-------------------------------------------------------------------------------------------------------------
// ---------------- CREAZIONE DELLA VERA A PROPRIA REGIONE DI INCIDENZA, COME SOMMA DELLE
// ----------------------------- SINGOLE FLATREGIONS DI PROIEZIONE -----------------------------
PtrOwner<ISurfFlatRegion> pSrf_Proj_Ext( CreateSurfFlatRegion()) ;
if ( IsNull( pSrf_Proj_Ext))
return false ;
for ( int i = 1 ; i < ( int)vCrvExtProj.size() ; ++ i) {
PtrOwner<ISurfFlatRegion> pSrf_H( CreateSurfFlatRegion()) ;
if ( IsNull( pSrf_H))
return false ;
pSrf_H->AddExtLoop( vCrvExtProj[i]->Clone()) ;
// inverto se le normali risultano opposte
if ( pSrf_H->IsValid()) {
if ( AreOppositeVectorApprox( pSrf_H->GetNormVersor() , pSfrOrig->GetNormVersor()))
pSrf_H->Invert() ;
}
if ( pSrf_Proj_Ext->GetChunkCount() == 0)
pSrf_Proj_Ext.Set( Release( pSrf_H)) ;
else
pSrf_Proj_Ext->Add( *Release( pSrf_H)) ;
}
// creo la vera e propria regione di proiezione, sommando la proiezione esterna con la superifcie originale da svuotare
PtrOwner<ISurfFlatRegion> pSrf_Proj( CloneSurfFlatRegion( pSrf_Proj_Ext)) ;
PtrOwner<ISurfFlatRegion> pSrf_ind0( CreateSurfFlatRegion()) ;
if ( IsNull( pSrf_Proj) || ! pSrf_Proj->IsValid() || IsNull( pSrf_ind0))
return false ;
pSrf_ind0->AddExtLoop( vCrvExtProj[0]->Clone()) ;
if ( AreOppositeVectorApprox( pSrf_ind0->GetNormVersor(), pSfrOrig->GetNormVersor()))
pSrf_ind0->Invert() ;
pSrf_Proj->Add( *pSrf_ind0) ;
int ooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_Proj->Clone()) ;
m_pGeomDB->SetMaterial( ooo, Color( 0.0, 1.0, 0.0, 0.3)) ;
// ===============================================================================================================
// Creo la nuova curva che dovrò restiturire alla fine della proiezione ( settando le rispettive proprietà)
PtrOwner<ICurveComposite> pCrvCompo_Final( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo_Final))
return false ;
pCrvCompo_Final->SetExtrusion( vtExtr) ;
pCrvCompo_Final->SetThickness( dThick) ;
pCrvCompo_Final->SetTempProp( nTmpProp0, 0) ;
pCrvCompo_Final->SetTempProp( nTmpProp1, 1) ;
// Clono la superificie originaria, portandola allo step corrente
PtrOwner<ISurfFlatRegion> pSrfOrig_clone( CloneSurfFlatRegion( pSfrOrig)) ;
if ( IsNull( pSrfOrig_clone) || ! pSrfOrig_clone->IsValid())
return false ;
pSrfOrig_clone->Translate( vtTrasl) ;
int oooo = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrfOrig_clone->Clone()) ;
m_pGeomDB->SetMaterial( oooo, Color( 0.0, 0.0, 0.0, 0.3)) ;
// controllo le curve della composita
bool bLoopL_isChanged = false ;
for ( int u = 0 ; u < pCrvCompo_Clone_Trasl->GetCurveCount() ; ++ u) {
PtrOwner<ICurve> pCrv_u( pCrvCompo_Clone_Trasl->GetCurve( u)->Clone()) ;
if ( IsNull( pCrv_u) || ! pCrv_u->IsValid())
return false ;
// ricavo la temp prop
int nTmpProp = pCrv_u->GetTempProp( 0) ;
if ( nTmpProp == 1) {
// se si tratta di un lato aperto...
// 1) clono il lato
PtrOwner<ICurve> pCrv_uOpen_clone( pCrv_u->Clone()) ;
if ( IsNull( pCrv_uOpen_clone) || ! pCrv_uOpen_clone->IsValid())
return false ;
pCrv_uOpen_clone->SetExtrusion( vtExtr) ;
// 2) effettuo l'Offset
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCrv_uOpen_clone, m_dDiam_Prec > 0 ? 0.5 * m_dDiam_Prec + m_dOffsetR_Prec :
0.5 * m_TParams.m_dDiam + GetOffsR(), ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0)
return false ;
// 3) ricavo la curva di Offset
PtrOwner<ICurve> pCrv_uOpen_Offs( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pCrv_uOpen_Offs) || ! pCrv_uOpen_Offs->IsValid())
return false ;
return true ;
// TOGLIEREEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE---
PtrOwner<ICurve> hhhhhh( pCrv_uOpen_Offs->Clone()) ;
int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, hhhhhh->Clone()) ;
m_pGeomDB->SetMaterial( aaa, YELLOW) ;
// -------------------------------------------------------------------------------------------------
// 4) classifico la curva di offset ricavata con la supericie originale
// NB. Tutti tratti di curva che sono esterni alla superificie originale e che si trovano all'interno della
// superificie di proeizione del grezzo lo rovineranno al di fuori della superficie originale, quindi
// vanno impostati come chiusi
CRVCVECTOR ccClass ;
if ( pSrfOrig_clone->GetCurveClassification( *pCrv_uOpen_Offs, 10 * EPS_SMALL, ccClass)) {
for ( int j = 0 ; j < ( int)ccClass.size() ; ++ j) {
// 5) scorro tutti i tratti di curva della classificazione
// NB. I parametri sulla curva di Offset e sulla curva originale sono in proporizione ( la curva
// è singola, quindi non ci sono raccordi). Posso quindi sfruttare i parametri della classificazione
// della curva Offsettata e utilizzarli per spezzare in sottocurve la curva originaria
PtrOwner<ICurve> pCrv_j_Offs( pCrv_uOpen_Offs->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
PtrOwner<ICurve> pCrv_uj( pCrv_u->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE)) ;
if ( IsNull( pCrv_j_Offs) || ! pCrv_j_Offs->IsValid() || IsNull( pCrv_uj) || ! pCrv_uj->IsValid())
continue ;
if ( ccClass[j].nClass == CRVC_OUT) {
CRVCVECTOR ccClass1 ;
bool bSetClose = false ;
if ( pSrf_Proj->GetCurveClassification( *pCrv_j_Offs, EPS_SMALL, ccClass1)) {
for ( int jj = 0 ; jj < ( int)ccClass1.size() && !bSetClose ; ++ jj) {
if ( ccClass1[jj].nClass == CRVC_IN) {
bLoopL_isChanged = true ;
bSetClose = true ;
//int ff = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_uj->Clone()) ;
//m_pGeomDB->SetMaterial( ff, Color( 0.95, 0.0, 0.63)) ;
}
}
}
pCrv_uj->SetTempProp( !bSetClose, 0) ;
pCrv_uj->SetTempProp( bSetClose ? -99 : 0, 1) ;
}
pCrvCompo_Final->AddCurve( pCrv_uj->Clone()) ;
} // chiusura ciclo for sui tratti di classificazione...
}
else // se classificazione errata -> lascio la curva invariata
pCrvCompo_Final->AddCurve( pCrv_u->Clone()) ;
}
else // se curva chiusa, la aggiungo
pCrvCompo_Final->AddCurve( pCrv_u->Clone()) ;
//m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo_Final->Clone()) ;
}
// se ci sono stati cambiamenti nella curva ...
if ( ! bLoopL_isChanged)
return true ;
// altrimenti sotituisco la curva originale, traslo e miglioro...
if ( pCrvCompo_Final != nullptr && pCrvCompo_Final->IsValid() && pCrvCompo_Final->IsClosed()) {
pCrvCompo_Final->Translate( - vtTrasl) ;
pCrvCompo_Final->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ;
pCrvCompo->Clear() ;
pCrvCompo->CopyFrom( pCrvCompo_Final) ;
}
return pCrvCompo != nullptr && pCrvCompo->IsValid() && pCrvCompo->GetCurveCount() > 0 ;
}
//----------------------------------------------------------------------------
@@ -9685,7 +9850,8 @@ Pocketing::ModifySurfByOpenEdge( ISurfFlatRegion* pSrf, ICRVCOMPOPOVECTOR& vCrvO
//----------------------------------------------------------------------------
bool
Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pStmRaw, const Vector3d& vtTrasl,
bool& bIsChanged, double dAreaToll, bool bInVsOut, bool bRemoveSmallRawParts)
bool& bIsChanged, double dAreaToll, bool bInVsOut, bool bRemoveSmallRawParts,
bool bComputeOpenEdge)
{
// se funzione non necessaria, esco subito
@@ -9760,9 +9926,14 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt
// essendo una curva derivante da un'intersezione di Trimesh ho una composita derivante da una polyLine,
// devo recuperare gli archi
PolyArc PA ;
Frame3d frPock ; frPock.Set( ptC, vtN) ;
if ( ! frPock.IsValid())
return false ;
pCrv->ToLoc( frPock) ;
pCrv->ApproxWithArcsEx( 5 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; // 500 * EPS_SMALL
pCrv->Clear() ;
pCrv->FromPolyArc( PA) ;
pCrv->ToGlob( frPock) ;
pCrv->SetExtrusion( vtExtr) ;
pCrv->SetThickness( dThick) ;
@@ -9825,9 +9996,12 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt
// riporto la superificie tagliata alla quota originale
pSrfByCurves->Translate( - vtTrasl) ;
// ricalcolo i lati aperti
if ( ! SetOpenOrCloseEdge( pSrfByCurves, pSfrPock))
return false ;
// ricalcolo i lati aperti ( se richisto)
if ( bComputeOpenEdge) {
PtrOwner<ISurfTriMesh> pStmRaw_clone( CloneSurfTriMesh( pStmRaw)) ;
if ( IsNull( pStmRaw_clone) || ! SetOpenOrCloseEdge( pSrfByCurves, pSfrPock, false, pStmRaw_clone, vtTrasl))
return false ;
}
// modifico la superficie da svuotare
pSfrPock->Clear() ;
@@ -9838,7 +10012,8 @@ Pocketing::IntersSurfWithRaw( ISurfFlatRegion* pSfrPock, const ISurfTriMesh* pSt
//----------------------------------------------------------------------------
bool
Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj)
Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj,
ISurfTriMesh* pStmRaw, Vector3d vtTrasl)
{
// controllo parametri
if ( pSrfTP == nullptr || pSrfTP->GetChunkCount() == 0 || pSrfOrig == nullptr || pSrfOrig->GetChunkCount() == 0)
@@ -9867,13 +10042,15 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p
for ( int c = 0 ; c < pSrfTP->GetChunkCount() ; ++ c) {
// per ogni loop ...
for ( int l = 0 ; l < pSrfTP->GetLoopCount( c) ; ++ l) {
// ricavo il loop come curva composita
PtrOwner<ICurveComposite> pCrv( GetCurveComposite( pSrfTP->GetLoop( c, l))) ;
if ( IsNull( pCrv))
return false ;
// sistemazioni varie
pCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
for ( int i = 0 ; i < pCrv->GetCurveCount() ; ++ i) {
pCrv->SetCurveTempProp( i, -1, 0) ; // setto proprietà da definire di default
if ( !bFromProj) // se non derivo da una proiezione, setto di Defualt le tmp prop della curva a -1
pCrv->SetCurveTempProp( i, -1, 0) ; // setto proprietà da definire di default
for ( int j = 0 ; j < ( int)vCrvAll.size() ; ++ j) {
int nStat = 0 ;
if ( ! SetTmpPropByOverlap( pCrv, i, vCrvAll[j], nStat, 1500 * EPS_SMALL))
@@ -9882,15 +10059,9 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p
break ;
}
}
/*for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) {
int nProp0 ; pCrv->GetCurveTempProp( u, nProp0, 0) ;
int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->GetCurve( u)->Clone()) ;
m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? AQUA : ORANGE) ;
}*/
// sistemo gli errori dovuti alle tolleranze
if ( ! CheckSmallPartsForOpenEdge( pCrv))
return false ;
// controllo che le isole definite sulla superificie originale siano coerenti con le nuove isole ricavate
ICRVCOMPOPOVECTOR vAllCrv_Isl ;
for ( int i = nExtLoop ; i < ( int)vCrvAll.size() ; ++ i) {
@@ -9924,8 +10095,8 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p
}
}
// controllo le sottocurve non definite ( non se sono nel caso di una proeizione)
for ( int i = 0 ; i < pCrv->GetCurveCount() && !bFromProj ; ++ i) { // nei casi di curve nuove ma senza overlap con isole ...
// controllo le sottocurve non definite con TmpProp = -1 ( non se sono nel caso di una proeizione)
for ( int i = 0 ; i < pCrv->GetCurveCount() && !bFromProj ; ++ i) {
int nProp ;
if ( pCrv->GetCurveTempProp( i, nProp) && nProp == -1) {
// controllo che quel lato non abbia un estremo in comune con un'isola
@@ -9939,16 +10110,13 @@ Pocketing::SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* p
pCrv->SetTempProp( nProp0, 0) ;
pCrv->SetTempProp( nProp1, 1) ;
//for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) {
// int nProp0 ; pCrv->GetCurveTempProp( u, nProp0, 0) ;
// int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->GetCurve( u)->Clone()) ;
// m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : ( nProp0 == 1) ? RED : GREEN) ;
//}
// controllo se i lati aperti impostati sono effettivamente aperti ( se non sono nella proieizone)
if ( ! bFromProj)
if ( ! AdjustFakeOpenEdges( pCrv, pSrfOrig, pStmRaw, vtTrasl))
return false ;
// aggiungo la curva alla nuova superificie
pSrfMod.AddCurve( pCrv->Clone()) ;
}
}
@@ -10747,7 +10915,7 @@ Pocketing::GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pSt
}
}
return false ;
return true ;
}
@@ -10986,7 +11154,7 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl,
if ( IsNull( pSrfOnPlPlus) || ! GetProjStmOnSfr( pSrf_clone_ChunkC, pStmRaw, pSrfOrig, pSrfOnPlPlus))
return false ;
if ( IsNull( pSrfOnPlPlus) || ! pSrfOnPlPlus->IsValid() || pSrfOnPlPlus->GetChunkCount() == 0)
continue ;
pSrfOnPlPlus.Set( pSrf_clone_ChunkC) ;
// inseirsco nel vettore
vSfr_gained.emplace_back( pSrfOnPlPlus->Clone()) ;
@@ -10994,8 +11162,59 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl,
// sommo il nuovo chunk ottenuto alla regione finale di proiezione
if ( pSrf_Final->GetChunkCount() == 0)
pSrf_Final.Set( Release( pSrfOnPlPlus)) ;
else
pSrf_Final->Add( *Release( pSrfOnPlPlus)) ;
else {
if ( ! pSrf_Final->Add( *pSrfOnPlPlus->Clone())) {
// ricavo il piano di svuotatura, estrusione e spessore
Plane3d plPock ;
PtrOwner<ICurve> pCrvH( pSrf->GetLoop( 0, 0)) ;
if ( IsNull( pCrvH) || ! pCrvH->IsValid())
return false ;
Point3d ptC ;
if ( ! pCrvH->GetCentroid( ptC))
if ( ! pCrvH->GetStartPoint( ptC))
return false ;
Vector3d vtN = pSrf->GetNormVersor() ;
plPock.Set( ptC, vtN) ;
if ( ! plPock.IsValid())
return false ;
plPock.Translate( vtTrasl) ;
Vector3d vtExtr ; pCrvH->GetExtrusion( vtExtr) ;
double dThick ; pCrvH->GetThickness( dThick) ;
// converto le due regioni in Trimesh
PtrOwner<ISurfTriMesh> pStm1( CloneSurfTriMesh( pSrf_Final->GetAuxSurf())) ;
PtrOwner<ISurfTriMesh> pStm2( CloneSurfTriMesh( pSrfOnPlPlus->GetAuxSurf())) ;
int rr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm1->Clone()) ;
int rrr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm2->Clone()) ;
m_pGeomDB->SetMaterial( rr, RED) ;
m_pGeomDB->SetMaterial( rrr, ORANGE) ;
if ( ! IsNull( pStm1) && ! IsNull( pStm2) && pStm1->IsValid() && pStm2->IsValid()) {
// controllo validità delle normali
Vector3d vtN1, vtN2 ;
if ( pStm1->GetFacetNormal( 0, vtN1) && pStm2->GetFacetNormal( 0, vtN2) &&
AreOppositeVectorApprox( vtN1, vtN2))
pStm2->Invert() ;
// creo la Zuppa di triangoli
StmFromTriangleSoup sTM_TSoup ;
sTM_TSoup.Start() ;
sTM_TSoup.AddSurfTriMesh( *Release( pStm1)) ;
sTM_TSoup.AddSurfTriMesh( *Release( pStm2)) ;
sTM_TSoup.End() ;
// ricavo la Trimesh della zuppa di triangoli
PtrOwner<ISurfTriMesh> pStmResult( sTM_TSoup.GetSurf()) ;
//pStm1->Add( *Release( pStm2)) ;
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmResult->Clone()) ;
if ( ! IsNull( pStmResult) && pStmResult->IsValid()) {
// dalla TriMesh ricavata ne estraggo la FlatRegion
PtrOwner<ISurfFlatRegion> pSfrResult( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrResult))
return false ;
if ( GetSfrByStm( pStmResult, pSfrResult, plPock, vtExtr, dThick))
pSrf_Final.Set( Release( pSfrResult)) ;
}
return false ;
}
}
}
}
// può capitare che da due Chunk distinti, mediante la proeizione questi si uniscano formandone uno solo...
@@ -11012,12 +11231,12 @@ Pocketing::ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrasl,
SetOpenOrCloseEdge( pSrfChunk_c, vSfr_gained[i], true) ;
if ( pSrf_Final_WithOCEdge->GetChunkCount() == 0)
pSrf_Final_WithOCEdge.Set( Release( pSrfChunk_c)) ;
pSrf_Final.Set( Release( pSrfChunk_c)) ;
else
pSrf_Final->Add( *Release( pSrfChunk_c)) ;
}
}
// aggiungo tutte le isole... <---------- !!!
// aggiungo tutte le isole...
for ( int is = 0 ; is < ( int)vCrvIsl.size() ; ++ is)
pSrf_Final->AddIntLoop( Release( vCrvIsl[is])) ;
@@ -12738,4 +12957,69 @@ Pocketing::GetDynamicClearedRegion( ISurfFlatRegion* pSrfPrec, const ICurveCompo
}
return true ;
}
//----------------------------------------------------------------------------
bool
Pocketing::GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const Plane3d plPock, const Vector3d& vtExtr,
const double dThick, double dToll)
{
// controllo validità dei parametri
if ( pStm == nullptr || ! pStm->IsValid() ||
! plPock.IsValid())
return false ;
// creo un Frame per il sistema di Riferimento Locale
Frame3d frPock ; frPock.Set( plPock.GetPoint(), plPock.GetVersN()) ;
if ( ! frPock.IsValid())
return false ;
// creo la FlatRegion da resitutiure
SurfFlatRegionByContours SrfChunkDef ;
// recupero i Loop della TriMesh salvandoli in un vettore di PolyLine
POLYLINEVECTOR vPl ;
pStm->GetLoops( vPl) ;
// per ogni PolyLine...
for ( int i = 0 ; i < ( int)vPl.size() ; ++ i) {
// recupero la curva composita
PolyLine PL = vPl[i] ;
PtrOwner<ICurveComposite> pCrv( CreateCurveComposite()) ;
pCrv->FromPolyLine( PL) ;
int yy = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( yy, GREEN) ;
// essendo una curva derivante da un'intersezione di Trimesh ho una composita derivante da una polyLine,
// devo recuperare gli archi
PolyArc PA ;
pCrv->ToLoc( frPock) ;
pCrv->ApproxWithArcsEx( 5 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA) ; // 500 * EPS_SMALL
pCrv->Clear() ;
pCrv->FromPolyArc( PA) ;
pCrv->ToGlob( frPock) ;
pCrv->SetExtrusion( vtExtr) ;
pCrv->SetThickness( dThick) ;
int yyy = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( yyy, BLACK) ;
// la converto in una semplice cruva per proiettarla su piano della svuotatura
// dato che le curve sono prese da una trimesh, le proietto sul piano per sicurezza e per evitare approssimazioni
double dS, dE ;
pCrv->GetDomain( dS, dE) ;
PtrOwner<ICurve> pCrv_c( pCrv->CopyParamRange( dS, dE)) ;
if ( IsNull( pCrv_c) || ! pCrv_c->IsValid())
return false ;
PtrOwner<ICurve> pCrv_proj( ProjectCurveOnPlane( *pCrv_c, plPock)) ;
int y = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv_proj->Clone()) ;
m_pGeomDB->SetMaterial( y, YELLOW) ;
SrfChunkDef.AddCurve( Release( pCrv_proj)) ; // aggiungo le curve proiettate
}
// recupero la FlatRegion
PtrOwner<ISurfFlatRegion> pSrfByCurves( SrfChunkDef.GetSurf()) ;
if ( IsNull( pSrfByCurves) || pSrfByCurves->GetChunkCount() == 0) // controllo validità della FlatRegion
return false ;
// restituisco la FlatRegion
pSfr->Clear() ;
pSfr->CopyFrom( pSrfByCurves) ;
return pSfr != nullptr && pSfr->IsValid() ;
}
+8 -4
View File
@@ -88,6 +88,8 @@ class Pocketing : public Machining
// ===================================================================
// =========================== GREZZO e GEOMETRIE ====================
bool GetSfrByStm( const ISurfTriMesh* pStm, ISurfFlatRegion* pSfr, const Plane3d plPock, const Vector3d& vtExtr,
const double dThick, double dToll = 5 * EPS_SMALL) ;
bool ProjectEdgesOnSelFace( const ISurfFlatRegion* pSfrFacet, const ISurfTriMesh* pStmEdge, INTVECTOR& vBannedId ,
int nFacet, ISurfFlatRegion* pSfrProj) ;
bool GetSurfByAdj( const ISurfTriMesh* pSrfOri, INTVECTOR& vBannedId, int idCurrFace) ;
@@ -97,18 +99,20 @@ class Pocketing : public Machining
const double& dDepth, const double& dStep) ;
bool AdaptSfrWithRaw( ISurfFlatRegion* pSrf, Vector3d vtTrasl, const double& dRawSecLen,
ICRVCOMPOPOVECTOR& vCrvOEFlags, bool& bChanged, double dAreaToll = 500 * EPS_SMALL) ;
bool AdjustFakeOpenEdges( ISurfFlatRegion* pSrf, const ISurfFlatRegion* pSrfOrig, const Vector3d vtTrasl) ;
bool AdjustFakeOpenEdges( ICurveComposite* pCrvCompo, const ISurfFlatRegion* pSrfOrig, const ISurfTriMesh* pStmRaw,
const Vector3d vtTrasl) ;
bool GetStmRawPart( int nId, ISurfTriMesh* pSrfTMRaw, Frame3d frPocket = GLOB_FRM) ;
bool CheckSmallPartsForOpenEdge( ICurveComposite* pCrvCompo, double dToll = 1500 * EPS_SMALL) ;
bool SetTmpPropWithRawProjectedFaces( ICurveComposite* pCrvCompo_NewExt, ICRVCOMPOPOVECTOR& vCrvExtProj,
const Vector3d& vtN, double dToll = 150 * EPS_SMALL) ;
bool IntersSurfWithRaw( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm, const Vector3d& vtTrasl,
bool& bIsChanged, double dAreaToll = 500 * EPS_SMALL, bool bInVsOut = true,
bool bRemoveSmallRawParts = false) ;
bool bRemoveSmallRawParts = false, bool bComputeOpenEdge = true) ;
bool ProjectRaw( ISurfFlatRegion* pSrf, const Vector3d& vtTrals, const ISurfTriMesh* pSrfProjRaw, int nId,
const double& dRawSecLen, const ISurfFlatRegion* pSrfOrig, double dAreaToll = 500 * EPS_SMALL) ;
bool AdjustAngleForProjectedFace( const ISurfFlatRegion* pSrfFaceT, ICurveComposite* pCrvEdgeBorder, double dAngle) ;
bool SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfO, bool bFromProj = false) ;
bool SetOpenOrCloseEdge( ISurfFlatRegion* pSrfTP, const ISurfFlatRegion* pSrfOrig, bool bFromProj = false,
ISurfTriMesh* pStmRaw = nullptr, Vector3d vtTrasl = V_NULL) ;
bool GetProjStmOnSfr( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, const ISurfFlatRegion* pSrfOrig,
ISurfFlatRegion* pSfrRawBoxProj) ;
bool CutProjectionToFitShape( ISurfFlatRegion* pSrfProjected, const ISurfFlatRegion* pSrfOrig) ;
@@ -325,7 +329,7 @@ class Pocketing : public Machining
bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo
double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto
bool m_bIntersRaw = true ; // flag per intersezione con grezzo
bool m_bProjectRaw = true ; // flag di proiezione del grezzo
bool m_bProjectRaw = false ; // flag di proiezione del grezzo
double m_dMaxLenRawProj = 100 ; // lunghezza massima per contatto di proiezione
bool m_bOptOffset = true ; // flag per ottimizzazione numero di Offset necessari
bool m_bOptOffsetCM = false ; // flag per ottimizzazione numero di Offset necessari con centroidi e medial Axis