From b4eccf1f18ee39a57e5ff3bfedc1d59ca3ec5ad7 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 17 Jan 2024 13:22:34 +0100 Subject: [PATCH] EgtExecutor : - aggiunta funzione Exe e Lua LineCurveInters. --- EXE_GdbCreateCurve.cpp | 7 +- EXE_GeoInters.cpp | 1375 +++++++++++++++++++++------------------- LUA_GeoInters.cpp | 310 +++++---- 3 files changed, 910 insertions(+), 782 deletions(-) diff --git a/EXE_GdbCreateCurve.cpp b/EXE_GdbCreateCurve.cpp index b72f951..61a5c4e 100644 --- a/EXE_GdbCreateCurve.cpp +++ b/EXE_GdbCreateCurve.cpp @@ -362,16 +362,13 @@ CreateLineTgTwoCurves( IGeomDB* pGeomDB, int nParentId, if ( pCrv2 == nullptr) return nullptr ; // porto la seconda curva nel riferimento della prima - PtrOwner pCrv2Loc( pCrv2->Clone()) ; - if ( IsNull( pCrv2Loc)) - return nullptr ; - pCrv2Loc->LocToLoc( frCrv2, frCrv1) ; + CurveLocal Crv2Loc( pGeomDB, nIdF, frCrv1) ; // porto il punto vicino al finale nel riferimento della prima curva Point3d ptN2loc( ptFin) ; ptN2loc.LocToLoc( frDest, frCrv1) ; // calcolo la retta tangente alle due curve PtrOwner pCrvLine ; - pCrvLine.Set( GetLineTgTwoCurves( *pCrv1, ptN1loc, *pCrv2Loc, ptN2loc)) ; + pCrvLine.Set( GetLineTgTwoCurves( *pCrv1, ptN1loc, *Crv2Loc, ptN2loc)) ; if ( IsNull( pCrvLine)) return nullptr ; // porto la linea nel riferimento del gruppo destinazione diff --git a/EXE_GeoInters.cpp b/EXE_GeoInters.cpp index 78ddb87..2ee0acc 100644 --- a/EXE_GeoInters.cpp +++ b/EXE_GeoInters.cpp @@ -24,6 +24,7 @@ #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkChainCurves.h" +#include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGkSurfLocal.h" @@ -43,7 +44,108 @@ using namespace std ; //------------------------------------------------------------------------------- bool -ExeLineBoxInters( const Point3d& ptP, const Vector3d& vtDir, const BBox3d& b3Box, INTDBLVECTOR& vInters) +MyLineCurveInters( const Point3d& ptP, const Vector3d& vtDir, const int nId, const int nRefType, + INTDBLVECTOR& vInters) +{ + vInters.clear() ; + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero il riferimento di calcolo + Frame3d frCalc ; + if ( nRefType == RTY_GLOB) + frCalc = GLOB_FRM ; + else if ( nRefType == RTY_GRID) + frCalc = pGeomDB->GetGridFrame() ; + else { + if ( ! pGeomDB->GetGlobFrame( nId, frCalc)) + return false ; + } + // recupero la curva in locale al gruppo destinazione + CurveLocal CrvLoc( pGeomDB, nId, frCalc) ; + // calcolo l'ingombro della curva + BBox3d b3Crv ; + if ( ! CrvLoc->GetLocalBBox( b3Crv)) + return false ; + b3Crv.Expand( 100 * EPS_SMALL) ; + // definisco la linea (punto e direzione sono già nel riferimento di calcolo) + double dLen = 2 * floor( b3Crv.MaxDistFromPoint( ptP)) ; + double dOffs = -dLen / 2 ; + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine) || ! pLine->SetPVL( ptP + dOffs * vtDir, vtDir, dLen) ) + return false ; + // intersezione fra le curve nel piano di calcolo + IntersCurveCurve intCC( *pLine, *CrvLoc, true) ; + int nInters = intCC.GetIntersCount() ; + // recupero i risultati + for ( int i = 0 ; i < nInters ; i++) { + IntCrvCrvInfo aInfo ; + intCC.GetIntCrvCrvInfo( i, aInfo) ; + // se intersezione puntuale + if ( ! aInfo.bOverlap) { + double dDist = dOffs + aInfo.IciA[0].dU * dLen ; + int nType = CLT_NONE ; + if ( aInfo.IciA[0].nPrevTy == ICCT_IN) { + if ( aInfo.IciA[0].nNextTy == ICCT_IN) + nType = CLT_TOUCH_IN ; + else if ( aInfo.IciA[0].nNextTy == ICCT_OUT) + nType = CLT_OUT ; + } + else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT) { + if ( aInfo.IciA[0].nNextTy == ICCT_IN) + nType = CLT_IN ; + else if ( aInfo.IciA[0].nNextTy == ICCT_OUT) + nType = CLT_TOUCH_OUT ; + } + vInters.emplace_back( nType, dDist) ; + } + // altrimenti sovrapposizione + else { + // inizio + double dDist1 = dOffs + aInfo.IciA[0].dU * dLen ; + int nType1 = CLT_NONE ; + if ( aInfo.IciA[0].nPrevTy == ICCT_IN) + nType1 = CLT_TGINI_IN ; + else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT) + nType1 = CLT_TGINI_OUT ; + vInters.emplace_back( nType1, dDist1) ; + // fine + double dDist2 = dOffs + aInfo.IciA[1].dU * dLen ; + int nType2 = CLT_NONE ; + if ( aInfo.IciA[1].nNextTy == ICCT_IN) + nType2 = CLT_TGFIN_IN ; + else if ( aInfo.IciA[1].nNextTy == ICCT_OUT) + nType2 = CLT_TGFIN_OUT ; + vInters.emplace_back( nType2, dDist2) ; + } + } + return true ; +} + +//------------------------------------------------------------------------------- +bool +ExeLineCurveInters( const Point3d& ptP, const Vector3d& vtDir, const int nId, const int nRefType, + INTDBLVECTOR& vInters) +{ + // eseguo + bool bOk = MyLineCurveInters( ptP, vtDir, nId, nRefType, vInters) ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtLineCurveInters({" + ToString( ptP) + "},{" + + ToString( vtDir) + "},{" + + ToString( nId) + "," + + RefTypeToString( nRefType) + ")" + + " -- Ok=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + // restituisco stato esecuzione + return bOk ; +} + +//------------------------------------------------------------------------------- +bool +ExeLineBoxInters( const Point3d& ptP, const Vector3d& vtDir, const BBox3d& b3Box, + INTDBLVECTOR& vInters) { // eseguo bool bOk = IntersLineBox( ptP, vtDir, 1, b3Box, vInters, false) ; @@ -59,6 +161,475 @@ ExeLineBoxInters( const Point3d& ptP, const Vector3d& vtDir, const BBox3d& b3Box return bOk ; } +//------------------------------------------------------------------------------- +static bool +MyLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, + INTDBLVECTOR& vInters) +{ + vInters.clear() ; + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero la superficie TriMesh + const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; + if ( pStm == nullptr) + return false ; + // recupero il suo riferimento globale + Frame3d frSurf ; + if ( ! pGeomDB->GetGlobFrame( nId, frSurf)) + return false ; + // porto in locale il punto e la direzione della linea + Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frSurf) ; + Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ; + vtDirL.Normalize() ; + // calcolo l'ingombro della trimesh + BBox3d b3Surf ; + if ( ! pStm->GetLocalBBox( b3Surf)) + return false ; + // calcolo l'intersezione + double dLen = b3Surf.MaxDistFromPoint( ptPL) ; + ILSIVECTOR vInfo ; + if ( ! IntersLineSurfTm( ptPL, vtDirL, dLen, *pStm, vInfo, false)) + return false ; + // ciclo sulle intersezioni + for ( const auto& Info : vInfo) { + // se intersezione puntuale + if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) { + int nFlag = SLT_TOUCH ; + if ( Info.dCosDN > EPS_ZERO) + nFlag = SLT_OUT ; + else if ( Info.dCosDN < -EPS_ZERO) + nFlag = SLT_IN ; + vInters.emplace_back( nFlag, Info.dU) ; + } + // se altrimenti intersezione con coincidenza + else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) { + vInters.emplace_back( SLT_TG_INI, Info.dU) ; + vInters.emplace_back( SLT_TG_FIN, Info.dU2) ; + } + } + // elimino intersezioni ripetute + for ( size_t j = 1 ; j < vInters.size() ; ) { + // intersezione precedente + size_t i = j - 1 ; + // se hanno lo stesso parametro + if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) { + // se sono entrambe entranti o uscenti, elimino la seconda + if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_IN) || + ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_OUT)) { + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una entrante e l'altra uscente, cambio in touch ed elimino la seconda + else if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_OUT) || + ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_IN)) { + vInters[i].first = SLT_TOUCH ; + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una puntuale e l'altra inizio di coincidenza, elimino la prima + else if ( ( vInters[i].first == SLT_IN || vInters[i].first == SLT_OUT || vInters[i].first == SLT_TOUCH) && vInters[j].first == SLT_TG_INI) { + vInters.erase( vInters.begin() + i) ; + continue ; + } + // se una fine di coincidenza e l'altra puntuale, elimino la seconda + else if ( vInters[i].first == SLT_TG_FIN && ( vInters[j].first == SLT_IN || vInters[j].first == SLT_OUT || vInters[j].first == SLT_TOUCH)) { + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe + else if ( i > 0 && vInters[i].first == SLT_TG_FIN && vInters[j].first == SLT_TG_INI) { + vInters.erase( vInters.begin() + j) ; + vInters.erase( vInters.begin() + i) ; + -- j ; + continue ; + } + } + // passo alla successiva + ++ j ; + } + + return true ; +} + +//------------------------------------------------------------------------------- +bool +ExeLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, + INTDBLVECTOR& vInters) +{ + // eseguo + bool bOk = MyLineSurfTmInters( ptP, vtDir, nId, nRefType, vInters) ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtLineSurfTmInters({" + ToString( ptP) + "},{" + + ToString( vtDir) + "}," + + ToString( nId) + "," + + RefTypeToString( nRefType) + ")" + + " -- Ok=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco l'identificativo della prima nuova entità + return bOk ; +} + +//------------------------------------------------------------------------------- +static bool +MyLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) +{ + vInters.clear() ; + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero lo Zmap + IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ; + if ( pVZM == nullptr) + return false ; + // recupero il suo riferimento globale + Frame3d frZmap ; + if ( ! pGeomDB->GetGlobFrame( nId, frZmap)) + return false ; + // porto in locale il punto e la direzione della linea + Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frZmap) ; + Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frZmap) ; + vtDirL.Normalize() ; + // calcolo l'ingombro dello Zmap + BBox3d b3Surf ; + if ( ! pVZM->GetLocalBBox( b3Surf)) + return false ; + // calcolo l'intersezione + ILZIVECTOR vInfo ; + if ( ! pVZM->GetLineIntersection( ptPL, vtDirL, vInfo)) + return false ; + // ciclo sulle intersezioni + for ( const auto& Info : vInfo) { + // se intersezione puntuale + if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) { + int nFlag = SLT_TOUCH ; + if ( vtDirL * Info.trTria.GetN() > EPS_ZERO) + nFlag = SLT_OUT ; + else if ( vtDirL * Info.trTria.GetN() < -EPS_ZERO) + nFlag = SLT_IN ; + vInters.emplace_back( nFlag, Info.dU) ; + } + // se altrimenti intersezione con coincidenza + else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) { + vInters.emplace_back( SLT_TG_INI, Info.dU) ; + vInters.emplace_back( SLT_TG_FIN, Info.dU2) ; + } + } + // elimino intersezioni ripetute + for ( size_t j = 1 ; j < vInters.size() ; ) { + // intersezione precedente + size_t i = j - 1 ; + // se hanno lo stesso parametro + if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) { + // se sono entrambe entranti o uscenti, elimino la seconda + if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_IN) || + ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_OUT)) { + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una entrante e l'altra uscente, cambio in touch ed elimino la seconda + else if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_OUT) || + ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_IN)) { + vInters[i].first = SLT_TOUCH ; + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una puntuale e l'altra inizio di coincidenza, elimino la prima + else if ( ( vInters[i].first == SLT_IN || vInters[i].first == SLT_OUT || vInters[i].first == SLT_TOUCH) && vInters[j].first == SLT_TG_INI) { + vInters.erase( vInters.begin() + i) ; + continue ; + } + // se una fine di coincidenza e l'altra puntuale, elimino la seconda + else if ( vInters[i].first == SLT_TG_FIN && ( vInters[j].first == SLT_IN || vInters[j].first == SLT_OUT || vInters[j].first == SLT_TOUCH)) { + vInters.erase( vInters.begin() + j) ; + continue ; + } + // se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe + else if ( i > 0 && vInters[i].first == SLT_TG_FIN && vInters[j].first == SLT_TG_INI) { + vInters.erase( vInters.begin() + j) ; + vInters.erase( vInters.begin() + i) ; + -- j ; + continue ; + } + } + // passo alla successiva + ++ j ; + } + + return true ; +} + +//------------------------------------------------------------------------------- +bool +ExeLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) +{ + // eseguo + bool bOk = MyLineVolZmapInters( ptP, vtDir, nId, nRefType, vInters) ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtLineVolZmapInters({" + ToString( ptP) + "},{" + + ToString( vtDir) + "}," + + ToString( nId) + "," + + RefTypeToString( nRefType) + ")" + + " -- Ok=" + ToString( bOk) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco stato operazione + return bOk ; +} + +//------------------------------------------------------------------------------- +static int +MyAddPlaneIntersResultToGeomDB( IGeomDB* pGeomDB, const PNTVECTOR& vPnt, const BIPNTVECTOR& vBpt, const TRIA3DVECTOR& vTria, + const Frame3d& frOrig, const Frame3d& frDest, int nId, int nDestGrpId, const Vector3d& vtExtr, + double dToler, int& nPntCount, int& nCrvCount, int& nSrfCount) +{ + // Inserisco il risultato nel DB + int nFirstId = GDB_ID_NULL ; + // Inserisco i punti nel DB + for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { + // creo il punto + PtrOwner pGeoPnt( CreateGeoPoint3d()) ; + if ( IsNull( pGeoPnt)) + return GDB_ID_NULL ; + // setto il punto + pGeoPnt->Set( vPnt[i]) ; + // porto il punto nel riferimento destinazione + pGeoPnt->LocToLoc( frOrig, frDest) ; + // lo inserisco nel DB geometrico + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + // copio il materiale + if ( ! pGeomDB->CopyMaterial( nId, nNewId)) + return GDB_ID_NULL ; + // aggiorno contatori + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nPntCount ; + } + // Inserisco le curve nel DB (dopo averle concatenate) + ChainCurves chainC ; + chainC.Init( false, dToler, int( vBpt.size())) ; + for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) { + Vector3d vtDir = vBpt[i].second - vBpt[i].first ; + vtDir.Normalize() ; + if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir)) + return GDB_ID_NULL ; + } + // recupero i percorsi concatenati + Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ; + INTVECTOR vId ; + while ( chainC.GetChainFromNear( ptNear, false, vId)) { + // creo una curva composita + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return GDB_ID_NULL ; + // recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita + bool bAdded = true ; + for ( int i = 0 ; i < int( vId.size()) ; ++ i) { + // creo un segmento di retta + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) + return GDB_ID_NULL ; + // recupero gli estremi (non vanno mai invertiti per opzione di concatenamento) + int nInd = abs( vId[i]) - 1 ; + Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ; + Point3d ptEnd = vBpt[nInd].second ; + // provo ad accodarlo alla composita + bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 && + pLine->Set( ptStart, ptEnd) && + pCrvCompo->AddCurve( Release( pLine), true, dToler)) ; + ptNear = ( bAdded ? ptEnd : ptStart) ; + } + // se lunghezza curva inferiore a 5 volte la tolleranza, la ignoro + double dCrvLen ; + if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler) + continue ; + // se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene + Point3d ptStart, ptEnd ; + if ( pCrvCompo->GetStartPoint( ptStart) && + pCrvCompo->GetEndPoint( ptEnd) && + AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) && + ! AreSamePointApprox( ptStart, ptEnd)) { + // porto il punto finale a coincidere esattamente con l'inizio + pCrvCompo->ModifyEnd( ptStart) ; + } + // assegno estrusione come direzione normale al piano + pCrvCompo->SetExtrusion( vtExtr) ; + // unisco segmenti allineati + pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ; + // porto la curva nel riferimento destinazione + pCrvCompo->LocToLoc( frOrig, frDest) ; + // la inserisco nel DB geometrico + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + // copio il materiale + if ( ! pGeomDB->CopyMaterial( nId, nNewId)) + return GDB_ID_NULL ; + // aggiorno contatori + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nCrvCount ; + } + // Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh) + StmFromTriangleSoup StmFts ; + if ( ! StmFts.Start()) + return GDB_ID_NULL ; + for ( int i = 0 ; i < int( vTria.size()) ; ++ i) + // inserisco il triangolo nella nuova superficie + StmFts.AddTriangle( vTria[i]) ; + // valido la superficie e calcolo le adiacenze + if ( ! StmFts.End()) + return GDB_ID_NULL ; + // se superficie con triangoli + PtrOwner pNewStm( StmFts.GetSurf()) ; + if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) { + // porto la superficie nel riferimento destinazione + pNewStm->LocToLoc( frOrig, frDest) ; + // la inserisco nel DB + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + // copio il materiale + if ( ! pGeomDB->CopyMaterial( nId, nNewId)) + return GDB_ID_NULL ; + // aggiorno contatori + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nSrfCount ; + } + + return nFirstId ; +} + +//------------------------------------------------------------------------------- +int +MyPlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int& nCount) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + // recupero la curva + const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; + if ( pCrv == nullptr) + return GDB_ID_NULL ; + // recupero il suo riferimento globale + Frame3d frCrv ; + if ( ! pGeomDB->GetGlobFrame( nId, frCrv)) + return GDB_ID_NULL ; + // recupero il riferimento del gruppo di destinazione + Frame3d frDest ; + if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) + return GDB_ID_NULL ; + + // definisco il piano in locale + Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frCrv) ; + Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frCrv) ; + Plane3d plPlane ; + plPlane.Set( ptOnL, vtNL) ; + + // approssimo la curva con polyline + PolyLine PL ; + if ( ! pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_SPECIAL, PL)) + return GDB_ID_NULL ; + + // per ogni tratto della polyline cerco l'intersezione con il piano + PNTVECTOR vPnt ; + BIPNTVECTOR vBpt ; + Point3d ptS, ptE ; + PL.GetFirstPoint( ptS) ; + while ( PL.GetNextPoint( ptE)) { + Point3d ptInt ; + int nRes = IntersLinePlane( ptS, ptE, plPlane, ptInt) ; + if ( nRes == ILPT_INPLANE) + vBpt.emplace_back( ptS, ptE) ; + else if ( nRes != ILPT_NO) + vPnt.emplace_back( ptInt) ; + // aggiorno ptS per tratto successivo + ptS = ptE ; + } + + // elimino segmenti ripetuti + for ( int i = 0 ; i < ( int)vBpt.size() ; ) { + bool bFound = false ; + for ( int j = i + 1 ; j < ( int)vBpt.size() ; j ++) { + if (( AreSamePointApprox( vBpt[i].first, vBpt[j].first) && AreSamePointApprox( vBpt[i].second, vBpt[j].second)) || + ( AreSamePointApprox( vBpt[i].first, vBpt[j].second) && AreSamePointApprox( vBpt[i].second, vBpt[j].first))) { + bFound = true ; + break ; + } + } + if ( bFound) + vBpt.erase( vBpt.begin() + i) ; + else + i ++ ; + } + + // elimino punti ripetuti + for ( int i = 0 ; i < ( int)vPnt.size() ; ) { + bool bFound = false ; + // cerco tra i punti rimanenti + for ( int j = i + 1 ; j < ( int)vPnt.size() ; j ++) { + if ( AreSamePointApprox( vPnt[i], vPnt[j])) { + bFound = true ; + break ; + } + } + // cerco eventualmente tra i segmenti + if ( ! bFound) { + for ( int j = 0 ; j < ( int)vBpt.size() ; j ++) { + if ( AreSamePointApprox( vPnt[i], vBpt[j].first) || AreSamePointApprox( vPnt[i], vBpt[j].second)) { + bFound = true ; + break ; + } + } + } + if ( bFound) + vPnt.erase( vPnt.begin() + i) ; + else + i ++ ; + } + + // aggiungo i risultati al DB geometrico + int nPntCount{ 0}, nCrvCount{ 0}, nTmp{ 0} ; + int nFirstId = MyAddPlaneIntersResultToGeomDB( pGeomDB, vPnt, vBpt, TRIA3DVECTOR(), frCrv, frDest, nId, nDestGrpId, vtNL, + EPS_SMALL, nPntCount, nCrvCount, nTmp) ; + nCount = nPntCount + nCrvCount ; + + // restituisco l'identificativo della prima entità creata + return nFirstId ; +} + +//------------------------------------------------------------------------------- +int +ExePlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int* pnCount) +{ + // eseguo + int nCount{ 0} ; + int nFirstId = MyPlaneCurveInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ; + // aggiorno contatori + if ( nFirstId != GDB_ID_NULL) { + if ( pnCount != nullptr) + *pnCount = nCount ; + ExeSetModified() ; + } + + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtPlaneCurveInters({" + ToString( ptOn) + "},{" + + ToString( vtN) + "},{" + + ToString( nId) + "," + + ToString( nDestGrpId) + "," + + RefTypeToString( nRefType) + ")" + + " -- Id=" + ToString( nFirstId) + ", nCnt=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + // restituisco l'identificativo della prima nuova entità + return nFirstId ; +} + //------------------------------------------------------------------------------- static int MyPlaneBoxInters( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box, int nDestGrpId, int nRefType, @@ -263,239 +834,6 @@ ExePlaneBoxInters( const Point3d& ptOn, const Vector3d& vtN, const BBox3d& b3Box return nFirstId ; } -//------------------------------------------------------------------------------- -static bool -MyLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) -{ - IGeomDB* pGeomDB = GetCurrGeomDB() ; - VERIFY_GEOMDB( pGeomDB, false) - // recupero la superficie TriMesh - const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; - if ( pStm == nullptr) - return false ; - // recupero il suo riferimento globale - Frame3d frSurf ; - if ( ! pGeomDB->GetGlobFrame( nId, frSurf)) - return false ; - // porto in locale il punto e la direzione della linea - Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frSurf) ; - Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ; - vtDirL.Normalize() ; - // calcolo l'ingombro della trimesh - BBox3d b3Surf ; - if ( ! pStm->GetLocalBBox( b3Surf)) - return false ; - // calcolo l'intersezione - double dLen = b3Surf.MaxDistFromPoint( ptPL) ; - ILSIVECTOR vInfo ; - if ( ! IntersLineSurfTm( ptPL, vtDirL, dLen, *pStm, vInfo, false)) - return false ; - // ciclo sulle intersezioni - for ( const auto& Info : vInfo) { - // se intersezione puntuale - if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) { - int nFlag = SLT_TOUCH ; - if ( Info.dCosDN > EPS_ZERO) - nFlag = SLT_OUT ; - else if ( Info.dCosDN < -EPS_ZERO) - nFlag = SLT_IN ; - vInters.emplace_back( nFlag, Info.dU) ; - } - // se altrimenti intersezione con coincidenza - else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) { - vInters.emplace_back( SLT_TG_INI, Info.dU) ; - vInters.emplace_back( SLT_TG_FIN, Info.dU2) ; - } - } - // elimino intersezioni ripetute - for ( size_t j = 1 ; j < vInters.size() ; ) { - // intersezione precedente - size_t i = j - 1 ; - // se hanno lo stesso parametro - if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) { - // se sono entrambe entranti o uscenti, elimino la seconda - if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_IN) || - ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_OUT)) { - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una entrante e l'altra uscente, cambio in touch ed elimino la seconda - else if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_OUT) || - ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_IN)) { - vInters[i].first = SLT_TOUCH ; - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una puntuale e l'altra inizio di coincidenza, elimino la prima - else if ( ( vInters[i].first == SLT_IN || vInters[i].first == SLT_OUT || vInters[i].first == SLT_TOUCH) && vInters[j].first == SLT_TG_INI) { - vInters.erase( vInters.begin() + i) ; - continue ; - } - // se una fine di coincidenza e l'altra puntuale, elimino la seconda - else if ( vInters[i].first == SLT_TG_FIN && ( vInters[j].first == SLT_IN || vInters[j].first == SLT_OUT || vInters[j].first == SLT_TOUCH)) { - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe - else if ( i > 0 && vInters[i].first == SLT_TG_FIN && vInters[j].first == SLT_TG_INI) { - vInters.erase( vInters.begin() + j) ; - vInters.erase( vInters.begin() + i) ; - -- j ; - continue ; - } - } - // passo alla successiva - ++ j ; - } - - return true ; -} - -//------------------------------------------------------------------------------- -bool -ExeLineSurfTmInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) -{ - // eseguo - bool bOk = MyLineSurfTmInters( ptP, vtDir, nId, nRefType, vInters) ; - // se richiesto, salvo il comando Lua equivalente - if ( IsCmdLog()) { - string sLua = "EgtLineSurfTmInters({" + ToString( ptP) + "},{" + - ToString( vtDir) + "}," + - ToString( nId) + "," + - RefTypeToString( nRefType) + ")" + - " -- Ok=" + ToString( bOk) ; - LOG_INFO( GetCmdLogger(), sLua.c_str()) ; - } - // restituisco l'identificativo della prima nuova entità - return bOk ; -} - -//------------------------------------------------------------------------------- -static int -MyAddPlaneIntersResultToGeomDB( IGeomDB* pGeomDB, const PNTVECTOR& vPnt, const BIPNTVECTOR& vBpt, const TRIA3DVECTOR& vTria, - const Frame3d& frOrig, const Frame3d& frDest, int nId, int nDestGrpId, const Vector3d& vtExtr, - double dToler, int& nPntCount, int& nCrvCount, int& nSrfCount) -{ - // Inserisco il risultato nel DB - int nFirstId = GDB_ID_NULL ; - // Inserisco i punti nel DB - for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { - // creo il punto - PtrOwner pGeoPnt( CreateGeoPoint3d()) ; - if ( IsNull( pGeoPnt)) - return GDB_ID_NULL ; - // setto il punto - pGeoPnt->Set( vPnt[i]) ; - // porto il punto nel riferimento destinazione - pGeoPnt->LocToLoc( frOrig, frDest) ; - // lo inserisco nel DB geometrico - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - // copio il materiale - if ( ! pGeomDB->CopyMaterial( nId, nNewId)) - return GDB_ID_NULL ; - // aggiorno contatori - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nPntCount ; - } - // Inserisco le curve nel DB (dopo averle concatenate) - ChainCurves chainC ; - chainC.Init( false, dToler, int( vBpt.size())) ; - for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) { - Vector3d vtDir = vBpt[i].second - vBpt[i].first ; - vtDir.Normalize() ; - if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir)) - return GDB_ID_NULL ; - } - // recupero i percorsi concatenati - Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ; - INTVECTOR vId ; - while ( chainC.GetChainFromNear( ptNear, false, vId)) { - // creo una curva composita - PtrOwner pCrvCompo( CreateCurveComposite()) ; - if ( IsNull( pCrvCompo)) - return GDB_ID_NULL ; - // recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita - bool bAdded = true ; - for ( int i = 0 ; i < int( vId.size()) ; ++ i) { - // creo un segmento di retta - PtrOwner pLine( CreateCurveLine()) ; - if ( IsNull( pLine)) - return GDB_ID_NULL ; - // recupero gli estremi (non vanno mai invertiti per opzione di concatenamento) - int nInd = abs( vId[i]) - 1 ; - Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ; - Point3d ptEnd = vBpt[nInd].second ; - // provo ad accodarlo alla composita - bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 && - pLine->Set( ptStart, ptEnd) && - pCrvCompo->AddCurve( Release( pLine), true, dToler)) ; - ptNear = ( bAdded ? ptEnd : ptStart) ; - } - // se lunghezza curva inferiore a 5 volte la tolleranza, la ignoro - double dCrvLen ; - if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler) - continue ; - // se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene - Point3d ptStart, ptEnd ; - if ( pCrvCompo->GetStartPoint( ptStart) && - pCrvCompo->GetEndPoint( ptEnd) && - AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) && - ! AreSamePointApprox( ptStart, ptEnd)) { - // porto il punto finale a coincidere esattamente con l'inizio - pCrvCompo->ModifyEnd( ptStart) ; - } - // assegno estrusione come direzione normale al piano - pCrvCompo->SetExtrusion( vtExtr) ; - // unisco segmenti allineati - pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ; - // porto la curva nel riferimento destinazione - pCrvCompo->LocToLoc( frOrig, frDest) ; - // la inserisco nel DB geometrico - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - // copio il materiale - if ( ! pGeomDB->CopyMaterial( nId, nNewId)) - return GDB_ID_NULL ; - // aggiorno contatori - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nCrvCount ; - } - // Inserisco i triangoli nel DB (dopo averli uniti in una superficie trimesh) - StmFromTriangleSoup StmFts ; - if ( ! StmFts.Start()) - return GDB_ID_NULL ; - for ( int i = 0 ; i < int( vTria.size()) ; ++ i) - // inserisco il triangolo nella nuova superficie - StmFts.AddTriangle( vTria[i]) ; - // valido la superficie e calcolo le adiacenze - if ( ! StmFts.End()) - return GDB_ID_NULL ; - // se superficie con triangoli - PtrOwner pNewStm( StmFts.GetSurf()) ; - if ( ! IsNull( pNewStm) && pNewStm->GetTriangleCount() > 0) { - // porto la superficie nel riferimento destinazione - pNewStm->LocToLoc( frOrig, frDest) ; - // la inserisco nel DB - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pNewStm)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - // copio il materiale - if ( ! pGeomDB->CopyMaterial( nId, nNewId)) - return GDB_ID_NULL ; - // aggiorno contatori - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nSrfCount ; - } - - return nFirstId ; -} - //------------------------------------------------------------------------------- static int MyPlaneSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, double dToler, @@ -658,6 +996,169 @@ ExeParPlanesSurfTmInters( const Point3d& ptOn, const Vector3d& vtN, const DBLVEC return nFirstId ; } +//---------------------------------------------------------------------------- +int +MyPlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int& nCount) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, false) + // recupero il riferimento locale + Frame3d frLoc ; + if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) + return GDB_ID_NULL ; + // recupero il riferimento destinazione + Frame3d frDest ; + if ( ! pGeomDB->GetGlobFrame( nDestGrpId, frDest)) + return GDB_ID_NULL ; + // porto in locale il punto e la normale del piano + Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ; + Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ; + // calcolo il piano di intersezione + Plane3d plPlane ; + if ( ! plPlane.Set( ptOnL, vtNL)) + return GDB_ID_NULL ; + // recupero lo Zmap e calcolo l'intersezione + IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ; + ICURVEPOVECTOR vpLoop ; + if ( pVZM == nullptr || ! pVZM->GetPlaneIntersection( plPlane, vpLoop)) + return GDB_ID_NULL ; + // inserisco le curve nel gruppo destinazione + int nFirstId = GDB_ID_NULL ; + for ( size_t i = 0 ; i < vpLoop.size() ; ++ i) { + PtrOwner pCrv( Release( vpLoop[i])) ; + if ( IsNull( pCrv)) + continue ; + pCrv->ToLoc( frDest) ; + // inserisco la curva composita nel gruppo destinazione + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, ::Release( pCrv)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nCount ; + } + // restituisco l'identificativo della prima nuova entità + return nFirstId ; +} + +//---------------------------------------------------------------------------- +int +ExePlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int* pnCount) +{ + // eseguo + int nCount = 0 ; + int nFirstId = MyPlaneVolZmapInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ; + if ( pnCount != nullptr) + *pnCount = nCount ; + ExeSetModified() ; + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtPlaneVolZmapInters({" + ToString( ptOn) + "},{" + + ToString( vtN) + "}," + + IdToString( nId) + "," + + ToString( nDestGrpId) + "," + + RefTypeToString( nRefType) + ")" + + " -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + // restituisco l'identificativo della prima nuova entità + return nFirstId ; +} + +//------------------------------------------------------------------------------- +int +MyCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int& nPntCount, int& nCrvCount) +{ + IGeomDB* pGeomDB = GetCurrGeomDB() ; + VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) + + int nFirstId = GDB_ID_NULL ; + + // recupero il riferimento del gruppo di destinazione + Frame3d frDest ; + if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) + return GDB_ID_NULL ; + + // recupero le curve in locale al gruppo destinazione + CurveLocal Crv1Loc( pGeomDB, nId1, frDest) ; + CurveLocal Crv2Loc( pGeomDB, nId2, frDest) ; + + // intersezione fra le curve nel piano XY locale + IntersCurveCurve intCC( *Crv1Loc, *Crv2Loc, true) ; + int nInters = intCC.GetIntersCount() ; + + // recupero i punti risultanti + for ( int i = 0 ; i < nInters ; i++) { + IntCrvCrvInfo aInfo ; + intCC.GetIntCrvCrvInfo( i, aInfo) ; + // verifico se punto + if ( ! aInfo.bOverlap) { + PtrOwner pGeoPnt( CreateGeoPoint3d()) ; + if ( IsNull( pGeoPnt)) + return GDB_ID_NULL ; + pGeoPnt->Set( aInfo.IciA[0].ptI) ; + // lo inserisco nel DB geometrico + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + // aggiorno parametri + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nPntCount ; + } + } + + // recupero le curve risultanti + for ( int i = 0 ; i < nInters ; i++) { + IntCrvCrvInfo aInfo ; + intCC.GetIntCrvCrvInfo( i, aInfo) ; + // verifico se curva + if ( aInfo.bOverlap) { + PtrOwner pCrvRes( Crv1Loc->CopyParamRange( aInfo.IciA[0].dU, aInfo.IciA[1].dU)) ; + if ( IsNull( pCrvRes)) + return GDB_ID_NULL ; + // lo inserisco nel DB geometrico + int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvRes)) ; + if ( nNewId == GDB_ID_NULL) + return GDB_ID_NULL ; + // aggiorno parametri + if ( nFirstId == GDB_ID_NULL) + nFirstId = nNewId ; + ++ nCrvCount ; + } + } + + return nFirstId ; +} + +//------------------------------------------------------------------------------- +int +ExeCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int* pnPntCount, int* pnCrvCount) +{ + // eseguo + int nPntCount{ 0}, nCrvCount{ 0} ; + int nFirstId = MyCurveCurveInters( nId1, nId2, nDestGrpId, nPntCount, nCrvCount) ; + // aggiorno contatori + if ( nFirstId != GDB_ID_NULL) { + if ( pnPntCount != nullptr) + *pnPntCount = nPntCount ; + if ( pnCrvCount != nullptr) + *pnCrvCount = nCrvCount ; + ExeSetModified() ; + } + // se richiesto, salvo il comando Lua equivalente + if ( IsCmdLog()) { + string sLua = "EgtCurveCurveInters(" + ToString( nId1) + "," + + ToString( nId2) + "," + + ToString( nDestGrpId) + ")" + + " -- Id=" + ToString( nFirstId) + ", nPntCnt=" + ToString( nPntCount) + ", nCrvCnt=" + ToString( nCrvCount) ; + LOG_INFO( GetCmdLogger(), sLua.c_str()) ; + } + + // restituisco l'identificativo della prima nuova entità + return nFirstId ; +} + //------------------------------------------------------------------------------- static bool MyChainCurvesForSurfSurfInters( const BIPNTVECTOR& vBpt, IGeomDB* pGeomDB, int nDestGrpId, int nId1, double dToler, @@ -878,409 +1379,3 @@ ExeSurfTmSurfTmInters( int nId1, int nId2, int nDestGrpId, double dToler, // restituisco l'identificativo della prima nuova entità return nFirstId ; } - -//------------------------------------------------------------------------------- -int -MyPlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int& nCount) -{ - IGeomDB* pGeomDB = GetCurrGeomDB() ; - VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) - // recupero la curva - const ICurve* pCrv = GetCurve( pGeomDB->GetGeoObj( nId)) ; - if ( pCrv == nullptr) - return GDB_ID_NULL ; - // recupero il suo riferimento globale - Frame3d frCrv ; - if ( ! pGeomDB->GetGlobFrame( nId, frCrv)) - return GDB_ID_NULL ; - // recupero il riferimento del gruppo di destinazione - Frame3d frDest ; - if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) - return GDB_ID_NULL ; - - // definisco il piano in locale - Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frCrv) ; - Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frCrv) ; - Plane3d plPlane ; - plPlane.Set( ptOnL, vtNL) ; - - // approssimo la curva con polyline - PolyLine PL ; - if ( ! pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_SPECIAL, PL)) - return GDB_ID_NULL ; - - // per ogni tratto della polyline cerco l'intersezione con il piano - PNTVECTOR vPnt ; - BIPNTVECTOR vBpt ; - Point3d ptS, ptE ; - PL.GetFirstPoint( ptS) ; - while ( PL.GetNextPoint( ptE)) { - Point3d ptInt ; - int nRes = IntersLinePlane( ptS, ptE, plPlane, ptInt) ; - if ( nRes == ILPT_INPLANE) - vBpt.emplace_back( ptS, ptE) ; - else if ( nRes != ILPT_NO) - vPnt.emplace_back( ptInt) ; - // aggiorno ptS per tratto successivo - ptS = ptE ; - } - - // elimino segmenti ripetuti - for ( int i = 0 ; i < ( int)vBpt.size() ; ) { - bool bFound = false ; - for ( int j = i + 1 ; j < ( int)vBpt.size() ; j ++) { - if (( AreSamePointApprox( vBpt[i].first, vBpt[j].first) && AreSamePointApprox( vBpt[i].second, vBpt[j].second)) || - ( AreSamePointApprox( vBpt[i].first, vBpt[j].second) && AreSamePointApprox( vBpt[i].second, vBpt[j].first))) { - bFound = true ; - break ; - } - } - if ( bFound) - vBpt.erase( vBpt.begin() + i) ; - else - i ++ ; - } - - // elimino punti ripetuti - for ( int i = 0 ; i < ( int)vPnt.size() ; ) { - bool bFound = false ; - // cerco tra i punti rimanenti - for ( int j = i + 1 ; j < ( int)vPnt.size() ; j ++) { - if ( AreSamePointApprox( vPnt[i], vPnt[j])) { - bFound = true ; - break ; - } - } - // cerco eventualmente tra i segmenti - if ( ! bFound) { - for ( int j = 0 ; j < ( int)vBpt.size() ; j ++) { - if ( AreSamePointApprox( vPnt[i], vBpt[j].first) || AreSamePointApprox( vPnt[i], vBpt[j].second)) { - bFound = true ; - break ; - } - } - } - if ( bFound) - vPnt.erase( vPnt.begin() + i) ; - else - i ++ ; - } - - // aggiungo i risultati al DB geometrico - int nPntCount{ 0}, nCrvCount{ 0}, nTmp{ 0} ; - int nFirstId = MyAddPlaneIntersResultToGeomDB( pGeomDB, vPnt, vBpt, TRIA3DVECTOR(), frCrv, frDest, nId, nDestGrpId, vtNL, - EPS_SMALL, nPntCount, nCrvCount, nTmp) ; - nCount = nPntCount + nCrvCount ; - - // restituisco l'identificativo della prima entità creata - return nFirstId ; -} - -//------------------------------------------------------------------------------- -int -ExePlaneCurveInters( const Point3d& ptOn, const Vector3d& vtN, const int nId, const int nDestGrpId, const int nRefType, int* pnCount) -{ - // eseguo - int nCount{ 0} ; - int nFirstId = MyPlaneCurveInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ; - // aggiorno contatori - if ( nFirstId != GDB_ID_NULL) { - if ( pnCount != nullptr) - *pnCount = nCount ; - ExeSetModified() ; - } - - // se richiesto, salvo il comando Lua equivalente - if ( IsCmdLog()) { - string sLua = "EgtPlaneCurveInters({" + ToString( ptOn) + "},{" + - ToString( vtN) + "},{" + - ToString( nId) + "," + - ToString( nDestGrpId) + "," + - RefTypeToString( nRefType) + ")" + - " -- Id=" + ToString( nFirstId) + ", nCnt=" + ToString( nCount) ; - LOG_INFO( GetCmdLogger(), sLua.c_str()) ; - } - - // restituisco l'identificativo della prima nuova entità - return nFirstId ; -} - -//------------------------------------------------------------------------------- -int -MyCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int& nPntCount, int& nCrvCount) -{ - IGeomDB* pGeomDB = GetCurrGeomDB() ; - VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) - - int nFirstId = GDB_ID_NULL ; - - // recupero il riferimento del gruppo di destinazione - Frame3d frDest ; - if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) - return GDB_ID_NULL ; - - // recupero le curve e le porto nel riferimento del gruppo di destinazione - ICurve* pOrigCrv1 = GetCurve( pGeomDB->GetGeoObj( nId1)) ; - if ( pOrigCrv1 == nullptr) - return GDB_ID_NULL ; - PtrOwner pCrv1( pOrigCrv1->Clone()) ; - if( IsNull( pCrv1)) - return GDB_ID_NULL ; - Frame3d frCrv1 ; - if ( ! pGeomDB->GetGlobFrame( nId1, frCrv1)) - return GDB_ID_NULL ; - pCrv1->LocToLoc( frCrv1, frDest) ; - - ICurve* pOrigCrv2 = GetCurve( pGeomDB->GetGeoObj( nId2)) ; - if ( pOrigCrv2 == nullptr) - return GDB_ID_NULL ; - PtrOwner pCrv2( pOrigCrv2->Clone()) ; - if( IsNull( pCrv2)) - return GDB_ID_NULL ; - Frame3d frCrv2 ; - if ( ! pGeomDB->GetGlobFrame( nId2, frCrv2)) - return GDB_ID_NULL ; - pCrv2->LocToLoc( frCrv2, frDest) ; - - // intersezione fra le curve nel piano XY locale - IntersCurveCurve intCC( *pCrv1, *pCrv2, true) ; - int nInters = intCC.GetIntersCount() ; - - // recupero i punti risultanti - for ( int i = 0 ; i < nInters ; i++) { - IntCrvCrvInfo aInfo ; - intCC.GetIntCrvCrvInfo( i, aInfo) ; - // verifico se punto - if ( ! aInfo.bOverlap) { - PtrOwner pGeoPnt( CreateGeoPoint3d()) ; - if ( IsNull( pGeoPnt)) - return GDB_ID_NULL ; - pGeoPnt->Set( aInfo.IciA[0].ptI) ; - // lo inserisco nel DB geometrico - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - // aggiorno parametri - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nPntCount ; - } - } - - // recupero le curve risultanti - for ( int i = 0 ; i < nInters ; i++) { - IntCrvCrvInfo aInfo ; - intCC.GetIntCrvCrvInfo( i, aInfo) ; - // verifico se curva - if ( aInfo.bOverlap) { - PtrOwner pCrvRes( pCrv1->CopyParamRange( aInfo.IciA[0].dU, aInfo.IciA[1].dU)) ; - if ( IsNull( pCrvRes)) - return GDB_ID_NULL ; - // lo inserisco nel DB geometrico - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvRes)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - // aggiorno parametri - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nCrvCount ; - } - } - - return nFirstId ; -} - -//------------------------------------------------------------------------------- -int -ExeCurveCurveInters( const int nId1, const int nId2, const int nDestGrpId, int* pnPntCount, int* pnCrvCount) -{ - // eseguo - int nPntCount{ 0}, nCrvCount{ 0} ; - int nFirstId = MyCurveCurveInters( nId1, nId2, nDestGrpId, nPntCount, nCrvCount) ; - // aggiorno contatori - if ( nFirstId != GDB_ID_NULL) { - if ( pnPntCount != nullptr) - *pnPntCount = nPntCount ; - if ( pnCrvCount != nullptr) - *pnCrvCount = nCrvCount ; - ExeSetModified() ; - } - - // restituisco l'identificativo della prima nuova entità - return nFirstId ; -} - -//------------------------------------------------------------------------------- -static bool -MyLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) -{ - IGeomDB* pGeomDB = GetCurrGeomDB() ; - VERIFY_GEOMDB( pGeomDB, false) - // recupero lo Zmap - IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ; - if ( pVZM == nullptr) - return false ; - // recupero il suo riferimento globale - Frame3d frZmap ; - if ( ! pGeomDB->GetGlobFrame( nId, frZmap)) - return false ; - // porto in locale il punto e la direzione della linea - Point3d ptPL = GetPointLocal( pGeomDB, ptP, nRefType, frZmap) ; - Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frZmap) ; - vtDirL.Normalize() ; - // calcolo l'ingombro dello Zmap - BBox3d b3Surf ; - if ( ! pVZM->GetLocalBBox( b3Surf)) - return false ; - // calcolo l'intersezione - ILZIVECTOR vInfo ; - if ( ! pVZM->GetLineIntersection( ptPL, vtDirL, vInfo)) - return false ; - // ciclo sulle intersezioni - for ( const auto& Info : vInfo) { - // se intersezione puntuale - if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) { - int nFlag = SLT_TOUCH ; - if ( vtDirL * Info.trTria.GetN() > EPS_ZERO) - nFlag = SLT_OUT ; - else if ( vtDirL * Info.trTria.GetN() < -EPS_ZERO) - nFlag = SLT_IN ; - vInters.emplace_back( nFlag, Info.dU) ; - } - // se altrimenti intersezione con coincidenza - else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) { - vInters.emplace_back( SLT_TG_INI, Info.dU) ; - vInters.emplace_back( SLT_TG_FIN, Info.dU2) ; - } - } - // elimino intersezioni ripetute - for ( size_t j = 1 ; j < vInters.size() ; ) { - // intersezione precedente - size_t i = j - 1 ; - // se hanno lo stesso parametro - if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) { - // se sono entrambe entranti o uscenti, elimino la seconda - if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_IN) || - ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_OUT)) { - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una entrante e l'altra uscente, cambio in touch ed elimino la seconda - else if ( ( vInters[i].first == SLT_IN && vInters[j].first == SLT_OUT) || - ( vInters[i].first == SLT_OUT && vInters[j].first == SLT_IN)) { - vInters[i].first = SLT_TOUCH ; - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una puntuale e l'altra inizio di coincidenza, elimino la prima - else if ( ( vInters[i].first == SLT_IN || vInters[i].first == SLT_OUT || vInters[i].first == SLT_TOUCH) && vInters[j].first == SLT_TG_INI) { - vInters.erase( vInters.begin() + i) ; - continue ; - } - // se una fine di coincidenza e l'altra puntuale, elimino la seconda - else if ( vInters[i].first == SLT_TG_FIN && ( vInters[j].first == SLT_IN || vInters[j].first == SLT_OUT || vInters[j].first == SLT_TOUCH)) { - vInters.erase( vInters.begin() + j) ; - continue ; - } - // se una fine di coincidenza e l'altra inizio di coincidenza, elimino entrambe - else if ( i > 0 && vInters[i].first == SLT_TG_FIN && vInters[j].first == SLT_TG_INI) { - vInters.erase( vInters.begin() + j) ; - vInters.erase( vInters.begin() + i) ; - -- j ; - continue ; - } - } - // passo alla successiva - ++ j ; - } - - return true ; -} - -//------------------------------------------------------------------------------- -bool -ExeLineVolZmapInters( const Point3d& ptP, const Vector3d& vtDir, int nId, int nRefType, INTDBLVECTOR& vInters) -{ - // eseguo - bool bOk = MyLineVolZmapInters( ptP, vtDir, nId, nRefType, vInters) ; - // se richiesto, salvo il comando Lua equivalente - if ( IsCmdLog()) { - string sLua = "EgtLineVolZmapInters({" + ToString( ptP) + "},{" + - ToString( vtDir) + "}," + - ToString( nId) + "," + - RefTypeToString( nRefType) + ")" + - " -- Ok=" + ToString( bOk) ; - LOG_INFO( GetCmdLogger(), sLua.c_str()) ; - } - // restituisco l'identificativo della prima nuova entità - return bOk ; -} - -//---------------------------------------------------------------------------- -int -MyPlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int& nCount) -{ - IGeomDB* pGeomDB = GetCurrGeomDB() ; - VERIFY_GEOMDB( pGeomDB, false) - // recupero il riferimento locale - Frame3d frLoc ; - if ( ! pGeomDB->GetGlobFrame( nId, frLoc)) - return GDB_ID_NULL ; - // recupero il riferimento destinazione - Frame3d frDest ; - if ( ! pGeomDB->GetGlobFrame( nDestGrpId, frDest)) - return GDB_ID_NULL ; - // porto in locale il punto e la normale del piano - Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frLoc) ; - Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frLoc) ; - // calcolo il piano di intersezione - Plane3d plPlane ; - if ( ! plPlane.Set( ptOnL, vtNL)) - return GDB_ID_NULL ; - // recupero lo Zmap e calcolo l'intersezione - IVolZmap* pVZM = GetVolZmap( pGeomDB->GetGeoObj( nId)) ; - ICURVEPOVECTOR vpLoop ; - if ( pVZM == nullptr || ! pVZM->GetPlaneIntersection( plPlane, vpLoop)) - return GDB_ID_NULL ; - // inserisco le curve nel gruppo destinazione - int nFirstId = GDB_ID_NULL ; - for ( size_t i = 0 ; i < vpLoop.size() ; ++ i) { - PtrOwner pCrv( Release( vpLoop[i])) ; - if ( IsNull( pCrv)) - continue ; - pCrv->ToLoc( frDest) ; - // inserisco la curva composita nel gruppo destinazione - int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, ::Release( pCrv)) ; - if ( nNewId == GDB_ID_NULL) - return GDB_ID_NULL ; - if ( nFirstId == GDB_ID_NULL) - nFirstId = nNewId ; - ++ nCount ; - } - // restituisco l'identificativo della prima nuova entità - return nFirstId ; -} - -//---------------------------------------------------------------------------- -int -ExePlaneVolZmapInters( const Point3d& ptOn, const Vector3d& vtN, int nId, int nDestGrpId, int nRefType, int* pnCount) -{ - // eseguo - int nCount = 0 ; - int nFirstId = MyPlaneVolZmapInters( ptOn, vtN, nId, nDestGrpId, nRefType, nCount) ; - if ( pnCount != nullptr) - *pnCount = nCount ; - ExeSetModified() ; - // se richiesto, salvo il comando Lua equivalente - if ( IsCmdLog()) { - string sLua = "EgtPlaneVolZmapInters({" + ToString( ptOn) + "},{" + - ToString( vtN) + "}," + - IdToString( nId) + "," + - ToString( nDestGrpId) + "," + - RefTypeToString( nRefType) + ")" + - " -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; - LOG_INFO( GetCmdLogger(), sLua.c_str()) ; - } - // restituisco l'identificativo della prima nuova entità - return nFirstId ; -} \ No newline at end of file diff --git a/LUA_GeoInters.cpp b/LUA_GeoInters.cpp index 84c4dac..a4c9eca 100644 --- a/LUA_GeoInters.cpp +++ b/LUA_GeoInters.cpp @@ -20,6 +20,41 @@ using namespace std ; +//---------------------------------------------------------------------------- +static int +LuaLineCurveInters( lua_State* L) +{ + // 3 o 4 parametri : ptP, vtDir, Id, [, nRefId] + Point3d ptP ; + LuaCheckParam( L, 1, ptP) + Vector3d vtDir ; + LuaCheckParam( L, 2, vtDir) + int nId ; + LuaCheckParam( L, 3, nId) + int nRefType = nId ; + LuaGetParam( L, 4, nRefType) ; + LuaClearStack( L) ; + // recupero i punti di intersezione tra linea e curva + INTDBLVECTOR vInters ; + if ( ExeLineCurveInters( ptP, vtDir, nId, nRefType, vInters)) { + LuaSetParam( L, true) ; + INTVECTOR vType( vInters.size()) ; + DBLVECTOR vPar( vInters.size()) ; + for ( size_t i = 0 ; i < vInters.size() ; ++ i) { + vType[i] = vInters[i].first ; + vPar[i] = vInters[i].second ; + } + LuaSetParam( L, vType) ; + LuaSetParam( L, vPar) ; + } + else { + LuaSetParam( L) ; + LuaSetParam( L) ; + LuaSetParam( L) ; + } + return 3 ; +} + //---------------------------------------------------------------------------- static int LuaLineBoxInters( lua_State* L) @@ -53,38 +88,6 @@ LuaLineBoxInters( lua_State* L) return 3 ; } -//---------------------------------------------------------------------------- -static int -LuaPlaneBoxInters( lua_State* L) -{ - // 4 o 5 parametri : ptOn, vtN, b3Box, nDestGrpId [, nRefType] - Point3d ptOn ; - LuaCheckParam( L, 1, ptOn) - Vector3d vtN ; - LuaCheckParam( L, 2, vtN) - BBox3d b3Box ; - LuaCheckParam( L, 3, b3Box) - int nDestGrpId ; - LuaCheckParam( L, 4, nDestGrpId) ; - int nRefType = RTY_DEFAULT ; - LuaGetParam( L, 5, nRefType) ; - LuaClearStack( L) ; - // eseguo l'intersezione - int nPntCount = 0 ; - int nCrvCount = 0 ; - int nSrfCount = 0 ; - int nNewId = ExePlaneBoxInters( ptOn, vtN, b3Box, nDestGrpId, nRefType, &nPntCount, &nCrvCount, &nSrfCount) ; - // restituisco il risultato - if ( nNewId != GDB_ID_NULL) - LuaSetParam( L, nNewId) ; - else - LuaSetParam( L) ; - LuaSetParam( L, nPntCount) ; - LuaSetParam( L, nCrvCount) ; - LuaSetParam( L, nSrfCount) ; - return 4 ; -} - //---------------------------------------------------------------------------- static int LuaLineSurfTmInters( lua_State* L) @@ -120,6 +123,101 @@ LuaLineSurfTmInters( lua_State* L) return 3 ; } +//---------------------------------------------------------------------------- +static int +LuaLineVolZmapInters( lua_State* L) +{ + // 3 o 4 parametri : ptP, vtDir, Id, [, nRefId] + Point3d ptP ; + LuaCheckParam( L, 1, ptP) + Vector3d vtDir ; + LuaCheckParam( L, 2, vtDir) + int nId ; + LuaCheckParam( L, 3, nId) + int nRefType = nId ; + LuaGetParam( L, 4, nRefType) ; + LuaClearStack( L) ; + // eseguo calcolo intersezione + INTDBLVECTOR vInters ; + if ( ExeLineVolZmapInters( ptP, vtDir, nId, nRefType, vInters)) { + LuaSetParam( L, true) ; + INTVECTOR vType( vInters.size()) ; + DBLVECTOR vPar( vInters.size()) ; + for ( size_t i = 0 ; i < vInters.size() ; ++ i) { + vType[i] = vInters[i].first ; + vPar[i] = vInters[i].second ; + } + LuaSetParam( L, vType) ; + LuaSetParam( L, vPar) ; + } + else { + LuaSetParam( L) ; + LuaSetParam( L) ; + LuaSetParam( L) ; + } + return 3 ; +} + +//---------------------------------------------------------------------------- +static int +LuaPlaneCurveInters( lua_State* L) +{ + // 4 o 5 parametri : ptOn, vtN, nId, nDestGrpId [, nRefType] + Point3d ptOn ; + LuaCheckParam( L, 1, ptOn) + Vector3d vtN ; + LuaCheckParam( L, 2, vtN) + int nId ; + LuaCheckParam( L, 3, nId) + int nDestGrpId ; + LuaCheckParam( L, 4, nDestGrpId) ; + int nRefType = RTY_DEFAULT ; + LuaGetParam( L, 5, nRefType) ; + LuaClearStack( L) ; + // eseguo l'intersezione + int nCount = 0 ; + int nNewId = ExePlaneCurveInters( ptOn, vtN, nId, nDestGrpId, nRefType, &nCount) ; + // restituisco il risultato + if ( nNewId != GDB_ID_NULL) + LuaSetParam( L, nNewId) ; + else + LuaSetParam( L) ; + LuaSetParam( L, nCount) ; + return 2 ; +} + +//---------------------------------------------------------------------------- +static int +LuaPlaneBoxInters( lua_State* L) +{ + // 4 o 5 parametri : ptOn, vtN, b3Box, nDestGrpId [, nRefType] + Point3d ptOn ; + LuaCheckParam( L, 1, ptOn) + Vector3d vtN ; + LuaCheckParam( L, 2, vtN) + BBox3d b3Box ; + LuaCheckParam( L, 3, b3Box) + int nDestGrpId ; + LuaCheckParam( L, 4, nDestGrpId) ; + int nRefType = RTY_DEFAULT ; + LuaGetParam( L, 5, nRefType) ; + LuaClearStack( L) ; + // eseguo l'intersezione + int nPntCount = 0 ; + int nCrvCount = 0 ; + int nSrfCount = 0 ; + int nNewId = ExePlaneBoxInters( ptOn, vtN, b3Box, nDestGrpId, nRefType, &nPntCount, &nCrvCount, &nSrfCount) ; + // restituisco il risultato + if ( nNewId != GDB_ID_NULL) + LuaSetParam( L, nNewId) ; + else + LuaSetParam( L) ; + LuaSetParam( L, nPntCount) ; + LuaSetParam( L, nCrvCount) ; + LuaSetParam( L, nSrfCount) ; + return 4 ; +} + //---------------------------------------------------------------------------- static int LuaPlaneSurfTmInters( lua_State* L) @@ -188,59 +286,32 @@ LuaParPlanesSurfTmInters( lua_State* L) //---------------------------------------------------------------------------- static int -LuaSurfTmSurfTmInters( lua_State* L) +LuaPlaneVolZmapInters( lua_State* L) { - // 3 o 4 parametri : Id1, nId2, nDestGrpId [, dToler] - int nId1 ; - LuaCheckParam( L, 1, nId1) - int nId2 ; - LuaCheckParam( L, 2, nId2) - int nDestGrpId ; - LuaCheckParam( L, 3, nDestGrpId) ; - double dToler = 20 * EPS_SMALL ; - LuaGetParam( L, 4, dToler) ; - LuaClearStack( L) ; - // eseguo l'intersezione - int nPntCount = 0 ; - int nCrvCount = 0 ; - int nSrfCount = 0 ; - int nNewId = ExeSurfTmSurfTmInters( nId1, nId2, nDestGrpId, dToler, &nPntCount, &nCrvCount, &nSrfCount) ; - // restituisco il risultato - if ( nNewId != GDB_ID_NULL) - LuaSetParam( L, nNewId) ; - else - LuaSetParam( L) ; - LuaSetParam( L, nPntCount) ; - LuaSetParam( L, nCrvCount) ; - LuaSetParam( L, nSrfCount) ; - return 4 ; -} - -//---------------------------------------------------------------------------- -static int -LuaPlaneCurveInters( lua_State* L) -{ - // 4 o 5 parametri : ptOn, vtN, nId, nDestGrpId [, nRefType] - Point3d ptOn ; - LuaCheckParam( L, 1, ptOn) + // 4 o 5 parametri : ptP, vtN, nId, nDestGrpId [, nRefType] + Point3d ptP ; + LuaCheckParam( L, 1, ptP) Vector3d vtN ; LuaCheckParam( L, 2, vtN) int nId ; LuaCheckParam( L, 3, nId) int nDestGrpId ; - LuaCheckParam( L, 4, nDestGrpId) ; + LuaCheckParam( L, 4, nDestGrpId) int nRefType = RTY_DEFAULT ; LuaGetParam( L, 5, nRefType) ; LuaClearStack( L) ; - // eseguo l'intersezione - int nCount = 0 ; - int nNewId = ExePlaneCurveInters( ptOn, vtN, nId, nDestGrpId, nRefType, &nCount) ; + // eseguo calcolo intersezione + int nCount ; + int nFirstId = ExePlaneVolZmapInters( ptP, vtN, nId, nDestGrpId, nRefType, &nCount) ; // restituisco il risultato - if ( nNewId != GDB_ID_NULL) - LuaSetParam( L, nNewId) ; - else + if ( nFirstId != GDB_ID_NULL) { + LuaSetParam( L, nFirstId) ; + LuaSetParam( L, nCount) ; + } + else { LuaSetParam( L) ; - LuaSetParam( L, nCount) ; + LuaSetParam( L) ; + } return 2 ; } @@ -272,68 +343,32 @@ LuaCurveCurveInters( lua_State* L) //---------------------------------------------------------------------------- static int -LuaLineVolZmapInters( lua_State* L) +LuaSurfTmSurfTmInters( lua_State* L) { - // 3 o 4 parametri : ptP, vtDir, Id, [, nRefId] - Point3d ptP ; - LuaCheckParam( L, 1, ptP) - Vector3d vtDir ; - LuaCheckParam( L, 2, vtDir) - int nId ; - LuaCheckParam( L, 3, nId) - int nRefType = nId ; - LuaGetParam( L, 4, nRefType) ; - LuaClearStack( L) ; - // eseguo calcolo intersezione - INTDBLVECTOR vInters ; - if ( ExeLineVolZmapInters( ptP, vtDir, nId, nRefType, vInters)) { - LuaSetParam( L, true) ; - INTVECTOR vType( vInters.size()) ; - DBLVECTOR vPar( vInters.size()) ; - for ( size_t i = 0 ; i < vInters.size() ; ++ i) { - vType[i] = vInters[i].first ; - vPar[i] = vInters[i].second ; - } - LuaSetParam( L, vType) ; - LuaSetParam( L, vPar) ; - } - else { - LuaSetParam( L) ; - LuaSetParam( L) ; - LuaSetParam( L) ; - } - return 3 ; -} - -//---------------------------------------------------------------------------- -static int -LuaPlaneVolZmapInters( lua_State* L) -{ - // 4 o 5 parametri : ptP, vtN, nId, nDestGrpId [, nRefType] - Point3d ptP ; - LuaCheckParam( L, 1, ptP) - Vector3d vtN ; - LuaCheckParam( L, 2, vtN) - int nId ; - LuaCheckParam( L, 3, nId) + // 3 o 4 parametri : Id1, nId2, nDestGrpId [, dToler] + int nId1 ; + LuaCheckParam( L, 1, nId1) + int nId2 ; + LuaCheckParam( L, 2, nId2) int nDestGrpId ; - LuaCheckParam( L, 4, nDestGrpId) - int nRefType = RTY_DEFAULT ; - LuaGetParam( L, 5, nRefType) ; + LuaCheckParam( L, 3, nDestGrpId) ; + double dToler = 20 * EPS_SMALL ; + LuaGetParam( L, 4, dToler) ; LuaClearStack( L) ; - // eseguo calcolo intersezione - int nCount ; - int nFirstId = ExePlaneVolZmapInters( ptP, vtN, nId, nDestGrpId, nRefType, &nCount) ; + // eseguo l'intersezione + int nPntCount = 0 ; + int nCrvCount = 0 ; + int nSrfCount = 0 ; + int nNewId = ExeSurfTmSurfTmInters( nId1, nId2, nDestGrpId, dToler, &nPntCount, &nCrvCount, &nSrfCount) ; // restituisco il risultato - if ( nFirstId != GDB_ID_NULL) { - LuaSetParam( L, nFirstId) ; - LuaSetParam( L, nCount) ; - } - else { + if ( nNewId != GDB_ID_NULL) + LuaSetParam( L, nNewId) ; + else LuaSetParam( L) ; - LuaSetParam( L) ; - } - return 2 ; + LuaSetParam( L, nPntCount) ; + LuaSetParam( L, nCrvCount) ; + LuaSetParam( L, nSrfCount) ; + return 4 ; } //------------------------------------------------------------------------------- @@ -341,15 +376,16 @@ bool LuaInstallGeoInters( LuaMgr& luaMgr) { bool bOk = ( &luaMgr != nullptr) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtLineCurveInters", LuaLineCurveInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtLineBoxInters", LuaLineBoxInters) ; - bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneBoxInters", LuaPlaneBoxInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtLineSurfTmInters", LuaLineSurfTmInters) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtLineVolZmapInters", LuaLineVolZmapInters) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneCurveInters", LuaPlaneCurveInters) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneBoxInters", LuaPlaneBoxInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneSurfTmInters", LuaPlaneSurfTmInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtParPlanesSurfTmInters", LuaParPlanesSurfTmInters) ; - bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmSurfTmInters", LuaSurfTmSurfTmInters) ; - bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneCurveInters", LuaPlaneCurveInters) ; - bOk = bOk && luaMgr.RegisterFunction( "EgtCurveCurveInters", LuaCurveCurveInters) ; - bOk = bOk && luaMgr.RegisterFunction( "EgtLineVolZmapInters", LuaLineVolZmapInters) ; bOk = bOk && luaMgr.RegisterFunction( "EgtPlaneVolZmapInters", LuaPlaneVolZmapInters) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtCurveCurveInters", LuaCurveCurveInters) ; + bOk = bOk && luaMgr.RegisterFunction( "EgtSurfTmSurfTmInters", LuaSurfTmSurfTmInters) ; return bOk ; -} \ No newline at end of file +}