17 #include "../DataManagement/mitkBoundingShapeUtil.h"
21 #include <vtkActor2D.h>
22 #include <vtkAppendPolyData.h>
23 #include <vtkCoordinate.h>
24 #include <vtkCubeSource.h>
26 #include <vtkPointData.h>
27 #include <vtkPolyData.h>
28 #include <vtkPolyDataMapper2D.h>
29 #include <vtkProperty2D.h>
30 #include <vtkSphereSource.h>
31 #include <vtkStripper.h>
32 #include <vtkTransformFilter.h>
33 #include <vtkTransformPolyDataFilter.h>
39 handle->SetPhiResolution(8);
40 handle->SetThetaResolution(16);
47 class BoundingShapeVtkMapper2D::Impl
55 for (
int i = 0; i < 6; ++i)
59 std::vector<Handle> HandlePropertyList;
64 mitk::BoundingShapeVtkMapper2D::LocalStorage::LocalStorage()
65 : m_Actor(vtkSmartPointer<vtkActor>::
New()),
66 m_HandleActor(vtkSmartPointer<vtkActor2D>::
New()),
67 m_SelectedHandleActor(vtkSmartPointer<vtkActor2D>::
New()),
68 m_Mapper(vtkSmartPointer<vtkPolyDataMapper>::
New()),
69 m_HandleMapper(vtkSmartPointer<vtkPolyDataMapper2D>::
New()),
70 m_SelectedHandleMapper(vtkSmartPointer<vtkPolyDataMapper2D>::
New()),
71 m_Cutter(vtkSmartPointer<vtkCutter>::
New()),
72 m_CuttingPlane(vtkSmartPointer<vtkPlane>::
New()),
74 m_PropAssembly(vtkSmartPointer<vtkPropAssembly>::
New()),
77 m_Actor->SetMapper(m_Mapper);
78 m_Actor->GetProperty()->SetOpacity(0.3);
79 m_Actor->VisibilityOn();
81 m_HandleActor->SetMapper(m_HandleMapper);
82 m_HandleActor->VisibilityOn();
84 m_SelectedHandleActor->VisibilityOn();
85 m_SelectedHandleActor->GetProperty()->SetColor(0, 1.0, 0);
86 m_SelectedHandleActor->SetMapper(m_SelectedHandleMapper);
89 tcoord->SetCoordinateSystemToWorld();
90 m_SelectedHandleMapper->SetTransformCoordinate(tcoord);
93 m_Cutter->SetCutFunction(m_CuttingPlane);
95 for (
int i = 0; i < 6; ++i)
98 m_PropAssembly->AddPart(m_Actor);
99 m_PropAssembly->AddPart(m_HandleActor);
100 m_PropAssembly->VisibilityOn();
103 bool mitk::BoundingShapeVtkMapper2D::LocalStorage::IsUpdateRequired(
mitk::BaseRenderer *renderer,
109 if (m_LastGenerateDataTime < worldGeometry->GetMTime())
112 unsigned int sliceNumber = renderer->
GetSlice();
114 if (m_LastSliceNumber != sliceNumber)
117 if (mapper && m_LastGenerateDataTime < mapper->GetMTime())
122 if (m_LastGenerateDataTime < dataNode->GetMTime())
127 if (data && m_LastGenerateDataTime < data->GetMTime())
134 mitk::BoundingShapeVtkMapper2D::LocalStorage::~LocalStorage()
140 this->GenerateDataForRenderer(renderer);
145 Superclass::SetDefaultProperties(node, renderer, overwrite);
148 mitk::BoundingShapeVtkMapper2D::BoundingShapeVtkMapper2D() :
m_Impl(new Impl)
152 mitk::BoundingShapeVtkMapper2D::~BoundingShapeVtkMapper2D()
157 void mitk::BoundingShapeVtkMapper2D::GenerateDataForRenderer(BaseRenderer *renderer)
163 LocalStorage *localStorage =
m_Impl->LocalStorageHandler.GetLocalStorage(renderer);
166 bool needGenerateData = localStorage->IsUpdateRequired(
167 renderer,
this, GetDataNode());
171 double scale = renderer->GetScaleFactorMMPerDisplayUnit();
173 if (std::abs(scale - localStorage->m_ZoomFactor) > 0.001)
175 localStorage->m_ZoomFactor = scale;
176 needGenerateData =
true;
179 if (needGenerateData)
182 GetDataNode()->GetVisibility(visible, renderer,
"visible");
186 localStorage->m_Actor->VisibilityOff();
190 if (shape ==
nullptr)
204 sqrt((p0[0] - p4[0]) * (p0[0] - p4[0]) + (p0[1] - p4[1]) * (p0[1] - p4[1]) + (p0[2] - p4[2]) * (p0[2] - p4[2]));
206 sqrt((p0[0] - p2[0]) * (p0[0] - p2[0]) + (p0[1] - p2[1]) * (p0[1] - p2[1]) + (p0[2] - p2[2]) * (p0[2] - p2[2]));
208 sqrt((p0[0] - p1[0]) * (p0[0] - p1[0]) + (p0[1] - p1[1]) * (p0[1] - p1[1]) + (p0[2] - p1[2]) * (p0[2] - p1[2]));
213 if (
m_Impl->HandlePropertyList.size() == 6)
223 m_Impl->HandlePropertyList[0].SetPosition(pointLeft);
224 m_Impl->HandlePropertyList[1].SetPosition(pointRight);
225 m_Impl->HandlePropertyList[2].SetPosition(pointTop);
226 m_Impl->HandlePropertyList[3].SetPosition(pointBottom);
227 m_Impl->HandlePropertyList[4].SetPosition(pointFront);
228 m_Impl->HandlePropertyList[5].SetPosition(pointBack);
232 double result0[3], result1[3], result2[3];
234 a[0] = (cornerPoints[5][0] - cornerPoints[6][0]);
235 a[1] = (cornerPoints[5][1] - cornerPoints[6][1]);
236 a[2] = (cornerPoints[5][2] - cornerPoints[6][2]);
238 b[0] = (cornerPoints[5][0] - cornerPoints[4][0]);
239 b[1] = (cornerPoints[5][1] - cornerPoints[4][1]);
240 b[2] = (cornerPoints[5][2] - cornerPoints[4][2]);
242 vtkMath::Cross(a, b, result0);
244 a[0] = (cornerPoints[0][0] - cornerPoints[6][0]);
245 a[1] = (cornerPoints[0][1] - cornerPoints[6][1]);
246 a[2] = (cornerPoints[0][2] - cornerPoints[6][2]);
248 b[0] = (cornerPoints[0][0] - cornerPoints[2][0]);
249 b[1] = (cornerPoints[0][1] - cornerPoints[2][1]);
250 b[2] = (cornerPoints[0][2] - cornerPoints[2][2]);
252 vtkMath::Cross(a, b, result1);
254 a[0] = (cornerPoints[2][0] - cornerPoints[7][0]);
255 a[1] = (cornerPoints[2][1] - cornerPoints[7][1]);
256 a[2] = (cornerPoints[2][2] - cornerPoints[7][2]);
258 b[0] = (cornerPoints[2][0] - cornerPoints[6][0]);
259 b[1] = (cornerPoints[2][1] - cornerPoints[6][1]);
260 b[2] = (cornerPoints[2][2] - cornerPoints[6][2]);
262 vtkMath::Cross(a, b, result2);
270 cube->SetXLength(extent[0] / spacing[0]);
271 cube->SetYLength(extent[1] / spacing[1]);
272 cube->SetZLength(extent[2] / spacing[2]);
275 vtkSmartPointer<vtkMatrix4x4> imageTransform = geometry->GetVtkTransform()->GetMatrix();
277 translation->Translate(center[0] - imageTransform->GetElement(0, 3),
278 center[1] - imageTransform->GetElement(1, 3),
279 center[2] - imageTransform->GetElement(2, 3));
282 transform->SetMatrix(imageTransform);
283 transform->PostMultiply();
284 transform->Concatenate(translation);
289 transformFilter->SetInputData(cube->GetOutput());
290 transformFilter->SetTransform(transform);
291 transformFilter->Update();
294 vtkSmartPointer<vtkPolyData> polydata = transformFilter->GetPolyDataOutput();
295 if (polydata ==
nullptr || (polydata->GetNumberOfPoints() < 1))
297 localStorage->m_Actor->VisibilityOff();
298 localStorage->m_HandleActor->VisibilityOff();
299 localStorage->m_SelectedHandleActor->VisibilityOff();
304 const PlaneGeometry *planeGeometry = renderer->GetCurrentWorldPlaneGeometry();
305 if ((planeGeometry ==
nullptr) || (!planeGeometry->IsValid()) || (!planeGeometry->HasReferenceGeometry()))
309 origin[0] = planeGeometry->GetOrigin()[0];
310 origin[1] = planeGeometry->GetOrigin()[1];
311 origin[2] = planeGeometry->GetOrigin()[2];
314 normal[0] = planeGeometry->GetNormal()[0];
315 normal[1] = planeGeometry->GetNormal()[1];
316 normal[2] = planeGeometry->GetNormal()[2];
319 localStorage->m_CuttingPlane->SetOrigin(origin);
320 localStorage->m_CuttingPlane->SetNormal(normal);
323 localStorage->m_Cutter->SetInputData(polydata);
324 localStorage->m_Cutter->SetGenerateCutScalars(1);
325 localStorage->m_Cutter->Update();
327 if (localStorage->m_PropAssembly->GetParts()->IsItemPresent(localStorage->m_HandleActor))
328 localStorage->m_PropAssembly->RemovePart(localStorage->m_HandleActor);
329 if (localStorage->m_PropAssembly->GetParts()->IsItemPresent(localStorage->m_Actor))
330 localStorage->m_PropAssembly->RemovePart(localStorage->m_Actor);
333 tcoord->SetCoordinateSystemToWorld();
334 localStorage->m_HandleMapper->SetTransformCoordinate(tcoord);
337 if (localStorage->m_Cutter->GetOutput()->GetNumberOfPoints() > 0)
340 dynamic_cast<mitk::DoubleProperty *
>(this->GetDataNode()->GetProperty(
"Bounding Shape.Handle Size Factor"));
343 if (handleSizeProperty !=
nullptr)
344 initialHandleSize = handleSizeProperty->GetValue();
346 initialHandleSize = 1.0 / 40.0;
349 double handleSize = ((displaySize[0] + displaySize[1]) / 2.0) * initialHandleSize;
356 dynamic_cast<mitk::IntProperty *
>(node->GetProperty(
"Bounding Shape.Active Handle ID"));
358 bool visible =
false;
359 bool selected =
false;
360 for (
auto handle : localStorage->m_Handles)
362 Point3D handleCenter =
m_Impl->HandlePropertyList[i].GetPosition();
364 handle->SetRadius(handleSize);
365 handle->SetCenter(handleCenter[0], handleCenter[1], handleCenter[2]);
368 double angle = vtkMath::DegreesFromRadians(acos(vtkMath::Dot(normal, result0)));
369 double angle1 = vtkMath::DegreesFromRadians(acos(vtkMath::Dot(normal, result1)));
370 double angle2 = vtkMath::DegreesFromRadians(acos(vtkMath::Dot(normal, result2)));
373 if ((((std::abs(angle - 0) < 0.001) || (std::abs(angle - 180) < 0.001)) && i != 0 && i != 1) ||
374 (((std::abs(angle1 - 0) < 0.001) || (std::abs(angle1 - 180) < 0.001)) && i != 2 && i != 3) ||
375 (((std::abs(angle2 - 0) < 0.001) || (std::abs(angle2 - 180) < 0.001)) && i != 4 && i != 5))
377 if (activeHandleId ==
nullptr)
379 appendPoly->AddInputConnection(handle->GetOutputPort());
383 if ((activeHandleId->GetValue() !=
m_Impl->HandlePropertyList[i].GetIndex()))
385 appendPoly->AddInputConnection(handle->GetOutputPort());
390 localStorage->m_SelectedHandleMapper->SetInputData(handle->GetOutput());
391 localStorage->m_SelectedHandleActor->VisibilityOn();
403 appendPoly->Update();
407 localStorage->m_HandleActor->VisibilityOff();
408 localStorage->m_SelectedHandleActor->VisibilityOff();
412 stripper->SetInputData(localStorage->m_Cutter->GetOutput());
416 cutPolyData->SetPoints(stripper->GetOutput()->GetPoints());
417 cutPolyData->SetPolys(stripper->GetOutput()->GetLines());
419 localStorage->m_Actor->GetMapper()->SetInputDataObject(cutPolyData);
421 if (selectedColor !=
nullptr)
424 localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]);
427 if (activeHandleId !=
nullptr)
429 localStorage->m_HandleActor->GetProperty()->SetColor(1, 0, 0);
433 localStorage->m_HandleActor->GetProperty()->SetColor(1, 1, 1);
435 localStorage->m_HandleActor->GetMapper()->SetInputDataObject(appendPoly->GetOutput());
438 localStorage->m_PropAssembly->AddPart(localStorage->m_Actor);
439 localStorage->m_PropAssembly->AddPart(localStorage->m_HandleActor);
442 localStorage->m_PropAssembly->AddPart(localStorage->m_SelectedHandleActor);
445 localStorage->m_PropAssembly->VisibilityOn();
446 localStorage->m_Actor->VisibilityOn();
447 localStorage->m_HandleActor->VisibilityOn();
451 localStorage->m_PropAssembly->VisibilityOff();
452 localStorage->m_Actor->VisibilityOff();
453 localStorage->m_HandleActor->VisibilityOff();
454 localStorage->m_SelectedHandleActor->VisibilityOff();
455 localStorage->UpdateGenerateDataTime();
457 localStorage->UpdateGenerateDataTime();
463 return m_Impl->LocalStorageHandler.GetLocalStorage(renderer)->m_PropAssembly;
vtkProp * GetVtkProp(BaseRenderer *renderer) override
virtual unsigned int GetSlice() const
Base of all data objects.
void ApplyColorAndOpacityProperties(BaseRenderer *, vtkActor *) override
Apply color and opacity properties read from the PropertyList. Called by mapper subclasses.
itk::SmartPointer< Self > Pointer
static void SetDefaultProperties(DataNode *node, BaseRenderer *renderer=nullptr, bool overwrite=false)
Organizes the rendering process.
DataCollection - Class to facilitate loading/accessing structured data.
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
std::vector< mitk::Point3D > GetCornerPoints(mitk::BaseGeometry::Pointer geometry, bool visualizationOffset)
helper function for calculating corner points of the bounding object from a given geometry ...
Base class of all mappers, Vtk as well as OpenGL mappers.
std::vector< int > GetHandleIndices(int index)
itk::SmartPointer< Self > Pointer
The ColorProperty class RGB color property.
Point< ScalarType, 3 > Point3D
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
void Normalize(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output)
const float selectedColor[]
Describes a two-dimensional, rectangular plane.
static vtkSmartPointer< vtkSphereSource > CreateHandle()
mitk::Point3D CalcAvgPoint(mitk::Point3D a, mitk::Point3D b)
helper function for calculating the average of two points
Class for nodes of the DataTree.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.