EgtMachKernel :
- finti lati aperti.
This commit is contained in:
+368
-84
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user