17 #include "vtkSphereWidget.h" 18 #include "vtkSplineWidget.h" 19 #include "vtkSplineWidget2.h" 20 #include "vtkSplineRepresentation.h" 21 #include "vtkRenderWindow.h" 22 #include <vtkSphere.h> 23 #include <vtkClipPolyData.h> 24 #include <vtkImageData.h> 48 mPreviousCenter(0,0,0),
51 mPatientModelService(patientModelService),
52 mViewService(viewService),
53 mActiveData(patientModelService->getActiveData())
56 QVBoxLayout* layout =
new QVBoxLayout(
this);
57 this->setToolTip(
"Erase parts of volumes/models");
59 mContinousEraseTimer =
new QTimer(
this);
63 QHBoxLayout* buttonLayout =
new QHBoxLayout;
64 layout->addLayout(buttonLayout);
65 QHBoxLayout* buttonLayout2 =
new QHBoxLayout;
66 layout->addLayout(buttonLayout2);
68 mShowEraserCheckBox =
new QCheckBox(
"Show eraser");
69 mShowEraserCheckBox->setToolTip(
"Show eraser sphere in the views.");
70 connect(mShowEraserCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(
toggleShowEraser(
bool)));
71 buttonLayout->addWidget(mShowEraserCheckBox);
73 mContinousEraseCheckBox =
new QCheckBox(
"Continous");
74 mContinousEraseCheckBox->setToolTip(
"Erase continously using the sphere. (might be slow)");
75 connect(mContinousEraseCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(
toggleContinous(
bool)));
76 buttonLayout2->addWidget(mContinousEraseCheckBox);
78 mDuplicateAction = this->
createAction(
this, QIcon(),
"Duplicate",
"Duplicate active volume - do this before erasing!",
81 mSaveAction = this->
createAction(
this, QIcon(),
"Save",
"Save modified image to disk",
84 mRemoveAction = this->
createAction(
this, QIcon(),
"Erase",
"Erase everything inside sphere",
88 double sphereRadius = 10;
92 layout->addWidget(mSphereSize);
97 eraseValue = image->
getMin();
104 layout->addWidget(mEraseValueWidget);
106 layout->addStretch();
108 this->enableButtons();
117 mEraseValueAdapter->setValueRange(
DoubleRange(image->getVTKMinValue(), image->getVTKMaxValue(), 1));
118 mEraseValueAdapter->setValue(image->getMin());
121 void EraserWidget::enableButtons()
123 bool e = mShowEraserCheckBox->isChecked();
125 mContinousEraseCheckBox->setEnabled(e);
128 mRemoveAction->setEnabled(e);
129 mSphereSize->setEnabled(e);
140 mContinousEraseTimer->start(300);
144 mContinousEraseTimer->stop();
150 Transform3D rMd = mViewService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
153 double r = mSphere->GetRadius();
170 mPatientModelService->insertData(duplicate);
171 mActiveData->setActive(duplicate);
175 for (
unsigned i = 0; i < mViewService->groupCount(); ++i)
177 if (mViewService->getGroup(i)->removeData(original->getUid()))
178 mViewService->getGroup(i)->addData(duplicate->getUid());
186 mSphere->SetRadius(mSphereSizeAdapter->getValue());
201 mPatientModelService->insertData(image);
205 template <
class TYPE>
206 void EraserWidget::eraseVolume(TYPE* volumePointer)
210 Eigen::Array3i dim(img->GetDimensions());
211 Eigen::Array3d spacing(img->GetSpacing());
212 Transform3D rMd = mViewService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
213 Eigen::Array3d c(mSphere->GetCenter());
215 double r = mSphere->GetRadius();
216 int replaceVal = mEraseValueAdapter->getValue();
221 Eigen::Array3d scaledRadius = r*spacing.inverse();
227 Eigen::Array3i lowVoxIdx = (c - scaledRadius).floor().cast<
int>();
228 lowVoxIdx = lowVoxIdx.max(0);
229 Eigen::Array3i highVoxIdx = (c + scaledRadius).
ceil().cast<
int>();
230 highVoxIdx = highVoxIdx.min(dim);
232 for (
int x = lowVoxIdx(0); x < highVoxIdx(0); ++x)
233 for (
int y = lowVoxIdx(1); y < highVoxIdx(1); ++y)
234 for (
int z = lowVoxIdx(2); z < highVoxIdx(2); ++z)
236 int index = x + y * dim[0] + z * dim[0] * dim[1];
237 if ((
Vector3D((x-c(0))*spacing[0], (y-c(1))*spacing[1], (z-c(2))*spacing[2])).length() < r)
238 volumePointer[index] = replaceVal;
267 int vtkScalarType = img->GetScalarType();
269 if (vtkScalarType==VTK_CHAR)
270 this->eraseVolume(static_cast<char*> (img->GetScalarPointer()));
271 else if (vtkScalarType==VTK_UNSIGNED_CHAR)
272 this->eraseVolume(static_cast<unsigned char*> (img->GetScalarPointer()));
273 else if (vtkScalarType==VTK_SIGNED_CHAR)
274 this->eraseVolume(static_cast<signed char*> (img->GetScalarPointer()));
275 else if (vtkScalarType==VTK_UNSIGNED_SHORT)
276 this->eraseVolume(static_cast<unsigned short*> (img->GetScalarPointer()));
277 else if (vtkScalarType==VTK_SHORT)
278 this->eraseVolume(static_cast<short*> (img->GetScalarPointer()));
279 else if (vtkScalarType==VTK_UNSIGNED_INT)
280 this->eraseVolume(static_cast<unsigned int*> (img->GetScalarPointer()));
281 else if (vtkScalarType==VTK_INT)
282 this->eraseVolume(static_cast<int*> (img->GetScalarPointer()));
284 reportError(QString(
"Unknown VTK ScalarType: %1").arg(vtkScalarType));
291 image->setVtkImageData(img);
294 image->setLookupTable2D(tf2D);
295 image->setTransferFunctions3D(tf3D);
303 mSphere = vtkSphereSourcePtr::New();
305 mSphere->SetRadius(40);
306 mSphere->SetThetaResolution(16);
307 mSphere->SetPhiResolution(12);
308 mSphere->LatLongTessellationOn();
310 double a = mSphereSizeAdapter->getValue();
311 mSphere->SetRadius(a);
313 MeshPtr glyph = mViewService->getGroup(0)->getOptions().mPickerGlyph;
314 glyph->setVtkPolyData(mSphere->GetOutput());
315 glyph->setColor(QColor(255, 204, 0));
316 glyph->setIsWireframe(
true);
319 for (
unsigned i=0; i<mViewService->groupCount(); ++i)
323 mViewService->getGroup(i)->setOptions(options);
328 mViewService->getGroup(0)->getOptions().mPickerGlyph->setVtkPolyData(NULL);
329 mContinousEraseCheckBox->setChecked(
false);
332 this->enableButtons();
void reportError(QString msg)
Vector3D ceil(const Vector3D &a)
void activeImageChangedSlot()
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
void continousRemoveSlot()
boost::shared_ptr< class ActiveImageProxy > ActiveImageProxyPtr
void toggleContinous(bool on)
virtual vtkImageDataPtr getBaseVtkImageData()
void sphereSizeChangedSlot()
ImagePtr duplicateImage(PatientModelServicePtr dataManager, ImagePtr image)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
static ActiveImageProxyPtr New(ActiveDataPtr activeData)
static StringPropertyActiveImagePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
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)
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
EraserWidget(PatientModelServicePtr patientModelService, ViewServicePtr viewService, QWidget *parent)
void activeImageChanged(const QString &uid)
The original image changed signal from DataManager.
boost::shared_ptr< class Mesh > MeshPtr
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr
void toggleShowEraser(bool on)
Namespace for all CustusX production code.