//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : EXE_ModifySurf.cpp Data : 04.05.15 Versione : 1.6e1 // Contenuto : Funzioni di modifica delle superfici per EXE. // // // // Modifiche : 09.03.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EXE.h" #include "EXE_Macro.h" #include "AuxTools.h" #include "GeoTools.h" #include "/EgtDev/Include/EXeExecutor.h" #include "/EgtDev/Include/EXeConst.h" #include "/EgtDev/Include/EgkCurveComposite.h" #include "/EgtDev/Include/EgkSurfFlatRegion.h" #include "/EgtDev/Include/EgkSurfTriMesh.h" #include "/EgtDev/Include/EgkSimpleCDSurfFrMove.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- bool ExeInvertSurface( const INTVECTOR& vIds) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, false) // eseguo inversione bool bOk = true ; for ( size_t i = 0 ; i < vIds.size() && bOk ; ++ i) { int nId = (( vIds[i] != GDB_ID_SEL) ? vIds[i] : pGeomDB->GetFirstSelectedObj()) ; while ( nId != GDB_ID_NULL && bOk) { // recupero la superficie e la inverto ISurf* pSurf = GetSurf( pGeomDB->GetGeoObj( nId)) ; if ( pSurf != nullptr && ! pSurf->Invert()) bOk = false ; // passo alla successiva nId = (( vIds[i] != GDB_ID_SEL) ? GDB_ID_NULL : pGeomDB->GetNextSelectedObj()) ; } } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtInvertSurf({" + IdListToString( vIds) + "})" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; } //------------------------------------------------------------------------------- static int MyExplodeSurfTriMesh( int nId, int* pnCount) { 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 ; // copio tutte le facce int nFirstId = GDB_ID_NULL ; int nCount = 0 ; int nFacet = pStm->GetFacetCount() ; for ( int i = 0 ; i < nFacet ; ++ i) { ISurfTriMesh* pFac = pStm->CloneFacet( i) ; if ( pFac == nullptr) continue ; // inserisco la superficie nello stesso gruppo e nello stesso posto del GeomDB int nFacId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_BEFORE, pFac) ; if ( nFacId == GDB_ID_NULL) return GDB_ID_NULL ; // copio gli attributi if ( ! pGeomDB->CopyAttributes( nId, nFacId)) return GDB_ID_NULL ; // aggiorno contatori if ( nFirstId == GDB_ID_NULL) nFirstId = nFacId ; ++ nCount ; } // elimino la superficie pGeomDB->Erase( nId) ; // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- static int MyExplodeSurfFlatRegion( int nId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie FlatRegion const ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; if ( pSfr == nullptr) return GDB_ID_NULL ; // copio tutti i componenti connessi (chunk) int nFirstId = GDB_ID_NULL ; int nCount = 0 ; int nChunk = pSfr->GetChunkCount() ; for ( int i = 0 ; i < nChunk ; ++ i) { ISurfFlatRegion* pChk = pSfr->CloneChunk( i) ; if ( pChk == nullptr) continue ; // inserisco la superficie nello stesso gruppo e nello stesso posto del GeomDB int nNewId = pGeomDB->InsertGeoObj( GDB_ID_NULL, nId, GDB_BEFORE, pChk) ; if ( nNewId == GDB_ID_NULL) return GDB_ID_NULL ; // copio gli attributi if ( ! pGeomDB->CopyAttributes( nId, nNewId)) return GDB_ID_NULL ; // aggiorno contatori if ( nFirstId == GDB_ID_NULL) nFirstId = nNewId ; ++ nCount ; } // elimino la superficie pGeomDB->Erase( nId) ; // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //------------------------------------------------------------------------------- int ExeExplodeSurface( int nId, int* pnCount) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero il tipo di superficie int nFirstId = GDB_ID_NULL ; int nCount = 0 ; switch ( pGeomDB->GetGeoType( nId)) { case SRF_TRIMESH : nFirstId = MyExplodeSurfTriMesh( nId, &nCount) ; break ; case SRF_FLATRGN : nFirstId = MyExplodeSurfFlatRegion( nId, &nCount) ; break ; } ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtExplodeSurface(" + ToString( nId) + ")" + " -- Id1=" + ToString( nFirstId) + ",Nbr=" + ToString( nCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultati if ( pnCount != nullptr) *pnCount = nCount ; return nFirstId ; } //---------------------------------------------------------------------------- bool ExeSurfFrAdd( int nId1, int nId2) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // 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 ; PtrOwnerpTmp ; if ( ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pSfr2L = pTmp ; } // eseguo l'unione tra le due superfici bOk = bOk && pSfr1->Add( *pSfr2L) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrAdd(" + ToString( nId1) + "," + ToString( nId2) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfFrSubtract( int nId1, int nId2) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // 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 ; PtrOwnerpTmp ; if ( ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pSfr2L = pTmp ; } // eseguo la sottrazione della seconda superficie dalla prima bOk = bOk && pSfr1->Subtract( *pSfr2L) ; // se il risultato è vuoto, cancello la FlatRegion if ( bOk && ! pSfr1->IsValid()) pGeomDB->Erase( nId1) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrSubtract(" + ToString( nId1) + "," + ToString( nId2) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfFrIntersect( int nId1, int nId2) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // 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 ; PtrOwnerpTmp ; if ( ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pSfr2L = pTmp ; } // eseguo l'intersezione tra le due superfici bOk = bOk && pSfr1->Intersect( *pSfr2L) ; // se il risultato è vuoto, cancello la FlatRegion if ( bOk && ! pSfr1->IsValid()) pGeomDB->Erase( nId1) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrIntersect(" + ToString( nId1) + "," + ToString( nId2) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- bool ExeSurfFrOffset( int nId, double dDist, int nType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie FlatRegion ISurfFlatRegion* pSfr = GetSurfFlatRegion( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pSfr != nullptr) ; // eseguo l'offset bOk = bOk && pSfr->Offset( dDist, nType) ; // se il risultato è vuoto, cancello la FlatRegion if ( bOk && ! pSfr->IsValid()) pGeomDB->Erase( nId) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtSurfFrOffset(" + ToString( nId) + "," + ToString( dDist) + "," + ToString( nType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } return bOk ; } //---------------------------------------------------------------------------- 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 ; } //---------------------------------------------------------------------------- bool ExeSurfFrMoveSimpleNoCollision( int nId1, int nId2, const Vector3d& vtDir, double& dLen, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // 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 ; PtrOwnerpTmp ; if ( ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pSfr2L = pTmp ; } // porto in locale alla prima superficie il versore di movimento Vector3d vtDirL = GetVectorLocal( pGeomDB, vtDir, nRefType, frSurf1) ; // calcolo massima lunghezza di traslazione della prima regione senza semplice collisione con la seconda return ( bOk && SimpleCDSurfFrMove( *pSfr1, *pSfr2L).Translate( vtDirL, dLen)) ; } //---------------------------------------------------------------------------- bool ExeSurfFrRotateSimpleNoCollision( int nId1, int nId2, const Point3d& ptCen, double& dAngDeg, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // 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 ; PtrOwnerpTmp ; if ( ! AreSameFrame( frSurf1, frSurf2)) { pTmp.Set( CloneSurfFlatRegion( pSfr2)) ; bOk = bOk && ! IsNull( pTmp) ; bOk = bOk && pTmp->LocToLoc( frSurf2, frSurf1) ; pSfr2L = pTmp ; } // porto in locale alla prima superficie il versore di movimento Point3d ptCenL = GetPointLocal( pGeomDB, ptCen, nRefType, frSurf1) ; // calcolo massimo angolo di rotazione della prima regione senza semplice collisione con la seconda return ( bOk && SimpleCDSurfFrMove( *pSfr1, *pSfr2L).Rotate(ptCenL, dAngDeg)) ; } //---------------------------------------------------------------------------- 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, 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, 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 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]) ; // 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 ; }