//---------------------------------------------------------------------------- // 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" using namespace std ; //---------------------------------------------------------------------------- BtlGeom::BtlGeom( void) { m_pGDB = nullptr ; m_nFlatVertPos = false ; m_bSpecialTrim = 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, 100) ; 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_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 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_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 ; 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 || m_pGDB->GetParentId( nPartId) != GDB_ID_ROOT) 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 ; // 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::SetPartProdNbr( int nProdNbr) { // 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 ; string sName = ToString( nProdNbr) ; // 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 il nome del pezzo if ( ! m_pGDB->SetInfo( m_nPartId, IKEY_NAME, sDes)) return false ; int nProdNbr = 0 ; m_pGDB->GetInfo( m_nPartId, IKEY_PROD_NBR, nProdNbr) ; string sName = ToString( nProdNbr) ; 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 : 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_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 && 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( int nUID, 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-" + ToString( nUID)) ; // assegno Id pezzo istanziato m_pGDB->SetInfo( nId, "!SOU", m_nPartId) ; // 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_RIGHT : case BTL_SIDE_LEFT : return m_vtDim.y ; } return 0 ; } //---------------------------------------------------------------------------- double BtlGeom::GetSideWidth( int nSide) const { switch ( nSide) { case BTL_SIDE_FRONT : case BTL_SIDE_BACK : case BTL_SIDE_RIGHT : case BTL_SIDE_LEFT : return m_vtDim.z ; case BTL_SIDE_TOP : case BTL_SIDE_BOTTOM : 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_RIGHT : case BTL_SIDE_LEFT : 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_RIGHT : frRef.Set( Point3d( m_vtDim.x, 0, 0), Y_AX, Z_AX, X_AX) ; break ; case BTL_SIDE_LEFT : frRef.Set( Point3d( 0, m_vtDim.y, 0), - Y_AX, Z_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_RIGHT : plPlane.Set( m_vtDim.x, X_AX) ; break ; case BTL_SIDE_LEFT : plPlane.Set( 0, -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_RIGHT : return X_AX ; case BTL_SIDE_LEFT : 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_RIGHT : return BTL_SIDE_LEFT ; case BTL_SIDE_LEFT : return BTL_SIDE_RIGHT ; } return BTL_SIDE_NONE ; } //---------------------------------------------------------------------------- bool BtlGeom::SetAlpha( int nId, int nAlpha) { Color cCol ; if ( ! m_pGDB->GetCalcMaterial( nId, cCol)) return false ; cCol.SetAlpha( nAlpha) ; return m_pGDB->SetMaterial( nId, cCol) ; } //---------------------------------------------------------------------------- bool BtlGeom::SortParts( void) { // tabella Id-SN dei pezzi INTINTVECTOR vIdSN ; // 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) ; 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 Point3d ptIns ; for ( int i = 0 ; i < int( vIdSN.size()) ; ++ i) { m_pGDB->Relocate( vIdSN[i].first, GDB_ID_ROOT, 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 + 300, 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) { Frame3d* pRefGrp = m_pGDB->GetGroupFrame( nPartId) ; if ( pRefGrp != nullptr) { if ( pRefGrp->Orig().y > dMaxY) { dMaxY = pRefGrp->Orig().y ; nMaxPartId = nPartId ; } } } nPartId = m_pGDB->GetNextGroup( nPartId) ; } // aggiorno l'origine per il prossimo inserimento if ( nMaxPartId != GDB_ID_NULL) { // reset origine m_ptOrig = ORIG ; // recupero sezione del pezzo double dHeight = 0 ; m_pGDB->GetInfo( nPartId, IKEY_HEIGHT, dHeight) ; double dWidth = 0 ; m_pGDB->GetInfo( nPartId, IKEY_WIDTH, dWidth) ; // aggiorno origine per prossimo pezzo switch ( m_nFlatVertPos) { case 0 : m_ptOrig.y += dMaxY + dHeight + PART_OFFSET ; break ; case 1 : m_ptOrig.y += dMaxY + max( dHeight, dWidth) + PART_OFFSET ; break ; case 2 : m_ptOrig.y += dMaxY + min( dHeight, dWidth) + PART_OFFSET ; break ; case 3 : m_ptOrig.y += dMaxY + dWidth + PART_OFFSET ; break ; } } return true ; }