]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/include/Copie de wxSTLWidget_03.cxx
BUG macOs
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / include / Copie de wxSTLWidget_03.cxx
1
2 #include "vtkObjectFactory.h"
3
4 #include "vtkActor.h"
5 #include "vtkCylinderSource.h"
6 #include "vtkPolyDataMapper.h"
7 #include "vtkRenderer.h"
8 #include "vtkRenderWindow.h"
9 #include "vtkRenderWindowInteractor.h"
10 #include "vtkProperty.h"
11 #include "vtkCamera.h"
12 #include "vtkPoints.h"
13 #include "vtkCellArray.h"
14 #include "vtkPolyData.h"
15 #include "vtkPolyDataMapper.h"
16 #include "vtkPolyDataWriter.h"
17 #include "vtkPolyDataReader.h"
18 #include "vtkImageReader.h"
19 #include "vtkImageViewer.h"
20 #include "vtkImageViewer2.h"
21 #include "vtkImageToStructuredPoints.h"
22 #include <vtkImageThreshold.h> 
23 #include "vtkImageWriter.h"
24
25
26 #include "vtkExtractVOI.h"
27 #include "vtkImageClip.h"
28 #include "vtkImageResample.h"
29 #include "vtkImageThreshold.h"
30 #include "vtkImageCast.h"
31 #include "vtkImageSeedConnectivity.h"
32 #include "vtkImageData.h"
33 #include "vtkMarchingCubes.h"
34 #include "vtkImageReslice.h"
35 #include "vtkTransform.h"
36 #include "vtkSphereSource.h"
37 #include "vtkDoubleArray.h"
38 #include "vtkPointData.h"
39 #include "vtkCommand.h"
40 #include "vtkCallbackCommand.h"
41 #include "vtkImageResample.h"
42 #include "vtkMath.h"
43 #include "vtkStripper.h"
44 #include <vtkSTLReader.h> 
45 #include "vtkMetaImageWriter.h"
46
47
48 #include "vtkTriangleFilter.h"
49 #include "vtkSTLWriter.h"
50 #include "vtkPolyDataConnectivityFilter.h"
51 #include "vtkClosePolyData.h"
52 #include "vtkAppendFilter.h"
53
54 #include "wxSTLWidget_03.h"
55
56 #include <wx/splitter.h>
57
58 #include <wx/filedlg.h>
59
60
61
62 //-------------------------------------------------------------------
63 //-------------------------------------------------------------------
64 //-------------------------------------------------------------------
65 wxSTLWidget_03::wxSTLWidget_03(wxWindow *parent, marInterface* mar)
66 : wxPanel( parent, -1) 
67 {
68         _wxMaracasMPR           = NULL;
69         _maxSize                = 2000;
70         _minSize                = 300;
71
72         _stlMarchingCubesLevel  = 128;
73         _stlDeltaGaussLevel             = 100;
74
75         _mar=new marInterface();        
76         _mar->_parameters->setRescaleSlope( mar->_parameters->getRescaleSlope() );
77         _mar->_parameters->setRescaleIntercept( mar->_parameters->getRescaleIntercept() );
78         _mar->_parameters->setIntParam( marParameters::e_voxel_type, marParameters::VOX_TYPE_MINIMUM );
79         _mar->_parameters->setDoubleParam( marParameters::e_voxel_x_dimension, mar->_parameters->getDoubleParam(marParameters::e_voxel_x_dimension) );
80         _mar->_parameters->setDoubleParam( marParameters::e_voxel_y_dimension, mar->_parameters->getDoubleParam(marParameters::e_voxel_y_dimension) );
81         _mar->_parameters->setDoubleParam( marParameters::e_voxel_z_dimension, mar->_parameters->getDoubleParam(marParameters::e_voxel_z_dimension) );
82         int voi[6];
83         mar->_experiment->getVOI( voi );
84         _mar->_experiment->setVOI( voi );
85         _mar->SetDicom(mar->_dicom);
86         _mar->initExperiment( );
87          
88
89         wxBoxSizer              *sizer          = new wxBoxSizer(wxVERTICAL  );
90         wxSplitterWindow        *pnlSplitter    = new wxSplitterWindow( this , -1);
91         wxPanel                 *viewPanel      = CreateViewPanel(pnlSplitter);
92 printf("EED wxSTLWidget_03::wxSTLWidget_03 01\n");
93         wxPanel                 *controlPanel   = CreateControlPanel(pnlSplitter);
94 printf("EED wxSTLWidget_03::wxSTLWidget_03 02\n");
95
96         sizer           -> Add( pnlSplitter ,1,wxGROW  ,0);
97         pnlSplitter     -> SetMinimumPaneSize( 150 );
98         pnlSplitter     -> SplitVertically( viewPanel, controlPanel, 600 );
99
100 //      pnlSplitter     -> SplitVertically( new wxPanel(pnlSplitter,-1), new wxPanel(pnlSplitter,-1) , 600 );
101 //      pnlSplitter     -> SplitVertically( viewPanel, new wxPanel(pnlSplitter,-1) , 600 );
102
103         this            -> SetSizer(sizer);
104
105         // Result 2: Volume + Axis
106 //      _2_prgov                = NULL;
107         _2_mapfinal             = NULL;
108         _2_stripfinal           = NULL;
109         _2_isoMapperMC6         = NULL;
110         _2_isoActorMC6          = NULL;
111         _2_isoMC6               = NULL;
112
113         //DHC STL SURFACES
114         stlInterna              = NULL;
115         stlExterna              = NULL;
116
117         _loadSTLMapper          = NULL;
118         _loadActorSTL           = NULL;
119
120         
121         //JOIN REGIONS
122         arteryImageData         = NULL;
123         joinMarchingCubes       = NULL;
124     joinMapper                  = NULL; 
125         joinActor               = NULL;
126 printf("EED wxSTLWidget_03::wxSTLWidget_03 03\n");
127
128
129 }
130 //-------------------------------------------------------------------
131 wxSTLWidget_03::~wxSTLWidget_03(){
132         ResetTree2_JF();
133         Reset_vtk_STLFile();
134 }
135 //-------------------------------------------------------------------
136 wxPanel* wxSTLWidget_03::CreateViewPanel(wxWindow *parent)
137 {
138         wxPanel *panel          =       new wxPanel(parent,-1);
139     wxBoxSizer *sizer   =       new wxBoxSizer(wxVERTICAL);
140
141
142    // MPR
143         vtkImageData *imagedata;
144         imagedata = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
145         imagedata->Update();    
146 printf("EED wxSTLWidget_03::CreateViewPanel  01 \n");
147         _wxMaracasMPR = new wxMaracasMPR( panel, new marImageData(imagedata), _mar->_parameters->getVoxelSize() );
148 printf("EED wxSTLWidget_03::CreateViewPanel  02 \n");
149         _wxMaracasMPR->ConfigureVTK();
150 printf("EED wxSTLWidget_03::CreateViewPanel  03 \n");
151         
152         sizer->Add(     _wxMaracasMPR , 1, wxEXPAND, 0);
153         panel->SetSizer(sizer);
154         panel->SetAutoLayout(true);
155         panel->SetSize(400,400);
156         panel->Layout();
157 printf("EED wxSTLWidget_03::CreateViewPanel  04 \n");
158         return panel;
159 }
160 //-------------------------------------------------------------------
161 wxWindow* wxSTLWidget_03::CreateSelectAPointPanel(wxWindow *parent)
162 {
163 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  01\n");
164         wxPanel *panel          = new wxPanel(parent,-1);
165
166 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  02\n");
167
168     wxFlexGridSizer *sizer = new wxFlexGridSizer(2);
169 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  03\n");
170
171         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
172         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
173 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  04\n");
174
175         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
176         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
177 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  05\n");
178
179         sizer->Add(new wxStaticText(panel,-1,_T(" Select a 3D Point...")));
180         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
181 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  06\n");
182
183         panel->SetSizer(sizer);
184         panel->SetAutoLayout(true);
185         panel->SetSize(400,600);
186         panel->Layout();
187 printf("EED wxSTLWidget_03::CreateSelectAPointPanel  07\n");
188
189
190         return panel;
191 }
192 //-------------------------------------------------------------------
193 wxWindow* wxSTLWidget_03::CreateSegmentationPanel(wxWindow *parent)
194 {
195         wxPanel *panel          = new wxPanel(parent,-1);
196
197
198         _opacity_Vol            = new wxSlider( panel, -1, 40, 0, 100                            , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS );
199         _opacity_Vol    ->SetSize(250,20);  
200         /*SIL
201         _sl_maxSize                     = new wxSlider( panel, -1, 300 , 0, 2000 , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL  |  wxSL_AUTOTICKS | wxSL_LABELS );
202         _sl_minSize                     = new wxSlider( panel, -1, 200 , 0, 2000 , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL  |  wxSL_AUTOTICKS | wxSL_LABELS );
203         
204         _sl_minSizeSpin = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT  );
205         _sl_minSizeSpin->SetRange(1,8);
206         _sl_minSizeSpin->SetValue(5);
207
208         _sl_maxSizeSpin = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT  );
209         _sl_maxSizeSpin->SetRange(1,8);
210         _sl_maxSizeSpin->SetValue(5);
211
212         */
213
214         _sl_RangeSizeSpin = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT  );
215         _sl_RangeSizeSpin->SetRange(1,8);
216         _sl_RangeSizeSpin->SetValue(5);
217
218
219         //SIL//
220         sl_barrange_segmentation = new mBarRange(panel, 300,70);
221         sl_barrange_segmentation -> setVisibleLabels ( true );
222         sl_barrange_segmentation -> setIfWithActualDrawed( false );
223         sl_barrange_segmentation -> setActiveStateTo ( true );
224         sl_barrange_segmentation -> setRepresentedValues (0,  2000);
225         sl_barrange_segmentation -> setDeviceBlitStart (10,10);
226         sl_barrange_segmentation -> setDeviceEndMargin(10);
227         parent->SetBackgroundColour(wxColour(255,255,255));
228         sl_barrange_segmentation-> setBackgroundColor( wxColour(255,255,255 ));
229
230
231         wxButton *btnExtract                            = new wxButton(panel,-1,_T("Segmentation"));
232         wxButton *btnSaveBinaryFile                     = new wxButton(panel,-1,_T("Save Binary File"));
233
234 //SIL// Connect(_sl_minSizeSpin->GetId()        , wxEVT_COMMAND_SLIDER_UPDATED   , (wxObjectEventFunction) &wxSTLWidget_03::OnMinSpin ); 
235 //SIL// Connect(_sl_maxSizeSpin->GetId()        , wxEVT_COMMAND_SLIDER_UPDATED   , (wxObjectEventFunction) &wxSTLWidget_03::OnMaxSpin ); 
236         Connect(_opacity_Vol->GetId()           , wxEVT_COMMAND_SLIDER_UPDATED  , (wxObjectEventFunction) &wxSTLWidget_03::OnOpacity_Vol                                        ); 
237         Connect(btnExtract->GetId()                     , wxEVT_COMMAND_BUTTON_CLICKED  , (wxObjectEventFunction) &wxSTLWidget_03::OnBtnExtraction                                      ); 
238         Connect(btnSaveBinaryFile->GetId()      , wxEVT_COMMAND_BUTTON_CLICKED  , (wxObjectEventFunction) &wxSTLWidget_03::OnBtnSaveBinaryFile                          ); 
239
240         //SIL//
241         Connect(_sl_RangeSizeSpin->GetId()      , wxEVT_COMMAND_SLIDER_UPDATED   , (wxObjectEventFunction) &wxSTLWidget_03::OnRangeSpin ); 
242         Connect(sl_barrange_segmentation->GetId(),wxEVT_TSBAR_START,(wxObjectEventFunction) (wxCommandEventFunction)  &wxSTLWidget_03::OnStartChanged_range );
243         Connect(sl_barrange_segmentation->GetId(),wxEVT_TSBAR_END,(wxObjectEventFunction) (wxCommandEventFunction)  &wxSTLWidget_03::OnEndChanged_range );      
244         Connect(sl_barrange_segmentation->GetId(),wxEVT_TSBAR_MOVED,(wxObjectEventFunction) (wxCommandEventFunction)  &wxSTLWidget_03::OnBarMoved_range );
245
246     wxFlexGridSizer *sizer = new wxFlexGridSizer(2);
247
248         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
249         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
250
251
252         sizer->Add(new wxStaticText(panel,-1,_T("  - - -  Segmentation - - - ")));
253         sizer->Add(new wxStaticText(panel,-1,_T("  "))); 
254         
255
256         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
257         sizer->Add(new wxStaticText(panel,-1,_T("  "))); 
258
259         /*sizer->Add(new wxStaticText(panel,-1,_T(" Threshold min")));
260         sizer->Add(new wxStaticText(panel,-1,_T("  "))); 
261         sizer->Add(_sl_minSizeSpin, 1, wxALL|wxEXPAND, 0);*/
262         //sizer->Add(_sl_minSize, 1, wxALL|wxEXPAND, 0);
263
264         sizer->Add(new wxStaticText(panel,-1,_T(" Threshold min-max")));
265         sizer->Add(new wxStaticText(panel,-1,_T("  "))); 
266         sizer->Add(_sl_RangeSizeSpin, 1, wxALL|wxEXPAND, 0);
267         sizer->Add(sl_barrange_segmentation,3,wxALL|wxGROW,0 );
268         
269         //SIL//sizer->Add(new wxStaticText(panel,-1,_T(" Threshold max")));
270         //SIL//sizer->Add(new wxStaticText(panel,-1,_T("  "))); 
271         //SIL// sizer->Add(_sl_maxSizeSpin, 1, wxALL|wxEXPAND, 0);
272         //SIL//sizer->Add(_sl_maxSize, 1, wxALL|wxEXPAND, 0);
273         
274         sizer->Add(btnExtract);
275         sizer->Add(new wxStaticText(panel,-1,_T(" ")));
276
277         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
278         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
279         sizer->Add(new wxStaticText(panel,-1,_T("Opacity - Result Volume")));
280         sizer->Add(_opacity_Vol);
281
282         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
283         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
284         sizer->Add(btnSaveBinaryFile);
285         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
286         
287         panel->SetSizer(sizer);
288         panel->SetAutoLayout(true);
289         panel->SetSize(400,600);
290         panel->Layout();
291
292         return panel;
293 }
294 //-------------------------------------------------
295 wxWindow* wxSTLWidget_03::CreateSmoothingPanel(wxWindow *parent)
296 {
297         wxPanel *panel          = new wxPanel(parent,-1);
298
299         stlSliderDeltaGauss     = new wxSlider( panel, -1, (int)(_stlDeltaGaussLevel) , 0, 300 , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS );
300         stlSliderMarchingCubes= new wxSlider( panel, -1, (int)(_stlMarchingCubesLevel) , 0, 256 , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS );
301         stlSliderOpacityInternal = new wxSlider(panel, -1, 100,0,100, wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS);
302         stlSliderOpacityExternal = new wxSlider(panel, -1, 100,0,100, wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS);
303         wxButton *btnFileSTL = new wxButton(panel,-1,_T("Generate STL files"));
304
305         Connect(btnFileSTL->GetId()                             , wxEVT_COMMAND_BUTTON_CLICKED  , (wxObjectEventFunction) &wxSTLWidget_03::OnBtnCreateFileSTL                   );
306         Connect(stlSliderDeltaGauss->GetId()    , wxEVT_SCROLL_THUMBRELEASE             , (wxObjectEventFunction) &wxSTLWidget_03::OnChangeSTLGaussLevel                );
307         Connect(stlSliderMarchingCubes->GetId() , wxEVT_SCROLL_THUMBRELEASE             , (wxObjectEventFunction) &wxSTLWidget_03::OnChangeSTLMarchingCubesLevel);
308         Connect(stlSliderOpacityInternal->GetId(), wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxSTLWidget_03::OnOpacitySTLInternal                 );
309         Connect(stlSliderOpacityExternal->GetId(), wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxSTLWidget_03::OnOpacitySTLExternal                 );
310
311
312     wxFlexGridSizer *sizer = new wxFlexGridSizer(2);
313
314         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
315         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
316
317         sizer->Add(new wxStaticText(panel,-1,_T("-- Smoothing --")));
318         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
319         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
320         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
321         
322         sizer->Add(new wxStaticText(panel,-1,_T(" Delta Gauss")));
323         sizer->Add(stlSliderDeltaGauss);
324
325         sizer->Add(new wxStaticText(panel,-1,_T(" Marching Cubes Level")));
326         sizer->Add(stlSliderMarchingCubes);
327
328         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
329         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
330         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
331         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
332
333         sizer->Add(new wxStaticText(panel, -1,_T(" Opacity STL Internal")));
334         sizer->Add(stlSliderOpacityInternal);
335
336         sizer->Add(new wxStaticText(panel, -1,_T(" Opacity STL External")));
337         sizer->Add(stlSliderOpacityExternal);
338
339         sizer->Add(btnFileSTL);
340         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
341
342
343         panel->SetSizer(sizer);
344         panel->SetAutoLayout(true);
345         panel->SetSize(400,600);
346         panel->Layout();
347         return panel;
348 }
349 //-------------------------------------------------
350 wxWindow* wxSTLWidget_03::CreateReadSTLFilePanel(wxWindow *parent)
351 {
352         wxPanel *panel          = new wxPanel(parent,-1);
353
354         wxButton *btnReadSTLFile                        = new wxButton(panel,-1,_T("Read STL File"));
355         wxButton *btnEraseReadSTLFile           = new wxButton(panel,-1,_T("Erase STL File"));
356         _sl_opacity_STL_file                            = new wxSlider( panel, -1, 100 , 0, 100 , wxDefaultPosition, wxSize(200,40), wxSL_HORIZONTAL | wxSL_LABELS );
357
358         Connect(btnReadSTLFile->GetId()                 , wxEVT_COMMAND_BUTTON_CLICKED  , (wxObjectEventFunction) &wxSTLWidget_03::OnBtnSTLFileLoad                     ); 
359         Connect(btnEraseReadSTLFile->GetId()    , wxEVT_COMMAND_BUTTON_CLICKED  , (wxObjectEventFunction) &wxSTLWidget_03::OnBtnSTLFileErase                    ); 
360         Connect(_sl_opacity_STL_file->GetId()   , wxEVT_SCROLL_THUMBRELEASE     , (wxObjectEventFunction) &wxSTLWidget_03::OnOpacitySTLFile                             ); 
361
362
363     wxFlexGridSizer *sizer = new wxFlexGridSizer(2);
364
365         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
366         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
367         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
368         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
369
370         sizer->Add(new wxStaticText(panel,-1,_T("-- Read STL File --")));
371         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
372
373         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
374         sizer->Add(new wxStaticText(panel,-1,_T("  ")));
375
376         sizer->Add(btnReadSTLFile );
377         sizer->Add(btnEraseReadSTLFile );
378         sizer->Add(new wxStaticText(panel, -1,_T(" Opacity STL File")));
379         sizer->Add(_sl_opacity_STL_file);
380
381
382         panel->SetSizer(sizer);
383         panel->SetAutoLayout(true);
384         panel->SetSize(400,600);
385         panel->Layout();
386         return panel;
387 }
388 //-------------------------------------------------------------------
389 wxPanel* wxSTLWidget_03::CreateControlPanel(wxWindow *parent)
390 {
391 printf("EED wxSTLWidget_03::CreateControlPanel 01\n");
392         wxPanel *panel                  = new wxPanel(parent,-1);
393
394         wxNotebook *noteBook    = new wxNotebook(panel, -1);
395 printf("EED wxSTLWidget_03::CreateControlPanel 02\n");
396         noteBook->AddPage(CreateSelectAPointPanel(noteBook),_T("0 ->") );
397 printf("EED wxSTLWidget_03::CreateControlPanel 03\n");
398         noteBook->AddPage(CreateSegmentationPanel(noteBook),_T("1 ->") );
399 printf("EED wxSTLWidget_03::CreateControlPanel 04\n");
400         noteBook->AddPage(CreateSmoothingPanel(noteBook)   ,_T("2 ->") );
401 printf("EED wxSTLWidget_03::CreateControlPanel 05\n");
402         noteBook->AddPage(CreateReadSTLFilePanel(noteBook) ,_T("3 "  ) );
403 printf("EED wxSTLWidget_03::CreateControlPanel 06\n");
404         noteBook->SetSelection(0);
405         noteBook->SetSize(350,250);
406     wxFlexGridSizer *sizer = new wxFlexGridSizer(2);
407         sizer->Add(noteBook);
408         panel->SetSizer(sizer);
409         panel->SetAutoLayout(true);
410         panel->SetSize(400,600);
411         panel->Layout();
412
413 printf("EED wxSTLWidget_03::CreateControlPanel 07\n");
414         return panel;
415 }
416 //------------------------------------------------------------------------
417 void wxSTLWidget_03::Refresh()
418 {
419         if (_wxMaracasMPR!=NULL){
420                 _wxMaracasMPR->RefreshView();
421         }
422 }
423
424 //------------------------------------------------------------------------
425
426
427 void wxSTLWidget_03::ConfigureProcessing(marImageData *marimagedata, int x, int y, int z)
428 {
429     wxBusyCursor wait;
430
431         _imagedata=marimagedata->GetImageData(); // image t=0
432         _imagedata->UpdateInformation();
433         _imagedata->SetUpdateExtent(_imagedata->GetWholeExtent());
434         _imagedata->Update();
435
436
437         double puntoactualprov[3];
438         puntoactualprov[0] = x;
439         puntoactualprov[1] = y;
440         puntoactualprov[2] = z;
441
442         double espprin[3];
443         int extprin[6];                         
444         
445         _imagedata->GetSpacing(espprin);
446         _imagedata->GetExtent(extprin);
447
448
449 // MAZV 27 sep 2006
450 //      puntoactualprov[0]=puntoactualprov[0]*espprin[0];
451 //      puntoactualprov[1]=puntoactualprov[1]*espprin[1];
452 //      puntoactualprov[2]=puntoactualprov[2]*espprin[2];
453         
454     _imagedata->GetScalarRange( _range );
455
456         // Update Controls
457         //SIL//
458         /*_sl_minSize->SetRange( (int)(_range[0]), (int)( _range[1]) );
459         _sl_minSize->SetValue( (int)(_range[1]/4) );
460
461         _sl_maxSize->SetRange( (int)(_range[0]) , (int)(_range[1]));
462         _sl_maxSize->SetValue( (int)(_range[1]/2) );*/
463
464         //SIL//
465         minRangeValue = _range[0];
466         maxRangeValue = _range[1];
467
468         sl_barrange_segmentation ->setRepresentedValues(minRangeValue, maxRangeValue);
469         sl_barrange_segmentation ->SetStart((int)(maxRangeValue/4));
470         sl_barrange_segmentation ->SetEnd((int)(maxRangeValue/2));
471         sl_barrange_segmentation -> RefreshForce();     
472         lastResizeRef_Value = ( maxRangeValue - minRangeValue)/2;       
473
474 // MAZV 27 sep 2006
475 //      _highthreshold->SetRange(_range[0], _range[1]);
476 //      _highthreshold->SetValue( _range[1] );
477
478 //      _zslice->SetRange(extprin[4], extprin[5]);
479 //      _zslice->SetValue(extprin[5]/2);
480         
481         _thresh = vtkImageThreshold::New();
482         _thresh->SetInput(_imagedata);
483         //_thresh->ReleaseDataFlagOff();
484         _thresh->SetInValue(255);
485         _thresh->SetOutputScalarTypeToUnsignedShort();
486         _thresh->SetOutValue(0);
487         //_thresh->ThresholdBetween(_sl_minSize->GetValue(), _range[1]);
488         //SIL//
489         _thresh->ThresholdBetween(sl_barrange_segmentation->GetStart(), sl_barrange_segmentation->GetEnd()); 
490
491         vtkImageCast *cast = vtkImageCast::New();
492         cast->SetInput(_thresh->GetOutput());
493         cast->SetOutputScalarTypeToUnsignedChar();
494         cast->Update();
495
496   
497         _connect = vtkImageSeedConnectivity::New();
498         _connect->SetInput(cast->GetOutput());
499         _connect->SetInputConnectValue(255);
500         _connect->SetOutputConnectedValue(255);
501         _connect->SetOutputUnconnectedValue(0);
502         _connect->AddSeed((int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2]));
503 //      _connect->Update();
504
505         cast3 = vtkImageCast::New();
506         cast3->SetInput(_connect->GetOutput());
507         cast3->SetOutputScalarTypeToUnsignedShort();
508         cast3->Update();
509 //SIL//
510         
511         _thresh2 = vtkImageThreshold::New();
512         _thresh2->SetInput(_imagedata);
513         //_thresh2->ReleaseDataFlagOff();
514         _thresh2->SetInValue(255);
515         _thresh2->SetOutputScalarTypeToUnsignedShort();
516         _thresh2->SetOutValue(0);
517         //SIL//_thresh2->ThresholdBetween(_sl_minSize->GetValue(), _sl_maxSize->GetValue());
518         _thresh2->ThresholdBetween(sl_barrange_segmentation->GetStart(), sl_barrange_segmentation->GetEnd());
519         
520         cast2 = vtkImageCast::New();
521         cast2->SetInput(_thresh2->GetOutput());
522         cast2->SetOutputScalarTypeToUnsignedChar();
523         cast2->Update();
524
525         _connect2 = vtkImageSeedConnectivity::New();
526         _connect2->SetInput(cast2->GetOutput());
527         _connect2->SetInputConnectValue(255);
528         _connect2->SetOutputConnectedValue(255);
529         _connect2->SetOutputUnconnectedValue(0);
530         _connect2->AddSeed( (int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2]));
531         _connect2->Update();
532
533         cast4 = vtkImageCast::New();
534         cast4->SetInput(_connect2->GetOutput());
535         cast4->SetOutputScalarTypeToUnsignedShort();
536         cast4->Update();
537 }
538
539 //------------------------------------------------------------------------
540
541
542
543 void wxSTLWidget_03::ConfigureVTK()
544 {
545         wxBusyCursor wait;
546 //      vtkImageData    *imagedata              = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
547         marImageData    *marimagedata           = _mar->_experiment->getDynData( )->GetMarImageData();
548         
549         //CONFIGURACION ADICIONAL
550         this->ConfigureSTL();
551         this->ConfigureProcessing(marimagedata,0,0,0);
552         
553 }
554
555 //------------------------------------------------------------------------
556
557 void wxSTLWidget_03::ResetTree2_JF()
558 {
559         // Remove 
560         vtkRenderer *ren = _wxMaracasMPR->GetWxvtkmpr3Dview_BB()->GetWxvtk3Dbaseview()->GetRenderer();
561
562     if (_2_isoActorMC6){
563                 ren->RemoveActor(_2_isoActorMC6);
564         }
565     if (_2_stripfinal){
566                 ren->RemoveActor(_2_stripfinal);
567         }
568
569         // Delete 
570 //      if (_2_prgov            ) {     _2_prgov                -> Delete(); }
571         if (_2_mapfinal         ) {     _2_mapfinal             -> Delete(); }
572         if (_2_stripfinal       ) {     _2_stripfinal   -> Delete(); }
573         if (_2_isoMapperMC6     ) {     _2_isoMapperMC6 -> Delete(); }
574         if (_2_isoActorMC6      ) {     _2_isoActorMC6  -> Delete(); }
575         if (_2_isoMC6           ) {     _2_isoMC6               -> Delete(); }
576
577         // Init
578 //      _2_prgov                = NULL;
579         _2_mapfinal             = NULL;
580         _2_stripfinal   = NULL;
581         _2_isoMapperMC6 = NULL;
582         _2_isoActorMC6  = NULL;
583         _2_isoMC6               = NULL;
584 }
585
586
587
588
589
590
591 //------------------------------------------------------------------------
592 void wxSTLWidget_03::ExtractSurface(int x, int y, int z)
593 {
594         
595         double opacityvol               = ((double)_opacity_Vol->GetValue())/100;
596 //      vtkImageData *imagedata = _mar->_experiment->getDynData( )->getVolume( )->castVtk();
597
598         double  puntoactualprov[3];
599         double  espprin[3];
600         int             extprin[6];                             
601
602
603         puntoactualprov[0]      =       x;
604         puntoactualprov[1]      =       y;
605         puntoactualprov[2]      =       z;
606         
607         _imagedata->UpdateInformation();
608         _imagedata->SetUpdateExtent(_imagedata->GetWholeExtent());
609         _imagedata->Update();
610
611         _imagedata->GetSpacing(espprin);
612         _imagedata->GetExtent(extprin);
613
614
615
616
617         _connect->RemoveAllSeeds ();
618         _connect->AddSeed( (int)(puntoactualprov[0] ), (int)(puntoactualprov[1]) ,(int)( puntoactualprov[2]) );
619         _connect->Update();
620         cast3->Update();
621
622
623
624         _thresh->ThresholdBetween(3000, 3002 );
625         _thresh2->ThresholdBetween(3000, 3001);
626 //      _thresh->Update();
627 //      _thresh2->Update();
628
629         _thresh->ThresholdBetween(_minSize, _range[1] );
630         _thresh->Update();
631
632         _thresh2->ThresholdBetween(_minSize, _maxSize);
633         _thresh2->Update();
634
635         cast2->Update();
636         _connect2->RemoveAllSeeds ();
637         _connect2->AddSeed( (int)(puntoactualprov[0]) , (int)(puntoactualprov[1]) , (int)(puntoactualprov[2]) );
638         _connect2->Update();
639         cast4->Update();
640
641
642
643
644         // Visualisation - result volume
645    
646     _2_isoMC6 = vtkMarchingCubes::New();
647         _2_isoMC6->SetInput(cast4->GetOutput());
648
649     _2_isoMC6->SetValue(0, 128);
650         _2_isoMC6->Update();
651
652         _2_isoMapperMC6 = vtkPolyDataMapper::New();
653     _2_isoMapperMC6->SetInput(_2_isoMC6->GetOutput());
654     _2_isoMapperMC6->ScalarVisibilityOff();
655     _2_isoMapperMC6->ImmediateModeRenderingOn();
656
657         vtkRenderer *ren = _wxMaracasMPR->GetWxvtkmpr3Dview_BB()->GetWxvtk3Dbaseview()->GetRenderer();
658
659         if (_2_isoActorMC6!=NULL)
660         {
661                 ren->RemoveActor(_2_isoActorMC6);
662         }
663
664
665         _2_isoActorMC6 = vtkActor::New();
666     _2_isoActorMC6->SetMapper(_2_isoMapperMC6);
667     _2_isoActorMC6->GetProperty()->SetColor(1.0, 1.0, 0.5);
668     _2_isoActorMC6->GetProperty()->SetOpacity( opacityvol );
669     
670         // Interface Update
671
672         ren->AddActor(_2_isoActorMC6);
673
674 }
675
676 //------------------------------------------------------------------------
677 void wxSTLWidget_03::OnOpacity_Vol(wxScrollEvent& event)
678 {
679         if (_2_isoActorMC6!=NULL){
680                 double value = ((double)_opacity_Vol->GetValue())/100;
681                 _2_isoActorMC6->GetProperty( )->SetOpacity( value );
682                 Refresh();
683         }
684 }
685 //------------------------------------------------------------------------
686
687 void wxSTLWidget_03::OnMinSpin          (       wxScrollEvent &          event           )      
688 {
689         /*wxSlider *sl_A=_sl_minSize;
690         wxSlider *sl_B=_sl_minSizeSpin;
691         int value = sl_A->GetValue();
692         int delta=(int)pow( 4 , sl_B->GetValue() );
693         int min=value - delta/2;
694         int max=value + delta/2;
695         if (min<0)
696         {
697                 min=0;
698                 max=delta;
699         }
700         sl_A->SetRange(min,max);
701
702
703         */
704 }
705
706 //------------------------------------------------------------------------
707
708 void wxSTLWidget_03::OnMaxSpin          (       wxScrollEvent &          event           )      
709 {
710         /*wxSlider *sl_A=_sl_maxSize;
711         wxSlider *sl_B=_sl_maxSizeSpin;
712         int value = sl_A->GetValue();
713         int delta = (int)pow( 4 , sl_B->GetValue() );
714         int min=value - delta/2;
715         int max=value + delta/2;
716         if (min<0)
717         {
718                 min=0;
719                 max=delta;
720         }
721         sl_A->SetRange(min,max);*/      
722 }
723
724 //------------------------------------------------------------------------
725
726 void wxSTLWidget_03::OnRangeSpin        (       wxScrollEvent &          event           )      
727 {
728         wxSlider *sl_B=_sl_RangeSizeSpin;
729
730         int value = lastResizeRef_Value;
731         int delta = (int)pow( 4 , sl_B->GetValue() );
732         int startResized = value - delta/2;
733         int endResized = value + delta/2;
734
735         if( startResized < minRangeValue )
736                 startResized = minRangeValue;
737
738         if( endResized > maxRangeValue )
739                 endResized = maxRangeValue;
740
741         sl_barrange_segmentation->setRepresentedValues(startResized,endResized);
742         sl_barrange_segmentation -> RefreshForce();     
743 }
744
745 //------------------------------------------------------------------------
746 void wxSTLWidget_03:: OnStartChanged_range(wxCommandEvent& event)
747 {
748         lastResizeRef_Value = sl_barrange_segmentation->GetStart();
749 }
750 //------------------------------------------------------------------------
751 void wxSTLWidget_03:: OnEndChanged_range(wxCommandEvent& event)
752 {
753         lastResizeRef_Value = sl_barrange_segmentation->GetEnd();   
754 }
755 //------------------------------------------------------------------------
756 void wxSTLWidget_03:: OnBarMoved_range(wxCommandEvent& event)
757 {
758         lastResizeRef_Value = (sl_barrange_segmentation->GetEnd() - sl_barrange_segmentation->GetStart())/2 ;
759 }
760 //------------------------------------------------------------------------
761
762 void wxSTLWidget_03::OnBtnSaveBinaryFile(wxCommandEvent& event)
763 {
764         wxString dirSTL = _mar->_parameters->getStringParam( 
765     marParameters::e_installation_directory ); 
766         dirSTL = ( dirSTL == _T("NO_DIRECTORY") ) ? wxGetHomeDir( ) : dirSTL;
767         wxFileDialog dialog( this, _T("Choose a directory..."), ( !dirSTL.IsEmpty( ) )?
768         dirSTL: wxGetHomeDir( ) );
769
770         if( dialog.ShowModal( ) == wxID_OK ) 
771         {
772                 vtkMetaImageWriter  *writer= vtkMetaImageWriter::New();
773                 writer->SetFileName( dialog.GetPath().mb_str(wxConvUTF8) );     
774                 writer->SetInput(cast4->GetOutput());
775                 writer->Write();
776                 writer->Delete();
777         }
778 }
779
780 //------------------------------------------------------------------------
781 void wxSTLWidget_03::OnBtnExtraction(wxCommandEvent& event)
782 {
783         /*wxBusyCursor wait;
784         _minSize = _sl_minSize->GetValue();
785         _maxSize = _sl_maxSize->GetValue();
786
787         double px=_wxMaracasMPR->GetVtkMPRBaseData()->GetX();
788         double py=_wxMaracasMPR->GetVtkMPRBaseData()->GetY();
789         double pz=_wxMaracasMPR->GetVtkMPRBaseData()->GetZ();
790         ExtractSurface((int)(px),(int)(py),(int)(pz));
791         generateSTLSurfaces(); //DHC: AFTER SEGMENTATION THE TREE, THE STL SURFACES ARE CALCULATED.
792
793         Refresh();
794 */
795         //SIL//
796         wxBusyCursor wait;
797         _minSize = sl_barrange_segmentation->GetStart();
798         _maxSize = sl_barrange_segmentation->GetEnd();
799
800         double px=_wxMaracasMPR->GetVtkMPRBaseData()->GetX();
801         double py=_wxMaracasMPR->GetVtkMPRBaseData()->GetY();
802         double pz=_wxMaracasMPR->GetVtkMPRBaseData()->GetZ();
803         ExtractSurface((int)(px),(int)(py),(int)(pz));
804         generateSTLSurfaces(); //DHC: AFTER SEGMENTATION THE TREE, THE STL SURFACES ARE CALCULATED.
805
806         Refresh();
807 }
808
809 //------------------------------------------------------------------------
810 void wxSTLWidget_03::OnOpacitySTLFile(wxScrollEvent& event)
811 {
812         if (_loadActorSTL!=NULL)
813         {
814                 double value = ((double)_sl_opacity_STL_file->GetValue())/100;
815                 _loadActorSTL->GetProperty( )->SetOpacity( value );
816                 Refresh();
817         }
818 }
819 //------------------------------------------------------------------------
820 void wxSTLWidget_03::Reset_vtk_STLFile()
821 {
822         // Remove
823         vtkRenderer *ren = _wxMaracasMPR->GetWxvtkmpr3Dview_BB()->GetWxvtk3Dbaseview()->GetRenderer();
824     if (_loadActorSTL){
825                 ren->RemoveActor(_loadActorSTL);
826         }
827
828         // Delete 
829         if (_loadSTLMapper              ) {     _loadSTLMapper          -> Delete(); }
830         if (_loadActorSTL               ) {     _loadActorSTL           -> Delete(); }
831
832         // Init
833         _loadSTLMapper          = NULL;
834         _loadActorSTL           = NULL;
835
836 }
837 //------------------------------------------------------------------------
838 void wxSTLWidget_03::OnBtnSTLFileErase(wxCommandEvent& event)
839 {
840         Reset_vtk_STLFile();
841         Refresh();
842 }
843 //------------------------------------------------------------------------
844 void wxSTLWidget_03::OnBtnSTLFileLoad(wxCommandEvent& event)
845 {
846         wxString dirSTL = _mar->_parameters->getStringParam( 
847     marParameters::e_installation_directory ); 
848         dirSTL = ( dirSTL == _T("NO_DIRECTORY") ) ? wxGetHomeDir( ) : dirSTL;
849         wxFileDialog dialog( this, _T("Choose a directory..."), ( !dirSTL.IsEmpty( ) )?
850         dirSTL: wxGetHomeDir( ) );
851
852         if( dialog.ShowModal( ) == wxID_OK ) 
853         {
854                 Reset_vtk_STLFile();
855                 vtkSTLReader *imgReader= vtkSTLReader::New();
856                 imgReader->SetFileName( dialog.GetPath().mb_str(wxConvUTF8) );  
857                 _loadSTLMapper = vtkPolyDataMapper::New();
858                 _loadSTLMapper->SetInput(imgReader->GetOutput());
859                 _loadActorSTL = vtkActor::New();
860                 _loadActorSTL->SetMapper(_loadSTLMapper);
861                 _loadActorSTL->GetProperty()->SetColor( 1, 0, 0);
862                 _loadActorSTL->GetProperty()->SetOpacity( 0.5 );
863                 vtkRenderer *ren = _wxMaracasMPR->GetWxvtkmpr3Dview_BB()->GetWxvtk3Dbaseview()->GetRenderer();
864                 ren->AddActor(_loadActorSTL);
865                 imgReader->Delete();
866         }
867         //By default *always* update e_installation_directory:
868         _mar->_parameters->setStringParam( marParameters::e_installation_directory, dialog.GetPath( ) ); 
869         _mar->saveParameters( );
870 }
871
872
873
874 // ------------------------------------------------------------------------
875 // END JOIN FUNCTIONS - DHC
876 // ------------------------------------------------------------------------
877
878 // ------------------------------------------------------------------------
879 // START STL FUNCTIONS - DHC
880 // ------------------------------------------------------------------------
881
882 void wxSTLWidget_03::ConfigureSTL()
883 {
884         stlExterna = vtkPolyData::New();
885         stlInterna = vtkPolyData::New();
886
887         dsm1 = vtkPolyDataMapper ::New();
888     dsm1->SetInput (stlInterna); 
889     dsm1->ScalarVisibilityOff();
890
891     actorInternal = vtkActor::New();
892     actorInternal->SetMapper (dsm1);
893     actorInternal->GetProperty()->SetColor (0,1,0);
894
895     dsm2 = vtkPolyDataMapper ::New();
896     dsm2->SetInput (stlExterna);
897     dsm2->ScalarVisibilityOff();
898
899     actorExternal= vtkActor::New();
900     actorExternal->SetMapper (dsm2);
901     actorExternal->GetProperty()->SetRepresentationToWireframe();
902
903 //    vtkRenderer *ren = _maracasSurfaceWidget->GetVtk3DSurfaceWidget()->GetRenderer();
904         vtkRenderer *ren = _wxMaracasMPR->GetWxvtkmpr3Dview_BB()->GetWxvtk3Dbaseview()->GetRenderer();
905     ren->AddActor(actorInternal);
906     ren->AddActor(actorExternal);
907
908         stlExtractor = new vtkSTLExtractor();  
909 }
910
911 void wxSTLWidget_03::generateSTLSurfaces()
912 {
913 // EED 09Janvier2007
914 //      stlExtractor->setVolume(_2_prgov->GetVolumen());
915
916         stlExtractor->setVolume(cast4->GetOutput());
917
918         stlExtractor->setSigmaLevel(_stlDeltaGaussLevel);
919         stlExtractor->setMarchingCubesLevel(_stlMarchingCubesLevel);
920         stlExtractor->calculate();
921         stlInterna->DeepCopy(stlExtractor->getInnerSurface());
922         stlExterna->DeepCopy(stlExtractor->getOuterSurface());
923 }
924
925
926 void wxSTLWidget_03::OnOpacitySTLExternal(wxScrollEvent& event){
927         double value = ((double)stlSliderOpacityExternal->GetValue())/100;
928     actorExternal->GetProperty( )->SetOpacity( value );
929         Refresh();
930 }
931
932
933 void wxSTLWidget_03::OnOpacitySTLInternal(wxScrollEvent& event){
934         double value = ((double)stlSliderOpacityInternal->GetValue())/100;
935     actorInternal->GetProperty( )->SetOpacity( value );
936         Refresh();
937 }
938
939 void wxSTLWidget_03::OnBtnCreateFileSTL(wxCommandEvent& event)
940 {
941
942         wxString dirSTL = _mar->_parameters->getStringParam( 
943     marParameters::e_installation_directory ); 
944         dirSTL = ( dirSTL == _T("NO_DIRECTORY") ) ? wxGetHomeDir( ) : dirSTL;
945
946         
947 //      wxDirDialog dialog( this, "Choose a directory...", ( !dirSTL.IsEmpty( ) )?dirSTL: wxGetHomeDir( ) );
948         wxFileDialog dialog( this, _T("Choose a directory..."), dirSTL , _T(""), _T("*.*"), wxSAVE );
949
950
951         if( dialog.ShowModal( ) == wxID_OK ) 
952         {
953            
954         
955                 // ------------------------------------------------------------------------
956                 //  1.  GENERATE STL FILES
957                 // ------------------------------------------------------------------------
958 //              const char* fileprefix = "c:\\Creatis\\";
959                 std::string prefix ( dialog.GetPath().mb_str(wxConvUTF8) );
960                 std::string filename;
961
962                 // 1.1. Se hace un filtro triangular puesto que el stl writer solo recibe poligonos triangulares.
963
964         vtkTriangleFilter *filtro = vtkTriangleFilter::New();
965                 filtro->SetInput(stlInterna);
966                 vtkPolyDataConnectivityFilter *pdcf = vtkPolyDataConnectivityFilter::New();
967         pdcf->SetInput( filtro->GetOutput() );
968         vtkClosePolyData *cpd = vtkClosePolyData::New();
969         cpd->SetInput( pdcf->GetOutput() );
970
971                 // 1.2 se escribe a disco el archivo stl de la superficie interna
972         cpd->Update();
973         vtkSTLWriter *writerI = vtkSTLWriter::New();
974         writerI->SetInput( cpd->GetOutput() );
975 //        prefix = fileprefix;
976                 filename=prefix+"_internal.stl";
977         writerI->SetFileName(filename.c_str());
978         writerI->SetFileTypeToASCII();
979         writerI->Write();
980         writerI->Delete();
981
982                 // 1.3 se escribe a disco el archivo stl de la superficie externa
983                 filtro->SetInput(stlExterna);
984         cpd->Update();
985         vtkSTLWriter *writerE = vtkSTLWriter::New();
986         writerE->SetInput( cpd->GetOutput() );
987 //        prefix = fileprefix;
988                 filename=prefix+"_external.stl";
989         writerE->SetFileName( filename.c_str() );
990         writerE->SetFileTypeToASCII();
991         writerE->Write();
992         writerE->Delete();
993    
994         filtro->Delete();
995         cpd->Delete();
996         pdcf->Delete();
997         }
998
999         //By default *always* update e_installation_directory:
1000         _mar->_parameters->setStringParam( marParameters::e_installation_directory, dialog.GetPath( ) ); 
1001         _mar->saveParameters( );
1002 }
1003
1004
1005 void wxSTLWidget_03::OnChangeSTLGaussLevel(wxScrollEvent& event)
1006 {
1007         wxBusyCursor wait;
1008         _stlDeltaGaussLevel  = ((double)stlSliderDeltaGauss->GetValue())/100;
1009         generateSTLSurfaces();
1010         Refresh();
1011 }
1012
1013
1014 void wxSTLWidget_03::OnChangeSTLMarchingCubesLevel(wxScrollEvent& event)
1015 {
1016         wxBusyCursor wait;
1017         _stlMarchingCubesLevel = ((double)stlSliderMarchingCubes->GetValue());
1018         generateSTLSurfaces();
1019         Refresh();
1020         
1021 }
1022
1023
1024 // ------------------------------------------------------------------------
1025 // END STL FUNCTIONS - DHC
1026 // ------------------------------------------------------------------------
1027
1028
1029
1030
1031
1032
1033