//---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- // File : BeamMgr.cpp Data : 30.08.20 Versione : 2.2h // Contenuto : Implementazione della classe per l'importazione BTL. // // // // Modifiche : 22.08.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "BeamMgr.h" #include "DllMain.h" #include "/EgtDev/Include/EExDllMain.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/EgtStringEncoder.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- IBeamMgr* CreateBeamMgr( void) { // verifico la chiave e le opzioni if ( ! TestKeyForEEx( GetEExKey(), KEYOPT_EEX_INPADV, GetEExLogger())) return nullptr ; // creo l'oggetto return static_cast ( new(nothrow) BeamMgr) ; } //---------------------------------------------------------------------------- BeamMgr::BeamMgr( void) { ; } //---------------------------------------------------------------------------- bool BeamMgr::Init( IGeomDB* pGDB, int nFlag) { // assegno il gestore di DB geometrico if ( pGDB == nullptr) return false ; m_pGDB = pGDB ; // inizializzo il gestore geometria pezzi Btl int nFlatVertPos = 0 ; if (( nFlag & EIBFLAG_TS3_POS) != 0) nFlatVertPos = 3 ; else if (( nFlag & EIBFLAG_FLAT_POS) != 0) nFlatVertPos = 1 ; else if (( nFlag & EIBFLAG_VERT_POS) != 0) nFlatVertPos = 2 ; bool bSpecialTrim = (( nFlag & EIBFLAG_SPECIAL_TRIM) != 0) ; bool bUseUAttr = (( nFlag & EIBFLAG_USEUATTR) != 0) ; if ( ! m_BtlGeom.Init( pGDB, nFlatVertPos, bSpecialTrim, bUseUAttr)) { LOG_ERROR( GetEExLogger(), " Error on BtlGeom.Init") return false ; } return true ; } //---------------------------------------------------------------------------- static int RegularizeTriMesh( IGeomDB* pGDB, int nSurfId, int DestGrpId, double dStep) { // recupero la superficie trimesh const ISurfTriMesh* pStm = GetSurfTriMesh( pGDB->GetGeoObj( nSurfId)) ; if ( pStm == nullptr) return GDB_ID_NULL ; // solo per superfici trimesh con poche facce (max4) int nFacetCnt = pStm->GetFacetCount() ; if ( nFacetCnt > 4) return nSurfId ; // box della superficie BBox3d b3Surf ; pStm->GetLocalBBox( b3Surf, BBF_STANDARD) ; if ( b3Surf.IsEmpty() || ( b3Surf.GetMax().x - b3Surf.GetMin().x) < 2 * dStep) return nSurfId ; // recupero le facce e le divido in X double dXmin = b3Surf.GetMin().x - 1 ; double dXmax = b3Surf.GetMax().x + 1 ; int nStep = int( floor( ( dXmax - dXmin) / dStep + 0.9)) ; dStep = ( dXmax - dXmin) / nStep ; PtrOwner pStmNew ; for ( int nF = 0 ; nF < nFacetCnt ; ++ nF) { // copio la faccia PtrOwner pFac( pStm->CloneFacet( nF)) ; if ( IsNull( pFac)) return nSurfId ; BBox3d b3Fac ; pFac->GetLocalBBox( b3Fac, BBF_STANDARD) ; // la taglio a fette double dX2 = dXmin ; for ( int nI = 1 ; nI <= nStep ; ++ nI) { double dX1 = dX2 ; dX2 = dX2 + dStep ; if ( b3Fac.GetMin().x < dX2 && b3Fac.GetMax().x > dX1) { // eseguo taglio Plane3d plMin ; plMin.Set( Point3d( dX1, 0, 0), -X_AX) ; pFac->Cut( plMin, true) ; Plane3d plMax ; plMax.Set( Point3d( dX2, 0, 0), X_AX) ; pFac->Cut( plMax, false) ; // recupero il nuovo contorno POLYLINEVECTOR vPL ; pFac->GetFacetLoops( 0, vPL) ; PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo) || vPL.size() == 0 || ! pCrvCompo->FromPolyLine( vPL[0])) return nSurfId ; // lo compatto pCrvCompo->MergeCurves( EPS_SMALL, ANG_RIGHT / 6, true) ; // creo la nuova faccia PtrOwner pStmTmp( GetSurfTriMeshByFlatContour( pCrvCompo, EPS_SMALL)) ; if ( IsNull( pStmTmp)) return nSurfId ; if ( IsNull( pStmNew)) pStmNew.Set( Release( pStmTmp)) ; else pStmNew->DoSewing( *pStmTmp) ; // recupero una nuova copia della faccetta originale pFac.Set( pStm->CloneFacet( nF)) ; if ( IsNull( pFac)) return nSurfId ; } } } // inserisco la nuova superficie nel DB geometrico int nNewSurfId = GDB_ID_NULL ; if ( ! IsNull( pStmNew)) nNewSurfId = pGDB->AddGeoObj( GDB_ID_NULL, DestGrpId, Release( pStmNew)) ; return ( nNewSurfId != GDB_ID_NULL ? nNewSurfId : nSurfId) ; } //---------------------------------------------------------------------------- bool BeamMgr::CalcSolid( int nPartId, bool bRecalc) { // Verifico validità DBG if ( m_pGDB == nullptr) return false ; // Verifico esistenza del pezzo if ( ! m_pGDB->ExistsObj( nPartId)) return false ; // Recupero identificativo del Box int nBoxId = m_pGDB->GetFirstNameInGroup( m_pGDB->GetFirstNameInGroup( nPartId, BOX_LAYER_NAME), BOX_BOX_NAME) ; if ( nBoxId == GDB_ID_NULL) return false ; // Verifico esistenza del solido int nSolLayId = m_pGDB->GetFirstNameInGroup( nPartId, SOLID_LAYER_NAME) ; if ( nSolLayId == GDB_ID_NULL) { nSolLayId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, GLOB_FRM) ; m_pGDB->SetName( nSolLayId, SOLID_LAYER_NAME) ; } int nSolidId = m_pGDB->GetFirstNameInGroup( nSolLayId, SOLID_SOLID_NAME) ; if ( bRecalc && nSolidId != GDB_ID_NULL) { m_pGDB->Erase( nSolidId) ; nSolidId = GDB_ID_NULL ; } if ( nSolidId == GDB_ID_NULL) { BBox3d b3Box ; m_pGDB->GetLocalBBox( nBoxId, b3Box, BBF_STANDARD) ; Point3d ptMin ; double dDimX, dDimY, dDimz ; if ( ! b3Box.GetMinDim( ptMin, dDimX, dDimY, dDimz)) return false ; PtrOwner pSTM( GetSurfTriMeshBox( dDimX, dDimY, dDimz, true)) ; if ( IsNull( pSTM)) return false ; pSTM->Translate( ptMin - ORIG) ; nSolidId = m_pGDB->AddGeoObj( GDB_ID_NULL, nSolLayId, Release( pSTM)) ; if ( nSolidId == GDB_ID_NULL) return false ; m_pGDB->SetName( nSolidId, SOLID_SOLID_NAME) ; m_pGDB->SetMaterial( nSolidId, Color(255, 160, 32)) ; } else { return true ; } BBox3d b3Solid ; m_pGDB->GetLocalBBox( nSolidId, b3Solid, BBF_STANDARD) ; double dSolidDimY = b3Solid.GetMax().y - b3Solid.GetMin().y ; double dSolidDimZ = b3Solid.GetMax().z - b3Solid.GetMin().z ; double dStep = 1.23 * min( max( dSolidDimY, dSolidDimZ), 2 * min( dSolidDimY, dSolidDimZ)) ; // Esecuzione intersezioni ISurfTriMesh* pStm = GetSurfTriMesh( m_pGDB->GetGeoObj( nSolidId)) ; if ( pStm == nullptr) return false ; // ciclo sulle features int nProcLayId = m_pGDB->GetFirstNameInGroup( nPartId, PROCESSINGS_LAYER_NAME) ; int nProcId = m_pGDB->GetFirstInGroup( nProcLayId) ; while ( nProcId != GDB_ID_NULL) { int nDO = 1 ; int nTrim = 1 ; m_pGDB->GetInfo( nProcId, IKEY_DO, nDO) ; m_pGDB->GetInfo( nProcId, IKEY_TRIM, nTrim) ; if ( nDO != 0 && nTrim != 0 && m_pGDB->GetGeoType( nProcId) == SRF_TRIMESH) { int nNewSurfId = RegularizeTriMesh( m_pGDB, nProcId, nSolLayId, dStep) ; const ISurfTriMesh* pStmProc = GetSurfTriMesh( m_pGDB->GetGeoObj( nNewSurfId)) ; if ( pStmProc == nullptr || ! pStm->Intersect( *pStmProc)) return false ; if ( nNewSurfId != nProcId) m_pGDB->Erase( nNewSurfId) ; } nProcId = m_pGDB->GetNext( nProcId) ; } return true ; } //---------------------------------------------------------------------------- int BeamMgr::GetSolid( int nPartId) { // Verifico validità DBG if ( m_pGDB == nullptr) return false ; // Recupero layer del solido e Id del solido int nSolLayId = m_pGDB->GetFirstNameInGroup( nPartId, SOLID_LAYER_NAME) ; int nSolidId = m_pGDB->GetFirstNameInGroup( nSolLayId, SOLID_SOLID_NAME) ; return nSolidId ; } //---------------------------------------------------------------------------- bool BeamMgr::ShowSolid( int nPartId, bool bShow) { // Verifico validità DBG if ( m_pGDB == nullptr) return false ; // Verifico esistenza del pezzo if ( ! m_pGDB->ExistsObj( nPartId)) return false ; // visualizzo il solido e nascondo le geometrie complementari e viceversa int nSolLayId = m_pGDB->GetFirstNameInGroup( nPartId, SOLID_LAYER_NAME) ; m_pGDB->SetStatus( nSolLayId, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ; int nBoxLayId = m_pGDB->GetFirstNameInGroup( nPartId, BOX_LAYER_NAME) ; m_pGDB->SetStatus( nBoxLayId, ( bShow ? GDB_ST_OFF : GDB_ST_ON)) ; int nOutlLayId = m_pGDB->GetFirstNameInGroup( nPartId, OUTLINE_LAYER_NAME) ; m_pGDB->SetStatus( nOutlLayId, ( bShow ? GDB_ST_OFF : GDB_ST_ON)) ; int nProcsLayId = m_pGDB->GetFirstNameInGroup( nPartId, PROCESSINGS_LAYER_NAME) ; m_pGDB->SetStatus( nProcsLayId, ( bShow ? GDB_ST_OFF : GDB_ST_ON)) ; return true ; }