From c602a4f2ac83fa520c975ac930122fc954e3af9f Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Wed, 4 Sep 2024 15:48:44 +0200 Subject: [PATCH] EgtExecutor : - correzioni a CreateSurfBzByExtrusion - aggiunta della CreateSurfBzByRegionExtrusion. --- EXE_GdbCreateSurf.cpp | 225 +++++++++++++++++++++++++++++++----------- LUA_GdbCreateSurf.cpp | 69 ++++++++++--- 2 files changed, 221 insertions(+), 73 deletions(-) diff --git a/EXE_GdbCreateSurf.cpp b/EXE_GdbCreateSurf.cpp index c0ebb88..d65f43a 100644 --- a/EXE_GdbCreateSurf.cpp +++ b/EXE_GdbCreateSurf.cpp @@ -2025,7 +2025,7 @@ ExeCreateSurfBzByRegion( int nParentId, const INTVECTOR& vCrvIds, double dLinTol //------------------------------------------------------------------------------- int -ExeCreateSurfBzByExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vector3d& vtExtr, bool bCapEnds, +ExeCreateSurfBzByExtrusion( int nParentId, int nCrvId, const Vector3d& vtExtr, bool bCapEnds, double dLinTol, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; @@ -2035,6 +2035,74 @@ ExeCreateSurfBzByExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vecto // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; + //recupero il riferimento della curva + Frame3d frCrv ; + bOk = bOk && pGeomDB->GetGlobFrame( nCrvId, frCrv) ; + // recupero la curva in locale + const ICurve* pCrvOrig = GetCurve( pGeomDB->GetGeoObj( nCrvId)) ; + PtrOwner pCrv( pCrvOrig->Clone()) ; + // porto in locale il vettore estrusione + Vector3d vtExtrL = GetVectorLocal( pGeomDB, vtExtr, nRefType, frLoc) ; + // creo la superficie e la inserisco nel DB + int nFirstId = GDB_ID_NULL ; + double dAndTolStdDeg = 15 ; + Plane3d plPlane ; + double dArea ; + PolyLine plApprox ; + pCrv->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_STD, plApprox) ; + double dOrthoExtr = 0 ; + if ( bCapEnds && plApprox.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)){ + dOrthoExtr = plPlane.GetVersN() * vtExtr ; + if ( ( abs( dOrthoExtr) < EPS_SMALL)) + return GDB_ID_NULL ; + if( dOrthoExtr < 0) + pCrv->Invert() ; + } + // creo l'estrusione della curva + ISurfBezier* pSbz = ( bOk ? GetSurfBezierByExtrusion( pCrv, vtExtrL, false, dLinTol) : nullptr ) ; + // inserisco la superficie nel DB + int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbz) : GDB_ID_NULL) ; + bOk = bOk && ( nNewId != GDB_ID_NULL) ; + + // se richiesta chiusura agli estremi + if ( bCapEnds) { + PtrOwner pSrfBzTop( CreateSurfBezier()) ; + pSrfBzTop->CreateByFlatContour( plApprox) ; + pSrfBzTop->Translate( vtExtrL) ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) ; + PtrOwner pSrfBzBottom( CreateSurfBezier()) ; + pSrfBzBottom->CreateByFlatContour( plApprox) ; + pSrfBzBottom->Invert() ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) ; + } + + ExeSetModified() ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtSurfBzByExtrusion(" + IdToString( nParentId) + "," + + IdToString( nCrvId) + ",{" + + ToString( vtExtr) + "}," + + ToString( dLinTol) + "," + + RefTypeToString( nRefType) + ")" + + " -- Id=" + ToString( nFirstId) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco l'identificativo della nuova entità + return nFirstId ; +} + +//------------------------------------------------------------------------------- +int +ExeCreateSurfBzByRegionExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vector3d& vtExtr, bool bCapEnds, + double dLinTol, int nRefType) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + nParentId = AdjustId( nParentId) ; + bool bOk = true ; + // recupero il riferimento locale + Frame3d frLoc ; + bOk = bOk && pGeomDB->GetGroupGlobFrame( nParentId, frLoc) ; // recupero le curve in locale CURVELOCALVECTOR vCrvLoc ; vCrvLoc.reserve( vCrvIds.size()) ; @@ -2055,72 +2123,74 @@ ExeCreateSurfBzByExtrusion( int nParentId, const INTVECTOR& vCrvIds, const Vecto // creo le superfici e le inserisco nel DB int nFirstId = GDB_ID_NULL ; double dAndTolStdDeg = 15 ; + + // riordino le curve in modo che la prima sia quella esterna e tutte le altre dopo + POLYLINEVECTOR vPLOrd ; + POLYLINEVECTOR vPL ; for ( int i = 0 ; i < int( vCrvP.size()) ; ++ i) { - Plane3d plPlane ; - double dArea ; - PolyLine plApprox ; - vCrvP[i]->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_STD, plApprox) ; - plApprox.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL) ; - PtrOwner pCrvToExtrude( vCrvP[i]->Clone()) ; - if( plPlane.GetVersN() * vtExtrL < 0) - pCrvToExtrude->Invert() ; + vPL.emplace_back() ; + if ( ! vCrvP[i]->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_SPECIAL, vPL.back())) + return false ; + } + Vector3d vtN ; + INTMATRIX vnPLIndMat ; + BOOLVECTOR vbInvert ; + if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat, vbInvert)) + return nFirstId ; + + // creo una copia delle curve, orientate giuste + ICURVEPOVECTOR vpCrvOr ; + for (int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) { + for ( int j = 0 ; j< int( vnPLIndMat[i].size()) ; ++j) { + vpCrvOr.emplace_back( vCrvP[vnPLIndMat[i][j]]->Clone()) ; + if( vbInvert[vnPLIndMat[i][j]]) + vpCrvOr.back()->Invert() ; + } + } + + // controlo se il vettore di estrusione è orientato come la normale della curva più grande o no + bool bOrientedAsExtrusion = false ; + Plane3d plPlane ; + double dArea ; + double dOrthoExtr = 0 ; + // verifico che la curva sia chiusa e piatta + if ( vPL[0].IsClosedAndFlat(plPlane, dArea, dLinTol)) { + dOrthoExtr = plPlane.GetVersN() * vtExtr ; + // controllo che ci sia una componente dell'estrusione perpendicolare al piano della curva + if( abs( dOrthoExtr) < EPS_SMALL) + return GDB_ID_NULL ; + if( dOrthoExtr > EPS_SMALL) + bOrientedAsExtrusion = true ; + } + else + bCapEnds = false ; + + // creo l'estrusione delle curve + for ( int i = 0 ; i < int( vpCrvOr.size()) ; ++ i) { // calcolo la superficie - ISurfBezier* pSbz = ( bOk ? GetSurfBezierByExtrusion( pCrvToExtrude, vtExtrL, false, dLinTol) : nullptr) ; + ISurfBezier* pSbz = ( bOk ? GetSurfBezierByExtrusion( vpCrvOr[i], vtExtrL, false, dLinTol) : nullptr ) ; + if( ! bOrientedAsExtrusion) + pSbz->Invert() ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbz) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; } + // se richiesta chiusura agli estremi if ( bCapEnds) { - // verifico che la curva sia chiusa e piatta - Plane3d plPlane ; - double dArea ; - PolyLine plApprox ; - vCrvP[0]->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_STD, plApprox) ; - if ( plApprox.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)) { - // componente dell'estrusione perpendicolare al piano della curva - double dOrthoExtr = plPlane.GetVersN() * vtExtr ; - if ( ( abs( dOrthoExtr) > EPS_SMALL)) { - if( vCrvIds.size() == 1) { - PtrOwner pSrfBzTop( CreateSurfBezier()) ; - pSrfBzTop->CreateByFlatContour( plApprox) ; - pSrfBzTop->Translate( vtExtrL) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) ; - PtrOwner pSrfBzBottom( CreateSurfBezier()) ; - pSrfBzBottom->CreateByFlatContour( plApprox) ; - pSrfBzBottom->Invert() ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) ; - } - else { - // riordino le curve in modo che la prima sia quella esterna e tutte le altre dopo - POLYLINEVECTOR vPLOrd ; - POLYLINEVECTOR vPL ; - for ( int i = 0 ; i < int( vCrvP.size()) ; ++ i) { - if ( ! vCrvP[i]->ApproxWithLines( dLinTol, dAndTolStdDeg, ICurve::APL_SPECIAL, vPL[i])) - return false ; - } - Vector3d vtN ; - INTMATRIX vnPLIndMat ; - if ( ! CalcRegionPolyLines( vPL, vPLOrd, vtN, vnPLIndMat)) - return nFirstId ; - // se componente estrusione negativa, inverto tutti i percorsi - if ( dOrthoExtr < 0) { - for ( int i = 0 ; i < int( vPL.size()) ; ++ i) - vPL[i].Invert() ; - } - PtrOwner pSrfBzTop( CreateSurfBezier()) ; - pSrfBzTop->CreateByRegion( vPL) ; - pSrfBzTop->Translate( vtExtrL) ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) ; - PtrOwner pSrfBzBottom( CreateSurfBezier()) ; - pSrfBzBottom->CreateByRegion( vPL) ; - pSrfBzBottom->Invert() ; - pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) ; - } - } - } + PtrOwner pSrfBzTop( CreateSurfBezier()) ; + pSrfBzTop->CreateByRegion( vPL) ; + pSrfBzTop->Translate( vtExtrL) ; + if( ! bOrientedAsExtrusion) + pSrfBzTop->Invert() ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzTop)) ; + PtrOwner pSrfBzBottom( CreateSurfBezier()) ; + pSrfBzBottom->CreateByRegion( vPL) ; + if( bOrientedAsExtrusion) + pSrfBzBottom->Invert() ; + pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSrfBzBottom)) ; } ExeSetModified() ; @@ -2161,6 +2231,15 @@ ExeCreateSurfBzByScrewing( int nParentId, int nCrvId, ISurfBezier* pSbz = ( bOk ? GetSurfBezierByScrewing( CrvLoc, ptAxL, vtAxL, dAngRotDeg, dMove, bCapEnds, dLinTol) : nullptr) ; // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbz) : GDB_ID_NULL) ; + + // se richiesto creo anche i cap + if ( bCapEnds && bOk) { + // la curva che fa da sezione alla superficie deve essere chiusa e piana + // lo screwing non deve essere una semplice rivoluzione + Plane3d plPlane ; + if ( CrvLoc->IsClosed() && CrvLoc->IsFlat( plPlane) && abs(abs(dAngRotDeg) - ANG_FULL) < EPS_SMALL && abs( dMove) < EPS_SMALL) { + } + } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { @@ -2269,7 +2348,7 @@ ExeCreateSurfBzByRevolve( int nParentId, int nCrvId, //------------------------------------------------------------------------------- int -ExeCreateSurfBzRuled( int nParentId, int nCrvId1, int nCrvId2, int nRuledType, double dLinTol) +ExeCreateSurfBzRuled( int nParentId, int nCrvId1, int nCrvId2, int nRuledType, bool bCapEnds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) @@ -2285,8 +2364,36 @@ ExeCreateSurfBzRuled( int nParentId, int nCrvId1, int nCrvId2, int nRuledType, d bOk = bOk && ( CrvLoc2.Get() != nullptr) ; // calcolo la superficie ISurfBezier* pSbz = ( bOk ? GetSurfBezierRuled( CrvLoc1, CrvLoc2, nRuledType, dLinTol) : nullptr) ; + // se le curve sono chiuse e la superficie guarda all'interno del "cilindro" allora inverto la superficie + if ( CrvLoc1->IsClosed() && CrvLoc2->IsClosed()) { + Point3d ptStart1 ; CrvLoc1->GetStartPoint( ptStart1) ; + Point3d ptStart2 ; CrvLoc2->GetStartPoint( ptStart2) ; + Vector3d vtRuling = ptStart2 - ptStart1 ; + Plane3d plApprox ; + } + // inserisco la superficie nel DB int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, pSbz) : GDB_ID_NULL) ; + + // se richiesto inserisco anche il cap + if ( bCapEnds && bOk) { + Plane3d plPlane1, plPlane2 ; + if ( CrvLoc1->IsClosed() && CrvLoc1->IsFlat( plPlane1) && CrvLoc2->IsClosed() && CrvLoc2->IsFlat( plPlane2)) { + // costruisco la superficie dalla curva 1 + PtrOwner pSbzFlat1( CreateSurfBezier()) ; + double dAngTolDeg = 5 ; + PolyLine pl1 ; CrvLoc1->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl1) ; + pSbzFlat1->CreateByFlatContour( pl1) ; + // inserisco la superficie nel DB + bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat1)) ; + // costruisco la superficie dalla curva 2 + PtrOwner pSbzFlat2( CreateSurfBezier()) ; + PolyLine pl2 ; CrvLoc2->ApproxWithLines(dLinTol, dAngTolDeg, ICurve::APL_STD, pl2) ; + pSbzFlat2->CreateByFlatContour( pl2) ; + // inserisco la superficie nel DB + bOk = bOk && pGeomDB->AddGeoObj( GDB_ID_NULL, nParentId, Release( pSbzFlat2)) ; + } + } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { @@ -2304,7 +2411,7 @@ ExeCreateSurfBzRuled( int nParentId, int nCrvId1, int nCrvId2, int nRuledType, d //------------------------------------------------------------------------------- int -ExeCreateSurfBzSkinned( int nParentId, const INTVECTOR& vCrvIds, double dLinTol) +ExeCreateSurfBzSkinned( int nParentId, const INTVECTOR& vCrvIds, bool bCapEnds, double dLinTol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) diff --git a/LUA_GdbCreateSurf.cpp b/LUA_GdbCreateSurf.cpp index 8a61dd3..1610a00 100644 --- a/LUA_GdbCreateSurf.cpp +++ b/LUA_GdbCreateSurf.cpp @@ -1028,7 +1028,38 @@ LuaCreateSurfBzByRegion( lua_State* L) static int LuaCreateSurfBzByExtrusion( lua_State* L) { - // 4 o 5 o 6 parametri : ParentId, CrvIds, vtExtr, bool bCapEnds [, dTol] [, nRefType] + // 3 o 4 o 5 o 6 parametri : ParentId, CrvId, vtExtr [, bool bCapEnds] [, dTol] [, nRefType] + int nParentId ; + LuaCheckParam( L, 1, nParentId) + int nCrvId ; + LuaCheckParam( L, 2, nCrvId) + Vector3d vtExtr ; + LuaCheckParam( L, 3, vtExtr) + bool bCapEnds = false ; + int nPar = 4 ; + if ( LuaGetParam( L, nPar, bCapEnds)) + ++ nPar ; + double dLinTol = LIN_TOL_SRF ; + if ( LuaGetParam( L, nPar, dLinTol)) + ++ nPar ; + int nRefType = RTY_DEFAULT ; + LuaGetParam( L, nPar, nRefType) ; + LuaClearStack( L) ; + // creo STM estrudendo uno o più percorsi, se piani si possono mettere i tappi + int nId = ExeCreateSurfBzByExtrusion( nParentId, nCrvId, vtExtr, bCapEnds, dLinTol, nRefType) ; + // restituisco il risultato + if ( nId != GDB_ID_NULL) + LuaSetParam( L, nId) ; + else + LuaSetParam( L) ; + return 1 ; +} + +//------------------------------------------------------------------------------- +static int +LuaCreateSurfBzByRegionExtrusion( lua_State* L) +{ + // 3 o 4 o 5 o 6 parametri : ParentId, CrvIds, vtExtr [, bool bCapEnds] [, dTol] [, nRefType] int nParentId ; LuaCheckParam( L, 1, nParentId) INTVECTOR vCrvIds ; @@ -1036,16 +1067,17 @@ LuaCreateSurfBzByExtrusion( lua_State* L) Vector3d vtExtr ; LuaCheckParam( L, 3, vtExtr) bool bCapEnds = false ; - LuaCheckParam( L, 4, bCapEnds) + int nPar = 4 ; + if ( LuaGetParam( L, nPar, bCapEnds)) + ++ nPar ; double dLinTol = LIN_TOL_SRF ; + if ( LuaGetParam( L, nPar, dLinTol)) + ++ nPar ; int nRefType = RTY_DEFAULT ; - if ( LuaGetParam( L, 5, dLinTol)) - LuaGetParam( L, 6, nRefType) ; - else - LuaGetParam( L, 5, nRefType) ; + LuaGetParam( L, nPar, nRefType) ; LuaClearStack( L) ; // creo STM estrudendo uno o più percorsi, se piani si possono mettere i tappi - int nId = ExeCreateSurfBzByExtrusion( nParentId, vCrvIds, vtExtr, bCapEnds, dLinTol, nRefType) ; + int nId = ExeCreateSurfBzByRegionExtrusion( nParentId, vCrvIds, vtExtr, bCapEnds, dLinTol, nRefType) ; // restituisco il risultato if ( nId != GDB_ID_NULL) LuaSetParam( L, nId) ; @@ -1130,7 +1162,7 @@ LuaCreateSurfBzByRevolve( lua_State* L) static int LuaCreateSurfBzByPointCurve( lua_State* L) { - // 3 o 4 o 5 o 6 parametri : ParentId, CrvId, ptAx, vtAx [, bCapEnds] [, dTol] [, nRefType] + // 4 o 5 o 6 o 7 parametri : ParentId, CrvId, ptAx, vtAx [, bCapEnds] [, dTol] [, nRefType] int nParentId ; LuaCheckParam( L, 1, nParentId) int nCrvId ; @@ -1162,7 +1194,7 @@ LuaCreateSurfBzByPointCurve( lua_State* L) static int LuaCreateSurfBzRuled( lua_State* L) { - // 4 o 5 parametri : ParentId, CrvId1, CrvId2, nRuledType [, dTol] + // 4 o 5 o 6 parametri : ParentId, CrvId1, CrvId2, nRuledType [, bCapEnds] [, dTol] int nParentId ; LuaCheckParam( L, 1, nParentId) int nCrvId1 ; @@ -1171,11 +1203,15 @@ LuaCreateSurfBzRuled( lua_State* L) LuaCheckParam( L, 3, nCrvId2) int nRuledType ; LuaCheckParam( L, 4, nRuledType) + bool bCapEnds = false ; + int nPar = 5 ; + if( LuaGetParam( L, nPar, bCapEnds)) + ++ nPar ; double dLinTol = LIN_TOL_SRF ; - LuaGetParam( L, 5, dLinTol) ; + LuaGetParam( L, nPar, dLinTol) ; LuaClearStack( L) ; // creo STM riempiendo un contorno piano - int nId = ExeCreateSurfBzRuled( nParentId, nCrvId1, nCrvId2, nRuledType, dLinTol) ; + int nId = ExeCreateSurfBzRuled( nParentId, nCrvId1, nCrvId2, nRuledType, bCapEnds, dLinTol) ; // restituisco il risultato if ( nId != GDB_ID_NULL) LuaSetParam( L, nId) ; @@ -1188,16 +1224,20 @@ LuaCreateSurfBzRuled( lua_State* L) static int LuaCreateSurfBzSkinned( lua_State* L) { - // 4 o 5 parametri : ParentId, vCrvIds, [, dTol] + // 2 o 3 o 4 parametri : ParentId, vCrvIds [, bCapEnds] [, dTol] int nParentId ; LuaCheckParam( L, 1, nParentId) INTVECTOR vCrvIds ; LuaCheckParam( L, 2, vCrvIds) + bool bCapEnds = false ; + int nPar = 3 ; + if ( LuaGetParam( L, nPar, bCapEnds)) + ++ nPar ; double dLinTol = LIN_TOL_SRF ; - LuaGetParam( L, 3, dLinTol) ; + LuaGetParam( L, nPar, dLinTol) ; LuaClearStack( L) ; // creo STM riempiendo un contorno piano - int nId = ExeCreateSurfBzSkinned( nParentId, vCrvIds, dLinTol) ; + int nId = ExeCreateSurfBzSkinned( nParentId, vCrvIds, bCapEnds, dLinTol) ; // restituisco il risultato if ( nId != GDB_ID_NULL) LuaSetParam( L, nId) ; @@ -1248,6 +1288,7 @@ LuaInstallGdbCreateSurf( LuaMgr& luaMgr) bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByFlatContour", LuaCreateSurfBzByFlatContour) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByRegion", LuaCreateSurfBzByRegion) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByExtrusion", LuaCreateSurfBzByExtrusion) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByRegionExtrusion", LuaCreateSurfBzByRegionExtrusion) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByScrewing", LuaCreateSurfBzByScrewing) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByRevolve", LuaCreateSurfBzByRevolve) ; bOk = bOk && luaMgr.RegisterFunction( "EgtSurfBzByPointCurve", LuaCreateSurfBzByPointCurve) ;