13 #include "../DataManagement/mitkBoundingShapeUtil.h" 17 #include <vtkActor2D.h> 18 #include <vtkAppendPolyData.h> 19 #include <vtkCoordinate.h> 20 #include <vtkCubeSource.h> 22 #include <vtkPointData.h> 23 #include <vtkPolyData.h> 24 #include <vtkPolyDataMapper2D.h> 25 #include <vtkProperty2D.h> 26 #include <vtkSphereSource.h> 27 #include <vtkStripper.h> 28 #include <vtkTransformFilter.h> 29 #include <vtkTransformPolyDataFilter.h> 33 auto handle = vtkSmartPointer<vtkSphereSource>::New();
35 handle->SetPhiResolution(8);
36 handle->SetThetaResolution(16);
43 class BoundingShapeVtkMapper2D::Impl
51 for (
int i = 0; i < 6; ++i)
55 std::vector<Handle> HandlePropertyList;
60 mitk::BoundingShapeVtkMapper2D::LocalStorage::LocalStorage()
61 : m_Actor(vtkSmartPointer<vtkActor>::New()),
62 m_HandleActor(vtkSmartPointer<vtkActor2D>::New()),
63 m_SelectedHandleActor(vtkSmartPointer<vtkActor2D>::New()),
64 m_Mapper(vtkSmartPointer<vtkPolyDataMapper>::New()),
65 m_HandleMapper(vtkSmartPointer<vtkPolyDataMapper2D>::New()),
66 m_SelectedHandleMapper(vtkSmartPointer<vtkPolyDataMapper2D>::New()),
67 m_Cutter(vtkSmartPointer<vtkCutter>::New()),
68 m_CuttingPlane(vtkSmartPointer<vtkPlane>::New()),
70 m_PropAssembly(vtkSmartPointer<vtkPropAssembly>::New()),
73 m_Actor->SetMapper(m_Mapper);
74 m_Actor->GetProperty()->SetOpacity(0.3);
75 m_Actor->VisibilityOn();
77 m_HandleActor->SetMapper(m_HandleMapper);
78 m_HandleActor->VisibilityOn();
80 m_SelectedHandleActor->VisibilityOn();
81 m_SelectedHandleActor->GetProperty()->SetColor(0, 1.0, 0);
82 m_SelectedHandleActor->SetMapper(m_SelectedHandleMapper);
84 vtkCoordinate *tcoord = vtkCoordinate::New();
85 tcoord->SetCoordinateSystemToWorld();
86 m_SelectedHandleMapper->SetTransformCoordinate(tcoord);
89 m_Cutter->SetCutFunction(m_CuttingPlane);
91 for (
int i = 0; i < 6; ++i)
94 m_PropAssembly->AddPart(m_Actor);
95 m_PropAssembly->AddPart(m_HandleActor);
96 m_PropAssembly->VisibilityOn();
99 bool mitk::BoundingShapeVtkMapper2D::LocalStorage::IsUpdateRequired(
mitk::BaseRenderer *renderer,
105 if (m_LastGenerateDataTime < worldGeometry->GetMTime())
108 unsigned int sliceNumber = renderer->
GetSlice();
110 if (m_LastSliceNumber != sliceNumber)
113 if (mapper && m_LastGenerateDataTime < mapper->GetMTime())
118 if (m_LastGenerateDataTime < dataNode->GetMTime())
123 if (data && m_LastGenerateDataTime < data->GetMTime())
130 mitk::BoundingShapeVtkMapper2D::LocalStorage::~LocalStorage()
136 this->GenerateDataForRenderer(renderer);
141 Superclass::SetDefaultProperties(node, renderer, overwrite);
144 mitk::BoundingShapeVtkMapper2D::BoundingShapeVtkMapper2D() : m_Impl(
new Impl)
148 mitk::BoundingShapeVtkMapper2D::~BoundingShapeVtkMapper2D()
153 void mitk::BoundingShapeVtkMapper2D::GenerateDataForRenderer(
BaseRenderer *renderer)
159 LocalStorage *localStorage = m_Impl->LocalStorageHandler.GetLocalStorage(renderer);
162 bool needGenerateData = localStorage->IsUpdateRequired(
169 if (std::abs(scale - localStorage->m_ZoomFactor) > 0.001)
171 localStorage->m_ZoomFactor = scale;
172 needGenerateData =
true;
175 if (needGenerateData)
183 localStorage->m_Actor->VisibilityOff();
187 if (shape ==
nullptr)
201 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]));
203 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]));
205 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]));
210 if (m_Impl->HandlePropertyList.size() == 6)
220 m_Impl->HandlePropertyList[0].SetPosition(pointLeft);
221 m_Impl->HandlePropertyList[1].SetPosition(pointRight);
222 m_Impl->HandlePropertyList[2].SetPosition(pointTop);
223 m_Impl->HandlePropertyList[3].SetPosition(pointBottom);
224 m_Impl->HandlePropertyList[4].SetPosition(pointFront);
225 m_Impl->HandlePropertyList[5].SetPosition(pointBack);
229 double cubeFaceNormal0[3], cubeFaceNormal1[3], cubeFaceNormal2[3];
231 a[0] = (cornerPoints[5][0] - cornerPoints[6][0]);
232 a[1] = (cornerPoints[5][1] - cornerPoints[6][1]);
233 a[2] = (cornerPoints[5][2] - cornerPoints[6][2]);
235 b[0] = (cornerPoints[5][0] - cornerPoints[4][0]);
236 b[1] = (cornerPoints[5][1] - cornerPoints[4][1]);
237 b[2] = (cornerPoints[5][2] - cornerPoints[4][2]);
239 vtkMath::Cross(a, b, cubeFaceNormal0);
241 a[0] = (cornerPoints[0][0] - cornerPoints[6][0]);
242 a[1] = (cornerPoints[0][1] - cornerPoints[6][1]);
243 a[2] = (cornerPoints[0][2] - cornerPoints[6][2]);
245 b[0] = (cornerPoints[0][0] - cornerPoints[2][0]);
246 b[1] = (cornerPoints[0][1] - cornerPoints[2][1]);
247 b[2] = (cornerPoints[0][2] - cornerPoints[2][2]);
249 vtkMath::Cross(a, b, cubeFaceNormal1);
251 a[0] = (cornerPoints[2][0] - cornerPoints[7][0]);
252 a[1] = (cornerPoints[2][1] - cornerPoints[7][1]);
253 a[2] = (cornerPoints[2][2] - cornerPoints[7][2]);
255 b[0] = (cornerPoints[2][0] - cornerPoints[6][0]);
256 b[1] = (cornerPoints[2][1] - cornerPoints[6][1]);
257 b[2] = (cornerPoints[2][2] - cornerPoints[6][2]);
259 vtkMath::Cross(a, b, cubeFaceNormal2);
266 auto cube = vtkCubeSource::New();
267 cube->SetXLength(extent[0] / spacing[0]);
268 cube->SetYLength(extent[1] / spacing[1]);
269 cube->SetZLength(extent[2] / spacing[2]);
272 vtkSmartPointer<vtkMatrix4x4> imageTransform = geometry->GetVtkTransform()->GetMatrix();
273 auto translation = vtkSmartPointer<vtkTransform>::New();
274 translation->Translate(center[0] - imageTransform->GetElement(0, 3),
275 center[1] - imageTransform->GetElement(1, 3),
276 center[2] - imageTransform->GetElement(2, 3));
278 auto transform = vtkSmartPointer<vtkTransform>::New();
279 transform->SetMatrix(imageTransform);
280 transform->PostMultiply();
281 transform->Concatenate(translation);
285 auto transformFilter = vtkSmartPointer<vtkTransformFilter>::New();
286 transformFilter->SetInputData(cube->GetOutput());
287 transformFilter->SetTransform(transform);
288 transformFilter->Update();
291 vtkSmartPointer<vtkPolyData> polydata = transformFilter->GetPolyDataOutput();
292 if (polydata ==
nullptr || (polydata->GetNumberOfPoints() < 1))
294 localStorage->m_Actor->VisibilityOff();
295 localStorage->m_HandleActor->VisibilityOff();
296 localStorage->m_SelectedHandleActor->VisibilityOff();
306 origin[0] = planeGeometry->
GetOrigin()[0];
307 origin[1] = planeGeometry->
GetOrigin()[1];
308 origin[2] = planeGeometry->
GetOrigin()[2];
310 double displayPlaneNormal[3];
311 displayPlaneNormal[0] = planeGeometry->
GetNormal()[0];
312 displayPlaneNormal[1] = planeGeometry->
GetNormal()[1];
313 displayPlaneNormal[2] = planeGeometry->
GetNormal()[2];
316 localStorage->m_CuttingPlane->SetOrigin(origin);
317 localStorage->m_CuttingPlane->SetNormal(displayPlaneNormal);
320 localStorage->m_Cutter->SetInputData(polydata);
321 localStorage->m_Cutter->SetGenerateCutScalars(1);
322 localStorage->m_Cutter->Update();
324 if (localStorage->m_PropAssembly->GetParts()->IsItemPresent(localStorage->m_HandleActor))
325 localStorage->m_PropAssembly->RemovePart(localStorage->m_HandleActor);
326 if (localStorage->m_PropAssembly->GetParts()->IsItemPresent(localStorage->m_Actor))
327 localStorage->m_PropAssembly->RemovePart(localStorage->m_Actor);
329 vtkCoordinate *tcoord = vtkCoordinate::New();
330 tcoord->SetCoordinateSystemToWorld();
331 localStorage->m_HandleMapper->SetTransformCoordinate(tcoord);
334 if (localStorage->m_Cutter->GetOutput()->GetNumberOfPoints() > 0)
340 if (handleSizeProperty !=
nullptr)
341 initialHandleSize = handleSizeProperty->GetValue();
343 initialHandleSize = 1.0 / 40.0;
346 double handleSize = ((displaySize[0] + displaySize[1]) / 2.0) * initialHandleSize;
348 auto appendPoly = vtkSmartPointer<vtkAppendPolyData>::New();
349 unsigned int handleIdx = 0;
353 dynamic_cast<mitk::IntProperty *
>(node->GetProperty(
"Bounding Shape.Active Handle ID"));
355 double angle0 = std::abs(vtkMath::DegreesFromRadians(vtkMath::AngleBetweenVectors(displayPlaneNormal, cubeFaceNormal0)));
356 if (angle0 > 179.0) angle0 -= 180.0;
357 double angle1 = std::abs(vtkMath::DegreesFromRadians(vtkMath::AngleBetweenVectors(displayPlaneNormal, cubeFaceNormal1)));
358 if (angle1 > 179.0) angle1 -= 180.0;
359 double angle2 = std::abs(vtkMath::DegreesFromRadians(vtkMath::AngleBetweenVectors(displayPlaneNormal, cubeFaceNormal2)));
360 if (angle2 > 179.0) angle2 -= 180.0;
362 bool visible =
false;
363 bool selected =
false;
364 for (
auto& handle : localStorage->m_Handles)
366 Point3D handleCenter = m_Impl->HandlePropertyList[handleIdx].GetPosition();
368 handle->SetRadius(handleSize);
369 handle->SetCenter(handleCenter[0], handleCenter[1], handleCenter[2]);
372 if ( (handleIdx != 0 && handleIdx != 1 && std::abs(angle0) < 0.1) ||
373 (handleIdx != 2 && handleIdx != 3 && std::abs(angle1) < 0.1) ||
374 (handleIdx != 4 && handleIdx != 5 && std::abs(angle2) < 0.1) )
376 if (activeHandleId ==
nullptr)
378 appendPoly->AddInputConnection(handle->GetOutputPort());
382 if ((activeHandleId->GetValue() != m_Impl->HandlePropertyList[handleIdx].GetIndex()))
384 appendPoly->AddInputConnection(handle->GetOutputPort());
389 localStorage->m_SelectedHandleMapper->SetInputData(handle->GetOutput());
390 localStorage->m_SelectedHandleActor->VisibilityOn();
402 appendPoly->Update();
406 localStorage->m_HandleActor->VisibilityOff();
407 localStorage->m_SelectedHandleActor->VisibilityOff();
410 auto stripper = vtkSmartPointer<vtkStripper>::New();
411 stripper->SetInputData(localStorage->m_Cutter->GetOutput());
414 auto cutPolyData = vtkSmartPointer<vtkPolyData>::New();
415 cutPolyData->SetPoints(stripper->GetOutput()->GetPoints());
416 cutPolyData->SetPolys(stripper->GetOutput()->GetLines());
418 localStorage->m_Actor->GetMapper()->SetInputDataObject(cutPolyData);
420 if (selectedColor !=
nullptr)
423 localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]);
426 if (activeHandleId !=
nullptr)
428 localStorage->m_HandleActor->GetProperty()->SetColor(1, 0, 0);
432 localStorage->m_HandleActor->GetProperty()->SetColor(1, 1, 1);
434 localStorage->m_HandleActor->GetMapper()->SetInputDataObject(appendPoly->GetOutput());
437 localStorage->m_PropAssembly->AddPart(localStorage->m_Actor);
438 localStorage->m_PropAssembly->AddPart(localStorage->m_HandleActor);
441 localStorage->m_PropAssembly->AddPart(localStorage->m_SelectedHandleActor);
444 localStorage->m_PropAssembly->VisibilityOn();
445 localStorage->m_Actor->VisibilityOn();
446 localStorage->m_HandleActor->VisibilityOn();
450 localStorage->m_PropAssembly->VisibilityOff();
451 localStorage->m_Actor->VisibilityOff();
452 localStorage->m_HandleActor->VisibilityOff();
453 localStorage->m_SelectedHandleActor->VisibilityOff();
454 localStorage->UpdateGenerateDataTime();
456 localStorage->UpdateGenerateDataTime();
462 return m_Impl->LocalStorageHandler.GetLocalStorage(renderer)->m_PropAssembly;
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr, bool fallBackOnDataProperties=true) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
vtkProp * GetVtkProp(BaseRenderer *renderer) override
virtual unsigned int GetSlice() const
Base of all data objects.
void ApplyColorAndOpacityProperties(BaseRenderer *, vtkActor *) override
Apply specific color and opacity properties read from the PropertyList. Reimplemented in GLmapper (do...
virtual DataNode * GetDataNode() const
Get the DataNode containing the data to map. Method only returns valid DataNode Pointer if the mapper...
Point2D GetDisplaySizeInMM() const
static void SetDefaultProperties(DataNode *node, BaseRenderer *renderer=nullptr, bool overwrite=false)
Organizes the rendering process.
double GetScaleFactorMMPerDisplayUnit() const
DataCollection - Class to facilitate loading/accessing structured data.
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
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)
bool HasReferenceGeometry() const
The ColorProperty class RGB color property.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey="visible") const
Convenience access method for visibility properties (instances of BoolProperty with property-key "vis...
Data class only having a BaseGeometry but not containing any specific data.
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
Point< ScalarType, 3 > Point3D
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
virtual bool IsValid() const
Is this BaseGeometry in a state that is valid?
void Normalize(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output)
Vector3D GetNormal() const
Normal of the plane.
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.