From 2d7630de7674a424584f2ab18e4a504fbcfe2f66 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 3 Mar 2020 09:38:43 +0000 Subject: [PATCH] =?UTF-8?q?EgtNesting=202.2c1=20:=20-=20aggiunta=20funzion?= =?UTF-8?q?e=20SetGuillotineMode=20=20(modalit=C3=A0=20ghigliottina=20funz?= =?UTF-8?q?iona=20solo=20per=20Sheet=20rettangolari=20e=20Pezzi=20senza=20?= =?UTF-8?q?ToolOutline).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AutoNester.cpp | 96 +++++++++++++++++++++++++++++++++++-------------- AutoNester.h | 13 +++++-- EgtNesting.rc | Bin 11638 -> 11638 bytes 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/AutoNester.cpp b/AutoNester.cpp index 61e0e8e..820e7fe 100644 --- a/AutoNester.cpp +++ b/AutoNester.cpp @@ -37,9 +37,9 @@ CreateAutoNester( void) //---------------------------------------------------------------------------- static void -GetCNSPath( const PolyArc& Outline, vector& vElem) +GetCNSPath( const PolyArc& Outline, double dOffsX, double dOffsY, vector& vElem) { - // converto nel formato Optalog +// converto nel formato Optalog int nElem = Outline.GetPointNbr() ; if ( Outline.IsClosed()) -- nElem ; @@ -48,7 +48,7 @@ GetCNSPath( const PolyArc& Outline, vector& vElem) bool bNext = Outline.GetFirstArc( ptIni, ptFin, dBulge) ; while ( bNext) { double dLeftDeflection = - dBulge * DistXY( ptIni, ptFin) / 2 ; - vElem.push_back( { ptFin.x, ptFin.y, dLeftDeflection}) ; + vElem.push_back( { dOffsX + ptFin.x, dOffsY + ptFin.y, dLeftDeflection}) ; bNext = Outline.GetNextArc( ptIni, ptFin, dBulge) ; } } @@ -81,7 +81,7 @@ AutoNester::Clear( void) m_pOrder = nullptr ; m_pComp = nullptr ; } - m_IdSheetPtr.clear() ; + m_IdSheetInfo.clear() ; m_IdPartPtr.clear() ; m_dInterpartGap = 0 ; return true ; @@ -98,25 +98,63 @@ AutoNester::Start( void) //---------------------------------------------------------------------------- bool -AutoNester::AddSheet( int nSheetId, const PolyArc& Outline, double dKerf, int nPriority, int nCount) +AutoNester::SetGuillotineMode( void) +{ + if ( m_pOrder == nullptr) + return false ; + CNS_SetShearMode(m_pOrder, 1) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +AutoNester::AddSheet( int nSheetId, const PolyArc& Outline, double dKerf, int nPriority, int nCount, bool* pbIsRect) { if ( m_pOrder == nullptr) return false ; // verifico outline if ( Outline.GetArcNbr() == 0 || ! Outline.IsClosed()) return false ; - // aggiungo contorno - vector vElem ; - GetCNSPath( Outline, vElem) ; - CNS_SheetPtr pSheet = CNS_AddNonRectangularSheet( m_pOrder, nCount, int( vElem.size()), vElem.data()) ; - if ( pSheet == nullptr) - return false ; + CNS_SheetPtr pSheet = nullptr ; + double dOffsX = 0 ; + double dOffsY = 0 ; + // se rettangolo + BBox3d b3Rect ; + if ( Outline.IsRectangleXY( b3Rect)) { + // imposto il rettangolo + Point3d ptMin ; double dDimX, dDimY, dDimZ ; + b3Rect.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; + pSheet = CNS_AddSheet( m_pOrder, nCount, dDimX, dDimY) ; + if ( pSheet == nullptr) + return false ; + // salvo offset per origine reale del rettangolo + dOffsX = ptMin.x ; + dOffsY = ptMin.y ; + // imposto altri dati + CNS_SetSheetGaps( pSheet, dKerf, dKerf, dKerf, dKerf) ; + // se richiesto, ritorno che è un rettangolo + if ( pbIsRect != nullptr) + *pbIsRect = true ; + } + // altrimenti forma generica + else { + // aggiungo contorno + vector vElem ; + GetCNSPath( Outline, 0, 0, vElem) ; + pSheet = CNS_AddNonRectangularSheet( m_pOrder, nCount, int( vElem.size()), vElem.data()) ; + if ( pSheet == nullptr) + return false ; + // imposto altri dati + CNS_SetNonRectangularSheetGaps( pSheet, dKerf, dKerf, dKerf, dKerf, dKerf) ; + // se richiesto, ritorno che non è un rettangolo + if ( pbIsRect != nullptr) + *pbIsRect = false ; + } // imposto altri dati CNS_SetSheetUserString( pSheet, ToString( nSheetId).c_str()) ; CNS_SetSheetPriority( pSheet, nPriority) ; - CNS_SetNonRectangularSheetGaps( pSheet, dKerf, dKerf, dKerf, dKerf, dKerf) ; // lo inserisco nel map - m_IdSheetPtr.emplace( nSheetId, pSheet) ; + m_IdSheetInfo.emplace( nSheetId, SheetInfo( pSheet, dOffsX, dOffsY)) ; return true ; } @@ -130,13 +168,15 @@ AutoNester::AddDefectToSheet( int nSheetId, const PolyArc& Outline) if ( Outline.GetArcNbr() == 0 || ! Outline.IsClosed()) return false ; // cerco lo sheet - const auto Iter = m_IdSheetPtr.find( nSheetId) ; - if ( Iter == m_IdSheetPtr.end()) + const auto Iter = m_IdSheetInfo.find( nSheetId) ; + if ( Iter == m_IdSheetInfo.end()) return false ; - CNS_SheetPtr pSheet = Iter->second ; - // aggiungo difetto tramite suo contorno + CNS_SheetPtr pSheet = Iter->second.pSheet ; + double dOffsX = Iter->second.dOffsX ; + double dOffsY = Iter->second.dOffsY ; + // aggiungo difetto tramite suo contorno vector vElem ; - GetCNSPath( Outline, vElem) ; + GetCNSPath( Outline, -dOffsX, -dOffsY, vElem) ; CNS_AddDefectToSheet( pSheet, int( vElem.size()), vElem.data()) ; return true ; } @@ -152,7 +192,7 @@ AutoNester::AddPart( int nPartId, const PolyArc& Outline, bool bCanFlip, bool bC return false ; // aggiungo contorno vector vElem ; - GetCNSPath( Outline, vElem) ; + GetCNSPath( Outline, 0, 0, vElem) ; CNS_PartPtr pPart = CNS_AddPart( m_pOrder, nCount, int( vElem.size()), vElem.data()) ; if ( pPart == nullptr) return false ; @@ -181,7 +221,7 @@ AutoNester::AddHoleToPart( int nPartId, const PolyArc& Hole) CNS_PartPtr pPart = Iter->second ; // aggiungo buco al pezzo vector vElem ; - GetCNSPath( Hole, vElem) ; + GetCNSPath( Hole, 0, 0, vElem) ; CNS_AddHoleToPart( pPart, int( vElem.size()), vElem.data()) ; return true ; } @@ -202,7 +242,7 @@ AutoNester::AddAnotherOutlineToPart( int nPartId, const PolyArc& AnotherOutline) CNS_PartPtr pPart = Iter->second ; // aggiungo contorno aggiuntivo al pezzo vector vElem ; - GetCNSPath( AnotherOutline, vElem) ; + GetCNSPath( AnotherOutline, 0, 0, vElem) ; CNS_AddExternalBoundaryToPart( pPart, int( vElem.size()), vElem.data()) ; return true ; } @@ -223,7 +263,7 @@ AutoNester::AddToolOutlineToPart( int nPartId, const PolyArc& ToolOutline) CNS_PartPtr pPart = Iter->second ; // aggiungo contorno di lavorazione vector vElem ; - GetCNSPath( ToolOutline, vElem) ; + GetCNSPath( ToolOutline, 0, 0, vElem) ; CNS_AddToolPathToPart( pPart, int( vElem.size()), vElem.data()) ; return true ; } @@ -257,8 +297,8 @@ AutoNester::Compute( bool bMinimizeOnXvsY, int nMaxTime) // gap tra i pezzi CNS_SetInterpartGap( m_pOrder, m_dInterpartGap) ; // gap sui difetti - for ( auto Iter = m_IdSheetPtr.begin() ; Iter != m_IdSheetPtr.end() ; ++ Iter) - CNS_SetDefectGap( Iter->second, m_dInterpartGap) ; + for ( auto Iter = m_IdSheetInfo.begin() ; Iter != m_IdSheetInfo.end() ; ++ Iter) + CNS_SetDefectGap( Iter->second.pSheet, m_dInterpartGap) ; } // per evitare pezzi posti inutilmente di sghembo su ultimo pannello CNS_SetObjective( m_pOrder, ( bMinimizeOnXvsY ? CNS_IntelligentMinimizeX : CNS_IntelligentMinimizeY)) ; @@ -338,7 +378,11 @@ AutoNester::GetResults( double& dTotFillRatio, ANIVECT& vANI) int nPartCount = CNS_GetNumberOfNestedParts( pNest) ; double dFillRatio = CNS_GetNestingFillRatio( pNest) ; vANI.push_back( { nMult, nSheetId, nPartCount, dFillRatio, 0, 0}) ; - // ciclo sui pezzi nestati + // offset per origine sheet rettangolari + const auto Iter = m_IdSheetInfo.find( nSheetId) ; + double dOffsX = ( Iter != m_IdSheetInfo.end() ? Iter->second.dOffsX : 0) ; + double dOffsY = ( Iter != m_IdSheetInfo.end() ? Iter->second.dOffsY : 0) ; + // ciclo sui pezzi nestati for ( int j = 0; j < nPartCount ; ++ j) { // dati del pezzo CNS_PartPtr pPart ; @@ -349,7 +393,7 @@ AutoNester::GetResults( double& dTotFillRatio, ANIVECT& vANI) int nPartId = 999 ; if ( szPartId != nullptr) FromString( szPartId, nPartId) ; - vANI.push_back( { 0, nPartId, nFlip, dX, dY, dAngRot}) ; + vANI.push_back( { 0, nPartId, nFlip, dOffsX + dX, dOffsY + dY, dAngRot}) ; } } return true ; diff --git a/AutoNester.h b/AutoNester.h index 12ca3e9..2095919 100644 --- a/AutoNester.h +++ b/AutoNester.h @@ -27,7 +27,8 @@ class AutoNester : public IAutoNester public : ~AutoNester( void) override ; bool Start( void) override ; - bool AddSheet( int nSheetId, const PolyArc& Outline, double dKerf, int nPriority, int nCount) override ; + bool SetGuillotineMode( void) override ; + bool AddSheet( int nSheetId, const PolyArc& Outline, double dKerf, int nPriority, int nCount, bool* pbIsRect = nullptr) override ; bool AddDefectToSheet( int nSheetId, const PolyArc& Outline) override ; bool AddPart( int nPartId, const PolyArc& Outline, bool bCanFlip, bool bCanRotate, double dRotStep, int nPriority, int nCount) override ; bool AddHoleToPart( int nPartId, const PolyArc& Hole) override ; @@ -48,13 +49,19 @@ class AutoNester : public IAutoNester bool Clear( void) ; private : - typedef std::unordered_map< int, CNS_Sheet*> IDSHEETPTR_UMAP ; + struct SheetInfo { + CNS_Sheet* pSheet ; + double dOffsX ; + double dOffsY ; + SheetInfo( CNS_Sheet* pS, double dX, double dY) : pSheet( pS), dOffsX( dX), dOffsY( dY) {} + } ; + typedef std::unordered_map< int, SheetInfo> IDSHEETINFO_UMAP ; typedef std::unordered_map< int, CNS_Part*> IDPARTPTR_UMAP ; private : CNS_LaunchingOrder* m_pOrder ; // ordine di esecuzione per OptaLog CNS_Computation* m_pComp ; // calcolo di ottimizzazione - IDSHEETPTR_UMAP m_IdSheetPtr ; // map dei pannelli basato su identificativi + IDSHEETINFO_UMAP m_IdSheetInfo ; // map dei pannelli basato su identificativi IDPARTPTR_UMAP m_IdPartPtr ; // map dei pannelli basato su identificativi double m_dInterpartGap ; // distanza minima tra i pezzi std::string m_sReportFile ; // file di report dei dati da inviare a Optalog in caso di problemi diff --git a/EgtNesting.rc b/EgtNesting.rc index 0d0ca6fc1ac1dacb541e33d1fa0b97ab352aa194..ba8c84313938da4ae0f1eff7f63c3362ad5a0885 100644 GIT binary patch delta 265 zcmews^(|_{I%aiGhCGIJh8%`ehGHOAV9;O)W+-7u1ma8}FBB-731Uxf)RLZjPc3V6 z9Lo$QM&r#F`3^Hp-o=^4oXlW2*-%h-Gmn%PCBtFNKHgAAM6KDupe@OZchZceDgiEY0Q{Xn;W&hG64WLsYVC@ delta 241 zcmews^(|_{I%aKGhCGIJh8%`WhGK>c1_cHUhESkLCPN8BDnkm89}HwAf_cT08?~f2 ze_&=}W;EJ-mhUjr