38 #include "vtkSphereWidget.h"
39 #include "vtkSplineWidget.h"
40 #include "vtkSplineWidget2.h"
41 #include "vtkSplineRepresentation.h"
42 #include "vtkRenderWindow.h"
43 #include <vtkSphere.h>
44 #include <vtkClipPolyData.h>
45 #include <vtkImageData.h>
68 mPreviousCenter(0,0,0),
71 mPatientModelService(patientModelService),
72 mVisualizationService(visualizationService)
76 QVBoxLayout* layout =
new QVBoxLayout(
this);
77 this->setToolTip(
"Erase parts of volumes/models");
79 mContinousEraseTimer =
new QTimer(
this);
80 connect(mContinousEraseTimer, SIGNAL(timeout()),
this, SLOT(continousRemoveSlot()));
82 QHBoxLayout* buttonLayout =
new QHBoxLayout;
83 layout->addLayout(buttonLayout);
84 QHBoxLayout* buttonLayout2 =
new QHBoxLayout;
85 layout->addLayout(buttonLayout2);
87 mShowEraserCheckBox =
new QCheckBox(
"Show");
88 mShowEraserCheckBox->setToolTip(
"Show eraser sphere in the views.");
89 connect(mShowEraserCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleShowEraser(
bool)));
90 buttonLayout->addWidget(mShowEraserCheckBox);
92 mContinousEraseCheckBox =
new QCheckBox(
"Continous");
93 mContinousEraseCheckBox->setToolTip(
"Erase continously using the sphere. (might be slow)");
94 connect(mContinousEraseCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleContinous(
bool)));
95 buttonLayout2->addWidget(mContinousEraseCheckBox);
97 mDuplicateAction = this->
createAction(
this, QIcon(),
"Duplicate",
"Duplicate active volume - do this before erasing!",
98 SLOT(duplicateSlot()), buttonLayout);
100 mSaveAction = this->
createAction(
this, QIcon(),
"Save",
"Save modified image to disk",
101 SLOT(saveSlot()), buttonLayout);
103 mRemoveAction = this->
createAction(
this, QIcon(),
"Erase",
"Erase everything inside sphere",
104 SLOT(removeSlot()), buttonLayout2);
107 double sphereRadius = 10;
111 layout->addWidget(mSphereSize);
113 ImagePtr image = mPatientModelService->getActiveImage();
116 eraseValue = image->getMin();
123 layout->addWidget(mEraseValueWidget);
125 layout->addStretch();
127 this->enableButtons();
130 void EraserWidget::activeImageChangedSlot()
132 ImagePtr image = mPatientModelService->getActiveImage();
136 mEraseValueAdapter->setValueRange(
DoubleRange(image->getVTKMinValue(), image->getVTKMaxValue(), 1));
137 mEraseValueAdapter->setValue(image->getMin());
140 void EraserWidget::enableButtons()
142 bool e = mShowEraserCheckBox->isChecked();
144 mContinousEraseCheckBox->setEnabled(e);
147 mRemoveAction->setEnabled(e);
148 mSphereSize->setEnabled(e);
155 void EraserWidget::toggleContinous(
bool on)
159 mContinousEraseTimer->start(300);
163 mContinousEraseTimer->stop();
167 void EraserWidget::continousRemoveSlot()
169 Transform3D rMd = mVisualizationService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
173 double r = mSphere->GetRadius();
182 void EraserWidget::duplicateSlot()
184 ImagePtr original = mPatientModelService->getActiveImage();
187 mPatientModelService->insertData(duplicate);
188 mPatientModelService->setActiveImage(duplicate);
192 for (
unsigned i = 0; i < mVisualizationService->groupCount(); ++i)
194 if (mVisualizationService->getGroup(i)->removeData(original->getUid()))
195 mVisualizationService->getGroup(i)->addData(duplicate->getUid());
199 void EraserWidget::sphereSizeChangedSlot()
203 mSphere->SetRadius(mSphereSizeAdapter->getValue());
212 void EraserWidget::saveSlot()
214 mPatientModelService->insertData(mPatientModelService->getActiveImage());
218 template <
class TYPE>
219 void EraserWidget::eraseVolume(TYPE* volumePointer)
221 ImagePtr image = mPatientModelService->getActiveImage();
225 Eigen::Array3i dim(img->GetDimensions());
226 Vector3D spacing(img->GetSpacing());
228 Transform3D rMd = mVisualizationService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
231 double r = mSphere->GetRadius();
235 DoubleBoundingBox3D bb_r(c[0]-r, c[0]+r, c[1]-r, c[1]+r, c[2]-r, c[2]+r);
241 double r_d = dMr.vector(r * Vector3D::UnitX()).length();
243 r = rawMr.vector(r * Vector3D::UnitX()).length();
244 DoubleBoundingBox3D bb0_raw =
transform(rawMr, bb_r);
245 IntBoundingBox3D bb1_raw(0, dim[0], 0, dim[1], 0, dim[2]);
250 for (
int i=0; i<3; ++i)
252 bb1_raw[2*i] = std::max<double>(bb1_raw[2*i], bb0_raw[2*i]);
253 bb1_raw[2*i+1] = std::min<double>(bb1_raw[2*i+1], bb0_raw[2*i+1]);
256 int replaceVal = mEraseValueAdapter->getValue();
258 for (
int x = bb1_raw[0]; x < bb1_raw[1]; ++x)
259 for (
int y = bb1_raw[2]; y < bb1_raw[3]; ++y)
260 for (
int z = bb1_raw[4]; z < bb1_raw[5]; ++z)
262 int index = x + y * dim[0] + z * dim[0] * dim[1];
263 if ((
Vector3D(x*spacing[0], y*spacing[1], z*spacing[2]) - c_d).
length() < r_d)
264 volumePointer[index] = replaceVal;
283 void EraserWidget::removeSlot()
288 ImagePtr image = mPatientModelService->getActiveImage();
291 int vtkScalarType = img->GetScalarType();
293 if (vtkScalarType==VTK_CHAR)
294 this->eraseVolume(static_cast<char*> (img->GetScalarPointer()));
295 else if (vtkScalarType==VTK_UNSIGNED_CHAR)
296 this->eraseVolume(static_cast<unsigned char*> (img->GetScalarPointer()));
297 else if (vtkScalarType==VTK_SIGNED_CHAR)
298 this->eraseVolume(static_cast<signed char*> (img->GetScalarPointer()));
299 else if (vtkScalarType==VTK_UNSIGNED_SHORT)
300 this->eraseVolume(static_cast<unsigned short*> (img->GetScalarPointer()));
301 else if (vtkScalarType==VTK_SHORT)
302 this->eraseVolume(static_cast<short*> (img->GetScalarPointer()));
303 else if (vtkScalarType==VTK_UNSIGNED_INT)
304 this->eraseVolume(static_cast<unsigned int*> (img->GetScalarPointer()));
305 else if (vtkScalarType==VTK_INT)
306 this->eraseVolume(static_cast<int*> (img->GetScalarPointer()));
308 reportError(QString(
"Unknown VTK ScalarType: %1").arg(vtkScalarType));
315 image->setVtkImageData(img);
318 image->setLookupTable2D(tf2D);
319 image->setTransferFunctions3D(tf3D);
322 void EraserWidget::toggleShowEraser(
bool on)
327 mSphere = vtkSphereSourcePtr::New();
329 mSphere->SetRadius(40);
330 mSphere->SetThetaResolution(16);
331 mSphere->SetPhiResolution(12);
332 mSphere->LatLongTessellationOn();
334 double a = mSphereSizeAdapter->getValue();
335 mSphere->SetRadius(a);
337 MeshPtr glyph = mVisualizationService->getGroup(0)->getOptions().mPickerGlyph;
338 glyph->setVtkPolyData(mSphere->GetOutput());
339 glyph->setColor(QColor(255, 204, 0));
340 glyph->setIsWireframe(
true);
343 for (
unsigned i=0; i<mVisualizationService->groupCount(); ++i)
345 ViewGroupData::Options options = mVisualizationService->getGroup(i)->getOptions();
346 options.mPickerGlyph = glyph;
347 mVisualizationService->getGroup(i)->setOptions(options);
352 mVisualizationService->getGroup(0)->getOptions().mPickerGlyph->setVtkPolyData(NULL);
353 mContinousEraseCheckBox->setChecked(
false);
356 this->enableButtons();
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
void reportError(QString msg)
Transform3D createTransformScale(const Vector3D &scale_)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Utility class for describing a bounded numeric range.
boost::shared_ptr< class Image > ImagePtr
boost::shared_ptr< class ActiveImageProxy > ActiveImageProxyPtr
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
ImagePtr duplicateImage(PatientModelServicePtr dataManager, ImagePtr image)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
EraserWidget(PatientModelServicePtr patientModelService, VisualizationServicePtr visualizationService, QWidget *parent)
void changed()
emit when the underlying data value is changed: The user interface will be updated.
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
void setDeepModified(vtkImageDataPtr image)
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
RealScalar length() const
static ActiveImageProxyPtr New(PatientModelServicePtr patientModelService)
void activeImageChanged(const QString &uid)
The original image changed signal from DataManager.
boost::shared_ptr< class Mesh > MeshPtr
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr