diff --git a/EXE_GdbModifyCurve.cpp b/EXE_GdbModifyCurve.cpp index eab13b3..03c6ebe 100644 --- a/EXE_GdbModifyCurve.cpp +++ b/EXE_GdbModifyCurve.cpp @@ -23,11 +23,13 @@ #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkExtTExt.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include using namespace std ; @@ -501,9 +503,12 @@ ExeSplitCurve( int nId, int nParts) bOk = bOk && pCurve->GetLength( dLenTot) ; // lunghezza di una parte double dLen = dLenTot / nParts ; + bOk = bOk && ( dLen > 10 * EPS_SMALL) ; + // recupero un intervallo di id contigui per tutte le parti + int nFirstId = pGeomDB->GetNewId() ; + bOk = bOk && pGeomDB->ChangeId( nId, nFirstId) ; + int nCurrId = nFirstId ; // eseguo la divisione - int nFirstId = GDB_ID_NULL ; - int nCurrId = nId ; for ( int i = 1; i < nParts ; ++ i) { // copio la curva int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; @@ -515,9 +520,6 @@ ExeSplitCurve( int nId, int nParts) // la copia diventa il nuovo corrente nCurrId = nCopyId ; pCurve = pCopyCrv ; - // salvo identificativo prima copia - if ( nFirstId == GDB_ID_NULL) - nFirstId = nCopyId ; } nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; ExeSetModified() ; @@ -592,6 +594,81 @@ ExeSplitCurveAtPoint( int nId, const Point3d& ptOn, int nRefType) return nNewId ; } +//---------------------------------------------------------------------------- +int +ExeSplitCurveAtSelfInters( int nId, int* pnCount) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + // recupero la curva + ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; + bool bOk = ( pCurve != nullptr) ; + // calcolo le auto-intersezioni + SelfIntersCurve sintC( *pCurve) ; + DBLVECTOR vU ; + IntCrvCrvInfo iccInfo ; + for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) { + if ( ! iccInfo.bOverlap) { + vU.push_back( iccInfo.IciA[0].dU) ; + vU.push_back( iccInfo.IciB[0].dU) ; + } + else { + vU.push_back( iccInfo.IciA[0].dU) ; + vU.push_back( iccInfo.IciA[1].dU) ; + vU.push_back( iccInfo.IciB[0].dU) ; + vU.push_back( iccInfo.IciB[1].dU) ; + } + } + // ordino il vettore in senso crescente + sort( vU.begin(), vU.end(), less()) ; + // calcolo il vettore delle lunghezze di ogni parte di curva + double dLen ; + bOk = bOk && pCurve->GetLength( dLen) ; + DBLVECTOR vPartLen ; + double dLenPrev = 0 ; + for ( const auto& dU : vU) { + double dULen, dPartLen ; + bOk = bOk && pCurve->GetLengthAtParam( dU, dULen) ; + dPartLen = dULen - dLenPrev ; + // le curve prima e dopo devono avere una lunghezza significativa + if ( dPartLen > EPS_SMALL && dLen - dULen > EPS_SMALL) { + vPartLen.push_back( dPartLen) ; + dLenPrev = dULen ; + } + } + // recupero un intervallo di id contigui per tutte le parti + int nFirstId = pGeomDB->GetNewId() ; + bOk = bOk && pGeomDB->ChangeId( nId, nFirstId) ; + int nCurrId = nFirstId ; + // eseguo la divisione + int nCount = 1 ; + for ( auto& dPartLen : vPartLen) { + // copio la curva + int nCopyId = pGeomDB->Copy( nCurrId, GDB_ID_NULL, nCurrId, GDB_AFTER) ; + ICurve* pCopyCrv = GetCurve( pGeomDB->GetGeoObj( nCopyId)) ; + bOk = bOk && ( pCopyCrv != nullptr) ; + ++ nCount ; + // tengo la prima parte dell'originale e la seconda parte della copia + bOk = bOk && pCurve->TrimEndAtLen( dPartLen) ; + bOk = bOk && pCopyCrv->TrimStartAtLen( dPartLen) ; + // la copia diventa il nuovo corrente + nCurrId = nCopyId ; + pCurve = pCopyCrv ; + } + nFirstId = ( bOk ? nFirstId : GDB_ID_NULL) ; + ExeSetModified() ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtSplitCurveAtSelfIntersections(" + ToString( nId) + ")" + + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco risultati + if ( pnCount != nullptr) + *pnCount = nCount ; + return nFirstId ; +} + //------------------------------------------------------------------------------- bool ExeModifyCurveCircleCPN( int nId, const Point3d& ptOn, int nRefType) diff --git a/EXE_GdbObjects.cpp b/EXE_GdbObjects.cpp index 9083719..f34e9f7 100644 --- a/EXE_GdbObjects.cpp +++ b/EXE_GdbObjects.cpp @@ -321,6 +321,16 @@ ExeRelocateGlob( int nSouId, int nRefId, int nSonBeforeAfter) return bOk ; } +//----------------------------------------------------------------------------- +int +ExeGetNewId( void) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + // richiedo valore nuovo Id + return pGeomDB->GetNewId() ; +} + //----------------------------------------------------------------------------- bool ExeChangeId( int nId, int nNewId) diff --git a/EXE_GeoSnap.cpp b/EXE_GeoSnap.cpp index 1c032a8..5a4896c 100644 --- a/EXE_GeoSnap.cpp +++ b/EXE_GeoSnap.cpp @@ -25,7 +25,7 @@ #include "/EgtDev/Include/EgkSurfTriMesh.h" #include "/EgtDev/Include/EgkExtText.h" #include "/EgtDev/Include/EgkDistPointCurve.h" -#include "/EgtDev/Include/EgkIntersCurveCurve.h" +#include "/EgtDev/Include/EgkIntersCurves.h" #include "/EgtDev/Include/EgtPointerOwner.h" //---------------------------------------------------------------------------- @@ -393,6 +393,32 @@ ExeIntersectionPoint( int nId1, int nId2, const Point3d& ptNear, int nRefId, Poi { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) + + // se auto-intersezione + if ( nId1 == nId2) { + // deve essere entità geometriche + const IGeoObj* pGObj1 ; + if ( ( pGObj1 = pGeomDB->GetGeoObj( nId1)) == nullptr) + return false ; + // se curva + if ( ( pGObj1->GetType() & GEO_CURVE) != 0) { + // recupero la curva + const ICurve* pCrv1 = GetCurve( pGObj1) ; + // porto il punto Near nel riferimento dell'entità + Point3d ptNearL = ptNear ; + if ( ! InvTrasformPoint( pGeomDB, nId1, nRefId, ptNearL)) + return false ; + // calcolo il punto di auto-intersezione sulla curva più vicino al punto di riferimento + SelfIntersCurve sintC( *pCrv1) ; + if ( ! sintC.GetIntersPointNearTo( ptNearL, ptP)) + return false ; + } + else + return false ; + // gestione trasformazione ( eventuale) + return TrasformPoint( pGeomDB, nId1, nRefId, ptP) ; + } + // devono essere entità geometriche const IGeoObj* pGObj1 ; if ( ( pGObj1 = pGeomDB->GetGeoObj( nId1)) == nullptr) @@ -693,6 +719,23 @@ ExeCurveThickness( int nId, double* pdThick) return ( pCurve != nullptr && pCurve->GetThickness( *pdThick)) ; } +//---------------------------------------------------------------------------- +bool +ExeCurveSelfIntersNbr( int nId, int* pnCount) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero la curva + ICurve* pCurve = GetCurve( pGeomDB->GetGeoObj( nId)) ; + bool bOk = ( pCurve != nullptr) ; + // calcolo le auto-intersezioni + SelfIntersCurve sintC( *pCurve) ; + // ne recupero il numero + if ( pnCount != nullptr) + *pnCount = sintC.GetNumInters() ; + return true ; +} + //---------------------------------------------------------------------------- bool ExeGetMinDistPointCurve( const Point3d& ptP, int nId, double* pdDist, double* pdU) diff --git a/EgtExecutor.rc b/EgtExecutor.rc index a621860..f7c457d 100644 Binary files a/EgtExecutor.rc and b/EgtExecutor.rc differ diff --git a/LUA_GdbModifyCurve.cpp b/LUA_GdbModifyCurve.cpp index 6d47851..573ace6 100644 --- a/LUA_GdbModifyCurve.cpp +++ b/LUA_GdbModifyCurve.cpp @@ -286,6 +286,25 @@ LuaSplitCurveAtPoint( lua_State* L) return 1 ; } +//---------------------------------------------------------------------------- +static int +LuaSplitCurveAtSelfInters( lua_State* L) +{ + // 1 parametro : Id + int nId ; + LuaCheckParam( L, 1, nId) + LuaClearStack( L) ; + // divido la curva negli eventuali punti di autointersezione + int nCount ; + int nNewId = ExeSplitCurveAtSelfInters( nId, &nCount) ; + if ( nNewId != GDB_ID_NULL) + LuaSetReturn( L, nNewId) ; + else + LuaSetReturn( L) ; + LuaSetReturn( L, nCount) ; + return 2 ; +} + //------------------------------------------------------------------------------- static int LuaApproxCurve( lua_State* L) @@ -378,6 +397,7 @@ LuaInstallGdbModifyCurve( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtTrimExtendCurveByLen", LuaTrimExtendCurveByLen) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSplitCurve", LuaSplitCurve) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSplitCurveAtPoint", LuaSplitCurveAtPoint) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSplitCurveAtSelfInters", LuaSplitCurveAtSelfInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtApproxCurve", LuaApproxCurve) ; bOk = bOk && luaMgr.RegisterFunction( "EgtModifyCurveArcRadius", LuaModifyCurveArcRadius) ; bOk = bOk && luaMgr.RegisterFunction( "EgtExplodeCurveCompo", LuaExplodeCurveCompo) ; diff --git a/LUA_GdbObjects.cpp b/LUA_GdbObjects.cpp index 11371cd..c2d74e8 100644 --- a/LUA_GdbObjects.cpp +++ b/LUA_GdbObjects.cpp @@ -437,6 +437,22 @@ LuaRelocateGlob( lua_State* L) return 1 ; } +//------------------------------------------------------------------------------- +static int +LuaGetNewId( lua_State* L) +{ + // nessun parametro + LuaClearStack( L) ; + // richiedo valore nuovo Id + int nNewId = ExeGetNewId() ; + // restituisco il risultato + if ( nNewId != GDB_ID_NULL) + LuaSetReturn( L, nNewId) ; + else + LuaSetReturn( L) ; + return 1 ; +} + //------------------------------------------------------------------------------- static int LuaChangeId( lua_State* L) @@ -511,6 +527,7 @@ LuaInstallGdbObjects( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtCopyGlob", LuaCopyGlob) ; bOk = bOk && luaMgr.RegisterFunction( "EgtRelocate", LuaRelocate) ; bOk = bOk && luaMgr.RegisterFunction( "EgtRelocateGlob", LuaRelocateGlob) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtGetNewId", LuaGetNewId) ; bOk = bOk && luaMgr.RegisterFunction( "EgtChangeId", LuaChangeId) ; bOk = bOk && luaMgr.RegisterFunction( "EgtErase", LuaErase) ; bOk = bOk && luaMgr.RegisterFunction( "EgtEmptyGroup", LuaEmptyGroup) ; diff --git a/LUA_GeoSnap.cpp b/LUA_GeoSnap.cpp index fc6b04d..90ea0d6 100644 --- a/LUA_GeoSnap.cpp +++ b/LUA_GeoSnap.cpp @@ -289,7 +289,7 @@ LuaCurveDomain( lua_State* L) LuaClearStack( L) ; // recupero il dominio della curva double dStart, dEnd ; - if ( ExeCurveDomain( nId, &dStart, &dEnd) != FALSE) { + if ( ExeCurveDomain( nId, &dStart, &dEnd)) { LuaSetReturn( L, dStart) ; LuaSetReturn( L, dEnd) ; return 2 ; @@ -310,7 +310,7 @@ LuaCurveLength( lua_State* L) LuaClearStack( L) ; // recupero la lunghezza della curva double dLen ; - if ( ExeCurveLength( nId, &dLen) != FALSE) + if ( ExeCurveLength( nId, &dLen)) LuaSetReturn( L, dLen) ; else LuaSetReturn( L) ; @@ -346,7 +346,7 @@ LuaCurveThickness( lua_State* L) LuaClearStack( L) ; // recupero lo spessore double dThick ; - if ( ExeCurveThickness( nId, &dThick) != FALSE) + if ( ExeCurveThickness( nId, &dThick)) LuaSetReturn( L, dThick) ; else LuaSetReturn( L) ; @@ -375,6 +375,23 @@ LuaExtrusionByThickness( lua_State* L) return 1 ; } +//---------------------------------------------------------------------------- +static int +LuaCurveSelfIntersNbr( lua_State* L) +{ + // 1 parametro : Id + int nId ; + LuaCheckParam( L, 1, nId) + LuaClearStack( L) ; + // recupero il numero di auto-intersezioni + int nCount ; + if ( ExeCurveSelfIntersNbr( nId, &nCount)) + LuaSetReturn( L, nCount) ; + else + LuaSetReturn( L) ; + return 1 ; +} + //---------------------------------------------------------------------------- static int LuaCurveArcRadius( lua_State* L) @@ -385,7 +402,7 @@ LuaCurveArcRadius( lua_State* L) LuaClearStack( L) ; // recupero il raggio double dRad ; - if ( ExeCurveArcRadius( nId, &dRad) != FALSE) + if ( ExeCurveArcRadius( nId, &dRad)) LuaSetReturn( L, dRad) ; else LuaSetReturn( L) ; @@ -591,6 +608,7 @@ LuaInstallGeoSnap( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtCurveLength", LuaCurveLength) ; bOk = bOk && luaMgr.RegisterFunction( "EgtCurveExtrusion", LuaCurveExtrusion) ; bOk = bOk && luaMgr.RegisterFunction( "EgtCurveThickness", LuaCurveThickness) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtCurveSelfIntersNbr", LuaCurveSelfIntersNbr) ; bOk = bOk && luaMgr.RegisterFunction( "EgtCurveArcRadius", LuaCurveArcRadius) ; bOk = bOk && luaMgr.RegisterFunction( "EgtCurveArcNormVersor", LuaCurveArcNormVersor) ; bOk = bOk && luaMgr.RegisterFunction( "EgtCurveCompoCenter", LuaCurveCompoCenter) ;