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>
67 mPreviousCenter(0,0,0),
71 QVBoxLayout* layout =
new QVBoxLayout(
this);
72 this->setToolTip(
"Erase parts of volumes/models");
74 mContinousEraseTimer =
new QTimer(
this);
75 connect(mContinousEraseTimer, SIGNAL(timeout()),
this, SLOT(continousRemoveSlot()));
77 QHBoxLayout* buttonLayout =
new QHBoxLayout;
78 layout->addLayout(buttonLayout);
79 QHBoxLayout* buttonLayout2 =
new QHBoxLayout;
80 layout->addLayout(buttonLayout2);
82 mShowEraserCheckBox =
new QCheckBox(
"Show");
83 mShowEraserCheckBox->setToolTip(
"Show eraser sphere in the views.");
84 connect(mShowEraserCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleShowEraser(
bool)));
85 buttonLayout->addWidget(mShowEraserCheckBox);
87 mContinousEraseCheckBox =
new QCheckBox(
"Continous");
88 mContinousEraseCheckBox->setToolTip(
"Erase continously using the sphere. (might be slow)");
89 connect(mContinousEraseCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleContinous(
bool)));
90 buttonLayout2->addWidget(mContinousEraseCheckBox);
92 mDuplicateAction = this->
createAction(
this, QIcon(),
"Duplicate",
"Duplicate active volume - do this before erasing!",
93 SLOT(duplicateSlot()), buttonLayout);
95 mSaveAction = this->
createAction(
this, QIcon(),
"Save",
"Save modified image to disk",
96 SLOT(saveSlot()), buttonLayout);
98 mRemoveAction = this->
createAction(
this, QIcon(),
"Erase",
"Erase everything inside sphere",
99 SLOT(removeSlot()), buttonLayout2);
102 double sphereRadius = 10;
104 connect(mSphereSizeAdapter.get(), SIGNAL(changed()),
this, SLOT(sphereSizeChangedSlot()));
106 layout->addWidget(mSphereSize);
108 layout->addStretch();
110 this->enableButtons();
113 void EraserWidget::enableButtons()
115 bool e = mShowEraserCheckBox->isChecked();
117 mContinousEraseCheckBox->setEnabled(e);
120 mRemoveAction->setEnabled(e);
121 mSphereSize->setEnabled(e);
128 void EraserWidget::toggleContinous(
bool on)
132 mContinousEraseTimer->start(300);
136 mContinousEraseTimer->stop();
140 void EraserWidget::continousRemoveSlot()
146 double r = mSphere->GetRadius();
155 void EraserWidget::duplicateSlot()
165 for (
unsigned i = 0; i <
viewService()->groupCount(); ++i)
167 if (
viewService()->getGroup(i)->removeData(original->getUid()))
168 viewService()->getGroup(i)->addData(duplicate->getUid());
172 void EraserWidget::sphereSizeChangedSlot()
176 mSphere->SetRadius(mSphereSizeAdapter->getValue());
185 void EraserWidget::saveSlot()
191 template <
class TYPE>
192 void EraserWidget::eraseVolume(TYPE* volumePointer, TYPE replaceVal)
197 Eigen::Array3i dim(img->GetDimensions());
198 Vector3D spacing(img->GetSpacing());
203 double r = mSphere->GetRadius();
207 DoubleBoundingBox3D bb_r(c[0]-r, c[0]+r, c[1]-r, c[1]+r, c[2]-r, c[2]+r);
213 double r_d = dMr.vector(r * Vector3D::UnitX()).length();
215 r = rawMr.vector(r * Vector3D::UnitX()).length();
216 DoubleBoundingBox3D bb0_raw =
transform(rawMr, bb_r);
217 IntBoundingBox3D bb1_raw(0, dim[0], 0, dim[1], 0, dim[2]);
222 for (
int i=0; i<3; ++i)
224 bb1_raw[2*i] = std::max<double>(bb1_raw[2*i], bb0_raw[2*i]);
225 bb1_raw[2*i+1] = std::min<double>(bb1_raw[2*i+1], bb0_raw[2*i+1]);
228 for (
int x = bb1_raw[0]; x < bb1_raw[1]; ++x)
229 for (
int y = bb1_raw[2]; y < bb1_raw[3]; ++y)
230 for (
int z = bb1_raw[4]; z < bb1_raw[5]; ++z)
232 int index = x + y * dim[0] + z * dim[0] * dim[1];
233 if ((
Vector3D(x*spacing[0], y*spacing[1], z*spacing[2]) - c_d).
length() < r_d)
234 volumePointer[index] = replaceVal;
253 void EraserWidget::removeSlot()
261 if (img->GetScalarType()==VTK_CHAR)
262 this->eraseVolume(static_cast<char*> (img->GetScalarPointer()), VTK_CHAR_MIN);
263 if (img->GetScalarType()==VTK_UNSIGNED_CHAR)
264 this->eraseVolume(static_cast<unsigned char*> (img->GetScalarPointer()), VTK_UNSIGNED_CHAR_MIN);
265 if (img->GetScalarType()==VTK_UNSIGNED_SHORT)
266 this->eraseVolume(static_cast<unsigned short*> (img->GetScalarPointer()), VTK_UNSIGNED_SHORT_MIN);
267 if (img->GetScalarType()==VTK_SHORT)
268 this->eraseVolume(static_cast<short*> (img->GetScalarPointer()), VTK_SHORT_MIN);
269 if (img->GetScalarType()==VTK_UNSIGNED_INT)
270 this->eraseVolume(static_cast<unsigned int*> (img->GetScalarPointer()), VTK_UNSIGNED_INT_MIN);
271 if (img->GetScalarType()==VTK_INT)
272 this->eraseVolume(static_cast<int*> (img->GetScalarPointer()), VTK_INT_MIN);
279 image->setVtkImageData(img);
282 image->setLookupTable2D(tf2D);
283 image->setTransferFunctions3D(tf3D);
286 void EraserWidget::toggleShowEraser(
bool on)
291 mSphere = vtkSphereSourcePtr::New();
293 mSphere->SetRadius(40);
294 mSphere->SetThetaResolution(16);
295 mSphere->SetPhiResolution(12);
296 mSphere->LatLongTessellationOn();
298 double a = mSphereSizeAdapter->getValue();
299 mSphere->SetRadius(a);
302 glyph->setVtkPolyData(mSphere->GetOutput());
303 glyph->setColor(QColor(255, 204, 0));
304 glyph->setIsWireframe(
true);
307 for (
unsigned i=0; i<
viewService()->groupCount(); ++i)
309 ViewGroupData::Options options =
viewService()->getGroup(i)->getOptions();
310 options.mPickerGlyph = glyph;
316 viewService()->getGroup(0)->getOptions().mPickerGlyph->setVtkPolyData(NULL);
317 mContinousEraseCheckBox->setChecked(
false);
320 this->enableButtons();
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
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
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
EraserWidget(QWidget *parent)
ImagePtr duplicateImage(PatientModelServicePtr dataManager, ImagePtr image)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
cxLogicManager_EXPORT ViewServicePtr viewService()
void setDeepModified(vtkImageDataPtr image)
cxLogicManager_EXPORT PatientModelServicePtr patientService()
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
RealScalar length() const
boost::shared_ptr< class Mesh > MeshPtr
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr