EgtExecutor 2.5k4 :

- aggiunta funzione Exe e Lua Pocketing.
This commit is contained in:
Riccardo Elitropi
2023-11-20 11:57:28 +01:00
parent de3cdb8a7f
commit 7b3f8a02f9
3 changed files with 308 additions and 0 deletions
+277
View File
@@ -40,8 +40,11 @@
#include "/EgtDev/Include/EGkPolygon3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkCalcPocketing.h"
#include <EgtDev/Include/EGkSfrCreate.h>
#include <functional>
using namespace std ;
//----------------------------------------------------------------------------
@@ -2351,3 +2354,277 @@ ExeProjectCurveOnSurfTm( int nCurveId, int nSurfTmId, const Vector3d& vtDir, int
return bOk ;
}
//----------------------------------------------------------------------------
static bool
MyChainCurves( const SELVECTOR vInds, ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo)
{
// preparo i dati per il concatenamento
bool bFirst = true ;
Point3d ptNear = ORIG ;
double dToler = 10 * EPS_SMALL ;
ChainCurves chainC ;
chainC.Init( true, dToler, int( vpCrvs.size())) ;
for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) {
// recupero la curva e il suo riferimento
ICurve* pCrv = vpCrvs[i] ;
if ( pCrv == nullptr)
continue ;
// recupero i dati della curva necessari al concatenamento e li assegno
Point3d ptStart, ptEnd ;
Vector3d vtStart, vtEnd ;
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) ||
! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd))
return false ;
if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd))
return false ;
// se prima curva, assegno inizio della ricerca
if ( bFirst) {
ptNear = ptStart + 10 * EPS_SMALL * vtStart ;
bFirst = false ;
}
}
// recupero i percorsi concatenati
INTVECTOR vnId2 ;
while ( chainC.GetChainFromNear( ptNear, false, vnId2)) {
// creo una curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo))
return false ;
// estrusione e spessore
Vector3d vtExtr = Z_AX ;
double dThick = 0 ;
// vettore Id originali
SELVECTOR vId2 ;
vId2.reserve( vnId2.size()) ;
// recupero le curve semplici e le inserisco nella curva composita
for ( size_t i = 0 ; i < vnId2.size() ; ++ i) {
int nId = abs( vnId2[i]) - 1 ;
bool bInvert = ( vnId2[i] < 0) ;
vId2.emplace_back( vInds[nId]) ;
// recupero la curva
ICurve* pCrv = vpCrvs[nId] ;
// se necessario, la inverto
if ( bInvert)
pCrv->Invert() ;
// recupero eventuali estrusione e spessore
Vector3d vtTemp ;
if ( pCrv->GetExtrusion( vtTemp)) {
vtExtr = vtTemp ;
double dTemp ;
if ( pCrv->GetThickness( dTemp) && abs( dTemp) > abs( dThick))
dThick = dTemp ;
}
// la aggiungo alla curva composta
if ( ! pCrvCompo->AddCurve( ::Release( vpCrvs[nId]), true, dToler))
return false ;
}
// se non sono state inserite curve, vado oltre
if ( pCrvCompo->GetCurveCount() == 0)
continue ;
// imposto estrusione e spessore
pCrvCompo->SetExtrusion( vtExtr) ;
pCrvCompo->SetThickness( dThick) ;
// aggiorno il nuovo punto vicino
pCrvCompo->GetEndPoint( ptNear) ;
// aggiungo la curva al vettore di curve composite concatenate
vCrvCompo.emplace_back( Release( pCrvCompo)) ;
}
return true ;
}
//----------------------------------------------------------------------------
static bool
MyGetCurves( SelData Id, ICURVEPLIST& lstPC, Vector3d& vtN)
{
// database geometrico
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false) ;
// ammessi : curve, testi, facce di trimesh o regioni
const IGeoObj* pGObj = pGeomDB->GetGeoObj( Id.nId) ;
if ( pGObj == nullptr)
return false ;
// ne recupero il riferimento globale
Frame3d frGlob ;
if ( ! pGeomDB->GetGlobFrame( Id.nId, frGlob))
return false ;
// se curva
if (( pGObj->GetType() & GEO_CURVE) != 0) {
PtrOwner<ICurve> pCurve ;
// se direttamente curva
if ( Id.nSub == SEL_SUB_ALL) {
// recupero la curva
const ICurve* pOriCurve = ::GetCurve( pGObj) ;
if ( pOriCurve == nullptr)
return false ;
pCurve.Set( pOriCurve->Clone()) ;
}
// altrimenti sottocurva di composita
else {
// recupero la composita
const ICurveComposite* pCompo = GetCurveComposite( pGObj) ;
if ( pCompo == nullptr)
return false ;
// recupero la curva semplice
const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ;
if ( pOriCurve == nullptr)
return false ;
// la duplico
pCurve.Set( pOriCurve->Clone()) ;
}
if ( IsNull( pCurve))
return false ;
// porto in globale
pCurve->ToGlob( frGlob) ;
// recupero estrusione
Vector3d vtExtr ;
// se estrusione mancante, imposto default
if ( ! pCurve->GetExtrusion( vtExtr) || vtExtr.IsSmall())
pCurve->SetExtrusion( Z_AX) ;
// corenza con vtTool
if ( ! vtN.IsValid())
vtN = vtExtr ;
else if ( ! AreSameVectorApprox( vtExtr, vtN))
return false ;
// verifico sia piana e se necessario la appiattisco
PtrOwner<ICurve> pFlatCrv( FlattenCurve( *pCurve, 50 * EPS_SMALL, 50 * EPS_ANG_SMALL, FLTCRV_USE_EXTR)) ;
if ( IsNull( pFlatCrv)) {
Plane3d plPlane ;
if ( ! pCurve->IsFlat( plPlane, true, 50 * EPS_SMALL))
;
else
;
return false ;
}
// aggiungo alla lista
lstPC.emplace_back( Release( pCurve)) ;
return true ;
}
// se altrimenti testo
else if ( pGObj->GetType() == EXT_TEXT)
return false ;
// se altrimenti superficie
else if ( pGObj->GetType() == SRF_TRIMESH)
return false ;
// se altrimenti regione
else if ( pGObj->GetType() == SRF_FLATRGN) {
// recupero la regione
const ISurfFlatRegion* pReg = ::GetSurfFlatRegion( pGObj) ;
if ( pReg == nullptr)
return false ;
PtrOwner<ISurfFlatRegion> pSfr( CloneSurfFlatRegion( pReg)) ;
if ( IsNull( pSfr))
return false ;
// porto in globale
pSfr->ToGlob( frGlob) ;
// recupero la normale della regione
Vector3d vtN_sfr = pSfr->GetNormVersor() ;
if ( vtN.IsSmall())
return false ;
if ( ! vtN.IsValid())
vtN_sfr = vtN ;
else if ( ! AreSameVectorApprox( vtN, vtN_sfr))
return false ;
// determino intervallo di chunk
int nCstart = 0 ;
int nCend = pSfr->GetChunkCount() ;
if ( Id.nSub != SEL_SUB_ALL) {
nCstart = Id.nSub ;
nCend = nCstart + 1 ;
}
// ciclo sui chunk
for ( int nC = nCstart ; nC < nCend ; ++ nC) {
// recupero i contorni del chunk
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; ++ nL) {
PtrOwner<ICurveComposite> pCrvLoop( ConvertCurveToComposite( pSfr->GetLoop( nC, nL))) ;
if ( IsNull( pCrvLoop))
return false ;
// unisco le eventuali parti allineate
pCrvLoop->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
// aggiungo il loop al vettore di curve
lstPC.emplace_back( Release( pCrvLoop)) ;
}
}
return true ;
}
// altrimenti errore
else
return false ;
}
//----------------------------------------------------------------------------
bool
ExePocketing( const INTVECTOR vId, double dRad, double dStep, double dAngle, int nType, bool bSmooth, int nDestGrpId,
int& nFirstId, int& nCrvCount)
{
// databse geometrico
IGeomDB* pGeomDB = GetCurrGeomDB() ;
VERIFY_GEOMDB( pGeomDB, false) ;
// vettore puntatori alle curve
ICURVEPOVECTOR vpCrvs ;
vpCrvs.reserve( vId.size()) ;
// vettore selettori delle curve originali
SELVECTOR vInds ;
// scorro le entità selezionate per creare la FlatRegion da svuotare
PtrOwner<ISurfFlatRegion> pSfrPock( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrPock))
return false ;
Vector3d vtN = V_INVALID ;
for ( auto& Id : vId) {
// vettore contente tutte le curve selezionate
ICURVEPLIST lstPC ;
if ( ! MyGetCurves( Id, lstPC, vtN))
; // entità scartata
for ( auto pCrv : lstPC) {
vpCrvs.emplace_back( pCrv) ;
vInds.emplace_back( Id) ;
}
}
// recupero i loop per pSfrPock dal concatenamento ( se necessario)
ICRVCOMPOPOVECTOR vCrvCompo ;
if ( ! MyChainCurves( vInds, vpCrvs, vCrvCompo))
return false ;
SurfFlatRegionByContours sfrBC ;
for ( int u = 0 ; u < int( vCrvCompo.size()) ; ++ u)
sfrBC.AddCurve( Release( vCrvCompo[u])) ;
// aggiorno pSfrPock
pSfrPock.Set( sfrBC.GetSurf()) ;
if ( IsNull( pSfrPock) || ! pSfrPock->IsValid())
return false ;
// recupero il riferimento del gruppo di destinazione
Frame3d frDest ;
if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest))
return false ;
// costruzione vettori di curve per Pocketing
ICRVCOMPOPOVECTOR vCrvCompoRes ;
// eseguo Pocketing
bool bOk = CalcPocketing( pSfrPock, dRad, dStep, dAngle, nType, bSmooth, vCrvCompoRes) ;
nFirstId = GDB_ID_NULL ; // primo Id da restituire
nCrvCount = int( vCrvCompoRes.size()) ;
if ( bOk && int( vCrvCompoRes.size()) > 0) {
// scorro le curve di Pocketing ottenute
for ( int u = 0 ; u < int( vCrvCompoRes.size()) ; ++ u) {
// inserisco la curva nel DB Geometrico
int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vCrvCompoRes[u])) ;
if ( nCurrId == GDB_ID_NULL)
return false ;
if ( u == 0)
nFirstId = nCurrId ; // memorizzo il primo Id da restituire
}
ExeSetModified() ;
}
if ( IsCmdLog()) {
string sLua = "EgtPocketing(" + ToString( vId) + "," +
ToString( dRad) + "," +
ToString( dStep) + "," +
ToString( dAngle) + "," +
ToString( nType) + ")" +
ToString( bSmooth) + ")" +
ToString( nDestGrpId) + ")" +
" -- Ok=" + ToString( bOk) + " FirstId=" + ToString( nFirstId) +
" nCurveCount=" + ToString( nCrvCount) ;
LOG_INFO( GetCmdLogger(), sLua.c_str()) ;
}
return bOk ;
}