From dbd7a962777af780297ef02c6c1267b9d145b50a Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Fri, 12 Oct 2018 07:34:13 +0000 Subject: [PATCH] EgtExecutor 1.9j3 : - aggiunta funzione Exe e Lua CreateSurfTmConvexHullInBBox. --- EXE_GdbCreateSurf.cpp | 238 ++++++++++++++++++++++++++++++++++-------- EgtExecutor.rc | Bin 16154 -> 16154 bytes GeoTools.cpp | 50 ++++++++- GeoTools.h | 10 +- LUA_GdbCreateSurf.cpp | 25 +++++ 5 files changed, 279 insertions(+), 44 deletions(-) diff --git a/EXE_GdbCreateSurf.cpp b/EXE_GdbCreateSurf.cpp index e277ebe..15c071b 100644 --- a/EXE_GdbCreateSurf.cpp +++ b/EXE_GdbCreateSurf.cpp @@ -24,6 +24,7 @@ #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" +#include "/EgtDev/Include/EGkPolygon3d.h" #include "/EgtDev/Include/EGkVolZmap.h" #include "/EgtDev/Include/EgkStringUtils3d.h" #include "/EgtDev/Include/EgkGeoPoint3d.h" @@ -348,56 +349,23 @@ MyCreateSurfTmPlaneInBBox( int nParentId, const Point3d& ptP, const Vector3d& vt IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) nParentId = AdjustId( nParentId) ; - // definisco contorno del piano nel suo riferimento intrinseco - double dRad ; - if ( ! b3Box.GetRadius( dRad)) + // costruisco il piano nel box + Plane3d plPlane ; + plPlane.Set( ptP, vtN) ; + PtrOwner pStm( GetSurfTriMeshPlaneInBox( plPlane, b3Box)) ; + if ( IsNull( pStm)) return GDB_ID_NULL ; - double dDiam = 2 * dRad ; - PolyLine PL ; - PL.AddUPoint( 0, Point3d( - dDiam, -dDiam, 0)) ; - PL.AddUPoint( 1, Point3d( dDiam, -dDiam, 0)) ; - PL.AddUPoint( 2, Point3d( dDiam, dDiam, 0)) ; - PL.AddUPoint( 3, Point3d( -dDiam, dDiam, 0)) ; - PL.AddUPoint( 4, Point3d( -dDiam, -dDiam, 0)) ; - // lo porto nel riferimento di definizione - Frame3d frPlane ; - if ( ! frPlane.Set( ptP, vtN)) - return GDB_ID_NULL ; - PL.ToGlob( frPlane) ; - // creo la superficie piano - PtrOwner pSTM( CreateSurfTriMesh()) ; - if ( IsNull( pSTM) || ! pSTM->CreateByFlatContour( PL)) - return GDB_ID_NULL ; - // la taglio con le pareti del box - Plane3d plBottom ; plBottom.Set( b3Box.GetMin(), -Z_AX) ; - if ( ! pSTM->Cut( plBottom, true)) - return GDB_ID_NULL ; - Plane3d plTop ; plTop.Set( b3Box.GetMax(), Z_AX) ; - if ( ! pSTM->Cut( plTop, true)) - return GDB_ID_NULL ; - Plane3d plLeft ; plLeft.Set( b3Box.GetMin(), -X_AX) ; - if ( ! pSTM->Cut( plLeft, true)) - return GDB_ID_NULL ; - Plane3d plRight ; plRight.Set( b3Box.GetMax(), X_AX) ; - if ( ! pSTM->Cut( plRight, true)) - return GDB_ID_NULL ; - Plane3d plFront ; plFront.Set( b3Box.GetMin(), -Y_AX) ; - if ( ! pSTM->Cut( plFront, true)) - return GDB_ID_NULL ; - Plane3d plBack ; plBack.Set( b3Box.GetMax(), Y_AX) ; - if ( ! pSTM->Cut( plBack, true)) - return GDB_ID_NULL ; - // recupero il riferimento locale + // recupero il riferimento locale del gruppo destinazione Frame3d frLoc ; if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) return GDB_ID_NULL ; // se necessario, porto la superficie piano trimmato nel riferimento locale if ( nRefType == RTY_GLOB) - pSTM->ToLoc( frLoc) ; + pStm->ToLoc( frLoc) ; else if ( nRefType == RTY_GRID) - pSTM->LocToLoc( pGeomDB->GetGridFrame(), frLoc) ; + pStm->LocToLoc( pGeomDB->GetGridFrame(), frLoc) ; // inserisco la superficie nel DB - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSTM)) ; + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pStm)) ; return nNewId ; } @@ -423,6 +391,192 @@ ExeCreateSurfTmPlaneInBBox( int nParentId, const Point3d& ptP, const Vector3d& v return nNewId ; } +//------------------------------------------------------------------------------- +static Triangle3d +MyCreateSidePlaneHull( const PNTVECTOR& vVert, bool bNXp, const BBox3d& b3Box, int nFace) +{ + // determino i vertici della superficie sui bordi della faccia Z+ del BBox + Triangle3d Tria ; + for ( int i = 0 ; i < int( vVert.size()) ; ++ i) { + if ( ( nFace == +2 && abs( vVert[i].y - b3Box.GetMax().y) > 100 * EPS_SMALL) || + ( nFace == -2 && abs( vVert[i].y - b3Box.GetMin().y) > 100 * EPS_SMALL) || + ( nFace == +3 && abs( vVert[i].z - b3Box.GetMax().z) > 100 * EPS_SMALL) || + ( nFace == -3 && abs( vVert[i].z - b3Box.GetMin().z) > 100 * EPS_SMALL)) + continue ; + if ( ( nFace == +2 && abs( vVert[i].z - b3Box.GetMin().z) < 10 * EPS_SMALL) || + ( nFace == -2 && abs( vVert[i].z - b3Box.GetMax().z) < 10 * EPS_SMALL) || + ( nFace == +3 && abs( vVert[i].y - b3Box.GetMax().y) < 10 * EPS_SMALL) || + ( nFace == -3 && abs( vVert[i].y - b3Box.GetMin().y) < 10 * EPS_SMALL)) { + int nI = ( bNXp ? 0 : 1) ; + Tria.SetP( nI, vVert[i]) ; + Tria.SetAttrib( nI, i) ; + Tria.SetGrade( Tria.GetGrade() + 2) ; + continue ; + } + if ( ( nFace == +2 && abs( vVert[i].z - b3Box.GetMax().z) < 10 * EPS_SMALL) || + ( nFace == -2 && abs( vVert[i].z - b3Box.GetMin().z) < 10 * EPS_SMALL) || + ( nFace == +3 && abs( vVert[i].y - b3Box.GetMin().y) < 10 * EPS_SMALL) || + ( nFace == -3 && abs( vVert[i].y - b3Box.GetMax().y) < 10 * EPS_SMALL)) { + int nI = ( bNXp ? 1 : 0) ; + Tria.SetP( nI, vVert[i]) ; + Tria.SetAttrib( nI, i) ; + Tria.SetGrade( Tria.GetGrade() + 1) ; + continue ; + } + } + Tria.SetAttrib( 2, -1) ; + if ( Tria.GetGrade() != 3) + return Tria ; + // determino il piano passante per questa linea che racchiude tutti i punti + for ( int i = 0 ; i < int( vVert.size()) ; ++ i) { + if ( i != Tria.GetAttrib( 0) && i != Tria.GetAttrib( 1)) { + if ( Tria.GetAttrib( 2) == -1 || + ( ( vVert[i] - Tria.GetP( 0)) * Tria.GetN() > EPS_ZERO)) { + Tria.SetP( 2, vVert[i]) ; + Tria.Validate( true) ; + Tria.SetAttrib( 2, i) ; + } + } + } + return Tria ; +} + +//---------------------------------------------------------------------------- +bool +MyDoSewing( ISurfTriMesh* pStm, const Polygon3d& Polyg) +{ + // verifico esistenza superficie + if ( pStm == nullptr) + return false ; + // se poligono vuoto, non devo fare alcunché + if ( Polyg.GetSideCount() == 0) + return true ; + // creo la superficie trimesh del poligono + PtrOwner pStm2( CreateSurfTriMesh()) ; + if ( IsNull( pStm2) || ! pStm2->CreateByFlatContour( Polyg.GetPolyLine())) + return false ; + // le unisco + return pStm->DoSewing( *pStm2) ; +} + +//------------------------------------------------------------------------------- +static int +MyCreateSurfTmConvexHullInBBox( int nParentId, int nId, const BBox3d& b3Box, int nRefType) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + // recupero la superficie TriMesh + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; + if ( pStm == nullptr) + return GDB_ID_NULL ; + // recupero il suo riferimento e lo porto in quello indicato + Frame3d frStm ; + if ( ! pGeomDB->GetGlobFrame( nId, frStm)) + return GDB_ID_NULL ; + frStm = GetFrameInRef( pGeomDB, frStm, GLOB_FRM, nRefType) ; + // ne calcolo la normale media + Vector3d vtN ; + Triangle3d Tria ; + int nT = pStm->GetFirstTriangle( Tria) ; + while ( nT != SVT_NULL) { + // sommo la normale moltiplicata per l'area del triangolo + vtN += Tria.GetArea() * Tria.GetN() ; + // passo al triangolo successivo + nT = pStm->GetNextTriangle( nT, Tria) ; + } + if ( ! vtN.Normalize()) + return GDB_ID_NULL ; + vtN.ToGlob( frStm) ; + bool bNXp = ( vtN.x >= 0) ; + // recupero i vertici e li porto nel riferimento indicato + PNTVECTOR vVert ; + for ( int i = 0 ; i < pStm->GetVertexSize() ; ++ i) { + Point3d ptP ; + if ( pStm->GetVertex( i, ptP)) { + ptP.ToGlob( frStm) ; + vVert.emplace_back( ptP) ; + } + } + // determino i piani che racchiudono tutta la superficie dalle tracce sulla facce laterali della stessa + Triangle3d vTria[4] ; + vTria[0] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, +3) ; + vTria[1] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, -3) ; + vTria[2] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, +2) ; + vTria[3] = MyCreateSidePlaneHull( vVert, bNXp, b3Box, -2) ; + // cerco uno o due piani validi + int nPlane1 = -1 ; + int nPlane2 = -1 ; + for ( int i = 0 ; i < 4 ; ++ i) { + if ( ! vTria[i].IsValid()) + continue ; + nPlane1 = i ; + for ( int j = i + 1 ; j < 4 ; ++ j) { + if ( vTria[j].IsValid() && + abs( vTria[i].GetN() * vTria[j].GetN()) < 0.94) { + nPlane2 = j ; + break ; + } + } + break ; + } + // se nessun piano valido + if ( nPlane1 == -1) + return GDB_ID_NULL ; + // se un solo piano valido + if ( nPlane2 == -1) + return MyCreateSurfTmPlaneInBBox( nParentId, vTria[nPlane1].GetP( 0), vTria[nPlane1].GetN(), b3Box, nRefType) ; + // altrimenti due piani validi + Polygon3d Polyg1 ; + if ( ! Polyg1.FromPlaneTrimmedWithBox( vTria[nPlane1].GetPlane(), b3Box.GetMin(), b3Box.GetMax())) + return GDB_ID_NULL ; + Polygon3d Polyg2 ; + if ( ! Polyg2.FromPlaneTrimmedWithBox( vTria[nPlane2].GetPlane(), b3Box.GetMin(), b3Box.GetMax())) + return GDB_ID_NULL ; + if ( ! Polyg1.Trim( Polyg2, true, true) || ! Polyg2.Trim( Polyg1, true, false)) + return GDB_ID_NULL ; + // creo la trimesh dalle due facce + PtrOwner pChStm( CreateSurfTriMesh()) ; + if ( IsNull( pChStm)) + return GDB_ID_NULL ; + if ( ! MyDoSewing( pChStm, Polyg1) || + ! MyDoSewing( pChStm, Polyg2)) + return GDB_ID_NULL ; + pChStm->DoCompacting() ; + // recupero il riferimento locale del gruppo destinazione + Frame3d frLoc ; + if ( ! pGeomDB->GetGroupGlobFrame( nParentId, frLoc)) + return GDB_ID_NULL ; + // se necessario, porto la superficie piano trimmato nel riferimento locale + if ( nRefType == RTY_GLOB) + pChStm->ToLoc( frLoc) ; + else if ( nRefType == RTY_GRID) + pChStm->LocToLoc( pGeomDB->GetGridFrame(), frLoc) ; + // inserisco la superficie nel DB + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pChStm)) ; + return nNewId ; +} + +//------------------------------------------------------------------------------- +int +ExeCreateSurfTmConvexHullInBBox( int nParentId, int nId, const BBox3d& b3Box, int nRefType) +{ + // creo il piano + int nNewId = MyCreateSurfTmConvexHullInBBox( nParentId, nId, b3Box, nRefType) ; + ExeSetModified() ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtSurfTmConvexHullInBBox(" + IdToString( nParentId) + "," + + IdToString( nId) + ",{" + + ToString( b3Box.GetMin()) + "},{" + + ToString( b3Box.GetMax()) + "}}," + + RefTypeToString( nRefType) + ")" + + " -- Id=" + ToString( nNewId) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco l'identificativo della nuova entità + return nNewId ; +} + //------------------------------------------------------------------------------- int ExeCreateSurfTmBBox( int nParentId, const BBox3d& b3Box, int nRefType) diff --git a/EgtExecutor.rc b/EgtExecutor.rc index d2d9972fb4625161112d32b32e4ef8cfa9990b45..c23e9ed5444e4f5bba7557ed8c9ded266e2c72f1 100644 GIT binary patch delta 97 zcmbPLH>+;LA2vqg%@@V4Gflq2na5~6Ignd-a{*Tk3sCf++-0W82LxfF21;&>n->Y| cF@rU@0x76sKgP|Iq`|@m7F0HjzS-v9sr delta 97 zcmbPLH>+;LA2vp#%@@V4Gflq2na5}}Ignd-a{*Tk3sCf++-0W82LxfF21;&>n->Y| cF@rU@0x76sKgP|Iq`|@m7F0HV?#*8l(j diff --git a/GeoTools.cpp b/GeoTools.cpp index f12227e..fb338f4 100644 --- a/GeoTools.cpp +++ b/GeoTools.cpp @@ -46,6 +46,18 @@ GetVectorLocal( IGeomDB* pGeomDB, const Vector3d& vtV, int nRefType, const Frame return vtVL ; } +//---------------------------------------------------------------------------- +Vector3d +GetVectorInRef( IGeomDB* pGeomDB, const Vector3d& vtV, const Frame3d& frLoc, int nRefType) +{ + Vector3d vtVL( vtV) ; + if ( nRefType == RTY_GLOB) + vtVL.ToGlob( frLoc) ; + else if ( nRefType == RTY_GRID) + vtVL.LocToLoc( frLoc, pGeomDB->GetGridFrame()) ; + return vtVL ; +} + //---------------------------------------------------------------------------- Point3d GetPointLocal( IGeomDB* pGeomDB, const Point3d& ptP, int nRefType, const Frame3d& frLoc) @@ -58,6 +70,18 @@ GetPointLocal( IGeomDB* pGeomDB, const Point3d& ptP, int nRefType, const Frame3d return ptPL ; } +//---------------------------------------------------------------------------- +Point3d +GetPointInRef( IGeomDB* pGeomDB, const Point3d& ptP, const Frame3d& frLoc, int nRefType) +{ + Point3d ptPL( ptP) ; + if ( nRefType == RTY_GLOB) + ptPL.ToGlob( frLoc) ; + else if ( nRefType == RTY_GRID) + ptPL.LocToLoc( frLoc, pGeomDB->GetGridFrame()) ; + return ptPL ; +} + //---------------------------------------------------------------------------- Plane3d GetPlaneLocal( IGeomDB* pGeomDB, const Plane3d& plPlane, int nRefType, const Frame3d& frLoc) @@ -70,6 +94,18 @@ GetPlaneLocal( IGeomDB* pGeomDB, const Plane3d& plPlane, int nRefType, const Fra return plPlaneL ; } +//---------------------------------------------------------------------------- +Plane3d +GetPlaneInRef( IGeomDB* pGeomDB, const Plane3d& plPlane, const Frame3d& frLoc, int nRefType) +{ + Plane3d plPlaneL( plPlane) ; + if ( nRefType == RTY_GLOB) + plPlaneL.ToGlob( frLoc) ; + else if ( nRefType == RTY_GRID) + plPlaneL.LocToLoc( frLoc, pGeomDB->GetGridFrame()) ; + return plPlaneL ; +} + //---------------------------------------------------------------------------- Frame3d GetFrameLocal( IGeomDB* pGeomDB, const Frame3d& frRef, int nRefType, const Frame3d& frLoc) @@ -82,6 +118,18 @@ GetFrameLocal( IGeomDB* pGeomDB, const Frame3d& frRef, int nRefType, const Frame return frRefL ; } +//---------------------------------------------------------------------------- +Frame3d +GetFrameInRef( IGeomDB* pGeomDB, const Frame3d& frRef, const Frame3d& frLoc, int nRefType) +{ + Frame3d frRefL( frRef) ; + if ( nRefType == RTY_GLOB) + frRefL.ToGlob( frLoc) ; + else if ( nRefType == RTY_GRID) + frRefL.LocToLoc( frLoc, pGeomDB->GetGridFrame()) ; + return frRefL ; +} + //---------------------------------------------------------------------------- bool TransformPoint( IGeomDB* pGeomDB, int nId, int nRefId, Point3d& ptP) @@ -269,4 +317,4 @@ VerifySameFrame( IGeomDB* pGeomDB, const INTVECTOR& vIds) } } return true ; -} \ No newline at end of file +} diff --git a/GeoTools.h b/GeoTools.h index fd66328..328ab0d 100644 --- a/GeoTools.h +++ b/GeoTools.h @@ -23,12 +23,20 @@ class IGeomDB ; int AdjustId( int nId) ; // Vettore espresso nel riferimento desiderato partendo da vettore nel riferimento RefType Vector3d GetVectorLocal( IGeomDB* pGeomDB, const Vector3d& vtV, int nRefType, const Frame3d& frLoc) ; +// Vettore espresso nel riferimento RefType partendo da vettore nel riferimento locale +Vector3d GetVectorInRef( IGeomDB* pGeomDB, const Vector3d& vtV, const Frame3d& frLoc, int nRefType) ; // Punto espresso nel riferimento desiderato partendo da punto nel riferimento RefType Point3d GetPointLocal( IGeomDB* pGeomDB, const Point3d& ptP, int nRefType, const Frame3d& frLoc) ; -// Pianoo espresso nel riferimento desiderato partendo da piano nel riferimento RefType +// Punto espresso nel riferimento RefType partendo da punto nel riferimento locale +Point3d GetPointInRef( IGeomDB* pGeomDB, const Point3d& ptP, const Frame3d& frLoc, int nRefType) ; +// Piano espresso nel riferimento desiderato partendo da piano nel riferimento RefType Plane3d GetPlaneLocal( IGeomDB* pGeomDB, const Plane3d& plPlane, int nRefType, const Frame3d& frLoc) ; +// Piano espresso nel riferimento RefType partendo da piano nel riferimento locale +Plane3d GetPlaneInRef( IGeomDB* pGeomDB, const Plane3d& plPlane, const Frame3d& frLoc, int nRefType) ; // Riferimento espresso nel riferimento desiderato partendo da riferimento nel riferimento RefType Frame3d GetFrameLocal( IGeomDB* pGeomDB, const Frame3d& frRef, int nRefType, const Frame3d& frLoc) ; +// Riferimento espresso nel riferimento RefType partendo da riferimento nel riferimento locale +Frame3d GetFrameInRef( IGeomDB* pGeomDB, const Frame3d& frRef, const Frame3d& frLoc, int nRefType) ; // Punto portato dal riferimento di nId a quello di nRefId bool TransformPoint( IGeomDB* pGeomDB, int nId, int nRefId, Point3d& ptP) ; // Trasformazione inversa della precedente, dal riferimento di nRefId a quello di nId diff --git a/LUA_GdbCreateSurf.cpp b/LUA_GdbCreateSurf.cpp index 7ff1f17..d0d0dd2 100644 --- a/LUA_GdbCreateSurf.cpp +++ b/LUA_GdbCreateSurf.cpp @@ -196,6 +196,30 @@ LuaCreateSurfTmPlaneInBBox( lua_State* L) return 1 ; } +//------------------------------------------------------------------------------- +static int +LuaCreateSurfTmConvexHullInBBox( lua_State* L) +{ + // 3 o 4 parametri : ParentId, StmId, BBox3d [, nRefType] + int nParentId ; + LuaCheckParam( L, 1, nParentId) + int nStmId ; + LuaCheckParam( L, 2, nStmId) + BBox3d b3Box ; + LuaCheckParam( L, 3, b3Box) + int nRefType = RTY_DEFAULT ; + LuaGetParam( L, 4, nRefType) ; + LuaClearStack( L) ; + // creo STM plane hull in bounding box + int nId = ExeCreateSurfTmConvexHullInBBox( nParentId, nStmId, b3Box, nRefType) ; + // restituisco il risultato + if ( nId != GDB_ID_NULL) + LuaSetParam( L, nId) ; + else + LuaSetParam( L) ; + return 1 ; +} + //------------------------------------------------------------------------------- static int LuaCreateSurfTmBBox( lua_State* L) @@ -641,6 +665,7 @@ LuaInstallGdbCreateSurf( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtSurfFrFatCurve", LuaCreateSurfFrFatCurve) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfFlatRegion", LuaCreateSurfFlatRegion) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmPlaneInBBox", LuaCreateSurfTmPlaneInBBox) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmConvexHullInBBox", LuaCreateSurfTmConvexHullInBBox) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmBBox", LuaCreateSurfTmBBox) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmBox", LuaCreateSurfTmBox) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmPyramid", LuaCreateSurfTmPyramid) ;