EgtExecutor 2.5k4 :
- aggiunta funzione Exe e Lua Pocketing.
This commit is contained in:
@@ -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 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user