]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/wxMaracas_ViewerWidget.cxx
86642eedc29c069e2b420eb7a9a30617c9b5f01f
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / wxMaracas_ViewerWidget.cxx
1 /*=========================================================================
2
3   Program:   wxMaracas
4   Module:    $RCSfile: wxMaracas_ViewerWidget.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/12/01 21:22:12 $
7   Version:   $Revision: 1.21 $
8
9   Copyright: (c) 2002, 2003
10   License:
11   
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notice for more information.
15
16 =========================================================================*/
17
18 //------------------------------------------------------------------------------------------------------------
19 // Definition includes
20 //------------------------------------------------------------------------------------------------------------
21 #include "wxMaracas_ViewerWidget.h"
22
23 //------------------------------------------------------------------------------------------------------------
24 // Other includes
25 //------------------------------------------------------------------------------------------------------------
26
27
28         //------------------------------------------------------------------------------------------------------------
29         // Constructors & Destructors
30         //------------------------------------------------------------------------------------------------------------
31
32
33         wxMaracas_ViewerWidget::wxMaracas_ViewerWidget(wxWindow *parent, vtkImageData* imagedata, int type, vtkMPRBaseData *vtkmprbasedata)
34                 : wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
35         {
36                 wxPanel *panel = this;
37                 wxWindow *wxwindow = NULL;
38
39                 mType = type;
40
41                 
42                 if (vtkmprbasedata==NULL)
43                 {
44                         minternalVtkmprbasedata                 = true;
45                         mvtkmprbasedata                                 = new vtkMPRBaseData(); 
46                         marImageData    *marimagedata   = new marImageData( imagedata );                        
47                         mvtkmprbasedata->SetMarImageData(marimagedata);
48                 } else {
49                         minternalVtkmprbasedata                 = false;
50                         mvtkmprbasedata                                 = vtkmprbasedata; 
51                 }
52                 
53
54                 mvtk2Dbaseview                          = NULL;
55                 mvtkmpr2Dview_X                         = NULL;
56                 mvtkmpr2Dview_Y                         = NULL;
57                 mvtkmpr2Dview_Z                         = NULL;
58                 mvtkplane2Dview                         = NULL;
59                 mwidgetMesure                           = NULL;
60                 mwxsphereview                           = NULL;
61                 mwxvtkclipping3Dview            = NULL;
62                 mwxvtk3Dbaseview_Clipping3D     = NULL;
63                 mwxvtkmpr3Dview                         = NULL;
64                 vtkmpr3Ddataviewer                      = NULL;
65
66
67                 if (type==-1)
68                 {
69                         mvtk2Dbaseview  = new wxVtk2DBaseView(panel);
70                         mvtk2Dbaseview->SetVtkBaseData(mvtkmprbasedata);
71                         wxwindow                = mvtk2Dbaseview->GetWxVTKRenderWindowInteractor();
72                 }
73
74
75                 if (type==0)
76                 {
77                         mvtkmpr2Dview_Z = new wxVtkMPR2DView(panel,2);
78                         mvtkmpr2Dview_Z->SetVtkBaseData(mvtkmprbasedata);
79                         wxwindow                = mvtkmpr2Dview_Z->GetWxVTKRenderWindowInteractor();
80                 }
81                 if (type==1)
82                 {
83                         mvtkmpr2Dview_X = new wxVtkMPR2DView(panel,0);
84                         mvtkmpr2Dview_X->SetVtkBaseData(mvtkmprbasedata);
85                         wxwindow                =       mvtkmpr2Dview_X->GetWxVTKRenderWindowInteractor();
86                 }
87
88                 if (type==2)
89                 {
90                         mvtkmpr2Dview_Y = new wxVtkMPR2DView(panel,1);
91                         mvtkmpr2Dview_Y->SetVtkBaseData(mvtkmprbasedata);
92                         wxwindow                = mvtkmpr2Dview_Y->GetWxVTKRenderWindowInteractor();
93                 }
94
95
96                 if (type==3)
97                 {
98                         mwidgetMesure           = new wxWidgetMesure2D_Plane_in_MPR(panel);
99                         mvtkplane2Dview         = new vtkPlane2DView( mwidgetMesure->GetWindow2());
100                         mwidgetMesure   -> SetVtkPlane2DView( mvtkplane2Dview );
101                         mvtkplane2Dview -> SetImgSize( 200 );
102                         mvtkplane2Dview -> SetVtkBaseData(mvtkmprbasedata);
103                         wxwindow                        = mwidgetMesure;
104                 }
105                 if (type==4)
106                 {
107                         mwxsphereview           = new wxSphereView( panel , mvtkmprbasedata, mvtkmprbasedata->GetImageData() );
108                         wxwindow=mwxsphereview->GetWxVTKRenderWindowInteractor();
109                 }
110
111
112                 if (type==5)
113                 {
114                         wxSplitterWindow        *panelClipping3D        = new wxSplitterWindow( panel , -1);
115                         mwxvtk3Dbaseview_Clipping3D                             = new wxVtk3DBaseView( panelClipping3D );
116
117                         mwxvtkclipping3Dview                                            = new wxVtkClipping3DView(mwxvtk3Dbaseview_Clipping3D);
118                         vtkClipping3DDataViewer *vtkclipping3Ddataviewer = new vtkClipping3DDataViewer(); 
119                         vtkclipping3Ddataviewer->SetVtkMPRBaseData(mvtkmprbasedata);
120                         vtkclipping3Ddataviewer->Configure();
121                         mwxvtkclipping3Dview->SetVtkClipping3DDataViewer(vtkclipping3Ddataviewer);
122
123                         mwxvtkmpr3Dview                                                 = new wxVtkMPR3DView( mwxvtk3Dbaseview_Clipping3D );
124                         vtkMPR3DDataViewer *vtkmpr3Ddataviewer  = new vtkMPR3DDataViewer(); 
125                         vtkmpr3Ddataviewer->SetVtkMPRBaseData(mvtkmprbasedata);
126                         vtkmpr3Ddataviewer->Configure();
127                         mwxvtkmpr3Dview->SetVtkMPR3DDataViewer(vtkmpr3Ddataviewer);
128
129                         wxWindow        *window3D                                       = mwxvtk3Dbaseview_Clipping3D->GetWxVTKRenderWindowInteractor();
130
131                         wxPanel                 *panelControl                   = new wxPanel(panelClipping3D,-1);      
132                         wxPanel                 *controlPanelMPR3D              = mwxvtkmpr3Dview->CreateControlPanel(panelControl, false);
133                         wxPanel                 *controlPanelClipping3D = mwxvtkclipping3Dview->CreateControlPanel(panelControl);
134         //                               mbtnCutImageData               = new wxCheckBox(panelControl,-1,_T("Cut Module"));
135         //              Connect(_btnCutImageData->GetId() , wxEVT_COMMAND_CHECKBOX_CLICKED  , (wxObjectEventFunction) &wxMPRWidget::OnCutImagaData );
136
137                         wxFlexGridSizer  *sizerCtrol             = new wxFlexGridSizer(1);
138                         sizerCtrol->Add(controlPanelMPR3D               , 1, wxALL|wxEXPAND, 2);
139                         sizerCtrol->Add(controlPanelClipping3D  , 1, wxALL|wxEXPAND, 2);
140         //              sizerCtrol->Add( mbtnCutImageData               , 1, wxALL, 2);
141
142                         panelControl->SetAutoLayout(true);
143                         panelControl->SetSizer(sizerCtrol);
144                         panelControl->SetSize(400,350);
145                         panelControl->Layout();
146                         panelClipping3D -> SetMinimumPaneSize( 5 );
147                         panelClipping3D -> SplitHorizontally( panelControl , window3D , 10  );
148                         wxwindow=panelClipping3D;
149                 }
150
151                 if (type==6)
152                 {
153                         wxSplitterWindow        *panelClipping3D        = new wxSplitterWindow( panel , -1);
154                         mwxvtk3Dbaseview_Clipping3D                             = new wxVtk3DBaseView( panelClipping3D );
155
156                         mwxvtkmpr3Dview                                                 = new wxVtkMPR3DView( mwxvtk3Dbaseview_Clipping3D );
157
158
159                         vtkmpr3Ddataviewer      = new vtkMPR3DDataViewer();     
160
161                         
162
163                         wxWindow        *window3D                                       = mwxvtk3Dbaseview_Clipping3D->GetWxVTKRenderWindowInteractor();
164
165                         wxPanel                 *panelControl                   = new wxPanel(panelClipping3D,-1);      
166                         wxPanel                 *controlPanelMPR3D              = mwxvtkmpr3Dview->CreateControlPanel(panelControl, false);
167
168                         wxFlexGridSizer  *sizerCtrol             = new wxFlexGridSizer(1);
169                         sizerCtrol->Add(controlPanelMPR3D               , 1, wxALL|wxEXPAND, 2);
170
171                         panelControl->SetAutoLayout(true);
172                         panelControl->SetSizer(sizerCtrol);
173                         panelControl->SetSize(400,350);
174                         panelControl->Layout();
175                         panelClipping3D -> SetMinimumPaneSize( 5 );
176                         panelClipping3D -> SplitHorizontally( panelControl , window3D , 10  );
177                         wxwindow=panelClipping3D;
178
179
180                         vtkmpr3Ddataviewer->SetVtkMPRBaseData(mvtkmprbasedata);                 
181                         //vtkmpr3Ddataviewer->Configure();
182
183                         mwxvtkmpr3Dview->SetVtkMPR3DDataViewer(vtkmpr3Ddataviewer);
184                         
185                 }
186
187                 if (type==7)
188                 {
189                         mwxvtk3Dbaseview_Clipping3D                             = new wxVtk3DBaseView( panel );
190                         wxWindow        *window3D                                       = mwxvtk3Dbaseview_Clipping3D->GetWxVTKRenderWindowInteractor();
191                         wxwindow=window3D;
192
193 /*Borrame
194                         wxSplitterWindow        *panelClipping3D        = new wxSplitterWindow( panel , -1);
195                         mwxvtk3Dbaseview_Clipping3D                             = new wxVtk3DBaseView( panelClipping3D );
196                         wxWindow        *window3D                                       = mwxvtk3Dbaseview_Clipping3D->GetWxVTKRenderWindowInteractor();
197                         panelClipping3D ->SetMinimumPaneSize( 5 );
198                         panelClipping3D ->SplitHorizontally( new wxPanel(panelClipping3D,-1) , window3D , 10  );
199                         wxwindow=panelClipping3D;
200 */
201
202 /*Borrame
203                         wxSplitterWindow        *panelClipping3D        = new wxSplitterWindow( panel , -1);
204                         mwxvtk3Dbaseview_Clipping3D                             = new wxVtk3DBaseView( panelClipping3D );
205                         mwxvtkmpr3Dview                                                 = new wxVtkMPR3DView( mwxvtk3Dbaseview_Clipping3D );
206                         vtkmpr3Ddataviewer      = new vtkMPR3DDataViewer();     
207                         wxWindow        *window3D                                       = mwxvtk3Dbaseview_Clipping3D->GetWxVTKRenderWindowInteractor();
208                         wxPanel                 *panelControl                   = new wxPanel(panelClipping3D,-1);      
209                         wxPanel                 *controlPanelMPR3D              = mwxvtkmpr3Dview->CreateControlPanel(panelControl);
210                         wxFlexGridSizer  *sizerCtrol             = new wxFlexGridSizer(1);
211                         sizerCtrol->Add(controlPanelMPR3D               , 1, wxALL|wxEXPAND, 2);
212                         panelControl->SetAutoLayout(true);
213                         panelControl->SetSizer(sizerCtrol);
214                         panelControl->SetSize(400,350);
215                         panelControl->Layout();
216                         panelClipping3D -> SetMinimumPaneSize( 5 );
217                         panelClipping3D -> SplitHorizontally( panelControl , window3D , 10  );
218                         wxwindow=panelClipping3D;
219                         vtkmpr3Ddataviewer->SetVtkMPRBaseData(mvtkmprbasedata);                 
220                         //vtkmpr3Ddataviewer->Configure();
221                         mwxvtkmpr3Dview->SetVtkMPR3DDataViewer(vtkmpr3Ddataviewer);
222 */
223                 }
224
225    
226         wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
227         sizer->Add( wxwindow , 1, wxGROW);      
228         panel->SetSizer(sizer);
229         panel->SetAutoLayout(true);
230         sizer->Layout();
231         panel->Layout();
232         panel->Refresh();
233
234         //   mbbtkViewerMaracas= NULL;
235         }
236         //-------------------------------------------------------------------------
237           
238         wxMaracas_ViewerWidget::~wxMaracas_ViewerWidget()
239         {
240                 
241                 if (minternalVtkmprbasedata==true)
242                 {
243                         if (mvtkmprbasedata)                    { delete mvtkmprbasedata;  }
244                 }       
245                 
246                 if (mvtk2Dbaseview)                             { delete mvtk2Dbaseview; }
247                 if (mvtkmpr2Dview_X)                    { delete mvtkmpr2Dview_X; }
248                 if (mvtkmpr2Dview_Y)                    { delete mvtkmpr2Dview_Y; }
249                 if (mvtkmpr2Dview_Z)                    { delete mvtkmpr2Dview_Z; }
250                 if (mwidgetMesure)                              { delete mwidgetMesure; }
251                 if (mvtkplane2Dview)                    { delete mvtkplane2Dview; }
252                 if (mwxsphereview)                              { delete mwxsphereview; }
253                 if (mwxvtkmpr3Dview)                    { delete mwxvtkmpr3Dview; }
254                 if (mwxvtkclipping3Dview)               { delete mwxvtkclipping3Dview; }
255                 if (mwxvtk3Dbaseview_Clipping3D){ delete mwxvtk3Dbaseview_Clipping3D; mwxvtk3Dbaseview_Clipping3D=NULL;}
256         }
257         //------------------------------------------------------------------------------------------------------------
258         // Methods
259         //------------------------------------------------------------------------------------------------------------
260
261         //-------------------------------------------------------------------------
262
263         void wxMaracas_ViewerWidget::ConfigureVTK()
264         {
265                 int x=0,y=0,z=0;
266                 int ext[6];
267                 ext[0]=0;
268                 ext[1]=0;
269                 ext[2]=0;
270                 ext[3]=0;
271                 ext[4]=0;
272                 ext[5]=0;
273                 double org[3],spc[3];
274                 org[0]=0;
275                 org[1]=0;
276                 org[2]=0;
277                 spc[0]=0;
278                 spc[1]=0;
279                 spc[2]=0;
280                 
281
282
283                 if (mvtkmprbasedata!=NULL)
284                 {
285                         mvtkmprbasedata->Configure();
286                         /*x = mvtkmprbasedata   ->      GetMaxPositionX()/2;
287                         y = mvtkmprbasedata     ->      GetMaxPositionY()/2;
288                         z = mvtkmprbasedata     ->      GetMaxPositionZ()/2;            */      
289                         
290                         if(mvtkmprbasedata->GetImageData() != NULL)
291                         {
292                                 mvtkmprbasedata->GetImageData()->GetExtent(ext);
293                                 mvtkmprbasedata->GetImageData()->GetOrigin(org);
294                                 mvtkmprbasedata->GetImageData()->GetSpacing(spc);
295
296                                 x = (ext[0]+ext[1])/2;
297                                 y = (ext[2]+ext[3])/2;
298                                 z = (ext[4]+ext[5])/2;
299
300                                 mvtkmprbasedata->SetX( x );
301                                 mvtkmprbasedata->SetY( y );
302                                 mvtkmprbasedata->SetZ( z );
303                         }
304                         else
305                         {
306                                 mvtkmprbasedata->SetX( 0 );
307                                 mvtkmprbasedata->SetY( 0 );
308                                 mvtkmprbasedata->SetZ( 0 );
309                         }
310                 }
311                 
312
313                 if ( mvtk2Dbaseview                             !=NULL ) { mvtk2Dbaseview                               ->      Configure();                            }
314                 if ( mvtkmpr2Dview_X                    !=NULL ) { mvtkmpr2Dview_X                              ->      Configure();                            }
315                 if ( mvtkmpr2Dview_Y                    !=NULL ) { mvtkmpr2Dview_Y                              ->      Configure();                            }
316                 if ( mvtkmpr2Dview_Z                    !=NULL ) { mvtkmpr2Dview_Z                              ->      Configure();                            }
317                 if ( mvtkplane2Dview                    !=NULL ) { mvtkplane2Dview                              ->      Configure();                            }
318                 if ( mwidgetMesure                              !=NULL ) { mwidgetMesure                                ->      ConfigureA(mvtkplane2Dview);}
319                 if ( mwidgetMesure                              !=NULL ) { mwidgetMesure                                ->      ConfigureA(mvtkplane2Dview);}
320                 if ( mwidgetMesure                              !=NULL ) { mwidgetMesure                                ->      SetActiveLink(true);            }
321                 if ( mwidgetMesure                              !=NULL ) { mwidgetMesure                                ->      SetMesureScale( 1 );            }
322                 if ( mwxsphereview                              !=NULL ) { mwxsphereview                                ->      Configure();                            }
323
324                 if (mwxvtk3Dbaseview_Clipping3D !=NULL) { mwxvtk3Dbaseview_Clipping3D   ->      Configure();                            
325                 }
326                 
327                 if (vtkmpr3Ddataviewer                  !=NULL) {                       
328                         vtkmpr3Ddataviewer->Configure();
329                         
330                 }
331                 if (mwxvtkmpr3Dview                             !=NULL) { 
332                         
333                         mwxvtkmpr3Dview                         ->      Configure();
334                         mwxvtkmpr3Dview                         ->ResetCamera(ext,org,spc);
335                         
336                         
337                 }
338
339                 if (mwxvtkclipping3Dview                !=NULL) { mwxvtkclipping3Dview                  ->      Configure();                            }
340                 
341                 
342
343                 
344                 //if(vtkmpr3Ddataviewer!=NULL){vtkmpr3Ddataviewer->Configure();}
345 //              RefreshView();
346
347                 //if (mwxvtkmpr3Dview                           !=NULL) {
348                 //      mwxvtkmpr3Dview->ResetCamera();
349                 //}
350
351         }
352
353         //-------------------------------------------------------------------------
354
355   void wxMaracas_ViewerWidget::Refresh(bool eraseBackground ,const wxRect* rect  )  // virtual  eraseBackground=true , rect=NULL
356   {
357     wxPanel::Refresh(false);
358   }
359
360         //-------------------------------------------------------------------------
361         void wxMaracas_ViewerWidget::RefreshView()
362         {
363                 
364                         if (mvtk2Dbaseview                              !=NULL ){ mvtk2Dbaseview                                -> Refresh();           }
365                         if (mvtkmpr2Dview_X                             !=NULL ){ mvtkmpr2Dview_X                               -> Refresh();           }
366                         if (mvtkmpr2Dview_Y                             !=NULL ){ mvtkmpr2Dview_Y                               -> Refresh();           }
367                         if (mvtkmpr2Dview_Z                             !=NULL ){ mvtkmpr2Dview_Z                               -> Refresh();           }
368                         if (mvtkplane2Dview                             !=NULL ){ mvtkplane2Dview                               -> Refresh();           }
369                         if (mwxsphereview                               !=NULL ){ mwxsphereview                                 -> Refresh();           }
370
371                         if (mwxvtkmpr3Dview                             !=NULL ){ mwxvtkmpr3Dview                               -> RefreshView();       }
372                         if (mwxvtkclipping3Dview                !=NULL ){ mwxvtkclipping3Dview                  -> Refresh();           }
373                         if (mwxvtk3Dbaseview_Clipping3D !=NULL ){ mwxvtk3Dbaseview_Clipping3D   -> Refresh();           }
374
375         }
376
377         //-------------------------------------------------------------------------
378
379         wxVtkBaseView *wxMaracas_ViewerWidget::GetwxVtkBaseView()
380         {
381                 wxVtkBaseView *wxvtkbaseview=NULL;
382                 if (mvtk2Dbaseview!=NULL)                               { 
383                         wxvtkbaseview = mvtk2Dbaseview;                 
384                 }
385                 if (mvtkmpr2Dview_X!=NULL){ 
386                         wxvtkbaseview = mvtkmpr2Dview_X;
387                 }
388                 if (mvtkmpr2Dview_Y!=NULL){ 
389                         wxvtkbaseview = mvtkmpr2Dview_Y;
390                 }
391                 if (mvtkmpr2Dview_Z!=NULL){ 
392                         wxvtkbaseview = mvtkmpr2Dview_Z;                
393                 }
394                 if (mvtkplane2Dview!=NULL){
395                         wxvtkbaseview = mvtkplane2Dview;                
396                 }
397                 if (mwxsphereview!=NULL){ 
398                         wxvtkbaseview = mwxsphereview;
399                 }
400                 if (mwxvtk3Dbaseview_Clipping3D!=NULL)  { 
401                         wxvtkbaseview = mwxvtk3Dbaseview_Clipping3D;
402                 }
403                 return wxvtkbaseview   ;
404         }
405
406         void wxMaracas_ViewerWidget::SetImage( vtkImageData *image      )
407         {
408                 if(mvtkmprbasedata !=NULL)
409                 {
410                         marImageData* mar = mvtkmprbasedata->GetMarImageData();
411                         mar->removeImageData(0);
412                         mar->AddImageData(image);
413                 }
414
415 //EED 26/11/2009
416 //              ConfigureVTK();
417 //              RefreshView();
418         }
419
420         double wxMaracas_ViewerWidget :: GetX()
421         {
422                 double value = -1;
423                 if(mvtkmprbasedata !=NULL)
424                 {
425                         value = mvtkmprbasedata->GetX();
426                 }
427                 return value;
428         }
429
430         double wxMaracas_ViewerWidget :: GetY()
431         {
432                 double value = -1;
433                 if(mvtkmprbasedata !=NULL)
434                 {
435                         value = mvtkmprbasedata->GetY();
436                 }
437                 return value;
438         }
439
440         double wxMaracas_ViewerWidget :: GetZ()
441         {
442                 double value = -1;
443                 if(mvtkmprbasedata !=NULL)
444                 {
445                         value = mvtkmprbasedata->GetZ();
446                 }
447                 return value;
448 //              return mvtk2Dbaseview->GetVtkBaseData()->GetZ();
449         }
450
451         void wxMaracas_ViewerWidget::setColorTransferFunction(vtkColorTransferFunction* colortable){            
452                 if(mvtkmpr2Dview_X!=NULL){
453                         mvtkmpr2Dview_X->setColorTransferFunction(colortable);
454                 }
455                 if(mvtkmpr2Dview_Y!=NULL){
456                         mvtkmpr2Dview_Y->setColorTransferFunction(colortable);
457                 }
458                 if(mvtkmpr2Dview_Z!=NULL){
459                         mvtkmpr2Dview_Z->setColorTransferFunction(colortable);
460                 }
461                 if(mwxvtkmpr3Dview!=NULL){
462                         mwxvtkmpr3Dview->setColorTransferFunction(colortable);
463                 }
464         }
465
466         void wxMaracas_ViewerWidget::setWindowLevel(double level){
467                 if(mvtkmpr2Dview_X!=NULL){
468                         mvtkmpr2Dview_X->setWindowLevel(level);
469                 }
470                 if(mvtkmpr2Dview_Y!=NULL){
471                         mvtkmpr2Dview_Y->setWindowLevel(level);
472                 }
473                 if(mvtkmpr2Dview_Z!=NULL){
474                         mvtkmpr2Dview_Z->setWindowLevel(level);
475                 }
476                 /*if(mwxvtkmpr3Dview!=NULL){
477                         mwxvtkmpr3Dview->setWindowLevel(level);
478                 }*/
479         }
480
481         void wxMaracas_ViewerWidget::setColorLevel(double level){
482                 if(mvtkmpr2Dview_X!=NULL){
483                         mvtkmpr2Dview_X->setColorLevel(level);
484                 }
485                 if(mvtkmpr2Dview_Y!=NULL){
486                         mvtkmpr2Dview_Y->setColorLevel(level);
487                 }
488                 if(mvtkmpr2Dview_Z!=NULL){
489                         mvtkmpr2Dview_Z->setColorLevel(level);
490                 }
491                 /*if(mwxvtkmpr3Dview!=NULL){
492                         mwxvtkmpr3Dview->setColorLevel(level);
493                 }*/
494     }
495