Imports System.Windows.Threading Imports EgtBEAMWALL.Core Imports EgtUILib Imports EgtWPFLib5 Public Class NestingRunningWndVM Inherits VMBase #Region "FIELDS & PROPERTIES" Public Enum OperationTypes ROTFLIP = 1 NESTING = 2 End Enum Friend Event m_CloseWindow(bDialogResult As Boolean) Private m_OperationType As OperationTypes Private m_Waiting_Timer As New DispatcherTimer Private m_TotIntervals As Integer = 0 Private m_Step As Double = 1 Private m_SectionIndex As Integer Private m_SectionProgressList As New List(Of SectionProgress) Friend ReadOnly Property SectionProgressList As List(Of SectionProgress) Get Return m_SectionProgressList End Get End Property Private m_RotFlipList As New List(Of BTLPartVM) Friend ReadOnly Property RotFlipList As List(Of BTLPartVM) Get Return m_RotFlipList End Get End Property Public ReadOnly Property RunningSection As SectionProgress Get Dim CurrRunningSection As SectionProgress = m_SectionProgressList.FirstOrDefault(Function(x) x.nState <> SectionProgress.NestStates.DONE) Return If(Not IsNothing(CurrRunningSection), CurrRunningSection, Nothing) End Get End Property Private m_bLDIntersOther As Boolean Private m_nMinScore As Integer Private m_CurrProgress_Value As Double = 0 Public Property CurrProgress_Value As Double Get Return m_CurrProgress_Value End Get Set(value As Double) m_CurrProgress_Value = value End Set End Property Private m_TotProgress_Value As Double = 0 Public Property TotProgress_Value As Double Get Return Math.Floor(m_TotProgress_Value) End Get Set(value As Double) m_TotProgress_Value = value End Set End Property ' tempo parziale e totale del segmento corrente Friend Shared m_CurrState As SectionProgress.NestStates Friend Shared m_CurrTime As Double Friend Shared m_TotTime As Double ' indice avanzamento RotFlip Friend Shared m_RotFlipIndex As Integer = 0 #Region "Messages" Public ReadOnly Property Section_Msg As String Get Return If(m_SectionProgressList.Count() > 0, "Section: " & m_SectionProgressList(m_SectionIndex).Section.sSectionXMaterial & "(" & m_SectionIndex + 1 & "/" & m_SectionProgressList.Count() & ")", "") End Get End Property Public ReadOnly Property Nesting_Msg As String Get Select Case m_CurrState Case SectionProgress.NestStates.CALCORIENTATION Return "Calculating wall orientation..." Case SectionProgress.NestStates.ADDPART Return "Calculating wall outlines..." Case SectionProgress.NestStates.NEST Return "Nesting walls in rawparts..." Case SectionProgress.NestStates.CALCRAWPART Return "Generating rawparts with nested parts..." End Select End Get End Property Public ReadOnly Property TotProgress_Msg As String Get Return m_TotProgress_Value.ToString("0.#") & "%" End Get End Property #End Region ' Messages ' Definizione comandi Private m_cmdCancel As ICommand #End Region ' FIELDS & PROPERTIES Sub New(OperationType As OperationTypes, SelPartType As Integer, Optional bLDIntersOther As Boolean = False, Optional nMinScore As Integer = 0) m_OperationType = OperationType m_bLDIntersOther = bLDIntersOther m_nMinScore = nMinScore Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\NestLog.txt" Dim dSectionTime As Double = GetMainPrivateProfileDouble(S_NEST, K_SECTIONTIME, 1) Dim dPartTime As Double = GetMainPrivateProfileDouble(S_NEST, K_PARTTIME, 1) SectionProgress.SetPartSectionTimes(dPartTime, dSectionTime) ' disabilito interfaccia Map.refProjectVM.SetCalcRunning(True) ' se ho selezionato nest per materiale e c'è una sezione selezionata diversa da sezione nulla If SelPartType = OptimizePanelVM.PartType.MATERIAL AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM.SelSection) AndAlso Map.refProjectVM.BTLStructureVM.SelSection.dH <> -1 Then m_SectionProgressList.Add(New SectionProgress(Map.refProjectVM.BTLStructureVM.SelSection)) Else ' altrimenti prendo tutte le sezioni For Each CurrSection In Map.refProjectVM.BTLStructureVM.SectionList If CurrSection.dH = -1 Then Continue For m_SectionProgressList.Add(New SectionProgress(CurrSection)) Next End If ' imposto contatore Select Case m_OperationType Case OperationTypes.ROTFLIP m_Waiting_Timer.Interval = TimeSpan.FromMilliseconds(70) Case OperationTypes.NESTING m_Waiting_Timer.Interval = TimeSpan.FromMilliseconds(700) End Select AddHandler m_Waiting_Timer.Tick, AddressOf WaitingTimer_Tick End Sub Sub New(SelPartType As Integer, BTLPart As BTLPartVM) m_OperationType = OperationTypes.ROTFLIP Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\RotFlipLog.txt" 'Dim dSectionTime As Double = GetMainPrivateProfileDouble(S_NEST, K_SECTIONTIME, 1) 'Dim dPartTime As Double = GetMainPrivateProfileDouble(S_NEST, K_PARTTIME, 1) 'SectionProgress.SetPartSectionTimes(dPartTime, dSectionTime) ' disabilito interfaccia Map.refProjectVM.SetCalcRunning(True) If Not IsNothing(BTLPart) Then m_RotFlipList.Add(BTLPart) ' se ho selezionato nest per materiale e c'è una sezione selezionata diversa da sezione nulla ElseIf SelPartType = OptimizePanelVM.PartType.MATERIAL AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM.SelSection) AndAlso Map.refProjectVM.BTLStructureVM.SelSection.dH <> -1 Then m_RotFlipList = Map.refProjectVM.BTLStructureVM.BTLPartVMList.Where(Function(x) x.Section = Map.refProjectVM.BTLStructureVM.SelSection).ToList() Else ' altrimenti prendo tutti i pezzi m_RotFlipList = Map.refProjectVM.BTLStructureVM.BTLPartVMList.ToList() End If ' imposto contatore m_Waiting_Timer.Interval = TimeSpan.FromMilliseconds(70) AddHandler m_Waiting_Timer.Tick, AddressOf WaitingTimer_Tick End Sub Private Sub WaitingTimer_Tick() Select Case m_OperationType Case OperationTypes.ROTFLIP m_TotProgress_Value = m_RotFlipIndex / Map.refProjectVM.BTLStructureVM.BTLPartVMList.Count() * 100 Case OperationTypes.NESTING Dim CurrTime As Double = 0 Dim CurrTotTime As Double = 0 Dim TotalTime As Double = 0 For Index = 0 To m_SectionProgressList.Count - 1 Dim SectionProgress As SectionProgress = m_SectionProgressList(Index) If Index < m_SectionIndex Then CurrTime += SectionProgress.dTotSectionTime ElseIf Index = m_SectionIndex Then Select Case m_CurrState Case SectionProgress.NestStates.ADDPART CurrTotTime = 100 CurrTime += m_CurrTime * SectionProgress.dAddPartTime / 100 Case SectionProgress.NestStates.NEST CurrTotTime = 100 CurrTime += SectionProgress.dAddPartTime + m_CurrTime * SectionProgress.dCalcNestTime / 100 Case SectionProgress.NestStates.CALCRAWPART CurrTotTime = 100 CurrTime += SectionProgress.dAddPartTime + SectionProgress.dCalcNestTime + m_CurrTime * SectionProgress.dCalcRawPartTime / 100 End Select End If TotalTime += SectionProgress.dTotSectionTime Next m_TotProgress_Value = CurrTime / TotalTime * 100 m_CurrProgress_Value = m_CurrTime End Select NotifyPropertyChanged(NameOf(CurrProgress_Value)) NotifyPropertyChanged(NameOf(TotProgress_Value)) NotifyPropertyChanged(NameOf(Section_Msg)) NotifyPropertyChanged(NameOf(Nesting_Msg)) NotifyPropertyChanged(NameOf(TotProgress_Msg)) End Sub Friend Sub StartCalculating() Select Case m_OperationType Case OperationTypes.ROTFLIP DoRotFlip() Case OperationTypes.NESTING DoNesting() End Select End Sub Friend Sub DoNesting() Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\RawPartLog.txt" Dim dSectionTime As Double = GetMainPrivateProfileDouble(S_NEST, K_SECTIONTIME, 1) Dim dPartTime As Double = GetMainPrivateProfileDouble(S_NEST, K_PARTTIME, 1) ' recupero parametri di calcolo Dim dRawL As Double = 0 Dim dRawW As Double = 0 Dim WhType = GetMainPrivateProfileInt(S_GENERAL, K_WAREHOUSE, 1) Dim sWarehouseIniPath As String = "" Dim dOffset As Double = WarehouseHelper.GetOffset(Map.refProjectVM.BTLStructureVM.nPROJTYPE) Dim dStartOffset As Double = 0 Dim dKerf As Double = 0 Select Case WhType Case WarehouseType.BASIC Dim nQuantity As Integer = WarehouseHelper.GetQuantity(Map.refProjectVM.BTLStructureVM.nPROJTYPE) If Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.BEAM Then ' leggo lunghezza barra WarehouseHelper.GetCurrentDimensions(Map.refProjectVM.BTLStructureVM.nPROJTYPE, 0, dRawL) ' leggo start offset e quantity dStartOffset = WarehouseHelper.GetStartOffset() ' riporto la stessa lunghezza in tutte le sezioni For Each SectionProgress In m_SectionProgressList SectionProgress.SParamList.Add(New SParam(SectionProgress.Section, dRawL, nQuantity)) Next ElseIf Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.WALL Then If Not WarehouseHelper.GetCurrentDimensions(Map.refProjectVM.BTLStructureVM.nPROJTYPE, dRawW, dRawL) Then ' riabilito interfaccia Map.refProjectVM.SetCalcRunning(False) CloseNesting() Return End If ' leggo kerf e quantity dKerf = WarehouseHelper.GetKerf() ' riporto le stesse dimensioni in tutte le sezioni For Each SectionProgress In m_SectionProgressList SectionProgress.SParamList.Add(New SParam(SectionProgress.Section, dRawW, dRawL, nQuantity, True)) Next End If Case WarehouseType.MEDIUM Dim sCurrL As String Dim nIndex As Integer = 1 ' aggiungo le sezioni con diverse lunghezze in base al warehouse If Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.BEAM Then ' leggo start offset dStartOffset = WarehouseHelper.GetStartOffset() ' leggo lunghezza barra e quantity WarehouseHelper.GetDimensionsAndQuantityForList(Map.refProjectVM.BTLStructureVM.nPROJTYPE, m_SectionProgressList) ElseIf Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.WALL Then dKerf = WarehouseHelper.GetKerf() If Not WarehouseHelper.GetDimensionsAndQuantityForList(Map.refProjectVM.BTLStructureVM.nPROJTYPE, m_SectionProgressList) Then ' riabilito interfaccia Map.refProjectVM.SetCalcRunning(False) CloseNesting() Return End If End If End Select ' calcolo lista dei pezzi per ogni sezione For Each SectionProgress In m_SectionProgressList 'Dim SectionPartList As New List(Of BTLPartM)(Map.refProjectVM.BTLStructureVM.BTLPartVMList.Where(Function(x) x.Section = Section.SectXMat).ToList()) Dim SectionPartList As List(Of BTLPartM) = (From x In Map.refProjectVM.BTLStructureVM.BTLPartVMList Where x.Section = SectionProgress.Section AndAlso x.bDO AndAlso x.nCNT + x.nADDED > x.nINPROD Select x.BTLPartM).ToList() SectionProgress.SetSectionPartList(SectionPartList) Next ' avvio timer avanzamento nesting m_CurrState = SectionProgress.NestStates.NULL m_TotTime = 0 m_CurrTime = 0 m_Waiting_Timer.Start() ' calcolo nesting For m_SectionIndex = 0 To m_SectionProgressList.Count - 1 Dim SectionProgress As SectionProgress = m_SectionProgressList(m_SectionIndex) ' passo a lua lista id pezzi da nestare If SectionProgress.SectionPartList.Count > 0 AndAlso SectionProgress.SParamList.Count > 0 AndAlso Not ExecNesting(sLogPath, CurrentMachine.sMachineName, SectionProgress.SectionPartList, SectionProgress.SParamList, dStartOffset, dOffset, dKerf, m_bLDIntersOther, m_nMinScore, SectionProgress.dCalcNestTime) Then Exit For End If Next ' update liste grezzi e pezzi della grafica Map.refProjectVM.MachGroupPanelVM.RefreshMachGroupList() ' seleziono ultimo gruppo Map.refProjectVM.MachGroupPanelVM.SelLastMachGroup() ' riabilito interfaccia Map.refProjectVM.SetCalcRunning(False) ' fermo timer e chiudo finestra CloseNesting() End Sub Friend Sub DoRotFlip() Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\RawPartLog.txt" ' avvio timer avanzamento nesting m_CurrState = SectionProgress.NestStates.CALCORIENTATION m_TotTime = 0 m_CurrTime = 0 m_RotFlipIndex = 0 m_Waiting_Timer.Start() ' calcolo RotFlip For Each BTLPart In m_RotFlipList ' eseguo funzione RotFlip If Not ExecRotFlip(BTLPart.nPartId) Then Exit For End If ' rileggo parametri Q per mostrare modifiche For Each Feature In BTLPart.BTLFeatureVMList Feature.BTLFeatureM.ReadQValues() Next ' incremento indice ProgressBar m_RotFlipIndex += 1 UpdateUI() Next ' rileggo ROTATED e INVERTED di tutti i pezzi Map.refProjectVM.BTLStructureVM.RefreshRotFlip() '' aggiorno eventuali Q della feature selezionata If Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart.SelBTLFeatureVM) Then For Each QParam In Map.refProjectVM.BTLStructureVM.SelBTLPart.SelBTLFeatureVM.QBTLParamVMList QParam.NotifyPropertyChanged(NameOf(QParam.sValue)) QParam.NotifyPropertyChanged(NameOf(QParam.bCustom)) Next End If 'Map.refProjectVM.MachGroupPanelVM.SelLastMachGroup() EgtDraw() ' riabilito interfaccia Map.refProjectVM.SetCalcRunning(False) ' fermo timer e chiudo finestra CloseNesting() End Sub Private Function CloseNesting() ' fermo timer e chiudo finestra m_Waiting_Timer.Stop() RaiseEvent m_CloseWindow(True) End Function #Region "COMMANDS" #Region "Cancel" ''' ''' Returns a command that do Open. ''' Public ReadOnly Property Cancel_Command As ICommand Get If m_cmdCancel Is Nothing Then m_cmdCancel = New Command(AddressOf Cancel) End If Return m_cmdCancel End Get End Property ''' ''' Execute the Open. This method is invoked by the OpenCommand. ''' Friend Sub Cancel() ' chiedo conferma If MessageBox.Show("Are you sure you want to stop the nesting?", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning) = MessageBoxResult.No Then Return ' fermo il nesting Map.refOptimizePanelVM.m_StopNesting = True '' fermo timer e chiudo finestra 'CloseNesting() End Sub #End Region ' Cancel #End Region ' COMMANDS End Class Public Class SectionProgress Public Enum NestStates As Integer NULL = 0 START = 1 CALCORIENTATION = 3 ADDRAWPART = -1 ADDPART = -2 NEST = 4 CALCRAWPART = -3 DONE = -4 End Enum Private Shared m_dSectionTime As Double Private Shared m_dPartTime As Double Private m_Section As SectionXMaterial Public ReadOnly Property Section As SectionXMaterial Get Return m_Section End Get End Property Private m_SParamList As New List(Of SParam) Public ReadOnly Property SParamList As List(Of SParam) Get Return m_SParamList End Get End Property Private m_SectionPartList As New List(Of BTLPartM) Public ReadOnly Property SectionPartList As List(Of BTLPartM) Get Return m_SectionPartList End Get End Property Private m_nState As NestStates = 0 Public ReadOnly Property nState As NestStates Get Return m_nState End Get End Property Public Sub SetState(value As NestStates) m_nState = value End Sub Public ReadOnly Property dTotSectionTime As Double Get Return If(SectionPartList.Count > 0 AndAlso SParamList.Count > 0, dAddPartTime + dCalcNestTime + dCalcRawPartTime, 0) End Get End Property Public ReadOnly Property dAddPartTime As Double Get Return If(SectionPartList.Count > 0 AndAlso SParamList.Count > 0, Math.Max(SectionPartList.Count / 5, 2), 0) End Get End Property Public ReadOnly Property dCalcNestTime As Double Get Return If(SectionPartList.Count > 0 AndAlso SParamList.Count > 0, Math.Max(5, m_dSectionTime) + (m_dPartTime * SectionPartList.Count), 0) End Get End Property Public ReadOnly Property dCalcRawPartTime As Double Get Return If(SectionPartList.Count > 0 AndAlso SParamList.Count > 0, Math.Max(SectionPartList.Count / 20, 2), 0) End Get End Property Sub New(Section As SectionXMaterial) m_Section = Section End Sub Friend Shared Sub SetPartSectionTimes(PartTime As Double, SectionTime As Double) m_dPartTime = PartTime m_dSectionTime = SectionTime End Sub Friend Sub SetSectionPartList(SectionPartList As List(Of BTLPartM)) m_SectionPartList = SectionPartList End Sub End Class