//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : MachMgr.cpp Data : 16.04.15 Versione : 1.6d3 // Contenuto : Implementazione gestione grezzi e pezzi della classe MachMgr. // // // // Modifiche : 16.04.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "DllMain.h" #include "MachMgr.h" #include "MachConst.h" #include "Disposition.h" #include "/EgtDev/Include/EMkMachiningGeoConst.h" #include "/EgtDev/Include/EXeCmdLogOff.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EGkStmFromCurves.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- int MachMgr::GetRawPartCount( void) const { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return 0 ; // ritorno numero dei grezzi della macchinata return m_pGeomDB->GetGroupObjs( nRawGroupId) ; } //---------------------------------------------------------------------------- int MachMgr::GetFirstRawPart( void) const { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero il primo sottogruppo int nId = m_pGeomDB->GetFirstGroupInGroup( nRawGroupId) ; return nId ; } //---------------------------------------------------------------------------- int MachMgr::GetNextRawPart( int nId) const { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // verifico che il gruppo ricevuto sia corretto if ( m_pGeomDB->GetParentId( nId) != nRawGroupId) return GDB_ID_NULL ; // recupero il successivo sottogruppo int nNextId = m_pGeomDB->GetNextGroup( nId) ; return nNextId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( const Point3d& ptOrig, double dLen, double dWidth, double dHeight, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // se definita una tavola corrente, esprimo il punto rispetto alla sua prima origine Point3d ptMyOrig = ptOrig ; Point3d ptRef1 ; if ( GetTableRef( 1, ptRef1)) ptMyOrig += ptRef1 ; // inserisco il gruppo del grezzo nei grezzi della macchinata int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, Frame3d( ptMyOrig)) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // assegno la fase al gruppo m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ; // creo solido e outline bOk = bOk && ModifyRawPart( nRawId, ptOrig, dLen, dWidth, dHeight, cCol) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // tutto ok return nRawId ; } //---------------------------------------------------------------------------- bool MachMgr::ModifyRawPart( int nRawId, const Point3d& ptOrig, double dLen, double dWidth, double dHeight, Color cCol) { // le dimensioni non possono essere nulle if ( dLen < EPS_SMALL || dWidth < EPS_SMALL || dHeight < EPS_SMALL) return false ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // creo il solido PtrOwner pStm( GetSurfTriMeshBox( dLen, dWidth, dHeight)) ; if ( IsNull( pStm)) return false ; // creo il contorno esterno PolyLine PL ; PL.AddUPoint( 0, ORIG) ; PL.AddUPoint( 1, Point3d( dLen, 0, 0)) ; PL.AddUPoint( 2, Point3d( dLen, dWidth, 0)) ; PL.AddUPoint( 3, Point3d( 0, dWidth, 0)) ; PL.AddUPoint( 4, ORIG) ; // creo la curva PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( PL) || ! pCrvCompo->SetExtrusion( Z_AX)) return false ; // cancello eventuali vecchi solidi e curve di outline int nOldRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nOldRawSolId != GDB_ID_NULL) m_pGeomDB->Erase( nOldRawSolId) ; int nOldRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ; if ( nOldRawOutId != GDB_ID_NULL) m_pGeomDB->Erase( nOldRawOutId) ; // se definita una tavola corrente, esprimo il punto rispetto alla sua prima origine Point3d ptMyOrig = ptOrig ; Point3d ptRef1 ; if ( GetTableRef( 1, ptRef1)) ptMyOrig += ptRef1 ; // aggiorno l'origine del gruppo m_pGeomDB->GetGroupFrame( nRawId)->ChangeOrig( ptMyOrig) ; // inserisco il solido nel gruppo int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ; bool bOk = ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // inserisco la curva composita nel DB int nCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) : GDB_ID_NULL) ; bOk = bOk && ( nCrvId != GDB_ID_NULL) ; // assegno il nome al contorno bOk = bOk && m_pGeomDB->SetName( nCrvId, MACH_RAW_OUTLINE) ; // assegno il colore al contorno bOk = bOk && m_pGeomDB->SetMaterial( nCrvId, cCol) ; return bOk ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPartWithPart( int nPartId, int nCrvSrfId, double dOverMat, Color cCol) { // verifico il gruppo dei grezzi nella macchinata corrente if ( GetCurrRawGroupId() == GDB_ID_NULL) return GDB_ID_NULL ; // verifico che il pezzo non sia già usato nella macchinata corrente if ( m_pGeomDB->GetParentId( nPartId) != GDB_ID_ROOT) return GDB_ID_NULL ; // recupero il tipo di oggetto per definire il grezzo int nGtype = m_pGeomDB->GetGeoType( nCrvSrfId) ; // punto di riferimento del pezzo nel grezzo Point3d ptRef ; // costruzione del grezzo int nRawId = GDB_ID_NULL ; // se grezzo da superficie (per ora senza possibilità di offset) if ( ( nGtype & GEO_SURF) != 0) { // inserisco il grezzo nRawId = AddRawPart( nCrvSrfId, cCol) ; // annullo il sovra-materiale dOverMat = 0 ; // calcolo il punto di inserimento nel grezzo // determino l'ingombro del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT)) return GDB_ID_NULL ; // recupero il box del solido del grezzo in globale int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; BBox3d b3RawSolid ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid)) return false ; // calcolo il punto di inserimento (come differenza tra i punti minimi) ptRef = b3Part.GetMin() + ( ORIG - b3RawSolid.GetMin()) ; } // se altrimenti grezzo da contorno else if ( ( nGtype & GEO_CURVE) != 0) { // determino l'ingombro del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT)) return GDB_ID_NULL ; // inserisco il grezzo double dZmin = b3Part.GetMin().z ; double dH = ( b3Part.GetMax() - b3Part.GetMin()).z ; if ( dH < RAW_MIN_H) dH = RAW_MIN_H ; nRawId = AddRawPart( nCrvSrfId, dOverMat, dZmin, dH, cCol) ; // calcolo il punto di inserimento nel grezzo // recupero il box del solido del grezzo in globale int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; BBox3d b3RawSolid ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid)) return false ; // calcolo il punto di inserimento (come differenza tra i punti minimi) ptRef = b3Part.GetMin() + ( ORIG - b3RawSolid.GetMin()) ; } // altrimenti grezzo rettangolare da ingombro pezzo else { // determino l'ingombro del pezzo BBox3d b3Part ; if ( ! m_pGeomDB->GetGlobalBBox( nPartId, b3Part, BBF_EXACT)) return GDB_ID_NULL ; // deduco i dati del grezzo b3Part.Expand( dOverMat, dOverMat, 0) ; Vector3d vtDiff = b3Part.GetMax() - b3Part.GetMin() ; if ( vtDiff.z < RAW_MIN_H) vtDiff.z = RAW_MIN_H ; // inserisco il grezzo nRawId = AddRawPart( ORIG, vtDiff.x, vtDiff.y, vtDiff.z, cCol) ; // il riferimento deve tenere conto dell'offset ptRef = Point3d( dOverMat, dOverMat, 0) ; } // verifico costruzione grezzo if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // se definita tavola, aggiusto posizione del grezzo Point3d ptTabRef ; if ( GetTableRef( 1, ptTabRef)) { // recupero box del solido int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; BBox3d b3RawSolid ; // lo porto nell'angolo in basso a sinistra della tavola if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3RawSolid)) m_pGeomDB->TranslateGlob( nRawId, ptTabRef - b3RawSolid.GetMin()) ; } // inserisco il pezzo nel grezzo if ( ! AddPartToRawPart( nPartId, ptRef, nRawId)) { RemoveRawPart( nRawId) ; return GDB_ID_NULL ; } return nRawId ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( int nCrvId, double dOverMat, double dZmin, double dHeight, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero l'ingombro della curva in globale BBox3d b3Crv ; if ( ! m_pGeomDB->GetGlobalBBox( nCrvId, b3Crv)) return GDB_ID_NULL ; // determino il riferimento del grezzo Point3d ptOrig = b3Crv.GetMin() ; ptOrig.z = dZmin ; Frame3d frRaw( ptOrig) ; // inserisco il gruppo del grezzo nella macchinata int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // assegno la fase al gruppo m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ; // creo solido e outline bOk = bOk && ModifyRawPart( nRawId, nCrvId, dOverMat, dZmin, dHeight, cCol) ; // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // tutto ok return nRawId ; } //---------------------------------------------------------------------------- bool MachMgr::ModifyRawPart( int nRawId, int nCrvId, double dOverMat, double dZmin, double dHeight, Color cCol) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il riferimento della curva Frame3d frCrv ; if ( ! m_pGeomDB->GetGlobFrame( nCrvId, frCrv)) return false ; // recupero la curva const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nCrvId)) ; if ( pCrv == nullptr) return false ; // copio la curva in una composita PtrOwner pMyCrv( CreateCurveComposite()) ; if ( IsNull( pMyCrv) || ! pMyCrv->AddCurve( *pCrv)) return false ; // determino il riferimento del grezzo Frame3d frRaw ; if ( ! m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw)) return false ; // porto la curva in questo riferimento pMyCrv->LocToLoc( frCrv, frRaw) ; // la schiaccio a Z = 0 if ( ! pMyCrv->Scale( Frame3d(), 1, 1, 0)) return false ; // se non è chiusa, la chiudo pMyCrv->Close() ; // la oriento in senso CCW double dAreaXY ; if ( ! pMyCrv->GetAreaXY( dAreaXY)) return false ; if ( dAreaXY < 0) pMyCrv->Invert() ; // ne eseguo l'offset OffsetCurve OffsCrv ; OffsCrv.Make( pMyCrv, dOverMat, ICurve::OFF_EXTEND) ; PtrOwner pOffsCrv( OffsCrv.GetLongerCurve()) ; if ( IsNull( pOffsCrv)) return false ; // creo il solido PtrOwner pStm( GetSurfTriMeshByExtrusion( pOffsCrv, Vector3d(0,0,dHeight), true)) ; if ( IsNull( pStm)) return false ; // cancello eventuali vecchi solidi e curve di outline int nOldRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nOldRawSolId != GDB_ID_NULL) m_pGeomDB->Erase( nOldRawSolId) ; int nOldRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ; if ( nOldRawOutId != GDB_ID_NULL) m_pGeomDB->Erase( nOldRawOutId) ; // inserisco il solido nel gruppo int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pStm)) ; bool bOk = ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // inserisco nel DB la curva di offset come contorno del grezzo int nOutCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pOffsCrv)) : GDB_ID_NULL) ; bOk = bOk && ( nOutCrvId != GDB_ID_NULL) ; // assegno il nome al contorno bOk = bOk && m_pGeomDB->SetName( nOutCrvId, MACH_RAW_OUTLINE) ; // assegno il colore al contorno bOk = bOk && m_pGeomDB->SetMaterial( nOutCrvId, cCol) ; return bOk ; } //---------------------------------------------------------------------------- int MachMgr::AddRawPart( int nSurfId, Color cCol) { // recupero il gruppo dei grezzi nella macchinata corrente int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId == GDB_ID_NULL) return GDB_ID_NULL ; // recupero l'ingombro della superficie in globale BBox3d b3Crv ; if ( ! m_pGeomDB->GetGlobalBBox( nSurfId, b3Crv)) return GDB_ID_NULL ; // inserisco il gruppo del grezzo nella macchinata Frame3d frRaw( b3Crv.GetMin()) ; int nRawId = m_pGeomDB->AddGroup( GDB_ID_NULL, nRawGroupId, frRaw) ; if ( nRawId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome al gruppo bool bOk = m_pGeomDB->SetName( nRawId, MACH_RAW_PART) ; // assegno la fase al gruppo m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, m_nCurrPhase) ; // copio la superficie nel gruppo int nId = m_pGeomDB->CopyGlob( nSurfId, GDB_ID_NULL, nRawId) ; bOk = bOk && ( nId != GDB_ID_NULL) ; // assegno il nome al solido bOk = bOk && m_pGeomDB->SetName( nId, MACH_RAW_SOLID) ; // assegno il colore al solido bOk = bOk && m_pGeomDB->SetMaterial( nId, cCol) ; // rendo visibile il solido bOk = bOk && m_pGeomDB->SetStatus( nId, GDB_ST_ON) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; // calcolo la curva di contorno if ( bOk) { // creo la curva PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo)) return GDB_ID_NULL ; // recupero la superficie trimesh ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nId)) ; if ( pStm == nullptr) return GDB_ID_NULL ; // recupero l'ingombro della superficie in locale BBox3d b3Srf ; pStm->GetLocalBBox( b3Srf) ; // ne calcolo la silhouette secondo Z+ POLYLINEVECTOR vPL ; bool bSilh = false ; if ( pStm->GetSilhouette( Z_AX, 10.0, vPL) && vPL.size() > 0) { // cerco il contorno esterno int nInd = - 1 ; double dMaxArea = 0 ; for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { double dArea ; if ( vPL[i].GetAreaXY( dArea) && abs( dArea) > dMaxArea) { if ( dArea < 0) vPL[i].Invert() ; dMaxArea = abs( dArea) ; nInd = i ; } } // ne deduco la curva PtrOwner pCrvSilh( CreateCurveComposite()) ; if ( nInd >= 0 && pCrvSilh->FromPolyLine( vPL[nInd])) { pCrvSilh->SetExtrusion( Z_AX) ; Plane3d plProj ; plProj.Set( b3Srf.GetMin(), Z_AX) ; pCrvCompo.Set( GetCurveComposite( ProjectCurveOnPlane( *pCrvSilh, plProj))) ; pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; bSilh = ( ! IsNull( pCrvCompo)) ; } } // non riuscita, la calcolo come contorno del box if ( ! bSilh) { Point3d ptMin ; double dDimX, dDimY, dDimZ ; b3Srf.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; PolyLine PL ; PL.AddUPoint( 0, ptMin) ; PL.AddUPoint( 1, ptMin + Vector3d( dDimX, 0,0)) ; PL.AddUPoint( 2, ptMin + Vector3d( dDimX, dDimY,0)) ; PL.AddUPoint( 3, ptMin + Vector3d( 0, dDimY,0)) ; PL.AddUPoint( 4, ptMin) ; if ( ! pCrvCompo->FromPolyLine( PL) && ! pCrvCompo->SetExtrusion( Z_AX)) bOk = false ; } // inserisco la curva composita nel DB int nCrvId = ( bOk ? m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pCrvCompo)) : GDB_ID_NULL) ; bOk = bOk && ( nCrvId != GDB_ID_NULL) ; // assegno il nome alla curva bOk = bOk && m_pGeomDB->SetName( nCrvId, MACH_RAW_SOLID) ; // assegno il colore alla curva bOk = bOk && m_pGeomDB->SetMaterial( nCrvId, cCol) ; } // se qualcosa è andato storto, cancello tutto if ( ! bOk) { m_pGeomDB->Erase( nRawId) ; return GDB_ID_NULL ; } // nascondo la superficie originale m_pGeomDB->SetStatus( nSurfId, GDB_ST_OFF) ; // tutto ok return nRawId ; } //---------------------------------------------------------------------------- bool MachMgr::ModifyRawPartSize( int nRawId, double dLength, double dWidth, double dHeight) { // le nuove dimensioni non possono essere nulle if ( dLength < EPS_SMALL || dWidth < EPS_SMALL || dHeight < EPS_SMALL) return false ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il solido del grezzo int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nRawSolId == GDB_ID_NULL) return false ; // recupero il contorno del grezzo int nRawOutId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ; if ( nRawOutId == GDB_ID_NULL) return false ; // recupero il box del grezzo BBox3d b3Raw ; if ( ! m_pGeomDB->GetLocalBBox( nRawSolId, b3Raw)) return false ; // determino il coefficente di scalatura in X double dOldL = b3Raw.GetMax().x - b3Raw.GetMin().x ; if ( dOldL < EPS_SMALL) return false ; double dCoeffX = dLength / dOldL ; // determino il coefficente di scalatura in Y double dOldW = b3Raw.GetMax().y - b3Raw.GetMin().y ; if ( dOldW < EPS_SMALL) return false ; double dCoeffY = dWidth / dOldW ; // determino il coefficente di scalatura in Z double dOldH = b3Raw.GetMax().z - b3Raw.GetMin().z ; if ( dOldH < EPS_SMALL) return false ; double dCoeffZ = dHeight / dOldH ; // eseguo scalature bool bOk = m_pGeomDB->Scale( nRawSolId, Frame3d( b3Raw.GetMin()), dCoeffX, dCoeffY, dCoeffZ) && m_pGeomDB->Scale( nRawOutId, Frame3d( b3Raw.GetMin()), dCoeffX, dCoeffY, dCoeffZ) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; return bOk ; } //---------------------------------------------------------------------------- bool MachMgr::ModifyRawPartHeight( int nRawId, double dHeight) { // la nuova altezza non può essere nulla if ( dHeight < EPS_SMALL) return false ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero il solido del grezzo int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nRawSolId == GDB_ID_NULL) return false ; // recupero il box del grezzo BBox3d b3Raw ; if ( ! m_pGeomDB->GetLocalBBox( nRawSolId, b3Raw)) return false ; // determino il coefficente di scalatura in Z double dOldH = b3Raw.GetMax().z - b3Raw.GetMin().z ; if ( dOldH < EPS_SMALL) return false ; double dCoeff = dHeight / dOldH ; // eseguo scalatura bool bOk = m_pGeomDB->Scale( nRawSolId, Frame3d( b3Raw.GetMin()), 1, 1, dCoeff) ; // calcolo il punto centro del solido bOk = bOk && SetRawPartCenter( nRawId) ; return bOk ; } //---------------------------------------------------------------------------- bool MachMgr::GetRawPartPhases( int nRawId, INTVECTOR& vPhase) const { // pulisco parametro di ritorno vPhase.clear() ; // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero le fasi in cui è presente il grezzo (se manca è fase 1) if ( ! m_pGeomDB->GetInfo( nRawId, MACH_RAW_PHASE, vPhase) || vPhase.empty()) vPhase.emplace_back( 1) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::KeepRawPart( int nRawId, int nSouPhase) { // verifico validità e recupero fasi in cui è presente INTVECTOR vPhase ; if ( ! GetRawPartPhases( nRawId, vPhase)) return false ; // se fase corrente già presente, non devo fare alcunché if ( find( vPhase.begin(), vPhase.end(), m_nCurrPhase) != vPhase.end()) return true ; // aggiungo la fase corrente vPhase.emplace_back( m_nCurrPhase) ; if ( ! m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, vPhase)) return false ; // annullo eventuali movimenti del grezzo (riferimento riportato a globale) Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ; if ( pfrRaw == nullptr) return false ; pfrRaw->Reset() ; // visualizzo il grezzo e ne attivo i pezzi if ( ! m_pGeomDB->SetStatus( nRawId, GDB_ST_ON)) return false ; if ( ! SwapRawPartParts( nRawId, true)) return false ; // se fase di origine non definita, esco con successo if ( nSouPhase == 0) return true ; // copio il posizionamento Disposition* pSouDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( nSouPhase))) ; Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( m_nCurrPhase))) ; if ( pSouDisp == nullptr || pDisp == nullptr) return false ; for ( int i = 0 ; ; ++ i) { int nId ; int nType ; Point3d ptPos ; int nFlag ; if ( pSouDisp->GetMoveRawData( i, nId, nType, ptPos, nFlag)) { if ( nId == nRawId) { switch ( nType) { case MoveRawData::COR : pDisp->MoveToCornerRawPart( nRawId, ptPos, nFlag, true, false) ; break ; case MoveRawData::CEN : pDisp->MoveToCenterRawPart( nRawId, ptPos, nFlag, true, false) ; break ; case MoveRawData::ROT : pDisp->ApplyRotationToRawPart( nRawId, ptPos.x, ptPos.y, ptPos.z, true) ; break ; } } } else break ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::VerifyRawPartPhase( int nRawId, int nPhase) const { // verifico validità e recupero fasi in cui è presente INTVECTOR vPhase ; if ( ! GetRawPartPhases( nRawId, vPhase)) return false ; return ( find( vPhase.begin(), vPhase.end(), nPhase) != vPhase.end()) ; } //---------------------------------------------------------------------------- bool MachMgr::RemoveRawPartFromCurrPhase( int nRawId) { // verifico validità e recupero fasi in cui è presente INTVECTOR vPhase ; if ( ! GetRawPartPhases( nRawId, vPhase)) return false ; // se non appartiene alla fase corrente, non devo fare alcunché auto iIter = find( vPhase.begin(), vPhase.end(), m_nCurrPhase) ; if ( iIter == vPhase.end()) return true ; // se appartiene solo a questa fase, lo elimino if ( vPhase.size() == 1) RemoveRawPart( nRawId) ; // altrimenti else { // tolgo dalla disposizione corrente gli eventuali movimenti registrati di questo grezzo Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( m_nCurrPhase))) ; if ( pDisp != nullptr) pDisp->RemoveRawPart( nRawId) ; // aggiorno l'elenco delle fasi di appartenenza vPhase.erase( iIter) ; m_pGeomDB->SetInfo( nRawId, MACH_RAW_PHASE, vPhase) ; // tolgo i pezzi dal grezzo e lo nascondo SwapRawPartParts( nRawId, false) ; m_pGeomDB->SetStatus( nRawId, GDB_ST_OFF) ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::RemoveRawPart( int nRawId) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // tolgo dalle disposizioni in cui compare gli eventuali movimenti registrati di questo grezzo for ( int nPhase = 1 ; nPhase <= m_nPhasesCount ; ++ nPhase) { Disposition* pDisp = GetDisposition( m_pGeomDB->GetUserObj( GetPhaseDisposition( nPhase))) ; if ( pDisp != nullptr) pDisp->RemoveRawPart( nRawId) ; } // devo estrarre i pezzi e riportarli in lista generale SwapRawPartParts( nRawId, false) ; // cancello il grezzo m_pGeomDB->Erase( nRawId) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::VerifyRawPart( int nRawId, bool bLinkedAllowed) const { // se il grezzo fa parte del gruppo dei grezzi, va bene int nRawGroupId = GetCurrRawGroupId() ; if ( nRawGroupId != GDB_ID_NULL && m_pGeomDB->GetParentId( nRawId) == nRawGroupId) return true ; // se consentito linkaggio ed il grezzo è linkato ad un gruppo della macchina corrente, va bene if ( bLinkedAllowed) { Machine* pMch = GetCurrMachine() ; if ( pMch != nullptr && pMch->IsLinkedRawPart( nRawId)) return true ; } // altrimenti errore return false ; } //---------------------------------------------------------------------------- bool MachMgr::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg) { // recupero l'oggetto disposizione corrente Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ; if ( pDisp == nullptr) return false ; // eseguo l'operazione if ( ! pDisp->RotateRawPart( nRawId, vtAx, dAngRotDeg)) { LOG_ERROR( GetEMkLogger(), "Error on RotateRawPart") ; return false ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag) { // recupero l'oggetto disposizione corrente Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ; if ( pDisp == nullptr) return false ; // eseguo l'operazione if ( ! pDisp->MoveToCornerRawPart( nRawId, ptP, nFlag)) { LOG_ERROR( GetEMkLogger(), "Error on MoveToCornerRawPart") ; return false ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag) { // recupero l'oggetto disposizione corrente Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ; if ( pDisp == nullptr) return false ; // eseguo l'operazione if ( ! pDisp->MoveToCenterRawPart( nRawId, ptP, nFlag)) { LOG_ERROR( GetEMkLogger(), "Error on MoveToCenterRawPart") ; return false ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::MoveRawPart( int nRawId, const Vector3d& vtMove) { // recupero l'oggetto disposizione corrente Disposition* pDisp = ::GetDisposition( m_pGeomDB->GetUserObj( m_nCurrDispId)) ; if ( pDisp == nullptr) return false ; // eseguo l'operazione if ( ! pDisp->MoveRawPart( nRawId, vtMove)) { LOG_ERROR( GetEMkLogger(), "Error on MoveRawPart") ; return false ; } return true ; } //---------------------------------------------------------------------------- bool MachMgr::SetRawPartCenter( int nRawId) { // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolId)) ; if ( pStm == nullptr) return false ; // recupero il punto centro, se non esiste lo creo int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; if ( nGPntId == GDB_ID_NULL) { PtrOwner pGeoPnt( CreateGeoPoint3d()) ; nGPntId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nRawId, Release( pGeoPnt)) ; m_pGeomDB->SetName( nGPntId, MACH_RAW_CENTER) ; Color cCol ; if ( m_pGeomDB->GetCalcMaterial( nRawSolId, cCol)) m_pGeomDB->SetMaterial( nGPntId, cCol) ; } IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ; if ( pGeoPnt == nullptr) return false ; // calcolo il valore del centro Point3d ptCen ; if ( ! pStm->GetCentroid( ptCen)) return false ; // aggiorno e imposto modo a standard return ( pGeoPnt->Set( ptCen) && m_pGeomDB->SetMode( nGPntId, GDB_MD_STD)) ; } //---------------------------------------------------------------------------- bool MachMgr::ResetRawPartCenter( int nRawId) { // recupero il punto centro int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; if ( nGPntId == GDB_ID_NULL) return true ; // imposto modo a bloccato return m_pGeomDB->SetMode( nGPntId, GDB_MD_HIDDEN) ; } //---------------------------------------------------------------------------- bool MachMgr::GetRawPartCenter( int nRawId, Point3d& ptCen) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // cerco di recuperare l'oggetto int nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; // ne verifico la validità int nMode ; if ( nGPntId == GDB_ID_NULL || ! m_pGeomDB->GetMode( nGPntId, nMode) || nMode != GDB_MD_STD) { // provo a crearlo SetRawPartCenter( nRawId) ; nGPntId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_CENTER) ; // se non riesco, errore if ( nGPntId == GDB_ID_NULL) return false ; } // ne recupero il riferimento globale Frame3d frGPnt ; if ( ! m_pGeomDB->GetGlobFrame( nGPntId, frGPnt)) return false ; // recupero il punto IGeoPoint3d* pGeoPnt = GetGeoPoint3d( m_pGeomDB->GetGeoObj( nGPntId)) ; if ( pGeoPnt == nullptr) return false ; ptCen = pGeoPnt->GetPoint() ; ptCen.ToGlob( frGPnt) ; return true ; } //---------------------------------------------------------------------------- bool MachMgr::GetRawPartBBox( int nRawId, BBox3d& b3Raw) { // verifica validità grezzo if ( ! VerifyRawPart( nRawId)) return false ; // recupero solido del grezzo int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; return m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) ; } //---------------------------------------------------------------------------- int MachMgr::SplitFlatRawPartWithMachinings( int nRawId, const INTVECTOR& vMchId) { if ( m_pGeomDB == nullptr) return GDB_ID_NULL ; // verifico sia un grezzo e non appartenga alla fase corrente if ( ! VerifyRawPart( nRawId) || VerifyRawPartPhase( nRawId, m_nCurrPhase)) return GDB_ID_NULL ; // disabilito eventuale registrazione comandi EXE (riabilitazione automatica) CmdLogOff cmdLogOff ; // recupero alcuni dati del grezzo // il solido del grezzo int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( nRawSolId == GDB_ID_NULL) return GDB_ID_NULL ; // il box del grezzo BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return GDB_ID_NULL ; double dZmin = b3Raw.GetMin().z ; double dHeight = b3Raw.GetMax().z - b3Raw.GetMin().z ; // il colore del grezzo Color cCol = AQUA ; m_pGeomDB->GetCalcMaterial( nRawSolId, cCol) ; // il riferimento del grezzo Frame3d frRaw ; if ( ! m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw)) return GDB_ID_NULL ; // creo la regione del grezzo a partire dal suo contorno // recupero il contorno int nOutCrvId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_OUTLINE) ; if ( nOutCrvId == GDB_ID_NULL) return GDB_ID_NULL ; // creo la regione INTVECTOR vCrvIds ; vCrvIds.emplace_back( nOutCrvId) ; int nSfrId = ExeCreateSurfFlatRegion( nRawId, vCrvIds, nullptr) ; if ( nSfrId == GDB_ID_NULL) return GDB_ID_NULL ; m_pGeomDB->SetLevel( nSfrId, GDB_LV_TEMP) ; // se esiste il kerf, ne creo la regione PtrOwner pSfrKerf ; int nKerfId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_KERF) ; ICurve* pKerfCrv = GetCurve( m_pGeomDB->GetGeoObj( nKerfId)) ; if ( pKerfCrv != nullptr) { SurfFlatRegionByContours SfrCntr ; SfrCntr.AddCurve( pKerfCrv->Clone()) ; pSfrKerf.Set( SfrCntr.GetSurf()) ; if ( IsNull( pSfrKerf)) return GDB_ID_NULL ; } // recupero le regioni delle lavorazioni INTVECTOR vMchRReg ; for ( auto nMchId : vMchId) { // recupero gruppo preview lavorazioni nella lavorazione int nPVGrp = m_pGeomDB->GetFirstNameInGroup( nMchId, MCH_PV) ; if ( nPVGrp == GDB_ID_NULL) return GDB_ID_NULL ; // se vuoto, cerco il rimando al preview nel pezzo if ( m_pGeomDB->GetGroupObjs( nPVGrp) == 0 && ! m_pGeomDB->GetInfo( nPVGrp, MCH_PV_KEY_RELOCATE, nPVGrp)) return GDB_ID_NULL ; // ciclo sui percorsi utensile (CL) int nClId = m_pGeomDB->GetFirstGroupInGroup( nPVGrp) ; while ( nClId != GDB_ID_NULL) { // tagli ridotti int nCrId = m_pGeomDB->GetFirstNameInGroup( nClId, MCH_PV_RRCUT) ; while ( nCrId != GDB_ID_NULL) { vMchRReg.emplace_back( nCrId) ; nCrId = m_pGeomDB->GetNextName( nCrId, MCH_PV_RRCUT) ; } // passo al successivo percorso utensile nClId = m_pGeomDB->GetNextGroup( nClId) ; } } // sottraggo queste regioni a quella del grezzo for ( auto nMchRReg : vMchRReg) { ExeSurfFrSubtract( nSfrId, nMchRReg) ; } // creo i grezzi risultanti // creo i nuovi grezzi INTVECTOR vNewIds ; int nCount ; int nChunk = 0 ; int nFirstLoopId = ExeExtractSurfFrChunkLoops( nSfrId, nChunk, nRawId, &nCount) ; while ( nFirstLoopId != GDB_ID_NULL) { // !!! in attesa di gestire i grezzi con i buchi !!! // cancello le eventuali curve successive (sono i loop interni ovvero i buchi) for ( int i = 1 ; i < nCount ; ++ i) { m_pGeomDB->Erase( nFirstLoopId + i) ; } // dichiaro temporanea la curva m_pGeomDB->SetLevel( nFirstLoopId, GDB_LV_TEMP) ; // creo il grezzo int nId = AddRawPart( nFirstLoopId, 0, dZmin, dHeight, cCol) ; if ( nId == GDB_ID_NULL) return GDB_ID_NULL ; vNewIds.emplace_back( nId) ; // imposto lo stato del contorno di questo grezzo come quello del grezzo di partenza int nStat = GDB_ST_ON ; if ( m_pGeomDB->GetStatus( nOutCrvId, nStat) && nStat == GDB_ST_OFF) m_pGeomDB->SetStatus( m_pGeomDB->GetFirstNameInGroup( nId, MACH_RAW_OUTLINE), nStat) ; // assegno la fase al gruppo m_pGeomDB->SetInfo( nId, MACH_RAW_PHASE, m_nCurrPhase) ; // se esiste il kerf uso questa curva per creare il kerf del nuovo grezzo if ( ! IsNull( pSfrKerf)) { // creo la regione con la curva SurfFlatRegionByContours SfrCntr ; SfrCntr.AddCurve( GetCurve( m_pGeomDB->RemoveGeoObjAndErase( nFirstLoopId))) ; PtrOwner pSfrNewKerf( SfrCntr.GetSurf()) ; if ( IsNull( pSfrNewKerf)) return GDB_ID_NULL ; // la limito con la regione di kerf precedente (va bene anche se fallisce) pSfrNewKerf->Intersect( *pSfrKerf) ; // se risultato non vuoto if ( pSfrNewKerf->IsValid()) { // riferimento del nuovo grezzo Frame3d frNewRaw ; if ( ! m_pGeomDB->GetGroupGlobFrame( nId, frNewRaw)) return GDB_ID_NULL ; // la porto dal riferimento del grezzo originale al riferimento di questo grezzo pSfrNewKerf->LocToLoc( frRaw, frNewRaw) ; // la porto sulla faccia sopra del grezzo pSfrNewKerf->Translate( Vector3d( 0, 0, dHeight)) ; // recupero il contorno e lo inserisco come kerf del nuovo grezzo PtrOwner pCrv( pSfrNewKerf->GetLoop( 0, 0)) ; int nNewKerfId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nId, Release( pCrv)) ; if ( nNewKerfId == GDB_ID_NULL) return GDB_ID_NULL ; m_pGeomDB->CopyMaterial( nKerfId, nNewKerfId) ; m_pGeomDB->SetName( nNewKerfId, MACH_RAW_KERF) ; } } // altrimenti la cancello else m_pGeomDB->Erase( nFirstLoopId) ; // passo alla prossima curva ++ nChunk ; nFirstLoopId = ExeExtractSurfFrChunkLoops( nSfrId, nChunk, nRawId, &nCount) ; } // cancello la regione m_pGeomDB->Erase( nSfrId) ; // verifico esista almeno un nuovo grezzo if ( vNewIds.empty()) return GDB_ID_NULL ; // inserisco i pezzi del grezzo originale nei nuovi grezzi int nGroupId = m_pGeomDB->GetFirstGroupInGroup( nRawId) ; while ( nGroupId != GDB_ID_NULL) { for ( auto nNewId : vNewIds) { // copio il gruppo int nNewGroupId = m_pGeomDB->CopyGlob( nGroupId, GDB_ID_NULL, nNewId) ; // scambio con pezzo int nPartId = SwapRawPartPart( nNewGroupId, true) ; // verifico se il pezzo sta nel grezzo int nLayerId = m_pGeomDB->GetFirstNameInGroup( nPartId, NST_EXT_LAYER) ; if ( nLayerId == GDB_ID_NULL || m_pGeomDB->GetGdbType( nLayerId) != GDB_TY_GROUP) nLayerId = m_pGeomDB->GetFirstGroupInGroup( nPartId) ; int nEntId = m_pGeomDB->GetFirstInGroup( nLayerId) ; int nEntGeoType = m_pGeomDB->GetGeoType( nEntId) ; Point3d ptTest ; if ( ( ( nEntGeoType & GEO_CURVE) != 0 && ExeMidPoint( nEntId, nNewId, ptTest)) || ( ( nEntGeoType & GEO_CURVE) == 0 && ExeCenterPoint( nEntId, nNewId, ptTest))) { int nOutCrvId = m_pGeomDB->GetFirstNameInGroup( nNewId, MACH_RAW_OUTLINE) ; BBox3d b3Raw ; m_pGeomDB->GetGlobalBBox( nOutCrvId, b3Raw) ; double dRawDiam = 0 ; b3Raw.GetDiameter( dRawDiam) ; BBox3d b3Part ; m_pGeomDB->GetGlobalBBox( nEntId, b3Part) ; double dPartDiam = 0 ; b3Part.GetDiameter( dPartDiam) ; if ( dRawDiam > 0.9 * dPartDiam) { ICurve* pCurve = GetCurve( m_pGeomDB->GetGeoObj( nOutCrvId)) ; if ( pCurve != nullptr) { int nSide ; double dDist ; DistPointCurve distPC( ptTest, *pCurve) ; if ( distPC.GetDist( dDist) && ( dDist < 100 * EPS_SMALL || ( distPC.GetSideAtMinDistPoint( 0, Z_AX, nSide) && nSide != MDS_RIGHT))) break ; } } } // altrimenti scambio pezzo ed elimino gruppo nNewGroupId = SwapRawPartPart( nPartId, false) ; m_pGeomDB->Erase( nNewGroupId) ; } nGroupId = m_pGeomDB->GetNextGroup( nGroupId) ; } return vNewIds[0] ; }