EgtNesting 2.2c1 :

- aggiunta funzione SetGuillotineMode  (modalità ghigliottina funziona solo per Sheet rettangolari e Pezzi senza ToolOutline).
This commit is contained in:
Dario Sassi
2020-03-03 09:38:43 +00:00
parent 2afaf0d608
commit 2d7630de76
3 changed files with 80 additions and 29 deletions
+70 -26
View File
@@ -37,9 +37,9 @@ CreateAutoNester( void)
//----------------------------------------------------------------------------
static void
GetCNSPath( const PolyArc& Outline, vector<CNS_Element>& vElem)
GetCNSPath( const PolyArc& Outline, double dOffsX, double dOffsY, vector<CNS_Element>& 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<CNS_Element>& 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<CNS_Element> 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<CNS_Element> 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<CNS_Element> 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<CNS_Element> 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<CNS_Element> 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<CNS_Element> 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<CNS_Element> 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 ;
+10 -3
View File
@@ -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
BIN
View File
Binary file not shown.