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);
73 mContinousEraseTimer =
new QTimer(
this);
74 connect(mContinousEraseTimer, SIGNAL(timeout()),
this, SLOT(continousRemoveSlot()));
81 QHBoxLayout* buttonLayout =
new QHBoxLayout;
82 layout->addLayout(buttonLayout);
83 QHBoxLayout* buttonLayout2 =
new QHBoxLayout;
84 layout->addLayout(buttonLayout2);
86 mShowEraserCheckBox =
new QCheckBox(
"Show");
87 mShowEraserCheckBox->setToolTip(
"Show eraser sphere in the views.");
88 connect(mShowEraserCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleShowEraser(
bool)));
89 buttonLayout->addWidget(mShowEraserCheckBox);
91 mContinousEraseCheckBox =
new QCheckBox(
"Continous");
92 mContinousEraseCheckBox->setToolTip(
"Erase continously using the sphere. (might be slow)");
93 connect(mContinousEraseCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleContinous(
bool)));
94 buttonLayout2->addWidget(mContinousEraseCheckBox);
96 mDuplicateAction = this->
createAction(
this, QIcon(),
"Duplicate",
"Duplicate active volume - do this before erasing!",
97 SLOT(duplicateSlot()), buttonLayout);
99 mSaveAction = this->
createAction(
this, QIcon(),
"Save",
"Save modified image to disk",
100 SLOT(saveSlot()), buttonLayout);
102 mRemoveAction = this->
createAction(
this, QIcon(),
"Erase",
"Erase everything inside sphere",
103 SLOT(removeSlot()), buttonLayout2);
106 double sphereRadius = 10;
108 connect(mSphereSizeAdapter.get(), SIGNAL(changed()),
this, SLOT(sphereSizeChangedSlot()));
110 layout->addWidget(mSphereSize);
112 layout->addStretch();
114 this->enableButtons();
117 void EraserWidget::enableButtons()
119 bool e = mShowEraserCheckBox->isChecked();
121 mContinousEraseCheckBox->setEnabled(e);
124 mRemoveAction->setEnabled(e);
125 mSphereSize->setEnabled(e);
135 "<h3>Functionality for erasing parts of volumes/meshes.</h3>"
142 void EraserWidget::toggleContinous(
bool on)
146 mContinousEraseTimer->start(300);
150 mContinousEraseTimer->stop();
154 void EraserWidget::continousRemoveSlot()
160 double r = mSphere->GetRadius();
169 void EraserWidget::duplicateSlot()
179 for (
unsigned i = 0; i <
viewService()->groupCount(); ++i)
181 if (
viewService()->getGroup(i)->removeData(original->getUid()))
182 viewService()->getGroup(i)->addData(duplicate->getUid());
186 void EraserWidget::sphereSizeChangedSlot()
190 mSphere->SetRadius(mSphereSizeAdapter->getValue());
199 void EraserWidget::saveSlot()
205 template <
class TYPE>
206 void EraserWidget::eraseVolume(TYPE* volumePointer, TYPE replaceVal)
211 Eigen::Array3i dim(img->GetDimensions());
212 Vector3D spacing(img->GetSpacing());
217 double r = mSphere->GetRadius();
221 DoubleBoundingBox3D bb_r(c[0]-r, c[0]+r, c[1]-r, c[1]+r, c[2]-r, c[2]+r);
227 double r_d = dMr.vector(r * Vector3D::UnitX()).length();
229 r = rawMr.vector(r * Vector3D::UnitX()).length();
230 DoubleBoundingBox3D bb0_raw =
transform(rawMr, bb_r);
231 IntBoundingBox3D bb1_raw(0, dim[0], 0, dim[1], 0, dim[2]);
236 for (
int i=0; i<3; ++i)
238 bb1_raw[2*i] = std::max<double>(bb1_raw[2*i], bb0_raw[2*i]);
239 bb1_raw[2*i+1] = std::min<double>(bb1_raw[2*i+1], bb0_raw[2*i+1]);
242 for (
int x = bb1_raw[0]; x < bb1_raw[1]; ++x)
243 for (
int y = bb1_raw[2]; y < bb1_raw[3]; ++y)
244 for (
int z = bb1_raw[4]; z < bb1_raw[5]; ++z)
246 int index = x + y * dim[0] + z * dim[0] * dim[1];
247 if ((
Vector3D(x*spacing[0], y*spacing[1], z*spacing[2]) - c_d).
length() < r_d)
248 volumePointer[index] = replaceVal;
267 void EraserWidget::removeSlot()
275 if (img->GetScalarType()==VTK_CHAR)
276 this->eraseVolume(static_cast<char*> (img->GetScalarPointer()), VTK_CHAR_MIN);
277 if (img->GetScalarType()==VTK_UNSIGNED_CHAR)
278 this->eraseVolume(static_cast<unsigned char*> (img->GetScalarPointer()), VTK_UNSIGNED_CHAR_MIN);
279 if (img->GetScalarType()==VTK_UNSIGNED_SHORT)
280 this->eraseVolume(static_cast<unsigned short*> (img->GetScalarPointer()), VTK_UNSIGNED_SHORT_MIN);
281 if (img->GetScalarType()==VTK_SHORT)
282 this->eraseVolume(static_cast<short*> (img->GetScalarPointer()), VTK_SHORT_MIN);
283 if (img->GetScalarType()==VTK_UNSIGNED_INT)
284 this->eraseVolume(static_cast<unsigned int*> (img->GetScalarPointer()), VTK_UNSIGNED_INT_MIN);
285 if (img->GetScalarType()==VTK_INT)
286 this->eraseVolume(static_cast<int*> (img->GetScalarPointer()), VTK_INT_MIN);
293 image->setVtkImageData(img);
296 image->setLookupTable2D(tf2D);
297 image->setTransferFunctions3D(tf3D);
300 void EraserWidget::toggleShowEraser(
bool on)
305 mSphere = vtkSphereSourcePtr::New();
307 mSphere->SetRadius(40);
308 mSphere->SetThetaResolution(16);
309 mSphere->SetPhiResolution(12);
310 mSphere->LatLongTessellationOn();
312 double a = mSphereSizeAdapter->getValue();
313 mSphere->SetRadius(a);
316 glyph->setVtkPolyData(mSphere->GetOutput());
317 glyph->setColor(QColor(255, 204, 0));
318 glyph->setIsWireframe(
true);
321 for (
unsigned i=0; i<
viewService()->groupCount(); ++i)
323 ViewGroupData::Options options =
viewService()->getGroup(i)->getOptions();
324 options.mPickerGlyph = glyph;
330 viewService()->getGroup(0)->getOptions().mPickerGlyph->setVtkPolyData(NULL);
331 mContinousEraseCheckBox->setChecked(
false);
334 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
virtual QString defaultWhatsThis() const
Returns a short description of what this widget will do for you.
boost::shared_ptr< class Mesh > MeshPtr
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr