//---------------------------------------------------------------------------- // 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 "EXE_Const.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/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkSurfFlatRegion.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EgkChainCurves.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGkCDSimpleSurfFrMove.h" #include "/EgtDev/Include/EGkIntersPlaneSurfTm.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 ; // recupero il numero di facce int nFacet = pStm->GetFacetCount() ; // se c'è una sola faccia, non devo fare alcunché if ( nFacet == 1) { if ( pnCount != nullptr) *pnCount = 1 ; return nId ; } // copio tutte le facce int nFirstId = GDB_ID_NULL ; int nCount = 0 ; 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 originale 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 ; // recupero il numero di componenti connessi (chunk) int nChunk = pSfr->GetChunkCount() ; // se c'è un solo componente, non devo fare alcunché if ( nChunk == 1) { if ( pnCount != nullptr) *pnCount = 1 ; return nId ; } // copio tutti i componenti connessi (chunk) int nFirstId = GDB_ID_NULL ; int nCount = 0 ; 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 = "EgtExplodeSurf(" + 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 in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; bOk = bOk && ( pSfr2L != nullptr) ; // 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 in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; bOk = bOk && ( pSfr2L != nullptr) ; // 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 in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; bOk = bOk && ( pSfr2L != nullptr) ; // 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 in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; bOk = bOk && ( pSfr2L != nullptr) ; // 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 && CDSimpleSurfFrMove( *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 in locale alla prima SurfLocal Surf2Loc( pGeomDB, nId2, frSurf1) ; const ISurfFlatRegion* pSfr2L = GetSurfFlatRegion( Surf2Loc) ; bOk = bOk && ( pSfr2L != nullptr) ; // 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 && CDSimpleSurfFrMove( *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 ; } //------------------------------------------------------------------------------- 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 ; } //------------------------------------------------------------------------------- static int MyGetSurfTmPlaneInters( int nId, const Point3d& ptOn, const Vector3d& vtN, int nDestGrpId, int nRefType, int* pnPntCount, int* pnCrvCount, int* pnSrfCount) { 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 ; // porto in locale il punto e la normale del piano Point3d ptOnL = GetPointLocal( pGeomDB, ptOn, nRefType, frSurf) ; Vector3d vtNL = GetVectorLocal( pGeomDB, vtN, nRefType, frSurf) ; // calcolo il piano di intersezione Plane3d plPlane ; if ( ! plPlane.Set( ptOnL, vtNL)) return GDB_ID_NULL ; // eseguo l'intersezione PNTVECTOR vPnt ; BIPNTVECTOR vBpt ; TRIA3DVECTOR vTria ; if ( ! IntersPlaneSurfTm( plPlane, *pStm, vPnt, vBpt, vTria)) return GDB_ID_NULL ; // Inserisco il risultato nel DB int nFirstId = GDB_ID_NULL ; int nPntCount = 0 ; int nCrvCount = 0 ; int nSrfCount = 0 ; // Inserisco i punti nel DB for ( size_t i = 0 ; i < 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( frSurf, 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 ; } // Concateno i tratti di curva double dToler = 20 * EPS_SMALL ; ChainCurves chainC ; chainC.Init( false, dToler, int( vBpt.size())) ; for ( size_t i = 0 ; i < vBpt.size() ; ++ i) { Vector3d vtDir = vBpt[i].second - vBpt[i].first ; vtDir.Normalize() ; if ( ! chainC.AddCurve( int( 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 for ( size_t i = 0 ; i < vId.size() ; ++ i) { // creo una segmento di retta int nInd = vId[i] - 1 ; PtrOwner pLine( CreateCurveLine()) ; if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second)) return GDB_ID_NULL ; // lo accodo alla composita if ( ! pCrvCompo->AddCurve( Release( pLine), true, dToler)) return GDB_ID_NULL ; // aggiorno il prossimo near ptNear = vBpt[nInd].second ; } // se lunghezza curva inferiore a 5 volte la tolleranza, la salto 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( plPlane.GetVersN()) ; // unisco segmenti allineati pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ; // porto la curva nel riferimento destinazione pCrvCompo->LocToLoc( frSurf, 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 ; } // Costruisco una superficie trimesh dall'insieme di triangoli StmFromTriangleSoup StmFts ; if ( ! StmFts.Start()) return GDB_ID_NULL ; for ( size_t i = 0 ; i < 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( frSurf, 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 ; } // aggiorno contatori if ( pnPntCount != nullptr) *pnPntCount = nPntCount ; if ( pnCrvCount != nullptr) *pnCrvCount = nCrvCount ; if ( pnSrfCount != nullptr) *pnSrfCount = nSrfCount ; // restituisco l'identificativo della prima nuova entità return nFirstId ; } //------------------------------------------------------------------------------- int ExeGetSurfTmPlaneInters( int nId, const Point3d& ptOn, const Vector3d& vtN, int nDestGrpId, int nRefType, int* pnPntCount, int* pnCrvCount, int* pnSrfCount) { // eseguo int nPntCount = 0 ; int nCrvCount = 0 ; int nSrfCount = 0 ; int nFirstId = MyGetSurfTmPlaneInters( nId, ptOn, vtN, nDestGrpId, nRefType, &nPntCount, &nCrvCount, &nSrfCount) ; // aggiorno contatori if ( pnPntCount != nullptr) *pnPntCount = nPntCount ; if ( pnCrvCount != nullptr) *pnCrvCount = nCrvCount ; if ( pnSrfCount != nullptr) *pnSrfCount = nSrfCount ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtGetSurfTmPlaneInters(" + ToString( nId) + ",{" + ToString( ptOn) + "},{" + ToString( vtN) + "}," + ToString( nDestGrpId) + "," + RefTypeToString( nRefType) + ")" + " -- Id1=" + ToString( nFirstId) + ", PntNbr=" + ToString( nPntCount) + ", CrvNbr=" + ToString( nCrvCount) + ", SrfNbr=" + ToString( nSrfCount) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco l'identificativo della prima nuova entità return nFirstId ; } //------------------------------------------------------------------------------- bool ExeCutSurfTm( int nId, const Point3d& ptOn, const Vector3d& vtN, bool bSaveOnEq, int nRefType) { IGeomDB* pGeomDB = GetCurrGeomDB() ; VERIFY_GEOMDB( pGeomDB, GDB_ID_NULL) // recupero la superficie TriMesh ISurfTriMesh* pStm = GetSurfTriMesh( pGeomDB->GetGeoObj( nId)) ; bool bOk = ( pStm != nullptr) ; // recupero il riferimento locale Frame3d frLoc ; bOk = bOk && pGeomDB->GetGlobFrame( nId, frLoc) ; // 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 taglio Plane3d plPlane ; bOk = bOk && plPlane.Set( ptOnL, vtNL) ; // eseguo il taglio bOk = bOk && pStm->Cut( plPlane, bSaveOnEq) ; ExeSetModified() ; // se richiesto, salvo il comando Lua equivalente if ( IsCmdLog()) { string sLua = "EgtCutSurfTm(" + ToString( nId) + ",{" + ToString( ptOn) + "},{" + ToString( vtN) + "}," + RefTypeToString( nRefType) + ")" + " -- Ok=" + ToString( bOk) ; LOG_INFO( GetCmdLogger(), sLua.c_str()) ; } // restituisco risultato return bOk ; }