//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : BtlGeom.cpp Data : 26.08.15 Versione : 1.6h5 // Contenuto : Implementazione della classe BtlGeom. // // // // Modifiche : 26.08.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "BtlGeom.h" #include "DllMain.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EGkExtText.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //---------------------------------------------------------------------------- string BtlGeom::m_sBtlAuxDir ; //---------------------------------------------------------------------------- BtlGeom::BtlGeom( void) { m_pGDB = nullptr ; m_nFlatVertPos = 0 ; m_bSpecialTrim = false ; m_bTrimWithOutline = false ; m_bUseUAttr = false ; m_BoxCol = Color( 255, 128, 0, 15) ; m_OutsCol = Color( 224, 128, 0, 50) ; m_ProcsCol = Color( 80, 160, 160, 100) ; m_ProcsOffCol = Color( 160, 160, 160, 30) ; m_MarkCol = Color( 96, 192, 192, 100) ; m_SolidCol = Color(255, 160, 32, 100) ; m_nInfoId = GDB_ID_NULL ; m_nAsseId = GDB_ID_NULL ; m_nRawPartsId = GDB_ID_NULL ; m_nCompositesId = GDB_ID_NULL ; m_ptOrig = ORIG ; m_nPartId = GDB_ID_NULL ; m_nAuxId = GDB_ID_NULL ; m_nBoxId = GDB_ID_NULL ; m_nOutsId = GDB_ID_NULL ; m_nProcsId = GDB_ID_NULL ; m_nSolidsId = GDB_ID_NULL ; m_vtDim = V_NULL ; m_nCount = 0 ; } //---------------------------------------------------------------------------- bool BtlGeom::Init( IGeomDB* pGDB, int nFlatVertPos, bool bSpecialTrim, bool bTrimWithOutline, bool bUseUAttr) { // salvo puntatore a DB geometrico m_pGDB = pGDB ; if ( m_pGDB == nullptr) return false ; // salvo i flag m_nFlatVertPos = nFlatVertPos ; m_bSpecialTrim = bSpecialTrim ; m_bTrimWithOutline = bTrimWithOutline ; m_bUseUAttr = bUseUAttr ; // se non esiste, creo gruppo per informazioni varie m_nInfoId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, INFO_GROUP_NAME) ; if ( m_nInfoId == GDB_ID_NULL && ! CreateInfoGroup()) return false ; // se non esiste, creo gruppo per assemblaggio m_nAsseId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, ASSEMBLY_GROUP_NAME) ; if ( m_nAsseId == GDB_ID_NULL && ! CreateAssemblyGroup()) return false ; // recupero eventuali riferimenti a gruppi per grezzi e compositi m_nRawPartsId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, RAWPARTS_GROUP_NAME) ; m_nCompositesId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, COMPOSITES_GROUP_NAME) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::CreateInfoGroup( void) { // creo il gruppo sotto la radice m_nInfoId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ; if ( m_nInfoId == GDB_ID_NULL) return false ; // assegno livello di sistema m_pGDB->SetLevel( m_nInfoId, GDB_LV_SYSTEM) ; // assegno nome m_pGDB->SetName( m_nInfoId, INFO_GROUP_NAME) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::CreateAssemblyGroup( void) { // creo il gruppo sotto la radice m_nAsseId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ; if ( m_nAsseId == GDB_ID_NULL) return false ; // assegno livello di sistema m_pGDB->SetLevel( m_nAsseId, GDB_LV_SYSTEM) ; // assegno nome m_pGDB->SetName( m_nAsseId, ASSEMBLY_GROUP_NAME) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::CreatePart( void) { // reset identificativi del pezzo precedente m_nPartId = GDB_ID_NULL ; m_nAuxId = GDB_ID_NULL ; m_nBoxId = GDB_ID_NULL ; m_nOutsId = GDB_ID_NULL ; m_nProcsId = GDB_ID_NULL ; m_nSolidsId = GDB_ID_NULL ; // default m_vtDim = V_NULL ; m_nCount = 1 ; // creazione nuovo pezzo int nPartId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d( m_ptOrig)) ; if ( nPartId == GDB_ID_NULL) return false ; // creo il layer ausiliario (per nome) int nAuxId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; if ( nAuxId == GDB_ID_NULL) return false ; m_pGDB->SetName( nAuxId, AUX_LAYER_NAME) ; m_pGDB->SetMaterial( nAuxId, BLACK) ; // creo il layer per il box (parallelepipedo) int nBoxId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; if ( nBoxId == GDB_ID_NULL) return false ; m_pGDB->SetName( nBoxId, BOX_LAYER_NAME) ; m_pGDB->SetMaterial( nBoxId, m_BoxCol) ; // creo il layer per l'outline (eventuali contorni) int nOutsId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; if ( nOutsId == GDB_ID_NULL) return false ; m_pGDB->SetName( nOutsId, OUTLINE_LAYER_NAME) ; m_pGDB->SetMaterial( nOutsId, m_OutsCol) ; // creo il layer per le lavorazioni (features o processings) int nProcsId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; if ( nProcsId == GDB_ID_NULL) return false ; m_pGDB->SetName( nProcsId, PROCESSINGS_LAYER_NAME) ; m_pGDB->SetMaterial( nProcsId, m_ProcsCol) ; // creo il layer per il solido int nSolidsId = m_pGDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ; if ( nSolidsId == GDB_ID_NULL) return false ; m_pGDB->SetName( nSolidsId, SOLID_LAYER_NAME) ; m_pGDB->SetMaterial( nSolidsId, m_SolidCol) ; // assegnazione identificativi m_nPartId = nPartId ; m_nAuxId = nAuxId ; m_nBoxId = nBoxId ; m_nOutsId = nOutsId ; m_nProcsId = nProcsId ; m_nSolidsId = nSolidsId ; // sistemazioni finali per il solido return ResetPartSolid() ; } //---------------------------------------------------------------------------- bool BtlGeom::SetPart( int nPartId) { // se non c'è il DB geometrico, errore if ( m_pGDB == nullptr) return false ; // verifico sia un pezzo valido if ( m_pGDB->GetGdbType( nPartId) != GDB_TY_GROUP) return false ; int nParentId = m_pGDB->GetParentId( nPartId) ; if ( nParentId != GDB_ID_ROOT) { int nParentLev ; if ( ! m_pGDB->GetCalcLevel( nParentId, nParentLev) || nParentLev != GDB_LV_SYSTEM) return false ; } int nAuxId = m_pGDB->GetFirstNameInGroup( nPartId, AUX_LAYER_NAME) ; if ( nAuxId == GDB_ID_NULL) return false ; int nBoxId = m_pGDB->GetFirstNameInGroup( nPartId, BOX_LAYER_NAME) ; if ( nBoxId == GDB_ID_NULL) return false ; int nOutsId = m_pGDB->GetFirstNameInGroup( nPartId, OUTLINE_LAYER_NAME) ; if ( nOutsId == GDB_ID_NULL) return false ; int nProcsId = m_pGDB->GetFirstNameInGroup( nPartId, PROCESSINGS_LAYER_NAME) ; if ( nProcsId == GDB_ID_NULL) return false ; int nSolidsId = m_pGDB->GetFirstNameInGroup( nPartId, SOLID_LAYER_NAME) ; if ( nSolidsId == GDB_ID_NULL) { // nei vecchi progetti può non esserci, quindi lo creo int nOldPartId = m_nPartId ; int nOldSolidsId = m_nSolidsId ; m_nPartId = nPartId ; if ( ! ResetPartSolid()) { m_nPartId = nOldPartId ; m_nSolidsId = nOldSolidsId ; return false ; } nSolidsId = m_nSolidsId ; } // assegnazione identificativi m_nPartId = nPartId ; m_nAuxId = nAuxId ; m_nBoxId = nBoxId ; m_nOutsId = nOutsId ; m_nProcsId = nProcsId ; m_nSolidsId = nSolidsId ; // recupero dati double dLength, dHeight, dWidth ; if ( m_pGDB->GetInfo( m_nPartId, IKEY_LENGTH, dLength) && m_pGDB->GetInfo( m_nPartId, IKEY_HEIGHT, dHeight) && m_pGDB->GetInfo( m_nPartId, IKEY_WIDTH, dWidth)) m_vtDim.Set( dLength, dHeight, dWidth) ; else m_vtDim = V_NULL ; int nCount ; if ( m_pGDB->GetInfo( m_nPartId, IKEY_COUNT, nCount)) m_nCount = nCount ; else m_nCount = 1 ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::ErasePart( void) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return false ; // rimuovo eventuali riferimenti e copie nell'assemblato int nAsseBaseRefId = GDB_ID_NULL ; if ( m_pGDB->GetInfo( m_nPartId, GDB_SI_LIST, nAsseBaseRefId)) { m_pGDB->Erase( nAsseBaseRefId) ; int nInd = 1 ; int nSouPartId = GDB_ID_NULL ; while ( m_pGDB->GetInfo( nAsseBaseRefId + nInd, GDB_SI_SOURCE, nSouPartId) && nSouPartId == m_nPartId) { m_pGDB->Erase( nAsseBaseRefId + nInd) ; ++ nInd ; } } // cancello il pezzo m_pGDB->Erase( m_nPartId) ; // annullo tutti gli identificativi del pezzo m_nPartId = GDB_ID_NULL ; m_nAuxId = GDB_ID_NULL ; m_nBoxId = GDB_ID_NULL ; m_nOutsId = GDB_ID_NULL ; m_nProcsId = GDB_ID_NULL ; m_nSolidsId = GDB_ID_NULL ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::VerifyNewPartProdNbr( int nProdNbr) { // se non c'è il DB geometrico, errore if ( m_pGDB == nullptr) return false ; // ciclo su tutti i pezzi int nPartId = m_pGDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && nLev == GDB_LV_USER) { int nSN = -1 ; // se SN richiesto già esiste, esco con errore if ( m_pGDB->GetInfo( nPartId, IKEY_PROD_NBR, nSN) && nSN >= 0 && nProdNbr == nSN) return false ; } nPartId = m_pGDB->GetNextGroup( nPartId) ; } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::SetPartProdNbr( int nProdNbr, int nPdnErr) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return false ; // assegno il numero di produzione del pezzo if ( ! m_pGDB->SetInfo( m_nPartId, IKEY_PROD_NBR, nProdNbr)) return false ; // se è correzione if ( nPdnErr >= 0) m_pGDB->SetInfo( m_nPartId, IKEY_PDN_ERR, nPdnErr) ; // costruisco il nome del pezzo string sName = ToString( nProdNbr) ; if ( nPdnErr >= 0) sName += "-X" ; string sDes ; if ( m_pGDB->GetInfo( m_nPartId, IKEY_NAME, sDes)) sName += "-" + sDes ; // assegnazione del nome al pezzo return m_pGDB->SetName( m_nPartId, sName) ; } //---------------------------------------------------------------------------- bool BtlGeom::SetPartName( const string& sDes) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return false ; // assegno la descrizione if ( ! m_pGDB->SetInfo( m_nPartId, IKEY_NAME, sDes)) return false ; // costruisco il nome del pezzo int nPdnErr = -1 ; m_pGDB->GetInfo( m_nPartId, IKEY_PDN_ERR, nPdnErr) ; int nProdNbr = 0 ; m_pGDB->GetInfo( m_nPartId, IKEY_PROD_NBR, nProdNbr) ; string sName = ToString( nProdNbr) ; if ( nPdnErr >= 0) sName += "-X" ; if ( ! sDes.empty()) sName += "-" + sDes ; // assegnazione del nome al pezzo return m_pGDB->SetName( m_nPartId, sName) ; } //---------------------------------------------------------------------------- string BtlGeom::GetPartName( void) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return "" ; string sName ; m_pGDB->GetName( m_nPartId, sName) ; return sName ; } //---------------------------------------------------------------------------- bool BtlGeom::SetPartCount( int nCount) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return false ; m_nCount = nCount ; return ( m_pGDB != nullptr && m_pGDB->SetInfo( m_nPartId, IKEY_COUNT, nCount)) ; } //---------------------------------------------------------------------------- bool BtlGeom::AddPartBox( double dLength, double dHeight, double dWidth) { // se non c'è il DB geometrico o il pezzo corrente, errore if ( m_pGDB == nullptr || m_nPartId == GDB_ID_NULL) return false ; // creo il solido (parallelepipedo) PtrOwner pStm( GetSurfTriMeshBox( dLength, dHeight, dWidth)) ; if ( IsNull( pStm)) return false ; // recupero eventuale box già presente int nOldId = m_pGDB->GetFirstNameInGroup( m_nBoxId, BOX_BOX_NAME) ; // se gia presente, lo rimpiazzo if ( nOldId != GDB_ID_NULL) { if ( ! m_pGDB->ReplaceGeoObj( nOldId, Release( pStm))) return false ; m_pGDB->SetMaterial( nOldId, m_BoxCol) ; } // altrimenti, lo inserisco nel layer box del pezzo else { int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nBoxId, Release( pStm)) ; if ( nId == GDB_ID_NULL) return false ; // assegno nome m_pGDB->SetName( nId, BOX_BOX_NAME) ; // assegno colore m_pGDB->SetMaterial( nId, m_BoxCol) ; } // salvo in info pezzo le sue dimensioni m_pGDB->SetInfo( m_nPartId, IKEY_LENGTH, dLength) ; m_pGDB->SetInfo( m_nPartId, IKEY_HEIGHT, dHeight) ; m_pGDB->SetInfo( m_nPartId, IKEY_WIDTH, dWidth) ; // imposto dimensioni pezzo corrente m_vtDim.Set( dLength, dHeight, dWidth) ; // se pezzo nuovo if ( nOldId == GDB_ID_NULL) { // imposto origine Frame3d* pRefGrp = m_pGDB->GetGroupFrame( m_nPartId) ; if ( pRefGrp != nullptr) *pRefGrp = Frame3d( m_ptOrig) ; // sistemo il posizionamento AdjustPartFlatOrVertPos() ; // aggiorno origine per prossimo pezzo switch ( m_nFlatVertPos) { case 0 : m_ptOrig.y += dHeight + PART_OFFSET ; break ; case 1 : case 4 : m_ptOrig.y += max( dHeight, dWidth) + PART_OFFSET ; break ; case 2 : m_ptOrig.y += min( dHeight, dWidth) + PART_OFFSET ; break ; case 3 : m_ptOrig.y += dWidth + PART_OFFSET ; break ; } } // scrittura del nome sulla superficie del box come testo del layer ausiliario string sName ; if ( ! m_pGDB->GetName( m_nPartId, sName) || sName.empty()) sName = "..." ; // aggiungo numero di pezzi da produrre sName += " - #" + ToString( m_nCount) ; // aggiungo dimensioni double dDim1 = dLength ; double dDim2 = max( dWidth, dHeight) ; double dDim3 = min( dWidth, dHeight) ; sName += "
(" + ToString( dDim1, 0) + "x" + ToString( dDim2, 0) + "x" + ToString( dDim3, 0) +")" ; PtrOwner pText( CreateExtText()) ; if ( IsNull( pText)) return false ; int nSide = BTL_SIDE_TOP ; if (( m_nFlatVertPos == 1 || m_nFlatVertPos == 4) && m_vtDim.z > m_vtDim.y + EPS_SMALL) nSide = BTL_SIDE_FRONT ; else if ( m_nFlatVertPos == 2 && m_vtDim.y < m_vtDim.z + EPS_SMALL) nSide = BTL_SIDE_FRONT ; else if ( m_nFlatVertPos == 3) nSide = BTL_SIDE_BACK ; double dSideLen = GetSideLength( nSide) ; double dSideWidth = GetSideWidth( nSide) ; double dTextHeight = 0.1 * min( dSideLen, dSideWidth) ; Point3d ptCen( 0.5 * dSideLen, 0.5 * dSideWidth, 0) ; if ( ! pText->Set( ptCen, Z_AX, X_AX, sName, "", 100, false, dTextHeight, 1, 0, ETXT_IPMC)) return false ; // eventuale scalatura del testo, se troppo grande BBox3d b3Text ; if ( pText->GetLocalBBox( b3Text)) { double dTextLen = b3Text.GetMax().x - b3Text.GetMin().x ; double dTextWidth = b3Text.GetMax().y - b3Text.GetMin().y ; if ( dTextLen > 0.5 * dSideLen || dTextWidth > 0.5 * dSideWidth) { double dCoeff = min( 0.5 * dSideLen / dTextLen, 0.5 * dSideWidth / dTextWidth) ; pText->Scale( Frame3d( ptCen), dCoeff, dCoeff, dCoeff) ; } } // porto il testo nel piano della faccia Frame3d frRef = GetSideFrame( nSide) ; pText->ToGlob( frRef) ; // recupero eventuale nome già presente int nOldTextId = m_pGDB->GetFirstNameInGroup( m_nAuxId, AUX_PART_NAME) ; // se gia presente, lo rimpiazzo if ( nOldTextId != GDB_ID_NULL) { if ( ! m_pGDB->ReplaceGeoObj( nOldTextId, Release( pText))) return false ; } // altrimenti, lo inserisco else { int nTextId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nAuxId, Release( pText)) ; if ( nTextId == GDB_ID_NULL) return false ; // assegno nome m_pGDB->SetName( nTextId, AUX_PART_NAME) ; } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustPartFlatOrVertPos( void) { // determino come modificare la posizione if ( m_nFlatVertPos == 0) return true ; // recupero il box del pezzo BBox3d b3Part ; int nBoxId = m_pGDB->GetFirstNameInGroup( m_nPartId, BOX_LAYER_NAME) ; if ( nBoxId == GDB_ID_NULL || ! m_pGDB->GetGlobalBBox( nBoxId, b3Part)) return false ; // dimensioni pezzo Vector3d vtDim = b3Part.GetMax() - b3Part.GetMin() ; // se richiesto piatto ed è in verticale, ruoto if (( m_nFlatVertPos == 1 || m_nFlatVertPos == 4) && vtDim.z > vtDim.y + EPS_SMALL) { Point3d ptAx = b3Part.GetMin() + 0.5 * Vector3d( 0, vtDim.y, vtDim.y) ; m_pGDB->RotateGlob( m_nPartId, ptAx, X_AX, 0, -1) ; } // se richiesto in verticale ed è piatto, ruoto else if ( m_nFlatVertPos == 2 && vtDim.y > vtDim.z + EPS_SMALL) { Point3d ptAx = b3Part.GetMin() + 0.5 * Vector3d( 0, vtDim.z, vtDim.z) ; m_pGDB->RotateGlob( m_nPartId, ptAx, X_AX, 0, 1) ; } // se richiesto come TechnoEssetre devo sempre ruotare di 90deg else if (m_nFlatVertPos == 3) { Point3d ptAx = b3Part.GetMin() + 0.5 * Vector3d( 0, vtDim.z, vtDim.z) ; m_pGDB->RotateGlob( m_nPartId, ptAx, X_AX, 0, 1) ; } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::ReadUserAttribute( const string& sString, string& sKey, string& sVal) { // recupero chiave e valore SplitFirst( sString, ":", sKey, sVal) ; // elimino i doppi apici Trim( sKey, " \"") ; Trim( sVal, " \"") ; // verifico return ( ! IsEmptyOrSpaces( sKey)) ; } //---------------------------------------------------------------------------- bool BtlGeom::SetUserAttribute( int nUAttrDest, const string& sString) { // se non c'è il DB geometrico, errore if ( m_pGDB == nullptr) return false ; // recupero chiave e valore string sKey, sVal ; if ( ! ReadUserAttribute( sString, sKey, sVal)) return false ; // li assegno if ( nUAttrDest == UATD_PART) return ( m_pGDB->SetInfo( m_nPartId, sKey, sVal)) ; else return ( m_pGDB->SetInfo( m_nInfoId, sKey, sVal)) ; } //---------------------------------------------------------------------------- bool BtlGeom::SetUserAttribute( int nUAttrDest, const string& sKey, const string& sVal) { // se non c'è il DB geometrico, errore if ( m_pGDB == nullptr) return false ; // li assegno if ( nUAttrDest == UATD_PART) return ( m_pGDB->SetInfo( m_nPartId, sKey, sVal)) ; else return ( m_pGDB->SetInfo( m_nInfoId, sKey, sVal)) ; } //---------------------------------------------------------------------------- bool BtlGeom::AddPartTransformation( const string& sUID, const Frame3d& frRef) { // creo un nuovo gruppo nell'assemblaggio int nId = m_pGDB->AddGroup( GDB_ID_NULL, m_nAsseId, frRef) ; if ( nId == GDB_ID_NULL) return false ; // assegno Nome con UID m_pGDB->SetName( nId, "UID-" + sUID) ; // assegno Id pezzo istanziato m_pGDB->SetInfo( nId, GDB_SI_SOURCE, m_nPartId) ; // nascondo e blocco m_pGDB->SetStatus( nId, GDB_ST_OFF) ; m_pGDB->SetMode( nId, GDB_MD_LOCKED) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::AddObjectRef( const string& sUID, const Frame3d& frRef) { // creo un nuovo gruppo nel pezzo int nId = m_pGDB->AddGroup( GDB_ID_NULL, m_nPartId, frRef) ; if ( nId == GDB_ID_NULL) return false ; // assegno Nome con UID m_pGDB->SetName( nId, "UID-" + sUID) ; // non posso ancora assegnare Id pezzo istanziato // nascondo e blocco m_pGDB->SetStatus( nId, GDB_ST_OFF) ; m_pGDB->SetMode( nId, GDB_MD_LOCKED) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::ResetPartSolid( void) { if ( m_pGDB == nullptr) return false ; if ( m_nPartId == GDB_ID_NULL) return false ; if ( ! m_pGDB->ExistsObj( m_nSolidsId)) { int nSolidsId = m_pGDB->AddGroup( GDB_ID_NULL, m_nPartId, Frame3d()) ; if ( nSolidsId == GDB_ID_NULL) return false ; m_pGDB->SetName( nSolidsId, SOLID_LAYER_NAME) ; m_pGDB->SetMaterial( nSolidsId, m_SolidCol) ; m_nSolidsId = nSolidsId ; } int nSolidId = m_pGDB->GetFirstNameInGroup( m_nSolidsId, SOLID_SOLID_NAME) ; PtrOwner pStm( CreateSurfTriMesh()) ; if ( IsNull( pStm) || ! pStm->Init( 3, 1) || ! pStm->AdjustTopology()) return false ; if ( nSolidId != GDB_ID_NULL) { if ( ! m_pGDB->ReplaceGeoObj( nSolidId, Release( pStm))) return false ; m_pGDB->RemoveInfo( nSolidId, IKEY_VALID) ; } else { int nNewId = m_pGDB->AddGeoObj( GDB_ID_NULL, m_nSolidsId, Release( pStm)) ; if ( nNewId == GDB_ID_NULL) return false ; m_pGDB->SetName( nNewId, SOLID_SOLID_NAME) ; } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::IsTrueSide( int nSide) const { return ( nSide >= BTL_SIDE_FRONT && nSide <= BTL_SIDE_TOP) ; } //---------------------------------------------------------------------------- string BtlGeom::GetOutlineOutName( int nSide) const { return ( ToString( nSide) + "-" + OL_OUTSTM_NAME) ; } //---------------------------------------------------------------------------- string BtlGeom::GetOutlineApertureName( int nSide) const { return ( ToString( nSide) + "-" + OL_APERTURESTM_NAME) ; } //---------------------------------------------------------------------------- string BtlGeom::GetOutlineTopName( int nSide) const { return ( ToString( nSide) + "-" + OL_TOPREGION_NAME) ; } //---------------------------------------------------------------------------- string BtlGeom::GetOutlineBottomName( int nSide) const { return ( ToString( nSide) + "-" + OL_BOTTOMREGION_NAME) ; } //---------------------------------------------------------------------------- double BtlGeom::GetSideLength( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : case BTL_SIDE_BACK : case BTL_SIDE_TOP : case BTL_SIDE_BOTTOM : return m_vtDim.x ; case BTL_SIDE_LEFT : case BTL_SIDE_RIGHT : return m_vtDim.z ; } return 0 ; } //---------------------------------------------------------------------------- double BtlGeom::GetSideWidth( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : case BTL_SIDE_BACK : return m_vtDim.z ; case BTL_SIDE_TOP : case BTL_SIDE_BOTTOM : case BTL_SIDE_LEFT : case BTL_SIDE_RIGHT : return m_vtDim.y ; } return 0 ; } //---------------------------------------------------------------------------- double BtlGeom::GetSideHeight( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : case BTL_SIDE_BACK : return m_vtDim.y ; case BTL_SIDE_TOP : case BTL_SIDE_BOTTOM : return m_vtDim.z ; case BTL_SIDE_LEFT : case BTL_SIDE_RIGHT : return m_vtDim.x ; } return 0 ; } //---------------------------------------------------------------------------- Frame3d BtlGeom::GetSideFrame( int nSide) const { Frame3d frRef ; switch ( nSide) { case BTL_SIDE_FRONT : frRef.Set( Point3d( 0, 0, 0), X_AX, Z_AX, -Y_AX) ; break ; case BTL_SIDE_BOTTOM : frRef.Set( Point3d( 0, m_vtDim.y, 0), X_AX, -Y_AX, -Z_AX) ; break ; case BTL_SIDE_BACK : frRef.Set( Point3d( 0, m_vtDim.y, m_vtDim.z), X_AX, -Z_AX, Y_AX) ; break ; case BTL_SIDE_TOP : frRef.Set( Point3d( 0, 0, m_vtDim.z), X_AX, Y_AX, Z_AX) ; break ; case BTL_SIDE_LEFT : frRef.Set( Point3d( 0, 0, 0), Z_AX, Y_AX, -X_AX) ; break ; case BTL_SIDE_RIGHT : frRef.Set( Point3d( m_vtDim.x, m_vtDim.y, 0), Z_AX, -Y_AX, X_AX) ; break ; } return frRef ; } //---------------------------------------------------------------------------- Plane3d BtlGeom::GetSidePlane( int nSide) const { Plane3d plPlane ; switch ( nSide) { case BTL_SIDE_FRONT : plPlane.Set( 0, -Y_AX) ; break ; case BTL_SIDE_BOTTOM : plPlane.Set( 0, -Z_AX) ; break ; case BTL_SIDE_BACK : plPlane.Set( m_vtDim.y, Y_AX) ; break ; case BTL_SIDE_TOP : plPlane.Set( m_vtDim.z, Z_AX) ; break ; case BTL_SIDE_LEFT : plPlane.Set( 0, -X_AX) ; break ; case BTL_SIDE_RIGHT : plPlane.Set( m_vtDim.x, X_AX) ; break ; default : plPlane.Reset() ; break ; } return plPlane ; } //---------------------------------------------------------------------------- Vector3d BtlGeom::GetSideVersN( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : return - Y_AX ; case BTL_SIDE_BOTTOM : return - Z_AX ; case BTL_SIDE_BACK : return Y_AX ; case BTL_SIDE_TOP : return Z_AX ; case BTL_SIDE_LEFT : return - X_AX ; case BTL_SIDE_RIGHT : return X_AX ; } return V_NULL ; } //---------------------------------------------------------------------------- int BtlGeom::GetOppositeSide( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : return BTL_SIDE_BACK ; case BTL_SIDE_TOP : return BTL_SIDE_BOTTOM ; case BTL_SIDE_BACK : return BTL_SIDE_FRONT ; case BTL_SIDE_BOTTOM : return BTL_SIDE_TOP ; case BTL_SIDE_LEFT : return BTL_SIDE_RIGHT ; case BTL_SIDE_RIGHT : return BTL_SIDE_LEFT ; } return BTL_SIDE_NONE ; } //---------------------------------------------------------------------------- bool BtlGeom::SetAlpha( int nId, int nAlpha) { Color cCol ; if ( ! m_pGDB->GetCalcMaterial( nId, cCol)) return false ; if ( nAlpha < ALPHA_LIM) m_pGDB->SetInfo( nId, IKEY_COL_A, nAlpha) ; else m_pGDB->RemoveInfo( nId, IKEY_COL_A) ; cCol.SetAlpha( nAlpha) ; return m_pGDB->SetMaterial( nId, cCol) ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustSnForParts( void) { // tabella Id-SN dei pezzi e massimo SN trovato INTINTVECTOR vIdSN ; int nMaxSN = 0 ; // recupero il numero di serie di ogni singolo pezzo int nPartId = m_pGDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && nLev == GDB_LV_USER) { int nSN = 0 ; m_pGDB->GetInfo( nPartId, IKEY_PROD_NBR, nSN) ; if ( nSN <= 0) nSN = 0 ; else if ( find_if( vIdSN.begin(), vIdSN.end(), [&]( const INTINT& Data) { return Data.second == nSN ; }) != vIdSN.end()) nSN = -abs( nSN) ; vIdSN.emplace_back( nPartId, nSN) ; nMaxSN = max( nMaxSN, nSN) ; } nPartId = m_pGDB->GetNextGroup( nPartId) ; } // aggiusto tutti gli SN nulli o negativi (derivano da mancanti o ripetuti) for ( auto& Data : vIdSN) { if ( Data.second <= 0) { SetPart( Data.first) ; SetPartProdNbr( ++ nMaxSN, -Data.second) ; AddPartBox( GetCurrPartLength(), GetCurrPartHeight(), GetCurrPartWidth()) ; Data.second = nMaxSN ; } } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::SortObjects( int nGroupId, Point3d& ptIns) { // verifico gruppo if ( nGroupId == GDB_ID_NULL || ! m_pGDB->ExistsObj( nGroupId)) return true ; // tabella Id-SN dei pezzi INTINTVECTOR vIdSN ; // recupero il numero di serie di ogni singolo pezzo int nPartId = m_pGDB->GetFirstGroupInGroup( nGroupId) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && ( nLev == GDB_LV_USER || nGroupId != GDB_ID_ROOT)) { int nSN = 0 ; m_pGDB->GetInfo( nPartId, IKEY_PROD_NBR, nSN) ; vIdSN.emplace_back( nPartId, nSN) ; } nPartId = m_pGDB->GetNextGroup( nPartId) ; } // ordino la tabella secondo SN sort( vIdSN.begin(), vIdSN.end(), []( const INTINT& a, const INTINT& b) { return a.second < b.second ; }) ; // cambio posizione dei pezzi nel DB come da ordine in tabella for ( int i = 0 ; i < int( vIdSN.size()) ; ++ i) { m_pGDB->Relocate( vIdSN[i].first, nGroupId, GDB_LAST_SON) ; BBox3d b3Part ; int nBoxId = m_pGDB->GetFirstNameInGroup( vIdSN[i].first, BOX_LAYER_NAME) ; m_pGDB->GetGlobalBBox( nBoxId, b3Part) ; m_pGDB->Translate( vIdSN[i].first, ptIns - b3Part.GetMin()) ; ptIns += Vector3d( 0, b3Part.GetMax().y - b3Part.GetMin().y + PART_OFFSET, 0) ; } return true ; } //---------------------------------------------------------------------------- bool BtlGeom::UpdateNextOrigin( void) { // ricerco il pezzo più lontano double dMaxY = 0 ; int nMaxPartId = GDB_ID_NULL ; int nPartId = m_pGDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && nLev == GDB_LV_USER) { // recupero il box del pezzo BBox3d b3Part ; int nBoxId = m_pGDB->GetFirstNameInGroup( m_pGDB->GetFirstNameInGroup( nPartId, BOX_LAYER_NAME), BOX_BOX_NAME) ; if ( nBoxId != GDB_ID_NULL) m_pGDB->GetGlobalBBox( nBoxId, b3Part, BBF_STANDARD) ; else m_pGDB->GetGlobalBBox( nPartId, b3Part, BBF_STANDARD) ; if ( ! b3Part.IsEmpty()) { if ( nMaxPartId == GDB_ID_NULL || b3Part.GetMax().y > dMaxY) { dMaxY = b3Part.GetMax().y ; nMaxPartId = nPartId ; } } } nPartId = m_pGDB->GetNextGroup( nPartId) ; } // aggiorno l'origine per il prossimo inserimento if ( nMaxPartId != GDB_ID_NULL) { // assegno la nuova origine m_ptOrig = ORIG ; m_ptOrig.y = dMaxY + PART_OFFSET ; } return true ; } //---------------------------------------------------------------------------- int BtlGeom::GetRawPartsGroup( bool bCreate) { // se non necessaria creazione ritorno quello che trovo if ( ! bCreate || m_nRawPartsId != GDB_ID_NULL) return m_nRawPartsId ; // creo il gruppo CreateRawPartsGroup() ; return m_nRawPartsId ; } //---------------------------------------------------------------------------- bool BtlGeom::CreateRawPartsGroup( void) { // se già definito, non faccio alcunchè m_nRawPartsId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, RAWPARTS_GROUP_NAME) ; if ( m_nRawPartsId != GDB_ID_NULL) return true ; // creo il gruppo sotto la radice m_nRawPartsId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ; if ( m_nRawPartsId == GDB_ID_NULL) return false ; // assegno livello di sistema m_pGDB->SetLevel( m_nRawPartsId, GDB_LV_SYSTEM) ; // assegno nome m_pGDB->SetName( m_nRawPartsId, RAWPARTS_GROUP_NAME) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustRawPart( int nRawPartId) { // verifico validità pezzo if ( nRawPartId == GDB_ID_NULL || ! m_pGDB->ExistsObj( nRawPartId)) return false ; // cerco il gruppo dei grezzi in cui spostarlo int nRpsGroupId = GetRawPartsGroup( true) ; if ( nRpsGroupId == GDB_ID_NULL) return false ; // lo sposto e lo nascondo return m_pGDB->Relocate( nRawPartId, nRpsGroupId) && m_pGDB->SetStatus( nRawPartId, GDB_ST_OFF) ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustRefForRawParts( void) { // verifico esistenza gruppo dei grezzi int nRpsGroupId = GetRawPartsGroup() ; if ( nRpsGroupId == GDB_ID_NULL) return true ; // tabella Id-UID dei pezzi std::unordered_map< int, int> umUIDId ; int nPartId = m_pGDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && nLev == GDB_LV_USER) { for ( int i = 1 ; ; ++ i) { int nUID ; string sUIDKey = "UID" + ToString( i) ; if ( ! m_pGDB->GetInfo( nPartId, sUIDKey, nUID)) break ; umUIDId.emplace( nUID, nPartId) ; } } nPartId = m_pGDB->GetNextGroup( nPartId) ; } // assegno riferimenti nei grezzi int nRawPartId = m_pGDB->GetFirstGroupInGroup( nRpsGroupId) ; while ( nRawPartId != GDB_ID_NULL) { int nRefId = m_pGDB->GetFirstNameInGroup( nRawPartId, "UID-*") ; while ( nRefId != GDB_ID_NULL) { string sName ; m_pGDB->GetName( nRefId, sName) ; int nUID ; if ( FromString( sName.substr( 4), nUID)) { auto Iter = umUIDId.find( nUID) ; if ( Iter != umUIDId.end()) m_pGDB->SetInfo( nRefId, GDB_SI_SOURCE, Iter->second) ; } nRefId = m_pGDB->GetNextName( nRefId, "UID-*") ; } nRawPartId = m_pGDB->GetNextGroup( nRawPartId) ; } return true ; } //---------------------------------------------------------------------------- int BtlGeom::GetCompositesGroup( bool bCreate) { // se non necessaria creazione ritorno quello che trovo if ( ! bCreate || m_nCompositesId != GDB_ID_NULL) return m_nCompositesId ; // creo il gruppo CreateCompositesGroup() ; return m_nCompositesId ; } //---------------------------------------------------------------------------- bool BtlGeom::CreateCompositesGroup( void) { // se già definito, non faccio alcunchè m_nCompositesId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, COMPOSITES_GROUP_NAME) ; if ( m_nCompositesId != GDB_ID_NULL) return true ; // creo il gruppo sotto la radice m_nCompositesId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ; if ( m_nCompositesId == GDB_ID_NULL) return false ; // assegno livello di sistema m_pGDB->SetLevel( m_nCompositesId, GDB_LV_SYSTEM) ; // assegno nome m_pGDB->SetName( m_nCompositesId, COMPOSITES_GROUP_NAME) ; return true ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustComposite( int nCompositeId) { // verifico validità pezzo if ( nCompositeId == GDB_ID_NULL || ! m_pGDB->ExistsObj( nCompositeId)) return false ; // cerco il gruppo dei compositi in cui spostarlo int nCmpGroupId = GetCompositesGroup( true) ; if ( nCmpGroupId == GDB_ID_NULL) return false ; // lo sposto e lo nascondo return m_pGDB->Relocate( nCompositeId, nCmpGroupId) && m_pGDB->SetStatus( nCompositeId, GDB_ST_OFF) ; } //---------------------------------------------------------------------------- bool BtlGeom::AdjustRefForComposites( void) { // verifico esistenza gruppo dei compositi int nCmpsGroupId = GetCompositesGroup() ; if ( nCmpsGroupId == GDB_ID_NULL) return true ; // tabella Id-UID dei pezzi e dei compositi std::unordered_map< int, int> umUIDId ; int nPartId = m_pGDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; while ( nPartId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nPartId, nLev) && nLev == GDB_LV_USER) { for ( int i = 1 ; ; ++ i) { int nUID ; string sUIDKey = "UID" + ToString( i) ; if ( ! m_pGDB->GetInfo( nPartId, sUIDKey, nUID)) break ; umUIDId.emplace( nUID, nPartId) ; } } nPartId = m_pGDB->GetNextGroup( nPartId) ; } int nCompoId = m_pGDB->GetFirstGroupInGroup( nCmpsGroupId) ; while ( nCompoId != GDB_ID_NULL) { int nLev ; if ( m_pGDB->GetCalcLevel( nCompoId, nLev) && nLev != GDB_LV_USER) { for ( int i = 1 ; ; ++ i) { int nUID ; string sUIDKey = "UID" + ToString( i) ; if ( ! m_pGDB->GetInfo( nCompoId, sUIDKey, nUID)) break ; umUIDId.emplace( nUID, nCompoId) ; } } nCompoId = m_pGDB->GetNextGroup( nCompoId) ; } // assegno riferimenti nei compositi int nCompositeId = m_pGDB->GetFirstGroupInGroup( nCmpsGroupId) ; while ( nCompositeId != GDB_ID_NULL) { int nRefId = m_pGDB->GetFirstNameInGroup( nCompositeId, "UID-*") ; while ( nRefId != GDB_ID_NULL) { string sName ; m_pGDB->GetName( nRefId, sName) ; int nUID ; if ( FromString( sName.substr( 4), nUID)) { auto Iter = umUIDId.find( nUID) ; if ( Iter != umUIDId.end()) m_pGDB->SetInfo( nRefId, GDB_SI_SOURCE, Iter->second) ; } nRefId = m_pGDB->GetNextName( nRefId, "UID-*") ; } nCompositeId = m_pGDB->GetNextGroup( nCompositeId) ; } return true ; }