//---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- // File : EXE_GeoSnap.cpp Data : 23.03.20 Versione : 2.2c3 // Contenuto : Funzioni di interrogazione di superfici del DBG per EXE. // // // // Modifiche : 23.03.20 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EXE.h" #include "EXE_Const.h" #include "EXE_Macro.h" #include "AuxTools.h" #include "GeoTools.h" #include "/EgtDev/Include/EXeExecutor.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkSurf.h" #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkSurfBezier.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EGkStringUtils3d.h" using namespace std ; //---------------------------------------------------------------------------- bool ExeSurfArea( int nId, double& dArea) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // verifico il parametro if ( &dArea == nullptr) return false ; // recupero la superficie ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ; // ne restituisco l'area return ( pSurf != nullptr && pSurf->GetArea( dArea)) ; } //---------------------------------------------------------------------------- bool ExeSurfIsClosed( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ; // verifico se è superficie chiusa return ( pSurf != nullptr && pSurf->IsClosed()) ; } //---------------------------------------------------------------------------- bool ExeSurfVolume( int nId, double& dVol) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // verifico il parametro if ( &dVol == nullptr) return false ; // recupero la superficie ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ; // ne restituisco l'eventuale volume (se è chiusa) return ( pSurf != nullptr && pSurf->GetVolume( dVol)) ; } //---------------------------------------------------------------------------- bool ExeSurfFrNormVersor( int nId, int nRefId, Vector3d& vtNorm) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la Regione const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; if ( pSfr == nullptr) return false ; // recupero la normale vtNorm = pSfr->GetNormVersor() ; // gestione trasformazione ( eventuale) return TransformVector( pGeomDB, nId, nRefId, vtNorm) ; } //---------------------------------------------------------------------------- bool ExeSurfFrGrossArea( int nId, double& dArea) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // verifico il parametro if ( &dArea == nullptr) return false ; // recupero la Regione const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; // ne restituisco l'area senza eventuali buchi return ( pSfr != nullptr && pSfr->GetGrossArea( dArea)) ; } //---------------------------------------------------------------------------- bool ExeSurfFrTestExternal( int nId1, int nId2, double dMinDist) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la prima superficie FlatRegion ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ; if ( pSfr1 == nullptr) return false ; // se richiesta distanza di sicurezza, ne faccio l'offset PtrOwner pSfr1O( pSfr1->Clone()) ; if ( IsNull( pSfr1O)) return false ; if ( dMinDist > 10 * EPS_SMALL) pSfr1O->Offset( dMinDist, ICurve::OFF_FILLET) ; // recupero il riferimento della superficie Frame3d frSurf1 ; if ( ! pGeomDB->GetGlobFrame( nId1, frSurf1)) return false ; // recupero il tipo della seconda entità int nType2 = pGeomDB->GetGeoType( nId2) ; // se seconda entità regione if ( nType2 == SRF_FLATRGN) { // recupero la seconda superficie FlatRegion in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; if ( pSfr2L == nullptr) return false ; // eseguo il test di intersezione tra le due regioni for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; ++ i) { for ( int j = 0 ; j < pSfr2L->GetChunkCount() ; ++ j) { if ( pSfr1O->GetChunkSimpleClassification( i, *pSfr2L, j) != REGC_OUT) return false ; } } return true ; } // se altrimenti curva else if ( (nType2 & GEO_CURVE) != 0) { // recupero la curva in locale alla regione CurveLocal Crv2Loc( pGeomDB, nId2, frSurf1) ; const ICurve* pCrv2L = Crv2Loc.Get() ; if ( pCrv2L == nullptr) return false ; // eseguo il test di intersezione tra regione e curva for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; ++ i) { PtrOwner pCrv1( pSfr1O->GetLoop( i, 0)) ; if ( pCrv1 == nullptr) return false ; IntersCurveCurve ccInt( *pCrv1, *pCrv2L) ; CRVCVECTOR vcClass ; if ( ! ccInt.GetCurveClassification( 1, EPS_SMALL, vcClass) || vcClass.empty()) return false ; for ( auto& cClass : vcClass) { if ( cClass.nClass == CRVC_IN || cClass.nClass == CRVC_NULL) return false ; } } return true ; } // se altrimenti punto else if ( nType2 == GEO_PNT3D) { // recupero il punto IGeoPoint3d* pGeoPt = GetGeoPoint3d( pGeomDB->GetGeoObj( nId2)) ; Point3d pt = pGeoPt->GetPoint() ; // porto il punto in locale Frame3d frPt ; if ( ! pGeomDB->GetGlobFrame( nId2, frPt)) return false ; pt.LocToLoc( frPt, frSurf1) ; for ( int i = 0 ; i < pSfr1O->GetChunkCount() ; i ++) { // verifico se è contenuto nel loop esterno PtrOwner pCrv( pSfr1O->GetLoop( i, 0)) ; PolyLine PL ; pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ; if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL)) { bool bInsideHole = false ; // verifico se è contenuto in un loop interno for ( int j = 1 ; j < pSfr1O->GetLoopCount( i) ; j ++) { PtrOwner pCrv( pSfr1O->GetLoop( i, j)) ; pCrv->ApproxWithLines( 10 * EPS_SMALL, 15, ICurve::APL_STD, PL) ; PL.Invert() ; if ( IsPointInsidePolyLine( pt, PL, EPS_SMALL)) bInsideHole = true ; } // se è contenuto nel loop esterno ma non è contenuto in nessuno dei loop interni allora il punto è interno if ( ! bInsideHole) return false ; } } return true ; } // altrimenti non valida else return false ; } //---------------------------------------------------------------------------- int ExeSurfFrChunkCount( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, 0) // recupero la regione const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; if ( pSfr == nullptr) return false ; // recupero il numero di chunk return pSfr->GetChunkCount() ; } //---------------------------------------------------------------------------- int ExeSurfFrChunkSimpleClassify( int nId1, int nChunk1, int nId2, int nChunk2, double dToler) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, 0) // recupero la prima superficie FlatRegion ISurfFlatRegion* pSfr1 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId1)) ; bool bOk = ( pSfr1 != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf1 ; bOk = bOk && pGeomDB->GetGlobFrame( nId1, frSurf1) ; // recupero la seconda superficie FlatRegion const ISurfFlatRegion* pSfr2 = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId2)) ; bOk = bOk && ( pSfr2 != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf2 ; bOk = bOk && pGeomDB->GetGlobFrame( nId2, frSurf2) ; // se riferimenti diversi, porto una copia della seconda nel riferimento della prima const ISurfFlatRegion* pSfr2L = pSfr2 ; PtrOwner pTmp ; if ( abs( dToler) > EPS_SMALL || ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( pSfr2->Clone()) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pTmp->Offset( -abs( dToler), ICurve::OFF_FILLET) ; pSfr2L = pTmp ; } // classifico il chunk della prima regione rispetto a quello della seconda int nRes = ( bOk ? pSfr1->GetChunkSimpleClassification( nChunk1, *pSfr2L, nChunk2) : REGC_NULL) ; return nRes ; } //---------------------------------------------------------------------------- int ExeExtractSurfFrChunkLoops( int nId, int nChunk, int nDestGrpId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie FlatRegion const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pSfr != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // richiedo i contorni del componente connesso (chunk) e li inserisco nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; int nL = 0 ; PtrOwner pCrv( bOk ? pSfr->GetLoop( nChunk, nL) : nullptr) ; while ( ! IsNull( pCrv)) { // porto la curva nel riferimento destinazione bOk = bOk && pCrv->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrv)) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; // passo alla prossima curva pCrv.Set( bOk ? pSfr->GetLoop( nChunk, ++nL) : nullptr) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtractSurfFrChunkLoops(" + ToString( nId) + "," + ToString( nChunk) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeSurfFrGetZigZagInfill( int nId, int nDestGrpId, double dStep, double dAng, bool bStepCorrection, bool bInvert, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie FlatRegion ISurfFlatRegion * pOrigSrf = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; if ( pOrigSrf == nullptr) return GDB_ID_NULL ; PtrOwner pSfr( pOrigSrf->Clone()) ; bool bOk = ( ! IsNull( pSfr)) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // creo il riferimento per il calcolo del percorso a zigzag Vector3d vtN ; if ( bOk) vtN = pSfr->GetNormVersor() ; bOk = bOk && vtN.ToGlob( frSurf) ; Frame3d frRef ; bOk = bOk && frRef.Set( ORIG, vtN) ; bOk = bOk && frRef.Rotate( ORIG, vtN, dAng) ; // calcolo il percorso a zigzag bOk = bOk && pSfr->LocToLoc( frSurf, frRef) ; ICRVCOMPOPOVECTOR vpCrvs ; bOk = bOk && pSfr->GetZigZagInfill( dStep, bStepCorrection, bInvert, vpCrvs) ; // inserisco le curve risultanti nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( int i = 0 ; bOk && i < ( int) vpCrvs.size() ; i ++) { // porto la curva nel riferimento di destinazione bOk = bOk && vpCrvs[i]->LocToLoc( frRef, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( vpCrvs[i])) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; } ExeSetModified() ; // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeSurfTmVertexCount( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, 0) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return 0 ; // recupero il numero di vertici return pStm->GetVertexCount() ; } //---------------------------------------------------------------------------- int ExeSurfTmFacetCount( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, 0) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return 0 ; // recupero il numero delle facce return pStm->GetFacetCount() ; } //---------------------------------------------------------------------------- int ExeSurfTmPartCount( int nId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, -1) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return -1 ; // recupero il numero di parti return pStm->GetPartCount() ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetVertex( int nId, int nVert, int nRefId, Point3d& ptVert) { 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 vertice di indice dato if ( ! pStm->GetVertex( nVert, ptVert)) return false ; // gestione trasformazioni ( eventuali) return TransformPoint( pGeomDB, nId, nRefId, ptVert) ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetNearestVertex( int nId, const Point3d& ptNear, int nRefId, int& nVert, Point3d& ptVert) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // porto il punto Near nel riferimento dell'entità Point3d ptNearL = ptNear ; if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL)) return false ; // recupero il vertice più vicino della superficie nVert = GetSurfTmNearestVertex( ptNearL, *pStm) ; if ( ! pStm->GetVertex( nVert, ptVert)) return false ; // gestione trasformazioni ( eventuali) return TransformPoint( pGeomDB, nId, nRefId, ptVert) ; } //---------------------------------------------------------------------------- int ExeSurfTmFacetFromTria( int nId, int nT) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, SVT_NULL) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return SVT_NULL ; // recupero il numero della faccia da quello di un suo triangolo return pStm->GetFacetFromTria( nT) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetAdjacencies( int nId, int nFacet, INTMATRIX& vAdj) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pStm != nullptr) ; // recupero le adiacenze bOk = bOk && pStm->GetFacetAdjacencies( nFacet, vAdj) ; return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetNearestEndPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId, Point3d& ptEnd, Vector3d& vtN) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // porto il punto Near nel riferimento dell'entità Point3d ptNearL = ptNear ; if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL)) return false ; // recupero il punto End più vicino della faccia if ( ! pStm->GetFacetNearestEndPoint( nFacet, ptNearL, ptEnd, vtN)) return false ; // gestione trasformazioni ( eventuali) return TransformPoint( pGeomDB, nId, nRefId, ptEnd) && TransformVector( pGeomDB, nId, nRefId, vtN) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetNearestMidPoint( int nId, int nFacet, const Point3d& ptNear, int nRefId, Point3d& ptMid, Vector3d& vtN) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // porto il punto Near nel riferimento dell'entità Point3d ptNearL = ptNear ; if ( ! InvTransformPoint( pGeomDB, nId, nRefId, ptNearL)) return false ; // recupero il punto Mid più vicino della faccia if ( ! pStm->GetFacetNearestMidPoint( nFacet, ptNearL, ptMid, vtN)) return false ; // gestione trasformazioni ( eventuali) return TransformPoint( pGeomDB, nId, nRefId, ptMid) && TransformVector( pGeomDB, nId, nRefId, vtN) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetCenter( int nId, int nFacet, int nRefId, Point3d& ptCen, Vector3d& vtN) { 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 centro della faccia if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN)) return false ; // gestione trasformazioni ( eventuali) return TransformPoint( pGeomDB, nId, nRefId, ptCen) && TransformVector( pGeomDB, nId, nRefId, vtN) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetNormVersor( int nId, int nFacet, int nRefId, Vector3d& vtNorm) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // recupero la normale della faccia if ( ! pStm->GetFacetNormal( nFacet, vtNorm)) return false ; // gestione trasformazione ( eventuale) return TransformVector( pGeomDB, nId, nRefId, vtNorm) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetMinAreaRectangle( int nId, int nFacet, int nRefId, Frame3d& frRect, double& dDimX, double& dDimY) { 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 centro e la normale della faccia Point3d ptCen ; Vector3d vtN ; if ( ! pStm->GetFacetCenter( nFacet, ptCen, vtN)) return false ; // calcolo il riferimento OCS della faccia Frame3d frFac ; if ( ! frFac.Set( ptCen, vtN)) return false ; // recupero il contorno esterno della faccia e lo porto nel suo riferimento POLYLINEVECTOR vPL ; pStm->GetFacetLoops( nFacet, vPL) ; if ( vPL.empty()) return false ; vPL[0].ToLoc( frFac) ; // derivo il rettangolo in XY di area minima di questa Point3d ptOri ; Vector3d vtAx ; if ( ! vPL[0].GetMinAreaRectangleXY( ptOri, vtAx, dDimX, dDimY) || ! frRect.Set( ptOri, Z_AX, vtAx)) return false ; // esprimo il riferimento rispetto a quello richiesto frRect.ToGlob( frFac) ; return TransformFrame( pGeomDB, nId, nRefId, frRect) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetOppositeSide( int nId, int nFacet, const Vector3d& vtDir, int nRefId, Point3d& ptP1, Point3d& ptP2) { Point3d ptPm ; Vector3d vtIn1, vtOut2; double dLen, dWidth ; return ExeSurfTmFacetOppositeSideEx( nId, nFacet, vtDir, nRefId, ptP1, ptPm, ptP2, vtIn1, vtOut2, dLen, dWidth) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetOppositeSideEx( int nId, int nFacet, const Vector3d& vtDir, int nRefId, Point3d& ptP1, Point3d& ptPm, Point3d& ptP2, Vector3d& vtIn1, Vector3d& vtOut2, double& dLen, double& dWidth) { 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()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[0])) 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 ( ! InvTransformVector( 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) ; // ne faccio una copia per usi successivi PtrOwner pCrvCopy( pCrvCompo->Clone()) ; // la direzione di riferimento è l'asse X, la sostituisco con quella perpendicolare alla curva più adatta Vector3d vtRef = X_AX ; double dCosMax = -1 ; const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; while ( pCrv != nullptr) { Vector3d vtDir ; pCrv->GetMidDir( vtDir) ; Vector3d vtPerp = Z_AX ^ vtDir ; double dCos = vtPerp * X_AX ; if ( dCos > dCosMax) { dCosMax = dCos ; vtRef = vtPerp ; } pCrv = pCrvCompo->GetNextCurve() ; } // la curva gira in senso antiorario attorno al contorno faccia vista dalla normale uscente // elimino i segmenti che hanno la direzione di riferimento a destra o quasi (46deg) const double COS_ANG_MAX = cos( 46.01 * DEGTORAD) ; const double MIN_DIR_LEN = 0.999 ; // cerco primo elemento del contorno non valido e vi pongo inizio/fine della curva int i = 0 ; pCrv = pCrvCompo->GetFirstCurve() ; while ( pCrv != nullptr) { double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ; Vector3d vtDir ; pCrv->GetMidDir( vtDir) ; if ( dCrvLen > MIN_DIR_LEN && ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) { vtIn1 = vtDir ; vtOut2 = vtDir ; pCrvCompo->ChangeStartPoint( i) ; break ; } pCrv = pCrvCompo->GetNextCurve() ; ++ i ; } // se non trovato almeno un lato non valido, errore if ( pCrv == nullptr) return false ; // a partire da questo elimino elementi non validi in avanti e indietro pCrv = pCrvCompo->GetFirstCurve() ; while ( pCrv != nullptr) { Vector3d vtDir ; pCrv->GetMidDir( vtDir) ; if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) { double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ; if ( dCrvLen > MIN_DIR_LEN) pCrv->GetMidDir( vtIn1) ; delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ; pCrv = pCrvCompo->GetFirstCurve() ; } else break ; } pCrv = pCrvCompo->GetLastCurve() ; while ( pCrv != nullptr) { Vector3d vtDir ; pCrv->GetMidDir( vtDir) ; if ( ( Z_AX ^ vtDir) * vtRef < COS_ANG_MAX) { double dCrvLen = 0 ; pCrv->GetLength( dCrvLen) ; if ( dCrvLen > MIN_DIR_LEN) pCrv->GetMidDir( vtOut2) ; delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ; pCrv = pCrvCompo->GetLastCurve() ; } else break ; } // elimino le curve estreme molto corte ( 0.5 mm) const double REF_LEN = 10.0 ; double dCompoLen ; if ( pCrvCompo->GetLength( dCompoLen) && dCompoLen > REF_LEN) { const double MIN_LEN = 0.5 ; double dCrvLen ; pCrv = pCrvCompo->GetFirstCurve() ; if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN) delete( pCrvCompo->RemoveFirstOrLastCurve( false)) ; pCrv = pCrvCompo->GetLastCurve() ; if ( pCrv != nullptr && pCrv->GetLength( dCrvLen) && dCrvLen < MIN_LEN) delete( pCrvCompo->RemoveFirstOrLastCurve( true)) ; } // recupero i punti estremi della curva if ( ! pCrvCompo->GetStartPoint( ptP1) || ! pCrvCompo->GetEndPoint( ptP2)) return false ; // ricavo il punto intermedio if ( pCrvCompo->GetCurveCount() == 1) ptPm = Media( ptP1, ptP2, 0.5) ; else if ( pCrvCompo->GetCurveCount() == 2) pCrvCompo->GetPointD1D2( 1.0, ICurve::FROM_MINUS, ptPm) ; else { double dLen ; pCrvCompo->GetLength( dLen) ; double dU ; pCrvCompo->GetParamAtLength( 0.5 * dLen, dU) ; pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptPm) ; } // determino la lunghezza e l'elevazione della faccia rispetto alla curva trovata Vector3d vtTg = ptP2 - ptP1 ; Frame3d frExtr ; if ( ! frExtr.Set( ORIG, Z_AX, vtTg) || ! frExtr.Invert()) return false ; BBox3d b3Extr ; pCrvCopy->GetBBox( frExtr, b3Extr) ; if ( ! b3Extr.IsEmpty()) { dLen = b3Extr.GetMax().x - b3Extr.GetMin().x ; dWidth = b3Extr.GetMax().y - b3Extr.GetMin().y ; } else { dLen = 0 ; dWidth = 0 ; } // porto i punti nel riferimento della superficie e poi in quello richiesto ptP1.ToGlob( frSpec) ; ptPm.ToGlob( frSpec) ; ptP2.ToGlob( frSpec) ; vtIn1.ToGlob( frSpec) ; vtOut2.ToGlob( frSpec) ; return ( TransformPoint( pGeomDB, nId, nRefId, ptP1) && TransformPoint( pGeomDB, nId, nRefId, ptPm) && TransformPoint( pGeomDB, nId, nRefId, ptP2) && TransformVector( pGeomDB, nId, nRefId, vtIn1) && TransformVector( pGeomDB, nId, nRefId, vtOut2)) ; } //---------------------------------------------------------------------------- bool ExeSurfTmFacetsContact( int nId, int nF1, int nF2, int nRefId, bool& bAdjac, Point3d& ptP1, Point3d& ptP2, double& dAng) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // recupero i dati di contatto tra le due facce if ( ! pStm->GetFacetsContact( nF1, nF2, bAdjac, ptP1, ptP2, dAng)) return false ; // gestione trasformazione ( eventuale) if ( bAdjac) return TransformPoint( pGeomDB, nId, nRefId, ptP1) && TransformPoint( pGeomDB, nId, nRefId, ptP2) ; else return true ; } //---------------------------------------------------------------------------- int ExeExtractSurfTmLoops( int nId, int nDestGrpId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pStm != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // recupero i loop come polilinee POLYLINEVECTOR vPL ; bOk = bOk && pStm->GetLoops( vPL) ; // dalle polilinee creo le curve e le inserisco nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( size_t i = 0 ; i < vPL.size() ; ++ i) { // creo la curva PtrOwner pCrvCompo( CreateCurveComposite()) ; bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ; // la porto nel riferimento destinazione bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtractSurfTmLoops(" + ToString( nId) + "," + ToString( nDestGrpId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeGetSurfTmSilhouette( int nId, const Vector3d& vtDir, double dToler, int nDestGrpId, int nRefType, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pStm != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // porto in locale alla superficie il versore di riferimento Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf) ; // recupero i loop come polilinee POLYLINEVECTOR vPL ; bOk = bOk && pStm->GetSilhouette( vtDirL, dToler, vPL) ; // dalle polilinee creo le curve e le inserisco nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( size_t i = 0 ; i < vPL.size() ; ++ i) { // creo la curva PtrOwner pCrvCompo( CreateCurveComposite()) ; bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ; // la porto nel riferimento destinazione bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtGetSurfTmSilhouette(" + ToString( nId) + ",{" + ToString( vtDir) + "}," + ToString( nDestGrpId) + "," + RefTypeToString( nRefType) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- int ExeExtractSurfTmFacetLoops( int nId, int nFacet, int nDestGrpId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pStm != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // recupero la normale della faccia (da usare come estrusione delle curve) Vector3d vtN ; bOk = bOk && pStm->GetFacetNormal( nFacet, vtN) ; // recupero i loop come polilinee POLYLINEVECTOR vPL ; bOk = bOk && pStm->GetFacetLoops( nFacet, vPL) ; // dalle polilinee creo le curve e le inserisco nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; for ( size_t i = 0 ; i < vPL.size() ; ++ i) { // creo la curva PtrOwner pCrvCompo( CreateCurveComposite()) ; bOk = bOk && pCrvCompo->FromPolyLine( vPL[i]) ; // imposto estrusione bOk = bOk && pCrvCompo->SetExtrusion( vtN) ; // la porto nel riferimento destinazione bOk = bOk && pCrvCompo->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCompo)) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtractSurfTmFacetLoops(" + ToString( nId) + "," + ToString( nFacet) + "," + ToString( nDestGrpId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- int ExeCopySurfTmFacet( int nId, int nFacet, int nDestGrpId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return GDB_ID_NULL ; // recupero il suo riferimento globale Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( nId, frSurf)) return GDB_ID_NULL ; // recupero il riferimento del gruppo di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // copio la faccia PtrOwner pFac( pStm->CloneFacet( nFacet)) ; if ( IsNull( pFac)) return GDB_ID_NULL ; pFac->LocToLoc( frSurf, frDest) ; // inserisco nel DB int nFacId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nDestGrpId, GDB_LAST_SON, Release( pFac)) ; if ( nFacId == GDB_ID_NULL) return GDB_ID_NULL ; // copio gli attributi if ( ! pGeomDB->CopyAttributes( nId, nFacId)) return GDB_ID_NULL ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtCopySurfTmFacet(" + ToString( nId) + "," + ToString( nFacet) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nFacId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return nFacId ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetAllVertInFacet( int nId, int nFacet, INTVECTOR& vVert) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // recupero la superficie TriMesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return false ; // recupero l'elenco dei vertici nella faccia return pStm->GetAllVertInFacet( nFacet, vVert) ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetFacetBBox( int nId, int nFacet, int nFlag, BBox3d& b3Box) { 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 bounding box della faccia dell'oggetto in locale return pStm->GetFacetLocalBBox( nFacet, b3Box, nFlag) ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetFacetBBoxGlob( int nId, int nFacet, int nFlag, BBox3d& b3Box) { 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 riferimento globale del gruppo cui appartiene Frame3d frGlob ; if ( nId != GDB_ID_ROOT && ! pGeomDB->GetGroupGlobFrame( pGeomDB->GetParentId( nId), frGlob)) return false ; // recupero il bounding box della faccia dell'oggetto in globale return pStm->GetFacetBBox( nFacet, frGlob, b3Box, nFlag) ; } //----------------------------------------------------------------------------- bool ExeSurfTmGetFacetBBoxRef( int nId, int nFacet, int nFlag, const Frame3d& frRef, BBox3d& b3Box) { 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 riferimento globale del gruppo cui appartiene Frame3d frGlob ; if ( nId != GDB_ID_ROOT && ! pGeomDB->GetGroupGlobFrame( pGeomDB->GetParentId( nId), frGlob)) return false ; // porto il riferimento di espressione in quello della superficie Frame3d frGlobL = frGlob ; frGlobL.ToLoc( frRef) ; // recupero il bounding box della faccia dell'oggetto in globale return pStm->GetFacetBBox( nFacet, frGlobL, b3Box, nFlag) ; } //---------------------------------------------------------------------------- bool ExeSurfBezierGetPoint( int nSurfId, double dU, double dV, int nRefId, Point3d& ptP) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; bool bOk = ( pSbz != nullptr) ; // richiedo il punto bOk = bOk && pSbz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP) ; // gestione trasformazioni ( eventuali) bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetPoint(" + ToString( nSurfId) + "," + ToString( dU) + "," + ToString( dV) + "," + ToString( nRefId) + ")" + " -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfBezierGetPointD1( int nSurfId, double dU, double dV, int nUsd, int nVsd, int nRefId, Point3d& ptP, Vector3d& vtDerU, Vector3d& vtDerV) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; bool bOk = ( pSbz != nullptr) ; // direzioni di approccio ISurfBezier::Side nSbzUsd = ( nUsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ; ISurfBezier::Side nSbzVsd = ( nVsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ; // richiedo il punto bOk = bOk && pSbz->GetPointD1D2( dU, dV, nSbzUsd, nSbzVsd, ptP, &vtDerU, &vtDerV) ; // gestione trasformazioni ( eventuali) bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) && TransformVector( pGeomDB, nSurfId, nRefId, vtDerU) && TransformVector( pGeomDB, nSurfId, nRefId, vtDerV) ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetPointD1(" + ToString( nSurfId) + "," + ToString( dU) + "," + ToString( dV) + "," + ToString( nUsd) + "," + ToString( nVsd) + "," + ToString( nRefId) + ")" + " -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") + " DerU=" + ( bOk ? "{" + ToString( vtDerU) + "}" : "nil") + " DerV=" + ( bOk ? "{" + ToString( vtDerV) + "}" : "nil") ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfBezierGetPointNrmD1( int nSurfId, double dU, double dV, int nUsd, int nVsd, int nRefId, Point3d& ptP, Vector3d& vtN, Vector3d& vtDerU, Vector3d& vtDerV) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; bool bOk = ( pSbz != nullptr) ; // direzioni di approccio ISurfBezier::Side nSbzUsd = ( nUsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ; ISurfBezier::Side nSbzVsd = ( nVsd > 0 ? ISurfBezier::FROM_PLUS : ISurfBezier::FROM_MINUS) ; // richiedo il punto bOk = bOk && pSbz->GetPointNrmD1D2( dU, dV, nSbzUsd, nSbzVsd, ptP, vtN, &vtDerU, &vtDerV) ; // gestione trasformazioni ( eventuali) bOk = bOk && TransformPoint( pGeomDB, nSurfId, nRefId, ptP) && TransformVector( pGeomDB, nSurfId, nRefId, vtN) && TransformVector( pGeomDB, nSurfId, nRefId, vtDerU) && TransformVector( pGeomDB, nSurfId, nRefId, vtDerV) ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetPointNrmD1(" + ToString( nSurfId) + "," + ToString( dU) + "," + ToString( dV) + "," + ToString( nUsd) + "," + ToString( nVsd) + "," + ToString( nRefId) + ")" + " -- Pnt=" + ( bOk ? "{" + ToString( ptP) + "}" : "nil") + " Nrm=" + ( bOk ? "{" + ToString( vtN) + "}" : "nil") + " DerU=" + ( bOk ? "{" + ToString( vtDerU) + "}" : "nil") + " DerV=" + ( bOk ? "{" + ToString( vtDerV) + "}" : "nil") ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return bOk ; } //---------------------------------------------------------------------------- int MySurfBezierGetCurveUV( int nSurfId, bool bIsU, double dPar, int nDestGrpId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; if ( pSbz == nullptr) return GDB_ID_NULL ; // recupero il riferimento della superficie Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( nSurfId, frSurf)) return GDB_ID_NULL ; // recupero il riferimento di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // richiedo la curva PtrOwner pCrv( bIsU ? pSbz->GetCurveOnU( dPar) : pSbz->GetCurveOnV( dPar)) ; if ( IsNull( pCrv)) return GDB_ID_NULL ; // se è una curva if ( ! pCrv->IsAPoint()) { // porto la curva nel riferimento destinazione pCrv->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrv)) ; // copio il materiale pGeomDB->CopyMaterial( nSurfId, nNewId) ; return nNewId ; } // altrimenti è collassata in un punto else { Point3d ptP ; pCrv->GetStartPoint( ptP) ; PtrOwner pGeoPnt( CreateGeoPoint3d()) ; if ( IsNull( pGeoPnt) || ! pGeoPnt->Set( ptP)) return GDB_ID_NULL ; // porto il punto nel riferimento destinazione pGeoPnt->LocToLoc( frSurf, frDest) ; // lo inserisco nel DB geometrico int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; // copio il materiale pGeomDB->CopyMaterial( nSurfId, nNewId) ; return nNewId ; } } //---------------------------------------------------------------------------- int ExeSurfBezierGetCurveU( int nSurfId, double dV, int nDestGrpId) { // creo la curva int nNewId = MySurfBezierGetCurveUV( nSurfId, true, dV, nDestGrpId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetCurveU(" + ToString( nSurfId) + "," + ToString( dV) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return nNewId ; } //---------------------------------------------------------------------------- int ExeSurfBezierGetCurveV( int nSurfId, double dU, int nDestGrpId) { // creo la curva int nNewId = MySurfBezierGetCurveUV( nSurfId, false, dU, nDestGrpId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetCurveV(" + ToString( nSurfId) + "," + ToString( dU) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return nNewId ; } //---------------------------------------------------------------------------- bool ExeSurfBezierGetInfo( int nSurfId, int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; bool bOk = ( pSbz != nullptr) ; // recupero le info (gradi in U e V, flag di razionale) bOk = bOk && pSbz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetInfo(" + ToString( nSurfId) + ")" + " -- DegU=" + ( bOk ? ToString( nDegU) : "nil") + " -- DegV=" + ( bOk ? ToString( nDegV) : "nil") + " -- SpanU=" + ( bOk ? ToString( nSpanU) : "nil") + " -- SpanV=" + ( bOk ? ToString( nSpanV) : "nil") + " -- IsRat=" + ( bOk ? ToString( bIsRat) : "nil") + " -- Trim=" + ( bOk ? ToString( bTrimmed) : "nil") ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return bOk ; } //---------------------------------------------------------------------------- int MySurfBezierGetControlCurveUV( int nSurfId, bool bIsU, int nInd, int nDestGrpId) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nSurfId)) ; if ( pSbz == nullptr) return GDB_ID_NULL ; // recupero il riferimento della superficie Frame3d frSurf ; if ( ! pGeomDB->GetGlobFrame( nSurfId, frSurf)) return GDB_ID_NULL ; // recupero il riferimento di destinazione Frame3d frDest ; if ( ! pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest)) return GDB_ID_NULL ; // richiedo i dati della polilinea PolyLine PL ; if ( bIsU) pSbz->GetControlCurveOnU( nInd, PL) ; else pSbz->GetControlCurveOnV( nInd, PL) ; // se è una curva if ( PL.GetPointNbr() > 1) { PtrOwner pCrvCo( CreateCurveComposite()) ; if ( IsNull( pCrvCo) || ! pCrvCo->FromPolyLine( PL)) return GDB_ID_NULL ; // porto la curva nel riferimento destinazione pCrvCo->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrvCo)) ; // copio il materiale pGeomDB->CopyMaterial( nSurfId, nNewId) ; return nNewId ; } // se altrimenti è collassata in un punto else if ( PL.GetPointNbr() == 1) { Point3d ptP ; PL.GetFirstPoint( ptP) ; PtrOwner pGeoPnt( CreateGeoPoint3d()) ; if ( IsNull( pGeoPnt) || ! pGeoPnt->Set( ptP)) return GDB_ID_NULL ; // porto il punto nel riferimento destinazione pGeoPnt->LocToLoc( frSurf, frDest) ; // lo inserisco nel DB geometrico int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pGeoPnt)) ; // copio il materiale pGeomDB->CopyMaterial( nSurfId, nNewId) ; return nNewId ; } // altrimenti è errore else return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int ExeSurfBezierGetControlCurveU( int nSurfId, int nIndV, int nDestGrpId) { // creo la curva int nNewId = MySurfBezierGetControlCurveUV( nSurfId, true, nIndV, nDestGrpId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetControlCurveU(" + ToString( nSurfId) + "," + ToString( nIndV) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return nNewId ; } //---------------------------------------------------------------------------- int ExeSurfBezierGetControlCurveV( int nSurfId, int nIndU, int nDestGrpId) { // creo la curva int nNewId = MySurfBezierGetControlCurveUV( nSurfId, false, nIndU, nDestGrpId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfBezierGetControlCurveV(" + ToString( nSurfId) + "," + ToString( nIndU) + "," + ToString( nDestGrpId) + ")" + " -- Id=" + ToString( nNewId) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati return nNewId ; } //---------------------------------------------------------------------------- int ExeExtractSurfBezierLoops( int nId, int nDestGrpId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie di Bezier const ISurfBezier* pSbz = GetSurfBezier( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pSbz != nullptr) ; // recupero il riferimento della superficie Frame3d frSurf ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frSurf) ; // recupero il riferimento di destinazione Frame3d frDest ; bOk = bOk && pGeomDB->GetGroupGlobFrame( nDestGrpId, frDest) ; // richiedo i contorni della superficie e li inserisco nel DB int nFirstId = GDB_ID_NULL ; int nCount = 0 ; int nL = 0 ; PtrOwner pCrv( bOk ? pSbz->GetLoop( nL) : nullptr) ; while ( ! IsNull( pCrv)) { // porto la curva nel riferimento destinazione bOk = bOk && pCrv->LocToLoc( frSurf, frDest) ; // la inserisco nel DB geometrico int nNewId = ( bOk ? pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrpId, Release( pCrv)) : GDB_ID_NULL) ; bOk = bOk && ( nNewId != GDB_ID_NULL) ; // copio il materiale if ( ! pGeomDB->CopyMaterial( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( bOk && nFirstId == GDB_ID_NULL) nFirstId = nNewId ; if ( bOk) ++ nCount ; // passo alla prossima curva pCrv.Set( bOk ? pSbz->GetLoop( ++nL) : nullptr) ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExtractSurfBezierLoops(" + ToString( nId) + "," + ToString( nDestGrpId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; }