diff --git a/Application.xaml.vb b/Application.xaml.vb index 3a94af7..8d504c4 100644 --- a/Application.xaml.vb +++ b/Application.xaml.vb @@ -143,6 +143,8 @@ Class Application Friend Const DRAWOPTIONPANEL_CLOSING As String = "DrawOptionPanel_Closing" Friend Const UPDATEOBJDATAINOBJTREE As String = "UpdateObjDataInObjTree" Friend Const SETINFOBOX As String = "SetInfoBox" + Friend Const RIGHTCLICKEDLAYERTREEITEM As String = "RightClickedLayerTreeItem" + Friend Const SAVEOBJECT As String = "SaveObject" ' StatusBar messages Friend Const STATUSGRIDCOMMAND As String = "StatusGridCommand" @@ -150,7 +152,6 @@ Class Application Friend Const STATUSCURRPOSTYPETEXT As String = "StatusCurrPosTypeText" Friend Const STATUSUNITSCOMMAND As String = "StatusUnitsCommand" Friend Const UPDATESTATUSUNITS As String = "UpdateStatusUnits" - Friend Const STATUSSTOPCOMMAND As String = "StatusStopCommand" Friend Const STATUSSNAPPOINTTYPETEXT As String = "StatusSnapPointTypeText" Friend Const STATUSSNAPPOINTTYPEBACKGROUND As String = "StatusSnapPointTypeBackground" Friend Const LOADSELECTEDMACHINE As String = "LoadSelectedMachine" diff --git a/Constants/ConstMsg.vb b/Constants/ConstMsg.vb index 5cd6d0e..2916592 100644 --- a/Constants/ConstMsg.vb +++ b/Constants/ConstMsg.vb @@ -7,6 +7,7 @@ Public Const MSG_MAINWINDOW As Integer = MSG_EGTCAM5 Public Const MSG_DRAWPANEL As Integer = MSG_EGTCAM5 + 200 Public Const MSG_GRIDVIEWPANEL As Integer = MSG_EGTCAM5 + 250 + Public Const MSG_SIMULATION As Integer = MSG_EGTCAM5 + 300 Public Const MSG_TOOLSDBPAGE As Integer = MSG_EGTCAM5 + 1000 Public Const MSG_TOOLSERRORS As Integer = MSG_EGTCAM5 + 1085 Public Const MSG_MACHININGSDBPAGE As Integer = MSG_EGTCAM5 + 1100 diff --git a/EgtCAM5.vbproj b/EgtCAM5.vbproj index f2ffffa..5fc63cf 100644 --- a/EgtCAM5.vbproj +++ b/EgtCAM5.vbproj @@ -86,6 +86,10 @@ ..\..\EgtProg\DllD32\EgtWPFLib5.dll False + + False + ..\..\EgtProg\EgtCAM5\Microsoft.Expression.Interactions.dll + diff --git a/IniFile.vb b/IniFile.vb index 08f5856..78b9464 100644 --- a/IniFile.vb +++ b/IniFile.vb @@ -19,6 +19,9 @@ Module IniFile Friend m_sMachinesRoot As String ' Project Page Friend m_ProjectSceneContext As Integer = 0 + Friend m_bScriptRunning As Boolean = False + Friend m_bStopScript As Boolean = False + ' TOOLS DB PAGE Friend m_sDbsCurrMachIniFilePath As String 'IniFile della macchina correntemente selezionata nella pagina di Db selezionata (Tools o Machinings) Friend m_sTdbCurrMachToolsDirPath As String diff --git a/MainWindow/MainWindowViewModel.vb b/MainWindow/MainWindowViewModel.vb index 1f41112..6e1063f 100644 --- a/MainWindow/MainWindowViewModel.vb +++ b/MainWindow/MainWindowViewModel.vb @@ -1,5 +1,7 @@ Imports System.Collections.ObjectModel Imports System.Threading +Imports System.Windows.Threading +Imports System.Runtime.InteropServices Imports System.Math Imports EgtUILib @@ -22,6 +24,8 @@ Namespace EgtCAM5 Friend Enum KEY_OPT As UInteger BASE = 1 End Enum + Private m_ProcEventsCallback As New ProcessEventsCallback(AddressOf ProcessEvents) + Private m_OutTextCallback As New OutTextCallback(AddressOf OutText) ' EGALTECH ENVIRONMENT FIELDS WITH PROPERTY @@ -381,12 +385,10 @@ Namespace EgtCAM5 '' Impostazioni MruLists 'm_MruFiles.Init(m_sIniFile, S_MRUFILES, 8) 'm_MruScripts.Init(m_sIniFile, S_MRUSCRIPTS, 8) - '' Impostazione Testi e ToolTips - 'SetMessages() - '' Installo funzione gestione eventi per lua - 'EgtSetProcessEvents(m_ProcEventsCallback) - '' Installo funzione output testo su status per lua - 'EgtSetOutText(m_OutTextCallback) + ' Installo funzione gestione eventi per lua + EgtSetProcessEvents(m_ProcEventsCallback) + ' Installo funzione output testo su status per lua + EgtSetOutText(m_OutTextCallback) ' Info su opzioni chiave EgtOutLog("KeyOptions : " & bKey.ToString() & " " & m_nKeyOptions.ToString()) @@ -452,6 +454,30 @@ Namespace EgtCAM5 End If End Sub + Public Function ProcessEvents(ByVal nProg As Integer, ByVal nPause As Integer) As Integer + ' Se previsto, imposto progress + If nProg > 0 Then + Application.Msn.NotifyColleagues(Application.NOTIFYSTATUSPROGRESS, nProg) + End If + ' Costringo ad aggiornare + Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Sub() + End Sub)) + ' Eventuale attesa + Thread.Sleep(nPause) + ' Ritorno eventuale stop + If m_bStopScript Then + m_bStopScript = False + Return 0 + Else + Return 1 + End If + End Function + + Public Function OutText(ByRef psText As IntPtr) As Boolean + Application.Msn.NotifyColleagues(Application.NOTIFYSTATUSOUTPUT, Marshal.PtrToStringUni(psText)) + Return True + End Function + #End Region #Region "Events" diff --git a/ProjectPage/DrawPanel/DrawPanelViewModel.vb b/ProjectPage/DrawPanel/DrawPanelViewModel.vb index 637e453..840af81 100644 --- a/ProjectPage/DrawPanel/DrawPanelViewModel.vb +++ b/ProjectPage/DrawPanel/DrawPanelViewModel.vb @@ -5,6 +5,8 @@ Namespace EgtCAM5 Public Class DrawPanelViewModel Inherits ViewModelBase + Private WithEvents IdleTimer As New System.Windows.Threading.DispatcherTimer(TimeSpan.FromMilliseconds(200), Windows.Threading.DispatcherPriority.ApplicationIdle, AddressOf OnIdle, Application.Current.Dispatcher) + #Region "FIELDS & PROPERTIES" #Region "ToolTip" @@ -1602,6 +1604,10 @@ Namespace EgtCAM5 #End Region ' Commands + Private Sub OnIdle() + CommandManager.InvalidateRequerySuggested() + End Sub + End Class End Namespace \ No newline at end of file diff --git a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/LayerTreeView.vb b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/LayerTreeView.vb index ea02ca0..bb0fbb2 100644 --- a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/LayerTreeView.vb +++ b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/LayerTreeView.vb @@ -29,6 +29,25 @@ Public Class LayerTreeViewItem End Set End Property + Private m_IsRightSelected As Boolean + ''' + ''' Property that determines if the Tool is selected or not + ''' + Public Property IsRightSelected As Boolean + Get + Return m_IsRightSelected + End Get + Set(value As Boolean) + ' In realtà il valore di value è insignificante perchè la cosa importante è che il click esegua questo Set + m_IsRightSelected = value + Application.Msn.NotifyColleagues(Application.RIGHTCLICKEDLAYERTREEITEM, Me.Id) + 'If value Then + ' ' recupero l'Id del nuovo oggetto selezionato + ' Application.Msn.NotifyColleagues(Application.UPDATEOBJINOBJTREE, Me.Id) + 'End If + End Set + End Property + Private m_Items As New ObservableCollection(Of LayerTreeViewItem) Public Property Items As ObservableCollection(Of LayerTreeViewItem) Get diff --git a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderView.xaml b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderView.xaml index 2af7fa1..c68af7b 100644 --- a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderView.xaml +++ b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderView.xaml @@ -1,8 +1,10 @@  + @@ -20,19 +22,21 @@ + + + + + - - - - + @@ -61,7 +65,20 @@ - + + + + + + + + + + + + + + diff --git a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderViewModel.vb b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderViewModel.vb index f20f559..d9411b8 100644 --- a/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderViewModel.vb +++ b/ProjectPage/OptionPanel/DrawOptionPanel/ManageLayerExpander/ManageLayerExpanderViewModel.vb @@ -39,6 +39,14 @@ Namespace EgtCAM5 Private m_cmdTreeViewDoubleClick As ICommand Private m_cmdTreeViewMouseUp As ICommand Private m_cmdTreeViewMouseRightButton As ICommand + Private m_cmdSelect As ICommand + Private m_cmdDeselect As ICommand + Private m_cmdName As ICommand + Private m_cmdInfo As ICommand + Private m_cmdRelocate As ICommand + Private m_cmdCopy As ICommand + Private m_cmdDelete As ICommand + Private m_cmdSave As ICommand ' Lista dei layer Private m_LayerList As New ObservableCollection(Of LayerTreeViewItem) @@ -51,13 +59,21 @@ Namespace EgtCAM5 End Set End Property + ' + Private m_RightClickedTreeItemId As Integer + Public ReadOnly Property RightClickedTreeItemId As Integer + Get + Return m_RightClickedTreeItemId + End Get + End Property + #End Region #Region "CONSTRUCTOR" Sub New() 'Imposto tempo di evidenziazione delle entità clickate - ObjTreeTimer.Interval = New TimeSpan(0, 0, 1) + ObjTreeTimer.Interval = TimeSpan.FromMilliseconds(200) Application.Msn.Register(Application.LOADOBJTREE, Sub() LoadObjTree() End Sub) @@ -82,6 +98,10 @@ Namespace EgtCAM5 Application.Msn.Register(Application.UPDATEOBJTREEOLDID, Sub(ObjTreeOldId As Integer) Me.m_nObjTreeOldId = ObjTreeOldId End Sub) + Application.Msn.Register(Application.RIGHTCLICKEDLAYERTREEITEM, Sub(Id As Integer) + m_RightClickedTreeItemId = Id + End Sub) + End Sub #End Region ' Constructor @@ -302,6 +322,256 @@ Namespace EgtCAM5 #End Region ' TreeViewMouseUpCommand +#Region "SelectCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property SelectCommand As ICommand + Get + If m_cmdSelect Is Nothing Then + m_cmdSelect = New RelayCommand(AddressOf SelectCmd, AddressOf CanSelect) + End If + Return m_cmdSelect + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub SelectCmd(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.SELECTPARTLAYEROBJ) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanSelect(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' SelectCommand + +#Region "DeselectCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property DeselectCommand As ICommand + Get + If m_cmdDeselect Is Nothing Then + m_cmdDeselect = New RelayCommand(AddressOf Deselect, AddressOf CanDeselect) + End If + Return m_cmdDeselect + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Deselect(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.DESELECTPARTLAYEROBJ) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanDeselect(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' DeselectCommand + +#Region "NameCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property NameCommand As ICommand + Get + If m_cmdName Is Nothing Then + m_cmdName = New RelayCommand(AddressOf Name, AddressOf CanName) + End If + Return m_cmdName + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Name(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.SETNAME) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanName(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' NameCommand + +#Region "InfoCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property InfoCommand As ICommand + Get + If m_cmdInfo Is Nothing Then + m_cmdInfo = New RelayCommand(AddressOf Info, AddressOf CanInfo) + End If + Return m_cmdInfo + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Info(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.SETINFO) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanInfo(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' InfoCommand + +#Region "RelocateCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property RelocateCommand As ICommand + Get + If m_cmdRelocate Is Nothing Then + m_cmdRelocate = New RelayCommand(AddressOf Relocate, AddressOf CanRelocate) + End If + Return m_cmdRelocate + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Relocate(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.RELOCATEPARTLAYEROBJ) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanRelocate(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' RelocateCommand + +#Region "CopyCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property CopyCommand As ICommand + Get + If m_cmdCopy Is Nothing Then + m_cmdCopy = New RelayCommand(AddressOf Copy, AddressOf CanCopy) + End If + Return m_cmdCopy + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Copy(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.COPYPARTLAYEROBJ) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanCopy(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' CopyCommand + +#Region "DeleteCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property DeleteCommand As ICommand + Get + If m_cmdDelete Is Nothing Then + m_cmdDelete = New RelayCommand(AddressOf Delete, AddressOf CanDelete) + End If + Return m_cmdDelete + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Delete(ByVal param As Object) + Application.Msn.NotifyColleagues(Application.SETLASTINTEGER, RightClickedTreeItemId) + Application.Msn.NotifyColleagues(Application.EXECUTECOMMAND, Controller.CMD.DELETE) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanDelete(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' DeleteCommand + +#Region "SaveCommand" + + ''' + ''' Returns a command that do Point. + ''' + Public ReadOnly Property SaveCommand As ICommand + Get + If m_cmdSave Is Nothing Then + m_cmdSave = New RelayCommand(AddressOf Save, AddressOf CanSave) + End If + Return m_cmdSave + End Get + End Property + + ''' + ''' Execute the Point. This method is invoked by the PointCommand. + ''' + Public Sub Save(ByVal param As Object) + Dim sDir As String = String.Empty + GetPrivateProfileString(S_GENERAL, K_LASTNGEOBJDIR, "", sDir) + Dim nType As NGE = DirectCast(GetPrivateProfileInt(S_GEOMDB, K_SAVETYPE, NGE.CMPTEXT), NGE) + Application.Msn.NotifyColleagues(Application.SAVEOBJECT, New SaveObjectParam(m_RightClickedTreeItemId, sDir, nType)) + End Sub + + ''' + ''' Returns always true. + ''' + Private Function CanSave(ByVal param As Object) As Boolean + Return True + End Function + +#End Region ' SaveCommand + #End Region ' Commands #Region "METHODS" diff --git a/ProjectPage/OptionPanel/MachiningOptionPanel/SimulationExpander/SimulationExpanderViewModel.vb b/ProjectPage/OptionPanel/MachiningOptionPanel/SimulationExpander/SimulationExpanderViewModel.vb index 5a5e4fe..c1e73bb 100644 --- a/ProjectPage/OptionPanel/MachiningOptionPanel/SimulationExpander/SimulationExpanderViewModel.vb +++ b/ProjectPage/OptionPanel/MachiningOptionPanel/SimulationExpander/SimulationExpanderViewModel.vb @@ -446,8 +446,6 @@ Namespace EgtCAM5 ResetSimulation() ' Nascondo tutte le lavorazioni 'HideAllMachinings() - ' Cancello eventuali messaggi - 'm_CurrProjPage.ClearMessage() End Sub @@ -480,29 +478,27 @@ Namespace EgtCAM5 ' Imposto stato Pausa m_nStatus = SIM_ST.ST_PAUSE ' Aggiornamenti per bottone Play/Pause - 'SetPlayPauseBtnToPlay() m_bPlay = True OnPropertyChanged("PlayPauseImage") End If ' Se movimento non riuscito Else m_nStatus = SIM_ST.ST_STOP + ' Aggiornamenti per bottone Play/Pause m_bPlay = True OnPropertyChanged("PlayPauseImage") - ' Aggiornamenti per bottone Play/Pause - 'SetPlayPauseBtnToPlay() - 'Select Case nMove - ' Case MCH_SIM.END_ - ' m_CurrProjPage.SetInfoMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 1)) 'Simulazione completata - ' Case MCH_SIM.OUTSTROKE - ' Dim sInfo As String = String.Empty - ' EgtGetOutstrokeInfo(sInfo) - ' m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 2) & " " & sInfo) 'Extracorsa ... - ' Case MCH_SIM.DIR_ERR - ' m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 3)) 'Direzione utensile irraggiungibile - ' Case Else - ' m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 4)) 'Errore - 'End Select + Select Case nMove + Case MCH_SIM.END_ + MsgBox(EgtMsg(MSG_SIMULATION + 1)) 'Simulazione completata + Case MCH_SIM.OUTSTROKE + Dim sInfo As String = String.Empty + EgtGetOutstrokeInfo(sInfo) + MsgBox(EgtMsg(MSG_SIMULATION + 2) & " " & sInfo, MsgBoxStyle.OkOnly, "ERROR") 'Extracorsa ... + Case MCH_SIM.DIR_ERR + MsgBox(EgtMsg(MSG_SIMULATION + 3), MsgBoxStyle.OkOnly, "ERROR") 'Direzione utensile irraggiungibile + Case Else + MsgBox(EgtMsg(MSG_SIMULATION + 4), MsgBoxStyle.OkOnly, "ERROR") 'Errore + End Select End If ' Aggiorno stato visualizzazione macchina (dipende anche da utensile) 'UpdateMachView() diff --git a/ProjectPage/ProjectViewModel.vb b/ProjectPage/ProjectViewModel.vb index 463b813..7033235 100644 --- a/ProjectPage/ProjectViewModel.vb +++ b/ProjectPage/ProjectViewModel.vb @@ -50,9 +50,7 @@ Namespace EgtCAM5 Private m_bMmUnits As Boolean 'Private m_MruFiles As New MruList 'Private m_MruScripts As New MruList - Private m_bScriptRunning As Boolean = False 'Private m_bStopExec As Boolean = False - Private m_bStopScript As Boolean = False 'Private m_ProcEventsCallback As New ProcessEventsCallback(AddressOf ProcessEvents) 'Private m_OutTextCallback As New OutTextCallback(AddressOf OutText) @@ -501,6 +499,9 @@ Namespace EgtCAM5 Application.Msn.Register(Application.DONE, Sub(sString As String) m_Controller.Done(sString) End Sub) + Application.Msn.Register(Application.SAVEOBJECT, Sub(SaveObjectParam As SaveObjectParam) + m_Controller.SaveObject(SaveObjectParam.nId, SaveObjectParam.sDir, SaveObjectParam.nType) + End Sub) End Sub Sub RegisterStatusBarCommands() @@ -524,10 +525,6 @@ Namespace EgtCAM5 LoadGridData() EgtDraw() End Sub) - Application.Msn.Register(Application.STATUSSTOPCOMMAND, Sub() - m_bStopScript = True - End Sub) - End Sub Sub RegisterControllerCommands() diff --git a/StatusBar/StatusBarViewModel.vb b/StatusBar/StatusBarViewModel.vb index e197321..bc1373a 100644 --- a/StatusBar/StatusBarViewModel.vb +++ b/StatusBar/StatusBarViewModel.vb @@ -316,7 +316,7 @@ Namespace EgtCAM5 ''' Execute the Point. This method is invoked by the CurrPosTypeCommand. ''' Public Sub StatusStop(ByVal param As Object) - Application.Msn.NotifyColleagues(Application.STATUSSTOPCOMMAND) + m_bStopScript = True End Sub ''' diff --git a/StructureDataForMessenger.vb b/StructureDataForMessenger.vb index 9bbb25d..625f2b2 100644 --- a/StructureDataForMessenger.vb +++ b/StructureDataForMessenger.vb @@ -1,4 +1,6 @@ -Namespace EgtCAM5 +Imports EgtUILib + +Namespace EgtCAM5 Public Class PrepareInputBoxParam Friend sTitle As String @@ -40,4 +42,17 @@ End Class + Public Class SaveObjectParam + Friend nId As Integer + Friend sDir As String + Friend nType As NGE + + Sub New(nId As Integer, sDir As String, nType As NGE) + Me.nId = nId + Me.sDir = sDir + Me.nType = nType + End Sub + + End Class + End Namespace