From 5c4f32a6e85fc30120df08e3d51409ea48e40787 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Thu, 16 Nov 2023 18:57:18 +0100 Subject: [PATCH] EgtExecutor : - aggiunta funzione Exe/Lua SurfTmFacetElevationInBBox. --- EXE_GdbGetSurf.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++ LUA_GdbGetSurf.cpp | 25 ++++++++++ 2 files changed, 138 insertions(+) diff --git a/EXE_GdbGetSurf.cpp b/EXE_GdbGetSurf.cpp index 2c88ba1..ece79a4 100644 --- a/EXE_GdbGetSurf.cpp +++ b/EXE_GdbGetSurf.cpp @@ -21,6 +21,7 @@ #include "/EgtDev/Include/EXeExecutor.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" +#include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkCurveLocal.h" @@ -29,6 +30,8 @@ #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h" +#include "/EgtDev/Include/EGkIntersCurves.h" +#include "/EgtDev/Include/EGkIntersLineBox.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EGkStringUtils3d.h" @@ -587,6 +590,116 @@ ExeSurfTmFacetMinAreaRectangle( int nId, int nFacet, int nRefId, Frame3d& frRect return TransformFrame( pGeomDB, nId, nRefId, frRect) ; } +//---------------------------------------------------------------------------- +bool +ExeSurfTmFacetElevationInBBox( int nId, int nFacet, const BBox3d& b3Box, int nRefId, double& dElev) +{ + // La faccia deve essere tutta contenuta nel Box + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero la superficie trimesh e il suo riferimento + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; + if ( pStm == nullptr) + return false ; + Frame3d frStm ; + if ( ! pGeomDB->GetGlobFrame( nId, frStm)) + return false ; + // verifico il box e ne recupero il riferimento + if ( b3Box.IsEmpty()) + return false ; + Frame3d frBox ; + if ( nRefId == GDB_ID_ROOT) + frBox = GLOB_FRM ; + else if ( nRefId == GDB_ID_GRID) + frBox = pGeomDB->GetGridFrame() ; + else { + // nRefId può essere un gruppo o una entità + if ( ! pGeomDB->GetGroupGlobFrame( nRefId, frBox) && + ! pGeomDB->GetGlobFrame( nRefId, frBox)) + return false ; + } + // recupero il centro e la normale della faccia e li porto nel riferimento del box + Point3d ptCen ; Vector3d vtN ; + if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN)) + return false ; + ptCen.LocToLoc( frStm, frBox) ; + vtN.LocToLoc( frStm, frBox) ; + // recupero il contorno esterno della faccia e lo porto nel riferimento del box + POLYLINEVECTOR vPL ; + pStm->GetFacetLoops( nFacet, vPL) ; + if ( vPL.empty()) + return false ; + vPL[0].LocToLoc( frStm, frBox) ; + // verifico sia contenuto nella faccia + BBox3d b3Fac ; + BBox3d b3ExpBox = b3Box ; b3ExpBox.Expand( 100 * EPS_SMALL) ; + if ( ! vPL[0].GetLocalBBox( b3Fac) || ! b3ExpBox.Encloses( b3Fac)) + return false ; + // calcolo elevazione massima del contorno della faccia + const double RAY_LEN = 100000 ; + dElev = 0 ; + Point3d ptP ; + bool bFound = vPL[0].GetFirstPoint( ptP) ; + while ( bFound) { + INTDBLVECTOR vInters ; + IntersLineBox( ptP, vtN, RAY_LEN, b3Box, vInters, true) ; + for ( int i = 0 ; i < int( vInters.size()) ; ++ i) { + if ( i == 0 && vInters[i].first == ILBT_IN) { + if ( vInters[i].second > 100 * EPS_SMALL) + break ; + } + else if ( vInters[i].first == ILBT_OUT || vInters[i].first == ILBT_TG_FIN) + dElev = max( dElev, vInters[i].second) ; + } + bFound = vPL[0].GetNextPoint( ptP, true) ; + } + // calcolo elevazione massima degli eventuali spigoli (e vertici) del box dalla parte positiva della faccia e che cadono in essa + BIPNTVECTOR vEdges( 12) ; + vEdges[0].first = b3Box.GetMin() ; vEdges[0].second = vEdges[0].first + b3Box.GetDimX() * X_AX ; + vEdges[1].first = vEdges[0].second ; vEdges[1].second = vEdges[1].first + b3Box.GetDimY() * Y_AX ; + vEdges[2].first = vEdges[1].second ; vEdges[2].second = vEdges[0].first + b3Box.GetDimY() * Y_AX ; + vEdges[3].first = vEdges[2].second ; vEdges[3].second = vEdges[0].first ; + vEdges[4].first = vEdges[0].first + b3Box.GetDimZ() * Z_AX ; vEdges[4].second = vEdges[0].second + b3Box.GetDimZ() * Z_AX ; + vEdges[5].first = vEdges[1].first + b3Box.GetDimZ() * Z_AX ; vEdges[5].second = vEdges[1].second + b3Box.GetDimZ() * Z_AX ; + vEdges[6].first = vEdges[2].first + b3Box.GetDimZ() * Z_AX ; vEdges[6].second = vEdges[2].second + b3Box.GetDimZ() * Z_AX ; + vEdges[7].first = vEdges[3].first + b3Box.GetDimZ() * Z_AX ; vEdges[7].second = vEdges[3].second + b3Box.GetDimZ() * Z_AX ; + vEdges[8].first = vEdges[0].first ; vEdges[8].second = vEdges[4].first ; + vEdges[9].first = vEdges[1].first ; vEdges[9].second = vEdges[5].first ; + vEdges[10].first = vEdges[2].first ; vEdges[10].second = vEdges[6].first ; + vEdges[11].first = vEdges[3].first ; vEdges[11].second = vEdges[7].first ; + // porto tutto nel riferimento intrinseco della faccia (già calcolato in quello del box) + Frame3d frOcs ; frOcs.Set( ptCen, vtN) ; + vPL[0].ToLoc( frOcs) ; + for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) { + vEdges[i].first.ToLoc( frOcs) ; + vEdges[i].second.ToLoc( frOcs) ; + } + // calcolo la curva di loop + PtrOwner pLoop( CreateCurveComposite()) ; + if ( IsNull( pLoop) || ! pLoop->FromPolyLine( vPL[0])) + return false ; + // eseguo i calcoli di elevazione + for ( int i = 0 ; i < int( vEdges.size()) ; ++ i) { + // se sta sul piano o sotto, lo salto + if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL) + continue ; + // calcolo il segmento di linea + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine) || ! pLine->Set( vEdges[i].first, vEdges[i].second)) + return false ; + // l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop + IntersCurveCurve intLL( *pLine, *pLoop) ; + IntCrvCrvInfo aInfo ; + for ( int i = 0 ; intLL.GetIntCrvCrvInfo( i, aInfo) ; ++ i) { + dElev = max( dElev, aInfo.IciA[0].ptI.z) ; + if ( aInfo.bOverlap) + dElev = max( dElev, aInfo.IciA[1].ptI.z) ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool ExeSurfTmFacetOppositeSide( int nId, int nFacet, const Vector3d& vtDir, int nRefId, diff --git a/LUA_GdbGetSurf.cpp b/LUA_GdbGetSurf.cpp index 0602f12..2bdd842 100644 --- a/LUA_GdbGetSurf.cpp +++ b/LUA_GdbGetSurf.cpp @@ -625,6 +625,30 @@ LuaSurfTmFacetMinAreaRectangle( lua_State* L) } } +//---------------------------------------------------------------------------- +static int +LuaSurfTmFacetElevationInBBox( lua_State* L) +{ + // 2 o 3 parametri : Id, nFacet [, nRefId] + int nId ; + LuaCheckParam( L, 1, nId) + int nFacet ; + LuaCheckParam( L, 2, nFacet) + BBox3d b3Box ; + LuaCheckParam( L, 3, b3Box) + int nRefId = nId ; + LuaGetParam( L, 4, nRefId) ; + LuaClearStack( L) ; + // calcolo elevazione + double dElev ; + bool bOk = ExeSurfTmFacetElevationInBBox( nId, nFacet, b3Box, nRefId, dElev) ; + if ( bOk) + LuaSetParam( L, dElev) ; + else + LuaSetParam( L) ; + return 1 ; +} + //---------------------------------------------------------------------------- static int LuaSurfTmFacetOppositeSide( lua_State* L) @@ -1065,6 +1089,7 @@ LuaInstallGdbGetSurf( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetCenter", LuaSurfTmFacetCenter) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetNormVersor", LuaSurfTmFacetNormVersor) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetMinAreaRectangle", LuaSurfTmFacetMinAreaRectangle) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetElevationInBBox", LuaSurfTmFacetElevationInBBox) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetOppositeSide", LuaSurfTmFacetOppositeSide) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetsContact", LuaSurfTmFacetsContact) ; bOk = bOk && luaMgr.RegisterFunction( "EgtExtractSurfTmLoops", LuaExtractSurfTmLoops) ;