diff --git a/EXE_GdbModifyCurve.cpp b/EXE_GdbModifyCurve.cpp index c3ff401..e406b6c 100644 --- a/EXE_GdbModifyCurve.cpp +++ b/EXE_GdbModifyCurve.cpp @@ -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 #include + 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 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 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 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 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 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 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 ; +} diff --git a/EgtExecutor.rc b/EgtExecutor.rc index 41809a5..4940cf8 100644 Binary files a/EgtExecutor.rc and b/EgtExecutor.rc differ diff --git a/LUA_GdbModifyCurve.cpp b/LUA_GdbModifyCurve.cpp index 4f35afd..09229f1 100644 --- a/LUA_GdbModifyCurve.cpp +++ b/LUA_GdbModifyCurve.cpp @@ -19,6 +19,7 @@ #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkLuaAux.h" +#include "/EgtDev/Include/EGkCalcPocketing.h" using namespace std ; @@ -968,6 +969,35 @@ LuaProjectCurveOnSurfTm( lua_State* L) return 1 ; } +//---------------------------------------------------------------------------- +static int +LuaPocketing( lua_State* L) { + // 7 parametri : vId, dRad, dStep, dAngle, nType, bSmooth, nDestGrpId + INTVECTOR vId ; + LuaCheckParam( L, 1, vId) ; + double dRad ; + LuaCheckParam( L, 2, dRad) ; + double dStep ; + LuaCheckParam( L, 3, dStep) ; + double dAngle ; + LuaCheckParam( L, 4, dAngle) ; + int nType ; + LuaCheckParam( L, 5, nType) ; + bool bSmooth ; + LuaCheckParam( L, 6, bSmooth) ; + int nDestGrpId ; + LuaCheckParam( L, 7, nDestGrpId) ; + LuaClearStack( L) ; + // calcolo delle curve elementari di svuotatura + int nFirstId ; + int nCrvCount ; + bool bOk = ExePocketing( vId, dRad, dStep, dAngle, nType, bSmooth, nDestGrpId, nFirstId, nCrvCount) ; + LuaSetParam( L, bOk) ; + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCrvCount) ; + return 3 ; +} + //------------------------------------------------------------------------------- bool LuaInstallGdbModifyCurve( LuaMgr& luaMgr) @@ -1024,5 +1054,6 @@ LuaInstallGdbModifyCurve( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtChainCurvesInGroup", LuaChainCurvesInGroup) ; bOk = bOk && luaMgr.RegisterFunction( "EgtReorderCurvesInGroup", LuaReorderCurvesInGroup) ; bOk = bOk && luaMgr.RegisterFunction( "EgtProjectCurveOnSurfTm", LuaProjectCurveOnSurfTm) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtPocketing", LuaPocketing) ; return bOk ; }