diff --git a/EXE_Trimming.cpp b/EXE_Trimming.cpp new file mode 100644 index 0000000..c7f3cea --- /dev/null +++ b/EXE_Trimming.cpp @@ -0,0 +1,797 @@ +//---------------------------------------------------------------------------- +// EgalTech 2025-2025 +//---------------------------------------------------------------------------- +// File : EXE_Trimming.cpp Data : 25.10.25 Versione : 2.7j3 +// Funzioni per le lavorazioni di Trimming. +// +// Modifiche : 23.10.25 RE Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "EXE.h" +#include "EXE_Macro.h" +#include "DllExchange.h" +#include "GeoTools.h" +#include "AuxTools.h" +#include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EXeExecutor.h" +#include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkSurfLocal.h" +#include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EGkTrimming.h" +#include "/EgtDev/Include/EGkStmFromTriangleSoup.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" +#include +#include + +using namespace std ; + +static string s_sKey_Sync_Coord = "KeyOldCoord" ; +static string s_sKey_Auto_Trim = "AutoTrim" ; + +// --------------------------------------------------------------------------- +bool +ExeTrimmingAutoSearch( int nParentId, int nSurfLayerId, double dShapeLinTol, double dShapeAngTol, + double dLinTol, double dEdgeLinTol, double dAngTol, double dAngFaceTol, + const STRVECTOR& vsShapes) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Se non ho geometrie da ricercare, non faccio nulla + if ( vsShapes.empty()) + return true ; + + // Recupero le superfici presenti nel Layer + CISURFPVECTOR vSurfs ; vSurfs.reserve( pGeomDB->GetGroupObjs( nSurfLayerId)) ; + int nId = pGeomDB->GetFirstInGroup( nSurfLayerId) ; + while ( nId != GDB_ID_NULL) { + // Recupero l'entità + const IGeoObj* pGeoObj = pGeomDB->GetGeoObj( nId) ; + if ( pGeoObj != nullptr) { + // Recupero il Tipo + int nType = pGeoObj->GetType() ; + if ( nType == SRF_TRIMESH || nType == SRF_BEZIER) { + // Recupero la superficie + const ISurf* pSurf = GetSurf( pGeoObj) ; + if ( pSurf != nullptr && pSurf->IsValid()) + vSurfs.emplace_back( pSurf) ; + } + } + nId = pGeomDB->GetNext( nId) ; + } + // Se non ho superfici non faccio nulla + if ( vSurfs.empty()) + return false ; + + // Recupero Le Superfici Selezionate, Le Curve e Le Bezier rigate + ISURFPOMATRIX matSelSurfMatrix ; + ICRVCOMPOPOMATRIX matCompoBorders ; + ISURFBEZPOVECTOR vSurfBz ; + bool bOk = GetTrimmingAutoEntities( vSurfs, dShapeLinTol, dShapeAngTol, dLinTol, dEdgeLinTol, dAngTol, dAngFaceTol, vsShapes, + matSelSurfMatrix, matCompoBorders, vSurfBz) ; + + // Per sicurezza verifico che tutte le entità siano a dimensione corretta + bOk = bOk && ( ssize( matSelSurfMatrix) == ssize( matCompoBorders)) && + ( ssize( matSelSurfMatrix) == ssize( vSurfBz)) ; + + // Per ogni Entità ricavata inserisco le Geometrie nel Layer + // NB. Ordine di Inserimento : Surf -> Edges -> bezier + // Una anomalia nella serie blocca il flusso corrente e passa al successivo + int nCount = -1 ; + for ( int i = 0 ; bOk && i < int( matSelSurfMatrix.size()) ; ++ i) { + // Verifico che la Superficie sia Valida + bool bOkEntity = true ; + for ( int j = 0 ; bOkEntity && j < ssize( matSelSurfMatrix[i]) ; ++ j) + bOkEntity = ( ! IsNull( matSelSurfMatrix[i][j]) && matSelSurfMatrix[i][j]->IsValid()) ; + if ( ! bOkEntity) + continue ; // anomalia serie livello superfici di selezione + for ( int j = 0 ; bOk && j < ssize( matSelSurfMatrix[i]) ; ++ j) { + int nSurfId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( matSelSurfMatrix[i][j])) ; + bOk = ( ( nSurfId != GDB_ID_NULL) && + ( pGeomDB->SetInfo( nSurfId, s_sKey_Auto_Trim, ToString( ++ nCount)))) ; + } + if ( ! bOk) + break ; // anomalia bloccante + // Verifico che Le Curve di Edges ( Bezier ) siano Valide + for ( int j = 0 ; bOkEntity && j < ssize( matCompoBorders[i]) ; ++ j) + bOkEntity = ( ! IsNull( matCompoBorders[i][j]) && matCompoBorders[i][j]->IsValid()) ; + if ( ! bOkEntity) + continue ; // anomalia serie livello curve di bordo + for ( int j = 0 ; bOk && j < ssize( matCompoBorders[i]) ; ++ j) { + int nCrvId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( matCompoBorders[i][j])) ; + bOk = ( ( nCrvId != GDB_ID_NULL) && + ( pGeomDB->SetInfo( nCrvId, s_sKey_Auto_Trim, ToString( nCount)))) ; + } + if ( ! bOk) + break ; // anomalia bloccante + // Verifico che le Superfici di Bezier rigate siano Valide + bOkEntity = ( ! IsNull( vSurfBz[i]) && vSurfBz[i]->IsValid()) ; + if ( ! bOkEntity) + continue ; // anomalia seria livello Bezier Rigata + int nBzId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vSurfBz[i])) ; + bOk = ( ( nBzId != GDB_ID_NULL) && + ( pGeomDB->SetInfo( nBzId, s_sKey_Auto_Trim, ToString( nCount)))) ; + if ( ! bOk) + break ; // anomali bloccante + } + + ExeSetModified() ; + + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingAutoSearch(" + ToString( nParentId) + "," + + ToString( nSurfLayerId) + "," + + ToString( dShapeLinTol) + "," + + ToString( dShapeAngTol) + "," + + ToString( dLinTol) + "," + + ToString( dEdgeLinTol) + "," + + ToString( dAngTol) + "," + + ToString( dAngFaceTol) + "," + + ToString( vsShapes) + ")" + + " -- bOk=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetSurfTmFaceAdj( int nSurfId, const INTVECTOR& vTria, const PNTVECTOR& vPts, + double dAngTol, double dSize, double dSizeTol, INTVECTOR& vOtherFaces) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Recupero la superficie TriMesh + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nSurfId)) ; + bool bOk = ( pStm != nullptr && pStm->IsValid()) ; + + // Verifico che le facce appartengano alla superficie + bOk = bOk && ( ! vTria.empty()) ; + + // Recupero l'insieme dei triangoli + if ( bOk) { + INTVECTOR vOtherTria ; vOtherTria.reserve( pStm->GetTriangleCount()) ; + bOk = GetTrimmingStmAdjTria( pStm, vTria, vPts, dAngTol, dSize, dSizeTol, vOtherTria) ; + // Per ogni triangolo ricavato, recupero la faccia corrispondente + set setFaces ; + for ( const int& nT : vOtherTria) + setFaces.insert( pStm->GetFacetFromTria( nT)) ; + vOtherFaces.assign( setFaces.begin(), setFaces.end()) ; + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetSurfTmFromFaceAdj(" + ToString( nSurfId) + "," + + ToString( vTria) + "," + + ToString( dAngTol) + ")" + + " -- bOk=" + ToString( bOk) + "vOtherFaces=" + ToString( vOtherFaces) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +int +ExeTrimmingGetSurfTmFromStmFaces( int nParentId, int nSurfId, const INTVECTOR& vFaces) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Recupero il riferimento del gruppo di destinazione + Frame3d frDest ; + if ( ! pGeomDB->GetGlobFrame( nParentId, frDest)) + return GDB_ID_NULL ; + + // Recupero la superficie TriMesh + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nSurfId)) ; + if ( pStm == nullptr || ! pStm->IsValid()) + return GDB_ID_NULL ; + + // Verifico che le facce appartengano alla superficie + if ( vFaces.empty()) + return CMD_ID_NULL ; + for ( int nF = 0 ; nF < int( vFaces.size()) ; ++ nF) { + double dArea = 0. ; + if ( ! pStm->GetFacetArea( vFaces[nF], dArea)) + return GDB_ID_NULL ; + } + + // Definisco la superficie + StmFromTriangleSoup TriaSoup ; + TriaSoup.Start() ; + for ( int nF = 0 ; nF < int( vFaces.size()) ; ++ nF) { + INTVECTOR vT ; + if ( ! pStm->GetAllTriaInFacet( vFaces[nF], vT)) + return GDB_ID_NULL ; + for ( int nT = 0 ; nT < int( vT.size()) ; ++ nT) { + Triangle3d Tria ; + if ( ! pStm->GetTriangle( vT[nT], Tria) || ! TriaSoup.AddTriangle( Tria)) + return GDB_ID_NULL ; + } + } + TriaSoup.End() ; + PtrOwner pStmTria( TriaSoup.GetSurf()) ; + if ( IsNull( pStmTria) || ! pStmTria->IsValid() || pStmTria->GetTriangleCount() == 0) + return GDB_ID_NULL ; + + // Aggiungo la superficie al DB + int nNewSurfId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStmTria)) ; + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "TrimmingGetSurfTmFromStmFaces(" + ToString( nParentId) + "," + + ToString( nSurfId) + "," + + ToString( vFaces) + ")" + + " -- nId=" + ToString( nNewSurfId) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return nNewSurfId ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetAdjSurfs( const INTVECTOR& vSurfId, const INTVECTOR& vOtherSurfId, double dLinTol, + double dAngTol, double dAngFaceTol, INTVECTOR& vResId) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Recupero le superfici di Riferimento + CISURFPVECTOR vRefSurf ; vRefSurf.reserve( vSurfId.size()) ; + bool bOk = true ; + for ( int i = 0 ; bOk && i < int( vSurfId.size()) ; ++ i) { + const ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( vSurfId[i])) ; + bOk = ( pSurf != nullptr && pSurf->IsValid()) ; + vRefSurf.emplace_back( pSurf) ; + } + + // Recupero le superfici complessive, escludendo eventualmente quelle di riferimento se presenti + CISURFPVECTOR vOtherSurf ; vOtherSurf.reserve( vOtherSurfId.size()) ; + INTVECTOR vIds ; + for ( int i = 0 ; bOk && i < int( vOtherSurfId.size()) ; ++ i) { + if ( find( vSurfId.begin(), vSurfId.end(), vOtherSurfId[i]) == vSurfId.end()) { + const ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( vOtherSurfId[i])) ; + bOk = ( pSurf != nullptr && pSurf->IsValid()) ; + vOtherSurf.emplace_back( pSurf) ; + vIds.push_back( vOtherSurfId[i]) ; + } + } + + // Recupero le facce adiancenti nella tolleranza richiesta + INTVECTOR vMyInds ; + bOk = bOk && GetTrimmingAdjSurfs( vRefSurf, vOtherSurf, dLinTol, dAngTol, dAngFaceTol, vMyInds) ; + if ( bOk) { + for ( const int& myInd : vMyInds) + vResId.push_back( vIds[myInd]) ; + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetAdjSurf(" + ToString( vSurfId) + "," + + ToString( vOtherSurfId) + "," + + ToString( dAngTol) + ")" + + " -- bOk=" + ToString( bOk) + ",vResId=" + ToString( vResId) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetBorders( int nParentId, const SELVECTOR& vIds, double dLinTol, double dAngTol, + int& nFirstId, int& nCount) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Parametri da restituire + nFirstId = GDB_ID_NULL ; + nCount = 0 ; + + // vIds : vettore di { nId = SurfId, nSubId = nSurfFace } + // Controllo che vIds non sia vuoto + bool bOk = ( ! vIds.empty()) ; + // Recupero il riferimento della prima superficie + Frame3d frSurf ; + bOk = bOk && pGeomDB->GetGlobFrame( vIds[0].nId, frSurf) ; + // Recupero il riferimento dei gruppi di destinazione + Frame3d frDest ; + bOk = bOk && pGeomDB->GetGlobFrame( nParentId, frDest) ; + // Recupero gli Id univoci delle superfici selezionate + INTSET setUniqueId ; + for ( const SelData& nIds : vIds) + setUniqueId.insert( nIds.nId) ; + // Recupero le superfici e le porto tutte in locale alla prima + unordered_map uMapPos ; uMapPos.reserve( setUniqueId.size()) ; + SURFLOCALVECTOR vSurfL ; vSurfL.reserve( setUniqueId.size()) ; + CISURFPVECTOR vpSurf ; vpSurf.reserve( setUniqueId.size()) ; + int nSurf = 0 ; + for ( auto nIter = setUniqueId.begin() ; bOk && nIter != setUniqueId.end() ; ++ nIter) { + vSurfL.emplace_back( pGeomDB, *nIter, frSurf) ; + bOk = ( vSurfL.back().Get() != nullptr) ; + vpSurf.emplace_back( vSurfL.back().Get()) ; + uMapPos[*nIter] = nSurf ; + ++ nSurf ; + } + // Recupero il vettore di Selezione associato non più agli Id delle superficie ma alle loro posizioni nel vettore + vector vFaces ; vFaces.reserve( vIds.size()) ; + for ( int i = 0 ; bOk && i < int( vIds.size()) ; ++ i) + vFaces.emplace_back( uMapPos[vIds[i].nId], vIds[i].nSub) ; + + // Calcolo le curve di Edge grezze ( quindi i tratti lineari) + ICRVCOMPOPOVECTOR vRawEdges ; + bOk = bOk && GetTrimmingRawEdges( vpSurf, vFaces, dLinTol, dAngTol, vRawEdges) && + ( ! vRawEdges.empty()) ; + + // Calcolo le curve di Edge approssimate mediante curve di Bezier + ICRVCOMPOPOVECTOR vBezierEdges ; + bOk = bOk && GetTrimmingBezierEdges( vRawEdges, dLinTol, dAngTol, vBezierEdges) ; + nCount = int( vBezierEdges.size()) ; + if ( bOk) { + // Scorro i gli Edges ottenuti + for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) { + vBezierEdges[nCrv]->ToLoc( frDest) ; + // Inserisco la curva nel DB Geometrico + int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nCrv])) ; + bOk = ( nCurrId != GDB_ID_NULL) ; + if ( nCrv == 0) + nFirstId = nCurrId ; + } + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetBorders(" + IdToString( nParentId) + "," + + ToString( dLinTol) + "," + + ToString( dAngTol) + ")" ; + sLua += " -- bOk=" + ToString( bOk) + + " -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetBordersByNormals( int nParentId, const SELVECTOR& vIds, double dLinTol, + double dAngTol, double dThick, Point3d& ptNear, int& nFirstId, int& nCount) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Parametri da restituire + nFirstId = GDB_ID_NULL ; + nCount = 0 ; + + // vIds : vettore di { nId = SurfId, nSubId = nSurfFace } + // Controllo che vIds non sia vuoto + bool bOk = ( ! vIds.empty()) ; + // Recupero il riferimento della prima superficie + Frame3d frSurf ; + bOk = bOk && pGeomDB->GetGlobFrame( vIds[0].nId, frSurf) ; + // Recupero il riferimento dei gruppi di destinazione + Frame3d frDest ; + bOk = bOk && pGeomDB->GetGlobFrame( nParentId, frDest) ; + // Recupero gli Id univoci delle superfici selezionate + INTSET setUniqueId ; + for ( const SelData& nIds : vIds) + setUniqueId.insert( nIds.nId) ; + // Recupero le superfici e le porto tutte in locale alla prima + unordered_map uMapPos ; uMapPos.reserve( setUniqueId.size()) ; + SURFLOCALVECTOR vSurfL ; vSurfL.reserve( setUniqueId.size()) ; + CISURFPVECTOR vpSurf ; vpSurf.reserve( setUniqueId.size()) ; + int nSurf = 0 ; + for ( auto nIter = setUniqueId.begin() ; bOk && nIter != setUniqueId.end() ; ++ nIter) { + vSurfL.emplace_back( pGeomDB, *nIter, frSurf) ; + bOk = ( vSurfL.back().Get() != nullptr) ; + vpSurf.emplace_back( vSurfL.back().Get()) ; + uMapPos[*nIter] = nSurf ; + ++ nSurf ; + } + // Recupero il vettore di Selezione associato non più agli Id delle superficie ma alle loro posizioni nel vettore + vector vFaces ; vFaces.reserve( vIds.size()) ; + for ( int i = 0 ; bOk && i < int( vIds.size()) ; ++ i) + vFaces.emplace_back( uMapPos[vIds[i].nId], vIds[i].nSub) ; + + // Calcolo le curve di Edge approssimate mediante curve di Bezier + ICRVCOMPOPOVECTOR vBezierEdges ; + bOk = bOk && GetTrimmingFinalBorders( vpSurf, vFaces, dLinTol, dAngTol, dThick, vBezierEdges) ; + if ( bOk) { + // Se non ho un punto di vicinanza, le inserisco tutte + if ( ! ptNear.IsValid()) { + nCount = int( vBezierEdges.size()) ; + // Scorro i gli Edges ottenuti + for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) { + vBezierEdges[nCrv]->ToLoc( frDest) ; + // Inserisco la curva nel DB Geometrico + int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nCrv])) ; + bOk = ( nCurrId != GDB_ID_NULL) ; + if ( nCrv == 0) + nFirstId = nCurrId ; + } + } + // Se ho un punto di vicinanza, cerco la coppia di curve più vicina + else { + // Se solo una coppia di curve, le inserisco e non ho ambiguità + if ( int( vBezierEdges.size()) == 2) { + nCount = int( vBezierEdges.size()) ; + // Scorro gli Edges ottenuti + for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) { + vBezierEdges[nCrv]->ToLoc( frDest) ; + // Inserisco la curva nel DB Geometrico + int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nCrv])) ; + bOk = ( nCurrId != GDB_ID_NULL) ; + if ( nCrv == 0) + nFirstId = nCurrId ; + } + } + // altrimenti cerco la coppia più vicia + else { + double dSqMinDist = INFINITO ; + int nInd = 0 ; + for ( int i = 0 ; i + 1 < int( vBezierEdges.size()) ; i = i + 2) { + double dSqDist = 0., dSqDist1 = 0. ; + if ( DistPointCurve( ptNear, *vBezierEdges[i]).GetSqDist( dSqDist) && + DistPointCurve( ptNear, *vBezierEdges[i + 1]).GetSqDist( dSqDist1)) { + double dCurrMinSqDist = min( dSqDist, dSqDist1) ; + if ( dCurrMinSqDist < dSqMinDist) { + dSqMinDist = dCurrMinSqDist ; + nInd = i ; + } + } + } + vBezierEdges[nInd]->ToLoc( frDest) ; + vBezierEdges[nInd + 1]->ToLoc( frDest) ; + int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nInd])) ; + int nCurrId1 = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vBezierEdges[nInd + 1])) ; + bOk = ( nCurrId != GDB_ID_NULL && nCurrId1 != GDB_ID_NULL) ; + if ( bOk) { + nFirstId = nCurrId1 ; + nCount = 2 ; + } + } + } + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetBorders(" + IdToString( nParentId) + "," + + ToString( dLinTol) + "," + + ToString( dAngTol) + ")" ; + sLua += " -- bOk=" + ToString( bOk) + + " -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetFinalBorders( int nParentId, const INTVECTOR& vCrvBezierId, double dLinTol, double dAngTol, + const PNTVECTOR& vBrkPts, double dThick, double dThickTol, + int& nFirstId, int& nCount) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Parametri da restituire + nFirstId = GDB_ID_NULL ; + nCount = 0 ; + + // Recupero il riferimento del gruppo di destinazione + Frame3d frDest ; + bool bOk = ( pGeomDB->GetGlobFrame( nParentId, frDest)) ; + + // Recupero le curve di Bordo approssimate come Bezier + ICRVCOMPOPOVECTOR vCompoBezierEdges ; vCompoBezierEdges.reserve( vCrvBezierId.size()) ; + for ( int nCrv = 0 ; bOk && nCrv < int( vCrvBezierId.size()) ; ++ nCrv) { + const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( vCrvBezierId[nCrv])) ; + bOk = ( pCrv != nullptr && pCrv->IsValid()) ; + if ( bOk) { + PtrOwner pCompoRawEdges( ConvertCurveToComposite( pCrv->Clone())) ; + bOk = ( ! IsNull( pCompoRawEdges) && pCompoRawEdges->IsValid() && + vCompoBezierEdges.emplace_back( Release( pCompoRawEdges))) ; + } + } + + // Converto i punti in coppie di punti ( se dispari l'ultimo viene ignorato) + BIPNTVECTOR vBreakingPts ; vBreakingPts.reserve( int( int( vBrkPts.size()) / 2)) ; + for ( int nPt = 0 ; bOk && nPt < int( vBrkPts.size()) - 1 ; nPt += 2) + vBreakingPts.emplace_back( make_pair( vBrkPts[nPt], vBrkPts[nPt+1])) ; + if ( int( vBrkPts.size()) % 2 != 0) + LOG_INFO( GetCmdLogger(), "Warning in EgtExtractSurfFrChunkLoops : Odd number of breaking points") ; + + // Calcolo le curve di Edge + bOk = bOk && GetTrimmingFinalBorders( vCompoBezierEdges, dLinTol, dAngTol, vBreakingPts, dThick, dThickTol) ; + nCount = int( vCompoBezierEdges.size()) ; + if ( bOk) { + // Scorro i gli Edges ottenuti + for ( int nCrv = 0 ; bOk && nCrv < nCount ; ++ nCrv) { + vCompoBezierEdges[nCrv]->ToLoc( frDest) ; + // Inserisco la curva nel DB Geometrico + int nCurrId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( vCompoBezierEdges[nCrv])) ; + bOk = ( nCurrId != GDB_ID_NULL) ; + if ( nCrv == 0) + nFirstId = nCurrId ; + } + ExeSetModified() ; + } + + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetFinalEdges(" + IdToString( nParentId) + "," + + ToString( vCrvBezierId) + "," + + ToString( dLinTol) + "," + + ToString( dAngTol) + "," ; + sLua += "{" ; + for ( int nP = 0 ; nP < int( vBrkPts.size()) ; ++ nP) { + sLua += "(" + ToString( vBrkPts[nP].x) + ", " + ToString( vBrkPts[nP].y) + ", " + ToString( vBrkPts[nP].z) + ")" + + ( nP != int( vBrkPts.size()) - 1 ? "," : "") ; + } + sLua += "}" ; + sLua += ToString( dThick) + "," + ToString( dThickTol) + ")" ; + sLua += " -- bOk=" + ToString( bOk) + + " -- FirstId=" + ToString( nFirstId) + " CurveCount=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +// --------------------------------------------------------------------------- +int +ExeTrimmingGetRuledBezier( int nParentId, const INTVECTOR& vIds, int nEdge1Id, int nEdge2Id, double dLinTol, + const INTVECTOR& vnLineId) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Aggiusto la tolleranza lineare se necessario + double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; + + // Recupero il riferimento dei gruppi di destinazione + Frame3d frDest ; + bool bOk = pGeomDB->GetGlobFrame( nParentId, frDest) ; + + // Recupero la prima curva + const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nEdge1Id)) ; + bOk = bOk && ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid()) ; + + // Recupero la seconda curva + const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nEdge2Id)) ; + bOk = bOk && ( pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ; + + // Se ci sono delle superfici di riferimento + CISURFPVECTOR vpSurf ; vpSurf.reserve( vIds.size()) ; + if ( ! vIds.empty()) { + SURFLOCALVECTOR vSurfL ; vSurfL.reserve( vIds.size()) ; + // Recupero il riferimento della prima superficie + Frame3d frSurf ; + bOk = bOk && ( pGeomDB->GetGlobFrame( vIds[0], frSurf)) ; + // Porto le altre nel riferimento della prima + for ( int nSurf = 0 ; bOk && nSurf < int( vIds.size()) ; ++ nSurf) { + vSurfL.emplace_back( pGeomDB, vIds[nSurf], frSurf) ; + if ( vSurfL.back().Get() == nullptr) { + bOk = false ; + break ; + } + vpSurf.emplace_back( vSurfL.back().Get()) ; + } + } + + // Recupero i punti di sincronizzazione ( se presenti) + BIPNTVECTOR vSyncPoints ; vSyncPoints.reserve( pGeomDB->GetGroupObjs( vnLineId.size())) ; + INTVECTOR vIndPriority ; vIndPriority.reserve( vSyncPoints.size()) ; + INTVECTOR vIndVisible ; vIndVisible.reserve( vSyncPoints.size()) ; + for ( int i = 0 ; bOk && i < int( vnLineId.size()) ; ++ i) { + // Recupero la Curva + const ICurve* pLine = GetCurve( pGeomDB->GetGeoObj( vnLineId[i])) ; + bOk = bOk && ( pLine != nullptr && pLine->IsValid()) ; + if ( bOk) { + Point3d ptStart ; pLine->GetStartPoint( ptStart) ; + Point3d ptEnd ; pLine->GetEndPoint( ptEnd) ; + vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ; + // Verifico se la linea è visibile all'utente + int nStatus = GDB_ST_OFF ; + if ( pGeomDB->GetStatus( vnLineId[i], nStatus) && nStatus == GDB_ST_ON) + vIndVisible.emplace_back( int( vSyncPoints.size() - 1)) ; + // Verifico mediante le Info se la curva è stata modificata o aggiunta ( quindi prioritaria) + DBLVECTOR vdOldCoor ; vdOldCoor.reserve( 6) ; + if ( ! pGeomDB->GetInfo( vnLineId[i], s_sKey_Sync_Coord, vdOldCoor) || + int( vdOldCoor.size()) != 6 || + ! AreSamePointApprox( ptStart, Point3d( vdOldCoor[0], vdOldCoor[1], vdOldCoor[2])) || + ! AreSamePointApprox( ptEnd, Point3d( vdOldCoor[3], vdOldCoor[4], vdOldCoor[5]))) + vIndPriority.emplace_back( int( vSyncPoints.size()) - 1) ; + } + } + + // Recupero la superficie Bezier rigata + PtrOwner pSurfBzRuled ; + if ( bOk) { + pSurfBzRuled.Set( GetTrimmingRuledBezier( vpSurf, pCrvEdge1, pCrvEdge2, dMyLinTol, vSyncPoints, vIndPriority, vIndVisible)) ; + bOk = bOk && ( ! IsNull( pSurfBzRuled) && pSurfBzRuled->IsValid()) ; + } + + // Inserisco la curva nel DB Geometrico + int nSurfBzId = GDB_ID_NULL ; + if ( bOk) { + pSurfBzRuled->ToLoc( frDest) ; + nSurfBzId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSurfBzRuled)) ; + bOk = bOk && ( nSurfBzId != GDB_ID_NULL) ; + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetRuledBezier(" + ToString( nParentId) + "," + + ToString( vIds) + "," + + ToString( nEdge1Id) + "," + + ToString( nEdge2Id) + "," + + ToString( dLinTol) + ")" + + " -- bOk=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + // Restituisco il risultato + return nSurfBzId ; +} + +// --------------------------------------------------------------------------- +bool +ExeTrimmingGetSurfBzSyncPoints( int nParentId, int nEdge1Id, int nEdge2Id, double dLinTol, + int& nFirstId, int& nCount) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Se necessario aggiusto le tolleranze + double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; + + // Recupero il riferimento del gruppo di destinazione + Frame3d frDest ; + bool bOk = ( pGeomDB->GetGlobFrame( nParentId, frDest)) ; + + // Recupero le due Curve di bordo + const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nEdge1Id)) ; + const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nEdge2Id)) ; + bOk = bOk && ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid() && + pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ; + + // Recupero i punti di sincronizzazione + BIPNTVECTOR vSyncPoints ; + bOk = bOk && GetTrimmingSurfBzSyncPoints( pCrvEdge1, pCrvEdge2, dMyLinTol, vSyncPoints) && + ( ! vSyncPoints.empty()) ; + nCount = int( vSyncPoints.size()) ; + + // Inserisco i tratti di sincronizzazione nel DB Geometrico + for ( int nL = 0 ; nL < int( vSyncPoints.size()) ; ++ nL) { + PtrOwner pLine( CreateCurveLine()) ; + if ( ! IsNull( pLine) && pLine->Set( vSyncPoints[nL].first, vSyncPoints[nL].second)) { + int nLineId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pLine)) ; + if ( nLineId != GDB_ID_NULL) { + if ( nL == 0) + nFirstId = nLineId ; + // Memorizzo come Info le coordinate dei punti ( per tenere traccia in futuro di modifiche) + DBLVECTOR vdCoordInfo = { vSyncPoints[nL].first.x, vSyncPoints[nL].first.y, vSyncPoints[nL].first.z, + vSyncPoints[nL].second.x, vSyncPoints[nL].second.y, vSyncPoints[nL].second.z} ; + pGeomDB->SetInfo( nLineId, s_sKey_Sync_Coord, vdCoordInfo) ; + } + } + } + + ExeSetModified() ; + // Se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtTrimmingGetSurfBzSyncPoints(" + ToString( nParentId) + "," + + ToString( nEdge1Id) + "," + + ToString( nEdge2Id) + "," + + ToString( dLinTol) + "," + + ToString( nFirstId) + "," + + ToString( nCount) + ")" + + " -- bOk=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExeTrimmingSkimSyncPoints( int nEdge1Id, int nEdge2Id, const INTVECTOR& vnLineId, double dLinTol, + double dAngTol, int nMaxInvLine) +{ + // Verifica database geometrico + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + // Se necessario aggiusto le tolleranze + double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ; + double dMyAngTol = Clamp( dAngTol, 1., 45.) ; + int nMyMaxInvLine = Clamp( nMaxInvLine, 1, 100) ; + + // Recupero le due Curve di bordo + const ICurve* pCrvEdge1 = GetCurve( pGeomDB->GetGeoObj( nEdge1Id)) ; + const ICurve* pCrvEdge2 = GetCurve( pGeomDB->GetGeoObj( nEdge2Id)) ; + bool bOk = ( pCrvEdge1 != nullptr && pCrvEdge1->IsValid() && pCrvEdge2 != nullptr && pCrvEdge2->IsValid()) ; + + // Definisco il vettore degli Estremi + BIPNTVECTOR vSyncPoints ; vSyncPoints.reserve( vnLineId.size()) ; + for ( int i = 0 ; bOk && i < int( vnLineId.size()) ; ++ i) { + const ICurve* pLine = GetCurve( pGeomDB->GetGeoObj( vnLineId[i])) ; + bOk = ( pLine != nullptr && pLine->IsValid()) ; + if ( bOk) { + Point3d ptStart, ptEnd ; + bOk = ( pLine->GetStartPoint( ptStart) && pLine->GetEndPoint( ptEnd)) ; + if ( bOk) + vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ; + } + } + + // Scelta di Selezione delle linee di sincronizzazione + // 1) In presenza di Spigoli, vengono sempre visualizzate ( Spigolo definito da tolleranza angolare) + // 2) 1 Curva su 'nMyMaxInvLine' viene mostrata altrimenti + int nInvisibleCount = 0 ; + for ( int nL = 0 ; bOk && nL < int( vSyncPoints.size()) ; ++ nL) { + bool bVisible = false ; + Point3d ptUseless = P_INVALID ; + // Recupero gli Estremi e controllo se sono su uno spigolo tra una delle due curve + double dUS = 0. ; + bOk = bOk && pCrvEdge1->GetParamAtPoint( vSyncPoints[nL].first, dUS, dMyLinTol) ; + if ( bOk) { + Vector3d vtPrev, vtAft ; + bOk = pCrvEdge1->GetPointD1D2( dUS, ICurve::FROM_MINUS, ptUseless, &vtPrev) && + pCrvEdge1->GetPointD1D2( dUS, ICurve::FROM_PLUS, ptUseless, &vtAft) ; + if ( bOk) { + vtPrev.Normalize() ; vtAft.Normalize() ; + bVisible = ( vtPrev * vtAft < cos( ( dMyAngTol + EPS_ANG_SMALL) * DEGTORAD)) ; + if ( ! bVisible) { + double dUE = 0. ; + bOk = bOk && pCrvEdge2->GetParamAtPoint( vSyncPoints[nL].second, dUE, dMyLinTol) ; + bOk = pCrvEdge2->GetPointD1D2( dUE, ICurve::FROM_MINUS, ptUseless, &vtPrev) && + pCrvEdge2->GetPointD1D2( dUE, ICurve::FROM_PLUS, ptUseless, &vtAft) ; + if ( bOk) { + vtPrev.Normalize() ; vtAft.Normalize() ; + bVisible = ( vtPrev * vtAft < cos( ( dMyAngTol + EPS_ANG_SMALL) * DEGTORAD)) ; + } + } + } + if ( bOk) { + // Imposto lo Stato + if ( ! bVisible) + ++ nInvisibleCount ; + if ( nInvisibleCount == nMyMaxInvLine) { + bVisible = true ; + nInvisibleCount = 0 ; + } + pGeomDB->SetStatus( vnLineId[nL], bVisible ? GDB_ST_ON : GDB_ST_OFF) ; + } + } + } + + return bOk ; +} diff --git a/EgtExecutor.vcxproj b/EgtExecutor.vcxproj index 044ba37..0a70be6 100644 --- a/EgtExecutor.vcxproj +++ b/EgtExecutor.vcxproj @@ -297,6 +297,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -324,6 +325,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtExecutor.vcxproj.filters b/EgtExecutor.vcxproj.filters index b1e895f..e214c45 100644 --- a/EgtExecutor.vcxproj.filters +++ b/EgtExecutor.vcxproj.filters @@ -407,6 +407,12 @@ File di origine\LUA + + File di origine\LUA + + + File di origine\EXE + File di origine\EXE diff --git a/LUA.h b/LUA.h index 3a56eaf..6a8e333 100644 --- a/LUA.h +++ b/LUA.h @@ -141,3 +141,5 @@ bool LuaInstallRedis( LuaMgr& luaMgr) ; //-------------------------- Base64 ------------------------------------------ bool LuaInstallBase64( LuaMgr& luaMgr) ; +//---------------------------------- Trimming ---------------------------------- +bool LuaInstallTrimming( LuaMgr& luaMgr) ; diff --git a/LUA_Base.cpp b/LUA_Base.cpp index fa1e8d4..e512718 100644 --- a/LUA_Base.cpp +++ b/LUA_Base.cpp @@ -194,7 +194,11 @@ LuaInstallEgtFunctions( LuaMgr& LuaMgr) LOG_ERROR( GetLogger(), "Error in LuaInstallBase64 (LuaInstallEgtFunctions)") return false ; } - + if ( ! LuaInstallTrimming( LuaMgr)) { + LOG_ERROR( GetLogger(), "Error in LuaInstallTrimming (LuaInstallEgtFunctions)") + return false ; + } + return true ; } diff --git a/Lua_Trimming.cpp b/Lua_Trimming.cpp new file mode 100644 index 0000000..60cf332 --- /dev/null +++ b/Lua_Trimming.cpp @@ -0,0 +1,304 @@ +//---------------------------------------------------------------------------- +// EgalTech 2025-2025 +//---------------------------------------------------------------------------- +// File : LUA_Trimming.cpp Data : 23.10.25 Versione : 2.7j3 +// Contenuto : Funzioni per le lavorazioni di Trimming. +// +// Modifiche : 23.10.25 RE Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "LUA.h" +#include "/EgtDev/Include/EXeExecutor.h" +#include "/EgtDev/Include/EXeConst.h" +#include "/EgtDev/Include/EGkLuaAux.h" +#include "/EgtDev/Include/EGnStringUtils.h" + +using namespace std ; + +// ------------------------------------------------------------------------------ +static int +LuaTrimmingAutoSearch( lua_State* L) +{ + // 9 parametri : nParentId, nSurfLayerId, dShapeLinTol, dShapeAngTol, dLinTol, dEdgeLinTol, dAngTol, dAngFaceTol, vsShapes + int nParentId ; + LuaCheckParam( L, 1, nParentId) + int nSurfLayerId ; + LuaCheckParam( L, 2, nSurfLayerId) + double dShapeLinTol ; + LuaCheckParam( L, 3, dShapeLinTol) + double dShapeAngTol ; + LuaCheckParam( L, 4, dShapeAngTol) + double dLinTol ; + LuaCheckParam( L, 5, dLinTol) + double dEdgeLinTol ; + LuaCheckParam( L, 6, dEdgeLinTol) + double dAngTol ; + LuaCheckParam( L, 7, dAngTol) + double dAngFaceTol ; + LuaCheckParam( L, 8, dAngFaceTol) + STRVECTOR vsShapes ; + LuaCheckParam( L, 9, vsShapes) + LuaClearStack( L) ; + // Recupero le lavorazioni di Trimming associate + INTVECTOR vOtherFaces ; + bool bOk = ExeTrimmingAutoSearch( nParentId, nSurfLayerId, dShapeLinTol, dShapeAngTol, dLinTol, + dEdgeLinTol, dAngTol, dAngFaceTol, vsShapes) ; + LuaSetParam( L, bOk) ; + return 1 ; +} + +// ------------------------------------------------------------------------------ +static int +LuaTrimmingGetSurfTmFaceAdj( lua_State* L) +{ + // 6 parametri : nSurfId, vTria, vPts, dAngTol, dSize, dSizeTol + int nSurfId ; + LuaCheckParam( L, 1, nSurfId) + INTVECTOR vTria ; + LuaCheckParam( L, 2, vTria) + PNTVECTOR vPts ; + LuaCheckParam( L, 3, vPts) + double dAngTol ; + LuaCheckParam( L, 4, dAngTol) + double dSize ; + LuaCheckParam( L, 5, dSize) + double dSizeTol ; + LuaCheckParam( L, 6, dSizeTol) + LuaClearStack( L) ; + // Recupero le facce adiacenti in tolleranza angolare + INTVECTOR vOtherFaces ; + bool bOk = ExeTrimmingGetSurfTmFaceAdj( nSurfId, vTria, vPts, dAngTol, dSize, dSizeTol, vOtherFaces) ; + LuaSetParam( L, bOk) ; + if ( bOk) + LuaSetParam( L, vOtherFaces) ; + else + LuaSetParam( L) ; + return 2 ; +} + +// ------------------------------------------------------------------------------ +static int +LuaTrimmingGetSurfTmFromStmFaces( lua_State* L) +{ + // 3 Parametri : nParentId, nSurfId, vFaces + int nParentId ; + LuaCheckParam( L, 1, nParentId) + int nSurfId ; + LuaCheckParam( L, 2, nSurfId) + INTVECTOR vFaces ; + LuaCheckParam( L, 3, vFaces) + LuaClearStack( L) ; + int nNewSurfId = ExeTrimmingGetSurfTmFromStmFaces( nParentId, nSurfId, vFaces) ; + LuaSetParam( L, nNewSurfId) ; + return 1 ; +} + +// ------------------------------------------------------------------------------ +static int +LuaTrimmingGetAdjSurfs( lua_State* L) +{ + // 5 parametri : nRefSfrId, vAllSurfId, dLinTol, dAngTol, dAngFaceTol + INTVECTOR vRefSurfId ; + LuaCheckParam( L, 1, vRefSurfId) + INTVECTOR vOtherSurfId ; + LuaCheckParam( L, 2, vOtherSurfId) + double dLinTol ; + LuaCheckParam( L, 3, dLinTol) + double dAngTol ; + LuaCheckParam( L, 4, dAngTol) + double dAngFaceTol ; + LuaCheckParam( L, 5, dAngFaceTol) + LuaClearStack( L) ; + // Calcolo le facce adiacenti per tolleranza + INTVECTOR vOtherSurf ; + bool bOk = ExeTrimmingGetAdjSurfs( vRefSurfId, vOtherSurfId, dLinTol, dAngTol, dAngFaceTol, vOtherSurf) ; + // Restituisco il risultato + LuaSetParam( L, bOk) ; + LuaSetParam( L, vOtherSurf) ; + return 2 ; +} + +// ------------------------------------------------------------------------------- +static int +LuaTrimmingGetBorders( lua_State* L) +{ + // 4 parametri : nParentId, vIds, dLinTol, dAngTol + int nParentId ; + LuaCheckParam( L, 1, nParentId) + SELVECTOR vIds ; + LuaCheckParam( L, 2, vIds) + double dLinTol ; + LuaCheckParam( L, 3, dLinTol) + double dAngTol ; + LuaCheckParam( L, 4, dAngTol) + LuaClearStack( L) ; + // Creo le curve di Edge grezze + int nFirstId = GDB_ID_NULL ; + int nCount = 0 ; + bool bOk = ExeTrimmingGetBorders( nParentId, vIds, dLinTol, dAngTol, nFirstId, nCount) ; + LuaSetParam( L, bOk) ; + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCount) ; + return 3 ; +} + +// ------------------------------------------------------------------------------- +static int +LuaTrimmingGetBordersByNormals( lua_State* L) +{ + // 5 o 6 parametri : nParentId, vIds, dLinTol, dAngTol, dThickness [, ptNear] + int nParentId ; + LuaCheckParam( L, 1, nParentId) + SELVECTOR vIds ; + LuaCheckParam( L, 2, vIds) + double dLinTol ; + LuaCheckParam( L, 3, dLinTol) + double dAngTol ; + LuaCheckParam( L, 4, dAngTol) + double dThickness ; + LuaCheckParam( L, 5, dThickness) + Point3d ptNear = P_INVALID ; + LuaGetParam( L, 6, ptNear) ; + LuaClearStack( L) ; + // Creo le curve di Edge grezze + int nFirstId = GDB_ID_NULL ; + int nCount = 0 ; + bool bOk = ExeTrimmingGetBordersByNormals( nParentId, vIds, dLinTol, dAngTol, dThickness, ptNear, nFirstId, nCount) ; + LuaSetParam( L, bOk) ; + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCount) ; + return 3 ; +} + +// ------------------------------------------------------------------------------- +static int +LuaTrimmingGetFinalBorders( lua_State* L) +{ + // 4 o 5 o 6 o 7 parametri : nParentId, vCrvBezierId, dLinTol, dAngTol [,vBreakingPts] [,dThick] [,dThickTol] + int nParentId ; + LuaCheckParam( L, 1, nParentId) + INTVECTOR vCrvBezierId ; + LuaCheckParam( L, 2, vCrvBezierId) + double dLinTol ; + LuaCheckParam( L, 3, dLinTol) + double dAngTol ; + LuaCheckParam( L, 4, dAngTol) + PNTVECTOR vBreakingPts ; + double dThick = 0., dThickTol = EPS_SMALL ; + int nInd = 5 ; + if ( LuaGetParam( L, nInd, vBreakingPts)) + ++ nInd ; + if ( LuaGetParam( L, nInd, dThick)) { + if ( ! LuaGetParam( L, nInd + 1, dThickTol)) { + LuaClearStack( L) ; + LuaSetParam( L, false) ; + return 1 ; + } + } + LuaClearStack( L) ; + // Creo le curve Edges + int nFirstId = GDB_ID_NULL ; + int nCount = 0 ; + bool bOk = ExeTrimmingGetFinalBorders( nParentId, vCrvBezierId, dLinTol, dAngTol, vBreakingPts, dThick, dThickTol, + nFirstId, nCount) ; + LuaSetParam( L, bOk) ; + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCount) ; + return 3 ; +} + +//------------------------------------------------------------------------------- +static int +LuaTrimmingGetRuledBezier( lua_State* L) +{ + // 5 o 6 parametri : nParentId, vIds, nEdge1Id, nEdge2Id, dLinTol [,vnLineId] + int nParentId ; + LuaCheckParam( L, 1, nParentId) + INTVECTOR vIds ; + LuaCheckParam( L, 2, vIds) ; // serve per orientare la superficie rigata ( Ids delle superfici) + int nEdge1Id ; + LuaCheckParam( L, 3, nEdge1Id) + int nEdge2Id ; + LuaCheckParam( L, 4, nEdge2Id) + double dLinTol ; + LuaCheckParam( L, 5, dLinTol) + INTVECTOR vnLineId ; + LuaGetParam( L, 6, vnLineId) ; + LuaClearStack( L) ; + // Calcolo la superficie di Bezier rigata + int nId = ExeTrimmingGetRuledBezier( nParentId, vIds, nEdge1Id, nEdge2Id, dLinTol, vnLineId) ; + LuaSetParam( L, nId) ; + return 1 ; +} + +//------------------------------------------------------------------------------- +static int +LuaTrimmingGetSurfBzSyncPoints( lua_State* L) +{ + // 4 parametri : nParentId, nEdge1Id, nEdge2Id, dLinTol + int nParentId ; + LuaCheckParam( L, 1, nParentId) + int nEdge1Id ; + LuaCheckParam( L, 2, nEdge1Id) + int nEdge2Id ; + LuaCheckParam( L, 3, nEdge2Id) + double dLinTol ; + LuaCheckParam( L, 4, dLinTol) + LuaClearStack( L) ; + // Inserisco i tratti lineari associati ai punti di sincronizzazione + int nFirstId = GDB_ID_NULL ; + int nCount = 0 ; + bool bOk = ExeTrimmingGetSurfBzSyncPoints( nParentId, nEdge1Id, nEdge2Id, dLinTol, nFirstId, nCount) ; + LuaSetParam( L, bOk) ; + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCount) ; + return 3 ; +} + +// ------------------------------------------------------------------------------ +static int +LuaTrimmingSkimSyncPoints( lua_State* L) +{ + // 5 o 6 parametri : nEdge1Id, nEdge2Id, vnLineId, dLinTol, dAngTol [,nMaxInvLine] + int nEdge1Id ; + LuaCheckParam( L, 1, nEdge1Id) + int nEdge2Id ; + LuaCheckParam( L, 2, nEdge2Id) + INTVECTOR vnLineId ; + LuaCheckParam( L, 3, vnLineId) + double dLinTol ; + LuaCheckParam( L, 4, dLinTol) + double dAngTol ; + LuaCheckParam( L, 5, dAngTol) + int nMaxInvLine = 4 ; + LuaGetParam( L, 6, nMaxInvLine) ; + LuaClearStack( L) ; + // Nascondo/Visualizzo i tratti lineari di sincronizzazione + bool bOk = ExeTrimmingSkimSyncPoints( nEdge1Id, nEdge2Id, vnLineId, dLinTol, dAngTol, nMaxInvLine) ; + LuaSetParam( L, bOk) ; + return 1 ; +} + +//------------------------------------------------------------------------------- +bool +LuaInstallTrimming( LuaMgr& luaMgr) +{ + bool bOk = ( &luaMgr != nullptr) ; + // --- + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingAutoSearch", LuaTrimmingAutoSearch) ; + // --- + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetSurfTmFaceAdj", LuaTrimmingGetSurfTmFaceAdj) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetSurfTmFromStmFaces", LuaTrimmingGetSurfTmFromStmFaces) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetAdjSurfs", LuaTrimmingGetAdjSurfs) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetBorders", LuaTrimmingGetBorders) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetBordersByNormals", LuaTrimmingGetBordersByNormals) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetFinalBorders", LuaTrimmingGetFinalBorders) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetRuledBezier", LuaTrimmingGetRuledBezier) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingGetSurfBzSyncPoints", LuaTrimmingGetSurfBzSyncPoints) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtTrimmingSkimSyncPoints", LuaTrimmingSkimSyncPoints) ; + return bOk ; +} \ No newline at end of file