CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxMemoryTester.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxMemoryTester.h"
13 #include <vtkImageData.h>
14 #include <vtkUnsignedCharArray.h>
15 #include <vtkPointData.h>
16 
17 namespace cx
18 {
19 
20 vtkImageDataPtr MemHolder::generateVtkImageData()
21 {
22  int dim[3];
23  dim[0] = 1024;
24  dim[1] = 768;
25  dim[2] = 1;
26  int numComp = 3;
27 
28  vtkImageDataPtr data = vtkImageDataPtr::New();
29  data->SetSpacing(1, 1, 1);
30  data->SetExtent(0, dim[0]-1, 0, dim[1]-1, 0, dim[2]-1);
31 // data->SetScalarTypeToUnsignedChar();
32 // data->SetScalarType(VTK_UNSIGNED_CHAR, 3);
33 // data->SetNumberOfScalarComponents(numComp);
34 
35  int scalarSize = dim[0]*dim[1]*dim[2]*numComp;
36 
37  unsigned char *rawchars = (unsigned char*)malloc(scalarSize+1);
38  char initValue = 1;
39  std::fill(rawchars,rawchars+scalarSize, initValue);
40 
41  vtkUnsignedCharArrayPtr array = vtkUnsignedCharArrayPtr::New();
42  array->SetNumberOfComponents(1);
43  //TODO: Whithout the +1 the volume is black
44  array->SetArray(rawchars, scalarSize+1, 0); // take ownership
45  data->GetPointData()->SetScalars(array);
46 
47  // A trick to get a full LUT in Image (automatic LUT generation)
48  // Can't seem to fix this by calling Image::resetTransferFunctions() after volume is modified
49  rawchars[0] = 255;
50  data->GetScalarRange();// Update internal data in vtkImageData. Seems like it is not possible to update this data after the volume has been changed.
51  rawchars[0] = 0;
52 
53  return data;
54 }
55 
57 {
58  int N = 500;
59 
60  std::vector<vtkImageDataPtr> storage;
61  for (unsigned i=0; i<N; ++i)
62  {
63  vtkImageDataPtr data = generateVtkImageData();
64  storage.push_back(data);
65  }
66  std::cout << "generated leak for images=" << N << std::endl;
67 
68 // vtkImageDataPtr temp = vtkImageDataPtr::New();
69 // temp->DeepCopy(mRedirecter->GetOutput());
70 // mTestStorage.push_back(temp);
71 //
72 // if (mTestStorage.size()==500)
73 // {
74 // mTestStorage.clear();
75 // mTestStorageCleared = true;
76 // std::cout << "cleared test storage for vtkImageData leak" << std::endl;
77 // }
78 
79 }
80 
81 //vtkImageDataPtr generateVtkImageData()
82 //{
83 // int dimension = 100; // generate 100^3 = 1Mb volume.
84 //
85 // vtkImageDataPtr data = vtkImageDataPtr::New();
86 // data->SetSpacing(1, 1, 1);
87 // data->SetExtent(0, dimension-1, 0, dimension-1, 0, dimension-1);
88 // data->SetScalarTypeToUnsignedChar();
89 // data->SetNumberOfScalarComponents(1);
90 //
91 // int scalarSize = dimension*dimension*dimension;
92 //
93 // unsigned char *rawchars = (unsigned char*)malloc(scalarSize+1);
94 // char initValue = 1;
95 // std::fill(rawchars,rawchars+scalarSize, initValue);
96 //
97 // vtkUnsignedCharArrayPtr array = vtkUnsignedCharArrayPtr::New();
98 // array->SetNumberOfComponents(1);
99 // //TODO: Whithout the +1 the volume is black
100 // array->SetArray(rawchars, scalarSize+1, 0); // take ownership
101 // data->GetPointData()->SetScalars(array);
102 //
103 // // A trick to get a full LUT in Image (automatic LUT generation)
104 // // Can't seem to fix this by calling Image::resetTransferFunctions() after volume is modified
105 // rawchars[0] = 255;
106 // data->GetScalarRange();// Update internal data in vtkImageData. Seems like it is not possible to update this data after the volume has been changed.
107 // rawchars[0] = 0;
108 //
109 // return data;
110 //}
111 
113 {
114  Block block;
115  int N = 100;
116  for (unsigned i=0; i<N; ++i)
117  {
118  block.mData.push_back(generateVtkImageData());
119  }
120 
121  mBlocks.push_back(block);
122  std::cout << QString("generated memory: %1 Mb, %2 blocks").arg(double(block.mData.front()->GetActualMemorySize() * N) / 1000.0).arg(mBlocks.size()).toStdString() << std::endl;
123  return N;
124 }
125 
127 {
128  mBlocks.pop_back();
129  std::cout << QString("removed one block, %1 left").arg(mBlocks.size()).toStdString() << std::endl;
130  return mBlocks.size();
131 }
132 
133 
134 
135 
136 
137 MemoryTester::MemoryTester(QWidget* parent) : QMainWindow(parent)
138 {
139  mMemory.reset(new MemHolder);
140 
141  this->setWindowTitle("QtSandbox");
142 
143 // mTextEdit = new QPlainTextEdit;
144 // setCentralWidget(mTextEdit);
145  this->setCentralWidget(new QPlainTextEdit);
146 
147  addActions();
148  addToolbar();
149  addMenu();
150  // play with this one:
151  //setUnifiedTitleAndToolBarOnMac(true);
152 
153  createStatusBar();
154 
155 // cx::LayoutEditor* editor = new cx::LayoutEditor(this);
156 // this->setCentralWidget(editor);
157 }
158 
159 void MemoryTester::addActions()
160 {
161  mAction1 = new QAction("Action1", this);
162  mAction1->setIcon(QIcon(":/images/go-home.png"));
163 // mAction1->setIcon(QIcon(":/images/workflow_state_navigation.png"));
164 
165  mAddMemAction = new QAction("AddMem", this);
166  mRemoveMemAction = new QAction("RemMem", this);
167  mLeakAction = new QAction("Leak", this);
168 
169  connect(mAddMemAction, SIGNAL(triggered()), mMemory.get(), SLOT(addBlock()));
170  connect(mRemoveMemAction, SIGNAL(triggered()), mMemory.get(), SLOT(removeBlock()));
171  connect(mLeakAction, SIGNAL(triggered()), mMemory.get(), SLOT(generateLeak()));
172 
173 // mAction2 = new QAction("Action2", this);
175 // mAction2->setIcon(QIcon(":/images/workflow_state_navigation2.png"));
176 
177 // mAction3 = new QAction("Action3", this);
178 // mAction3->setIcon(QIcon(":/images/workflow_state_patient_data.png"));
179 
180 // mAction4 = new QAction("Action4", this);
181 // mAction4->setIcon(QIcon(":/images/workflow_state_patient_data2.png"));
182 
183  mAboutQtAct = new QAction(tr("About &Qt"), this);
184  mAboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
185  connect(mAboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
186 
187  mAboutAct = new QAction(tr("About QtSandbox"), this);
188  mAboutAct->setStatusTip(tr("Show the Application's About box"));
189  connect(mAboutAct, SIGNAL(triggered()), this, SLOT(about()));
190 
191  mCrashAct = new QAction(tr("Color crash"), this);
192  connect(mCrashAct, SIGNAL(triggered()), this, SLOT(colorCrash()));
193 }
194 
195 void MemoryTester::addToolbar()
196 {
197  mToolbar = this->addToolBar("Mytoolbar");
198  mToolbar->addAction(mAction1);
199  mToolbar->addAction(mAddMemAction);
200  mToolbar->addAction(mLeakAction);
201  mToolbar->addAction(mRemoveMemAction);
202 // mToolbar->addAction(mCrashAct);
203 }
204 
205 void MemoryTester::addMenu()
206 {
207  QMenu* fileMenu = menuBar()->addMenu(tr("&File"));
208  fileMenu->addAction(mAction1);
209  fileMenu->addAction(mCrashAct);
210 
211  QMenu* helpMenu = menuBar()->addMenu(tr("&Help"));
212  helpMenu->addAction(mAboutQtAct);
213  helpMenu->addAction(mAboutAct);
214 }
215 
216 
217 void MemoryTester::about()
218 {
219  QMessageBox::about(this, tr("About QtSandbox"),
220  tr("The <b>QtSandbox</b> is a place where you can "
221  "test out nifty Qt features in a small app. Enjoy!"));
222 }
223 
224 void MemoryTester::createStatusBar()
225 {
226  statusBar()->showMessage(tr("Ready"));
227 }
228 
229 void MemoryTester::colorCrash()
230 {
231 #if QT_VERSION >= 0x040500
232  QColorDialog dialog(QColor("white"), this);
233  dialog.exec();
234 #else
235  QColor result = QColorDialog::getColor(QColor("white"), this);
236 #endif
237 }
238 }
std::vector< Block > mBlocks
vtkSmartPointer< class vtkUnsignedCharArray > vtkUnsignedCharArrayPtr
MemoryTester(QWidget *parent=0)
void fill(Eigen::Affine3d *self, vtkMatrix4x4Ptr m)
QToolBar * mToolbar
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
std::vector< vtkImageDataPtr > mData
Namespace for all CustusX production code.