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);
60 connect(mContinousEraseTimer, SIGNAL(timeout()),
this, SLOT(continousRemoveSlot()));
62 QHBoxLayout* buttonLayout =
new QHBoxLayout;
63 layout->addLayout(buttonLayout);
64 QHBoxLayout* buttonLayout2 =
new QHBoxLayout;
65 layout->addLayout(buttonLayout2);
67 mShowEraserCheckBox =
new QCheckBox(
"Show");
68 mShowEraserCheckBox->setToolTip(
"Show eraser sphere in the views.");
69 connect(mShowEraserCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleShowEraser(
bool)));
70 buttonLayout->addWidget(mShowEraserCheckBox);
72 mContinousEraseCheckBox =
new QCheckBox(
"Continous");
73 mContinousEraseCheckBox->setToolTip(
"Erase continously using the sphere. (might be slow)");
74 connect(mContinousEraseCheckBox, SIGNAL(toggled(
bool)),
this, SLOT(toggleContinous(
bool)));
75 buttonLayout2->addWidget(mContinousEraseCheckBox);
77 mDuplicateAction = this->
createAction(
this, QIcon(),
"Duplicate",
"Duplicate active volume - do this before erasing!",
78 SLOT(duplicateSlot()), buttonLayout);
80 mSaveAction = this->
createAction(
this, QIcon(),
"Save",
"Save modified image to disk",
81 SLOT(saveSlot()), buttonLayout);
83 mRemoveAction = this->
createAction(
this, QIcon(),
"Erase",
"Erase everything inside sphere",
84 SLOT(removeSlot()), buttonLayout2);
87 double sphereRadius = 10;
91 layout->addWidget(mSphereSize);
96 eraseValue = image->
getMin();
103 layout->addWidget(mEraseValueWidget);
105 layout->addStretch();
107 this->enableButtons();
110 void EraserWidget::activeImageChangedSlot()
116 mEraseValueAdapter->setValueRange(
DoubleRange(image->getVTKMinValue(), image->getVTKMaxValue(), 1));
117 mEraseValueAdapter->setValue(image->getMin());
120 void EraserWidget::enableButtons()
122 bool e = mShowEraserCheckBox->isChecked();
124 mContinousEraseCheckBox->setEnabled(e);
127 mRemoveAction->setEnabled(e);
128 mSphereSize->setEnabled(e);
135 void EraserWidget::toggleContinous(
bool on)
139 mContinousEraseTimer->start(300);
143 mContinousEraseTimer->stop();
147 void EraserWidget::continousRemoveSlot()
149 Transform3D rMd = mViewService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
153 double r = mSphere->GetRadius();
162 void EraserWidget::duplicateSlot()
167 mPatientModelService->insertData(duplicate);
168 mActiveData->setActive(duplicate);
172 for (
unsigned i = 0; i < mViewService->groupCount(); ++i)
174 if (mViewService->getGroup(i)->removeData(original->getUid()))
175 mViewService->getGroup(i)->addData(duplicate->getUid());
179 void EraserWidget::sphereSizeChangedSlot()
183 mSphere->SetRadius(mSphereSizeAdapter->getValue());
192 void EraserWidget::saveSlot()
194 mPatientModelService->insertData(mActiveData->getActive<
Image>());
198 template <
class TYPE>
199 void EraserWidget::eraseVolume(TYPE* volumePointer)
205 Eigen::Array3i dim(img->GetDimensions());
206 Vector3D spacing(img->GetSpacing());
208 Transform3D rMd = mViewService->getGroup(0)->getOptions().mPickerGlyph->get_rMd();
211 double r = mSphere->GetRadius();
221 double r_d = dMr.vector(r * Vector3D::UnitX()).length();
223 r = rawMr.vector(r * Vector3D::UnitX()).length();
230 for (
int i=0; i<3; ++i)
232 bb1_raw[2*i] = std::max<double>(bb1_raw[2*i], bb0_raw[2*i]);
233 bb1_raw[2*i+1] = std::min<double>(bb1_raw[2*i+1], bb0_raw[2*i+1]);
236 int replaceVal = mEraseValueAdapter->getValue();
238 for (
int x = bb1_raw[0]; x < bb1_raw[1]; ++x)
239 for (
int y = bb1_raw[2]; y < bb1_raw[3]; ++y)
240 for (
int z = bb1_raw[4]; z < bb1_raw[5]; ++z)
242 int index = x + y * dim[0] + z * dim[0] * dim[1];
243 if ((
Vector3D(x*spacing[0], y*spacing[1], z*spacing[2]) - c_d).
length() < r_d)
244 volumePointer[index] = replaceVal;
263 void EraserWidget::removeSlot()
271 int vtkScalarType = img->GetScalarType();
273 if (vtkScalarType==VTK_CHAR)
274 this->eraseVolume(static_cast<char*> (img->GetScalarPointer()));
275 else if (vtkScalarType==VTK_UNSIGNED_CHAR)
276 this->eraseVolume(static_cast<unsigned char*> (img->GetScalarPointer()));
277 else if (vtkScalarType==VTK_SIGNED_CHAR)
278 this->eraseVolume(static_cast<signed char*> (img->GetScalarPointer()));
279 else if (vtkScalarType==VTK_UNSIGNED_SHORT)
280 this->eraseVolume(static_cast<unsigned short*> (img->GetScalarPointer()));
281 else if (vtkScalarType==VTK_SHORT)
282 this->eraseVolume(static_cast<short*> (img->GetScalarPointer()));
283 else if (vtkScalarType==VTK_UNSIGNED_INT)
284 this->eraseVolume(static_cast<unsigned int*> (img->GetScalarPointer()));
285 else if (vtkScalarType==VTK_INT)
286 this->eraseVolume(static_cast<int*> (img->GetScalarPointer()));
288 reportError(QString(
"Unknown VTK ScalarType: %1").arg(vtkScalarType));
295 image->setVtkImageData(img);
298 image->setLookupTable2D(tf2D);
299 image->setTransferFunctions3D(tf3D);
302 void EraserWidget::toggleShowEraser(
bool on)
307 mSphere = vtkSphereSourcePtr::New();
309 mSphere->SetRadius(40);
310 mSphere->SetThetaResolution(16);
311 mSphere->SetPhiResolution(12);
312 mSphere->LatLongTessellationOn();
314 double a = mSphereSizeAdapter->getValue();
315 mSphere->SetRadius(a);
317 MeshPtr glyph = mViewService->getGroup(0)->getOptions().mPickerGlyph;
318 glyph->setVtkPolyData(mSphere->GetOutput());
319 glyph->setColor(QColor(255, 204, 0));
320 glyph->setIsWireframe(
true);
323 for (
unsigned i=0; i<mViewService->groupCount(); ++i)
327 mViewService->getGroup(i)->setOptions(options);
332 mViewService->getGroup(0)->getOptions().mPickerGlyph->setVtkPolyData(NULL);
333 mContinousEraseCheckBox->setChecked(
false);
336 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
virtual vtkImageDataPtr getBaseVtkImageData()
ImagePtr duplicateImage(PatientModelServicePtr dataManager, ImagePtr image)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
static ActiveImageProxyPtr New(ActiveDataPtr activeData)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
Representation of an integer bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
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())
RealScalar length() const
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
Namespace for all CustusX production code.