diff --git a/EXE_GeoSnap.cpp b/EXE_GeoSnap.cpp index 23779b5..fff7ed5 100644 --- a/EXE_GeoSnap.cpp +++ b/EXE_GeoSnap.cpp @@ -1116,6 +1116,97 @@ ExeSurfTmFacetNormVersor( int nId, int nFacet, int nRefId, Vector3d& vtNorm) return TrasformVector( pGeomDB, nId, nRefId, vtNorm) ; } +//---------------------------------------------------------------------------- +bool +ExeSurfTmFacetOppositeSide( int nId, int nFacet, const Vector3d& vtDir, int nRefId, Point3d& ptP1, Point3d& ptP2) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero il riferimento della trimesh + Frame3d frStm ; + if ( ! pGeomDB->GetGlobFrame( nId, frStm)) + return false ; + // recupero la superficie trimesh + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; + if ( pStm == nullptr) + return false ; + // recupero i contorni della faccia + POLYLINEVECTOR vPL ; + pStm->GetFacetLoops( nFacet, vPL) ; + if ( vPL.empty()) + return false ; + // recupero la normale esterna della faccia + Point3d ptCen ; + Vector3d vtN ; + if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN)) + return false ; + // creo la curva a partire dal contorno esterno + PtrOwner pCrvCompo( CreateCurveComposite()) ; + pCrvCompo->FromPolyLine( vPL[0]) ; + if ( ! pCrvCompo->IsValid()) + return false ; + // unisco parti allineate + pCrvCompo->MergeCurves( LIN_TOL_STD, ANG_TOL_STD_DEG) ; + // porto la direzione nel riferimento della superficie + Vector3d vtDirL = vtDir ; + if ( ! InvTrasformVector( pGeomDB, nId, nRefId, vtDirL)) + return false ; + // costruisco un riferimento con Z su normale e X vicino a direzione + Frame3d frSpec ; + if ( ! frSpec.Set( ptCen, vtN, vtDirL)) + return false ; + // porto il contorno in questo riferimento + pCrvCompo->ToLoc( frSpec) ; + // ingombro + BBox3d b3Box ; + pCrvCompo->GetLocalBBox( b3Box) ; + double dMin = b3Box.GetMin().x ; + double dMax = b3Box.GetMax().x ; + double dTol = min( ( dMax - dMin) / 4., 20.) ; + // cerco il punto medio delle curve più vicino all'estremo desiderato + double dRef = dMax ; + const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + dRef = min( dRef, ptMid.x) ; + pCrv = pCrvCompo->GetNextCurve() ; + } + // elimino le linee troppo discoste dal riferimento dall'inizio e poi dalla fine + pCrv = pCrvCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + if ( ptMid.x > dRef + dTol) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; + delete( pErase) ; + pCrv = pCrvCompo->GetFirstCurve() ; + } + else if ( pCrvCompo->IsClosed()) { + pCrvCompo->ChangeStartPoint( 1) ; + pCrv = pCrvCompo->GetFirstCurve() ; + } + else + break ; + } + pCrv = pCrvCompo->GetLastCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + if ( ptMid.x > dRef + dTol) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; + delete( pErase) ; + pCrv = pCrvCompo->GetLastCurve() ; + } + else + break ; + } + // recupero i punti estremi della curva + if ( ! pCrvCompo->GetStartPoint( ptP1) || ! pCrvCompo->GetEndPoint( ptP2)) + return false ; + // li porto nel riferimento della superficie e poi in quello richiesto + ptP1.ToGlob( frSpec) ; + ptP2.ToGlob( frSpec) ; + return TrasformPoint( pGeomDB, nId, nRefId, ptP1) && TrasformPoint( pGeomDB, nId, nRefId, ptP2) ; +} + //---------------------------------------------------------------------------- bool ExeSurfTmFacetsContact( int nId, int nF1, int nF2, int nRefId, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng) diff --git a/EgtExecutor.rc b/EgtExecutor.rc index ef8c80d..387c03f 100644 Binary files a/EgtExecutor.rc and b/EgtExecutor.rc differ diff --git a/GeoTools.cpp b/GeoTools.cpp index 3c9f6c7..77db7cb 100644 --- a/GeoTools.cpp +++ b/GeoTools.cpp @@ -166,6 +166,34 @@ TrasformVector( IGeomDB* pGeomDB, int nId, int nRefId, Vector3d& vtV) return vtV.LocToLoc( frSou, frDest) ; } +//---------------------------------------------------------------------------- +bool +InvTrasformVector( IGeomDB* pGeomDB, int nId, int nRefId, Vector3d& vtV) +{ + // se non va trasformato, esco + if ( nRefId == nId) + return true ; + // recupero il riferimento in cui va espresso il punto (quello dell'entità a cui va riferito) + Frame3d frSou ; + if ( ! pGeomDB->GetGlobFrame( nId, frSou)) + return false ; + // se viene da globale, trasformo ed esco + if ( nRefId == GDB_ID_ROOT) + return vtV.ToLoc( frSou) ; + // recupero il riferimento da cui proviene + Frame3d frDest ; + if ( nRefId == GDB_ID_GRID) + frDest = pGeomDB->GetGridFrame() ; + else { + // nRefId può essere un gruppo o una entità + if ( ! pGeomDB->GetGroupGlobFrame( nRefId, frDest) && + ! pGeomDB->GetGlobFrame( nRefId, frDest)) + return false ; + } + // eseguo la trasformazione inversa + return vtV.LocToLoc( frDest, frSou) ; +} + //---------------------------------------------------------------------------- bool TrasformFrame( IGeomDB* pGeomDB, int nId, int nRefId, Frame3d& frF) diff --git a/GeoTools.h b/GeoTools.h index 48e3dc5..a4553e2 100644 --- a/GeoTools.h +++ b/GeoTools.h @@ -35,6 +35,8 @@ bool TrasformPoint( IGeomDB* pGeomDB, int nId, int nRefId, Point3d& ptP) ; bool InvTrasformPoint( IGeomDB* pGeomDB, int nId, int nRefId, Point3d& ptP) ; // Vettore portato dal riferimento di nId a quello di nRefId bool TrasformVector( IGeomDB* pGeomDB, int nId, int nRefId, Vector3d& vtV) ; +// Trasformazione inversa della precedente, dal riferimento di nRefId a quello di nId +bool InvTrasformVector( IGeomDB* pGeomDB, int nId, int nRefId, Vector3d& vtV) ; // Riferimento portato dal riferimento di nId a quello di nRefId bool TrasformFrame( IGeomDB* pGeomDB, int nId, int nRefId, Frame3d& frF) ; // Verifica che tutti gli oggetti dell'insieme abbiano lo stesso riferimento diff --git a/LUA_GeoSnap.cpp b/LUA_GeoSnap.cpp index 8cd258a..cf6a3ed 100644 --- a/LUA_GeoSnap.cpp +++ b/LUA_GeoSnap.cpp @@ -806,6 +806,33 @@ LuaSurfTmFacetNormVersor( lua_State* L) return 1 ; } +//---------------------------------------------------------------------------- +static int +LuaSurfTmFacetOppositeSide( lua_State* L) +{ + // 3 o 4 parametri : Id, nFacet, vtDir [, nRefId] + int nId ; + LuaCheckParam( L, 1, nId) + int nFacet ; + LuaCheckParam( L, 2, nFacet) + Vector3d vtDir ; + LuaCheckParam( L, 3, vtDir) + int nRefId = nId ; + LuaGetParam( L, 4, nRefId) ; + LuaClearStack( L) ; + // recupero i punti estremi della parte di faccia opposta alla direzione + Point3d ptP1, ptP2 ; + if ( ExeSurfTmFacetOppositeSide( nId, nFacet, vtDir, nRefId, ptP1, ptP2)) { + LuaSetParam( L, ptP1) ; + LuaSetParam( L, ptP2) ; + } + else { + LuaSetParam( L) ; + LuaSetParam( L) ; + } + return 2 ; +} + //---------------------------------------------------------------------------- static int LuaSurfTmFacetsContact( lua_State* L) @@ -956,6 +983,7 @@ LuaInstallGeoSnap( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetNearestMidPoint", LuaSurfTmFacetNearestMidPoint) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetCenter", LuaSurfTmFacetCenter) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetNormVersor", LuaSurfTmFacetNormVersor) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetOppositeSide", LuaSurfTmFacetOppositeSide) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmFacetsContact", LuaSurfTmFacetsContact) ; bOk = bOk && luaMgr.RegisterFunction( "EgtVolZmapVolume", LuaVolZmapVolume) ; bOk = bOk && luaMgr.RegisterFunction( "EgtVolZmapPartCount", LuaVolZmapPartCount) ;