'---------------------------------------------------------------------------- ' EgalTech 2015-2015 '---------------------------------------------------------------------------- ' File : Camera.vb Data : 08.10.15 Versione : 1.6j1 ' Contenuto : Classe Camera (gestione della macchina fotografica). ' ' ' ' Modifiche : 08.10.15 DS Creazione modulo. ' ' '---------------------------------------------------------------------------- Imports System.Threading Imports System.IO Imports EgtUILib Public Class Camera ' Riferimento alla MainWindow Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow) ' Dati Private m_bCameraLink As Boolean = False Private m_bCalcContour As Boolean = False Private m_nCameraCount As Integer = 0 Private m_sCameraPath As String = String.Empty Private m_sCameraPath2 As String = String.Empty Private m_sCameraProcName As String = String.Empty Private m_sCameraProcName2 As String = String.Empty Private m_sImage As String = String.Empty Private m_sImage2 As String = String.Empty Private m_sInfo As String = String.Empty Private m_sInfo2 As String = String.Empty Private m_sResult As String = String.Empty Private m_sResult2 As String = String.Empty Private m_sContour As String = String.Empty Private m_sContour2 As String = String.Empty Private m_nThreshold As Integer = 60 Private m_dTolerance As Double = 5 Private m_nTimeout As Integer = 30 Private m_sImageDir As String = String.Empty ' Flag per foto in esecuzione Friend m_bBusy As Boolean = False Public Function Init() As Boolean ' Lettura dati di configurazione da file Ini m_bCameraLink = (GetPrivateProfileInt(S_GENERAL, K_CAMERALINK, 0, m_MainWindow.GetIniFile()) <> 0) And Not m_MainWindow.GetKeyOption( MainWindow.KEY_OPT.OFFICE_TYPE) m_nCameraCount = GetPrivateProfileInt(S_CAMERA, K_CAM_COUNT, 1, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_EXEPATH, "", m_sCameraPath, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_IMAGE, "", m_sImage, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_INFO, "", m_sInfo, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_RESULT, "", m_sResult, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_CONTOUR, "", m_sContour, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_EXEPATH2, "", m_sCameraPath2, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_IMAGE2, "", m_sImage2, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_INFO2, "", m_sInfo2, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_RESULT2, "", m_sResult2, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_CAMERA, K_CAM_CONTOUR2, "", m_sContour2, m_MainWindow.GetIniFile()) m_nThreshold = GetPrivateProfileInt(S_CAMERA, K_CAM_THRESHOLD, 60, m_MainWindow.GetIniFile()) m_dTolerance = GetPrivateProfileDouble(S_CAMERA, K_CAM_TOLERANCE, 5, m_MainWindow.GetIniFile()) m_nTimeout = GetPrivateProfileInt(S_CAMERA, K_CAM_TIMEOUT, 30, m_MainWindow.GetIniFile()) GetPrivateProfileString(S_GENERAL, K_IMAGEDIR, "", m_sImageDir, m_MainWindow.GetIniFile()) ' Verifico abilitazione riconoscimento contorno automatico del grezzo m_bCalcContour = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.AUTO_PHOTO) AndAlso (GetPrivateProfileInt(S_GENERAL, K_CONTOURFROMCAMERA, 1, m_MainWindow.GetIniFile()) <> 0) ' Ricavo il nome del processo associato m_sCameraProcName = Path.GetFileNameWithoutExtension(m_sCameraPath) m_sCameraProcName2 = Path.GetFileNameWithoutExtension(m_sCameraPath2) ' Se camera abilitata, lancio l'esecuzione in cieco If m_bCameraLink Then If m_nCameraCount <> 2 Then Dim bOk As Boolean = True If Not CameraHide(1) Then bOk = False EgtOutLog("CameraMng not starting") End If Return bOk Else Dim bOk As Boolean = True If Not CameraHide(1) Then bOk = False EgtOutLog("CameraMng 1 not starting") End If If Not CameraHide(2) Then bOk = False EgtOutLog("CameraMng 2 not starting") End If Return bOk End If Else Return True End If End Function Public Function Close() As Boolean If m_bBusy Then Return False If m_bCameraLink Then If m_nCameraCount <> 2 Then KillProcess(1) Else KillProcess(1) KillProcess(2) End If End If Return True End Function Public Function GetCalcContour() As Boolean Return m_bCalcContour End Function Public Function GetCameraLink() As Boolean Return m_bCameraLink End Function Friend Property Threshold As Integer Get Return m_nThreshold End Get Set(value As Integer) ' Porto il valore nel range valido If value < 10 Then value = 10 ElseIf value > 90 Then value = 90 End If ' Se cambiato, aggiorno file INI If value <> m_nThreshold And WritePrivateProfileString(S_CAMERA, K_CAM_THRESHOLD, DoubleToString(value, 3), m_MainWindow.GetIniFile()) Then ' Aggiorno il valore corrente m_nThreshold = value End If End Set End Property Friend Property Tolerance As Double Get Return m_dTolerance End Get Set(value As Double) ' Porto il valore nel range valido If value < 100 * EPS_SMALL Then value = 100 * EPS_SMALL End If ' Se cambiato, aggiorno file INI If value <> m_dTolerance And WritePrivateProfileString(S_CAMERA, K_CAM_TOLERANCE, DoubleToString(value, 3), m_MainWindow.GetIniFile()) Then ' Aggiorno il valore corrente m_dTolerance = value End If End Set End Property Public Function CameraHide(nInd As Integer) As Boolean ' Lancio il programma in cieco, se già attivo lo nascondo Try Process.Start(If(nInd <> 2, m_sCameraPath, m_sCameraPath2), "0") Return True Catch ex As Exception Return False End Try End Function Public Function CameraShow(nInd As Integer) As Boolean ' Lancio il programma in modo visibile, se già attivo lo rendo visibile Try Process.Start(If(nInd <> 2, m_sCameraPath, m_sCameraPath2), "1") Return True Catch ex As Exception Return False End Try End Function Public Function CameraTest(nInd As Integer) As Boolean ' Cancello il risultato If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sResult, m_sResult2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sResult, m_sResult2)) End If ' Lancio il programma per sapere se macchina fotografica collegata Try ' Interrogo Process.Start(If(nInd <> 2, m_sCameraPath, m_sCameraPath2), "3") ' Ciclo di attesa risultato Dim nMaxThick = 10 * 4 For nThick As Integer = 0 To nMaxThick ' Se esiste il file di risultato Dim nErr = 999 If VerifyResult(nInd, nErr) Then Return (nErr = 0) End If ' Aspetto 100 ms Thread.Sleep(100) Next Catch ex As Exception ' End Try Return False End Function Private Function PrepareCamera() As Integer ' Determino la camera da utilizzare, se più di una (max 2) Dim nInd As Integer = 1 If m_nCameraCount = 2 Then nInd = GetCurrentTable() ' verifico se la macchina è configurata per fotocamera sulla tavola di lavoro If (GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ENABLE, 0, m_MainWindow.GetMachIniFile()) <> 0) AndAlso (GetPrivateProfileInt(S_CAMERAHQ, K_CAMERAHQ_ACTIVATE, 0, m_MainWindow.GetMachIniFile()) <> 0) Then ' forzo l'utilizzo della seconda camera (sopra alla tavola di lavoro) nInd = 2 End If If nInd <> 1 And nInd <> 2 Then Return 0 End If ' Se gestore macchina non attivo, lo lancio in modo cieco If Not ProcessIsRunning(nInd) Then If Not CameraHide(nInd) Then Return 0 End If ' Aspetto 5000 ms Thread.Sleep(5000) ' Altrimenti richiedo verifica di camera connessa Else If Not CameraTest(nInd) Then Return 0 End If ' Aspetto 100 ms Thread.Sleep(100) End If Return nInd End Function Public Function CameraBackImage() As Boolean ' Verifiche preliminari Dim nInd As Integer = PrepareCamera() If nInd = 0 Then Return False ' Visualizzo progressbar m_bBusy = True m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Visibility = Visibility.Visible m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = 1 ' Cancellazione eventuali vecchi file rimasti Try If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sResult, m_sResult2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sResult, m_sResult2)) End If Catch ex As Exception End Try ' Scatto una foto come sfondo (il programma deve essere già attivo) Dim bOk As Boolean = False Try Process.Start(If(nInd <> 2, m_sCameraPath, m_sCameraPath2), "4") bOk = WaitBackImage(nInd) Catch ex As Exception bOk = False End Try ' Nascondo progressbar m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Visibility = Visibility.Hidden m_bBusy = False Return bOk End Function Private Function WaitBackImage(nInd As Integer) As Boolean ' Ciclo di ricerca foto scattata Dim nMaxThick = 10 * m_nTimeout For nThick As Integer = 0 To nMaxThick ' Se esiste il file di risultato Dim nErr = 999 If VerifyResult(nInd, nErr) Then If nErr = 0 Then Return True Else EgtOutLog("Camera err=" & nErr.ToString()) Return False End If ' Altrimenti aspetto Else ' Imposto ProgressBar Dim nProgress As Integer = CInt(nThick * 100 / nMaxThick) m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = nProgress ' Costringo ad aggiornare UI UpdateUI() ' Aspetto 100 ms Thread.Sleep(100) End If Next EgtOutLog("Camera generic error") ' Chiudo il gestore della macchina per resettarlo KillProcess(nInd) Return False End Function Public Function CameraClick() As Boolean ' Verifiche preliminari Dim nInd As Integer = PrepareCamera() ' Visualizzo progressbar m_bBusy = True m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Visibility = Visibility.Visible m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = 1 ' Cancellazione eventuali vecchi file rimasti Try If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sResult, m_sResult2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sResult, m_sResult2)) End If If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sImage, m_sImage2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sImage, m_sImage2)) End If If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sContour, m_sContour2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sContour, m_sContour2)) End If If My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sInfo, m_sInfo2)) Then My.Computer.FileSystem.DeleteFile(If(nInd <> 2, m_sInfo, m_sInfo2)) End If Catch ex As Exception End Try ' ------------------------------------ accensione riflettori ------------------------------------ Dim sPLCVarSpotLight1 As String = String.Empty GetPrivateProfileString(S_NCDATA, K_SPOTLIGHT1, "", sPLCVarSpotLight1, m_MainWindow.GetMachIniFile()) Dim sPLCVarSpotLight2 As String = String.Empty GetPrivateProfileString(S_NCDATA, K_SPOTLIGHT2, "", sPLCVarSpotLight2, m_MainWindow.GetMachIniFile()) Dim nPhotoDeley As Integer = GetPrivateProfileInt(S_NCNUM, K_PHOTODELEY, "100", m_MainWindow.GetMachIniFile()) ' eventualmente rimuovo inizio stringa: "PLC, ___" Dim sItemString1() As String = Split(sPLCVarSpotLight1, ","c) If sItemString1.Count > 1 Then sPLCVarSpotLight1 = sItemString1(1).Trim End If Dim sItemString2() As String = Split(sPLCVarSpotLight2, ","c) If sItemString2.Count > 1 Then sPLCVarSpotLight2 = sItemString2(1).Trim End If Select Case m_MainWindow.m_CNCommunication.m_nNCType Case 1, 2 If m_MainWindow.m_CNCommunication.m_nNCType = 2 Then ' solo per Flexium m_MainWindow.m_CNCommunication.m_CN.DPlcVariables_WriteVariables(If(nInd <> 2, sPLCVarSpotLight1, sPLCVarSpotLight2), "1") ' altrimenti scrittura delle variabili E Else m_MainWindow.m_CNCommunication.m_CN.DVariables_WriteVariables2(If(nInd <> 2, sPLCVarSpotLight1, sPLCVarSpotLight2), "1") End If System.Threading.Thread.Sleep(nPhotoDeley) Case 3 ' SIEMENS End Select ' ------------------------------------ accensione riflettori ------------------------------------ ' Scatto una foto con eventuale riconoscimento del contorno (il programma deve essere già attivo) Dim bOk As Boolean = False Dim sArgs As String = "2 0" If m_bCalcContour Then sArgs = " 5 0 " & m_nThreshold.ToString() & " 0" Try Process.Start(If(nInd <> 2, m_sCameraPath, m_sCameraPath2), sArgs) bOk = WaitPhoto(nInd) Catch ex As Exception EgtOutLog(ex.Message()) bOk = False End Try ' Nascondo progressbar m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Visibility = Visibility.Hidden m_bBusy = False Return bOk End Function Private Function WaitPhoto(nInd As Integer) As Boolean ' Ciclo di ricerca foto scattata Dim nMaxThick = 10 * m_nTimeout For nThick As Integer = 0 To nMaxThick ' Se esiste il file di risultato Dim nErr = 999 If VerifyResult(nInd, nErr) Then If nErr = 0 Then ' Copio i file Dim sImageDest As String = m_sImageDir & "\" & Path.GetFileName(If(nInd <> 2, m_sImage, m_sImage2)) Dim sInfoDest As String = Path.ChangeExtension(sImageDest, "txt") File.Copy(If(nInd <> 2, m_sImage, m_sImage2), sImageDest, True) File.Copy(If(nInd <> 2, m_sInfo, m_sInfo2), sInfoDest, True) ' Se richiesto il riconoscimento del contorno Dim sContourDest As String = String.Empty If m_bCalcContour Then sContourDest = Path.ChangeExtension(sImageDest, "dxf") File.Copy(If(nInd <> 2, m_sContour, m_sContour2), sContourDest, True) ' altrimenti cancello eventuale contorno presente Else m_MainWindow.m_CurrentProjectPageUC.RemoveContour() End If ' Lancio caricamento della foto e del contorno m_MainWindow.m_CadCutPageUC.PostPhoto(sImageDest, sContourDest) Return True Else EgtOutLog("Camera err=" & nErr.ToString()) Return False End If ' Altrimenti aspetto Else ' Imposto ProgressBar Dim nProgress As Integer = CInt(nThick * 100 / nMaxThick) m_MainWindow.m_CurrentProjectPageUC.PhotoProgress.Value = nProgress ' Costringo ad aggiornare UI UpdateUI() ' Aspetto 100 ms Thread.Sleep(100) End If Next EgtOutLog("Camera generic error") ' Chiudo il gestore della macchina per resettarlo KillProcess(nInd) Return False End Function Private Function VerifyResult(nInd As Integer, ByRef nErr As Integer) As Boolean ' Se non esiste il file con il risultato If Not My.Computer.FileSystem.FileExists(If(nInd <> 2, m_sResult, m_sResult2)) Then Return False End If ' Leggo il file Dim bOk As Boolean = False Try ' Controllo errori nel file di info Dim sLine As String = String.Empty Dim sr As StreamReader = New StreamReader(If(nInd <> 2, m_sResult, m_sResult2)) Do While sr.Peek() > -1 sLine = sr.ReadLine() sLine = sLine.Replace(" ", "") If sLine.StartsWith("Err=") Then If Int32.TryParse(sLine.Substring(4), nErr) Then bOk = True Exit Do End If End If Loop sr.Close() Catch ex As Exception bOk = False End Try Return bOk End Function Private Function ProcessIsRunning(nInd As Integer) As Boolean Dim Procs() As Process Procs = Process.GetProcessesByName(If(nInd <> 2, m_sCameraProcName, m_sCameraProcName2)) Return (Procs.Length() > 0) End Function Private Sub KillProcess(nInd As Integer) Dim Procs() As Process Procs = Process.GetProcessesByName(If(nInd <> 2, m_sCameraProcName, m_sCameraProcName2)) For i As Integer = 0 To Procs.Length() - 1 Procs(i).Kill() Procs(i).WaitForExit(2000) Next i End Sub End Class