diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp index 825f472f76..e315d83c12 100755 --- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp @@ -1,676 +1,675 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkPointSetVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkPointSet.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if (VTK_MAJOR_VERSION >= 5) #include #else #include #endif #include const mitk::PointSet* mitk::PointSetVtkMapper3D::GetInput() { return static_cast ( GetData() ); } mitk::PointSetVtkMapper3D::PointSetVtkMapper3D() : m_vtkSelectedPointList(NULL), m_vtkUnselectedPointList(NULL), //m_vtkContourPolyData(NULL), m_VtkSelectedPolyDataMapper(NULL), m_VtkUnselectedPolyDataMapper(NULL), //m_vtkContourPolyDataMapper(NULL), m_vtkTextList(NULL), //m_Contour(NULL), //m_TubeFilter(NULL), m_NumberOfSelectedAdded(0), m_NumberOfUnselectedAdded(0), m_PointSize(1.0), m_ContourRadius(0.5) { //propassembly m_PointsAssembly = vtkPropAssembly::New(); //creating actors to be able to set transform m_SelectedActor = vtkActor::New(); m_UnselectedActor = vtkActor::New(); m_ContourActor = vtkActor::New(); } mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D() { m_PointsAssembly->Delete(); m_SelectedActor->Delete(); m_UnselectedActor->Delete(); m_ContourActor->Delete(); } void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin) { m_PointsAssembly->ReleaseGraphicsResources(renWin); m_SelectedActor->ReleaseGraphicsResources(renWin); m_UnselectedActor->ReleaseGraphicsResources(renWin); m_ContourActor->ReleaseGraphicsResources(renWin); } void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects() { m_vtkSelectedPointList = vtkAppendPolyData::New(); m_vtkUnselectedPointList = vtkAppendPolyData::New(); m_PointsAssembly->VisibilityOn(); if(m_PointsAssembly->GetParts()->IsItemPresent(m_SelectedActor)) m_PointsAssembly->RemovePart(m_SelectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_UnselectedActor)) m_PointsAssembly->RemovePart(m_UnselectedActor); if(m_PointsAssembly->GetParts()->IsItemPresent(m_ContourActor)) m_PointsAssembly->RemovePart(m_ContourActor); // exceptional displaying for PositionTracker -> MouseOrientationTool int mapperID; bool isInputDevice=false; if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice ) { if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2) return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed } // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { m_PointsAssembly->VisibilityOff(); return; } mitk::PointSet::PointsContainer::Iterator pointsIter; mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; m_NumberOfSelectedAdded = 0; m_NumberOfUnselectedAdded = 0; //create contour bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { this->CreateContour(NULL); } //now fill selected and unselected pointList //get size of Points in Property m_PointSize = 2; mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); if ( pointSizeProp.IsNotNull() ) m_PointSize = pointSizeProp->GetValue(); //get the property for creating a label onto every point only once bool showLabel = true; this->GetDataNode()->GetBoolProperty("show label", showLabel); const char * pointLabel=NULL; if(showLabel) { if(dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != NULL) pointLabel =dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue(); else showLabel = false; } //check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected) bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); //now add an object for each point in data pointDataIter = itkPointSet->GetPointData()->Begin(); for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End(); pointsIter++, j++) { //check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected list int pointType; if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken) pointType = mitk::PTUNDEFINED; else pointType = pointDataIter.Value().pointSpec; #if (VTK_MAJOR_VERSION >= 5) vtkPolyDataAlgorithm *source; #else vtkPolyDataSource *source; #endif switch (pointType) { case mitk::PTUNDEFINED: { vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); //sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]); //MouseOrientation Tool (PositionTracker) if(isInputDevice) { sphere->SetThetaResolution(10); sphere->SetPhiResolution(10); } else { sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); } source = sphere; } break; case mitk::PTSTART: { vtkCubeSource *cube = vtkCubeSource::New(); cube->SetXLength(m_PointSize/2); cube->SetYLength(m_PointSize/2); cube->SetZLength(m_PointSize/2); itk::Point point1 = pointsIter->Value(); cube->SetCenter(point1[0],point1[1],point1[2]); source = cube; } break; case mitk::PTCORNER: { vtkConeSource *cone = vtkConeSource::New(); cone->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cone->SetCenter(point1[0],point1[1],point1[2]); cone->SetResolution(20); source = cone; } break; case mitk::PTEDGE: { vtkCylinderSource *cylinder = vtkCylinderSource::New(); cylinder->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); cylinder->SetCenter(point1[0],point1[1],point1[2]); cylinder->SetResolution(20); source = cylinder; } break; case mitk::PTEND: { vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; default: { vtkSphereSource *sphere = vtkSphereSource::New(); sphere->SetRadius(m_PointSize); itk::Point point1 = pointsIter->Value(); sphere->SetCenter(point1[0],point1[1],point1[2]); sphere->SetThetaResolution(20); sphere->SetPhiResolution(20); source = sphere; } break; } if (!pointDataBroken) { if (pointDataIter.Value().selected) { m_vtkSelectedPointList->AddInput(source->GetOutput()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInput(source->GetOutput()); ++m_NumberOfUnselectedAdded; } } else { m_vtkUnselectedPointList->AddInput(source->GetOutput()); ++m_NumberOfUnselectedAdded; } source->Delete(); if (showLabel) { char buffer[20]; std::string l = pointLabel; if ( input->GetSize()>1 ) { sprintf(buffer,"%d",j+1); l.append(buffer); } // Define the text for the label vtkVectorText *label = vtkVectorText::New(); label->SetText(l.c_str()); //# Set up a transform to move the label to a new position. vtkTransform *aLabelTransform =vtkTransform::New(); aLabelTransform->Identity(); itk::Point point1 = pointsIter->Value(); aLabelTransform->Translate(point1[0]+2,point1[1]+2,point1[2]); aLabelTransform->Scale(5.7,5.7,5.7); //# Move the label to a new position. vtkTransformPolyDataFilter *labelTransform = vtkTransformPolyDataFilter::New(); labelTransform->SetTransform(aLabelTransform); aLabelTransform->Delete(); labelTransform->SetInput(label->GetOutput()); label->Delete(); //add it to the wright PointList if (pointType) { m_vtkSelectedPointList->AddInput(labelTransform->GetOutput()); ++m_NumberOfSelectedAdded; } else { m_vtkUnselectedPointList->AddInput(labelTransform->GetOutput()); ++m_NumberOfUnselectedAdded; } labelTransform->Delete(); } if(pointDataIter != itkPointSet->GetPointData()->End()) pointDataIter++; } // end FOR //now according to number of elements added to selected or unselected, build up the rendering pipeline if (m_NumberOfSelectedAdded > 0) { m_VtkSelectedPolyDataMapper = vtkPolyDataMapper::New(); m_VtkSelectedPolyDataMapper->SetInput(m_vtkSelectedPointList->GetOutput()); //create a new instance of the actor m_SelectedActor->Delete(); m_SelectedActor = vtkActor::New(); m_SelectedActor->SetMapper(m_VtkSelectedPolyDataMapper); m_VtkSelectedPolyDataMapper->Delete(); m_PointsAssembly->AddPart(m_SelectedActor); } m_vtkSelectedPointList->Delete(); if (m_NumberOfUnselectedAdded > 0) { m_VtkUnselectedPolyDataMapper = vtkPolyDataMapper::New(); m_VtkUnselectedPolyDataMapper->SetInput(m_vtkUnselectedPointList->GetOutput()); //create a new instance of the actor m_UnselectedActor->Delete(); m_UnselectedActor = vtkActor::New(); m_UnselectedActor->SetMapper(m_VtkUnselectedPolyDataMapper); m_VtkUnselectedPolyDataMapper->Delete(); m_PointsAssembly->AddPart(m_UnselectedActor); } m_vtkUnselectedPointList->Delete(); } void mitk::PointSetVtkMapper3D::GenerateData() { //create new vtk render objects (e.g. sphere for a point) this->CreateVTKRenderObjects(); //apply props Superclass::ApplyProperties( m_ContourActor, NULL ); this->ApplyProperties(NULL); } void mitk::PointSetVtkMapper3D::GenerateData( mitk::BaseRenderer *renderer ) { SetVtkMapperImmediateModeRendering(m_VtkSelectedPolyDataMapper); SetVtkMapperImmediateModeRendering(m_VtkUnselectedPolyDataMapper); mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("pointsize")); mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize")); // only create new vtk render objects if property values were changed if ( pointSizeProp.IsNotNull() && contourSizeProp.IsNotNull() ) { if (m_PointSize!=pointSizeProp->GetValue() || m_ContourRadius!= contourSizeProp->GetValue()) { this->CreateVTKRenderObjects(); } } Superclass::ApplyProperties( m_ContourActor, renderer ); this->ApplyProperties(renderer); if(IsVisible(renderer)==false) { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); m_ContourActor->VisibilityOff(); return; } bool showPoints = true; this->GetDataNode()->GetBoolProperty("show points", showPoints); if(showPoints) { m_UnselectedActor->VisibilityOn(); m_SelectedActor->VisibilityOn(); } else { m_UnselectedActor->VisibilityOff(); m_SelectedActor->VisibilityOff(); } if(dynamic_cast(this->GetDataNode()->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetProperty("opacity")); float opacity = pointOpacity->GetValue(); m_ContourActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetOpacity(opacity); m_SelectedActor->GetProperty()->SetOpacity(opacity); } bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour); if (makeContour) { m_ContourActor->VisibilityOn(); } else { m_ContourActor->VisibilityOff(); } } void mitk::PointSetVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ ) { m_PointsAssembly->VisibilityOff(); } vtkProp* mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/) { return m_PointsAssembly; } void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { vtkLinearTransform * vtktransform = this->GetDataNode()->GetVtkTransform(this->GetTimestep()); m_SelectedActor->SetUserTransform(vtktransform); m_UnselectedActor->SetUserTransform(vtktransform); m_ContourActor->SetUserTransform(vtktransform); } void mitk::PointSetVtkMapper3D::ApplyProperties(mitk::BaseRenderer* renderer) { //check for color props and use it for rendering of selected/unselected points and contour //due to different params in VTK (double/float) we have to convert! //vars to convert to vtkFloatingPointType unselectedColor[4]={1.0f,1.0f,0.0f,1.0f};//yellow vtkFloatingPointType selectedColor[4]={1.0f,0.0f,0.0f,1.0f};//red vtkFloatingPointType contourColor[4]={1.0f,0.0f,0.0f,1.0f};//red //different types for color!!! mitk::Color tmpColor; double opacity = 1.0; //check if there is an unselected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue(); unselectedColor[0] = tmpColor[0]; unselectedColor[1] = tmpColor[1]; unselectedColor[2] = tmpColor[2]; unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value } else { //check if the node has a color float unselectedColorTMP[4]={1.0f,1.0f,0.0f,1.0f};//yellow m_DataNode->GetColor(unselectedColorTMP, NULL); unselectedColor[0] = unselectedColorTMP[0]; unselectedColor[1] = unselectedColorTMP[1]; unselectedColor[2] = unselectedColorTMP[2]; //unselectedColor[3] stays 1.0f } //get selected property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; } //get contour property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } if(dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } else if(dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")) != NULL) { mitk::FloatProperty::Pointer pointOpacity =dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")); opacity = pointOpacity->GetValue(); } //finished color / opacity fishing! //check if a contour shall be drawn bool makeContour = false; this->GetDataNode()->GetBoolProperty("show contour", makeContour, renderer); int visibleBefore = m_ContourActor->GetVisibility(); if(makeContour && (m_ContourActor != NULL) ) { if ( visibleBefore == 0)//was not visible before, so create it. this->CreateContour(renderer); m_ContourActor->GetProperty()->SetColor(contourColor); m_ContourActor->GetProperty()->SetOpacity(opacity); } m_SelectedActor->GetProperty()->SetColor(selectedColor); m_SelectedActor->GetProperty()->SetOpacity(opacity); m_UnselectedActor->GetProperty()->SetColor(unselectedColor); m_UnselectedActor->GetProperty()->SetOpacity(opacity); } void mitk::PointSetVtkMapper3D::CreateContour(mitk::BaseRenderer* renderer) { vtkAppendPolyData* vtkContourPolyData = vtkAppendPolyData::New(); vtkPolyDataMapper* vtkContourPolyDataMapper = vtkPolyDataMapper::New(); vtkPoints *points = vtkPoints::New(); vtkCellArray *polys = vtkCellArray::New(); mitk::PointSet::PointsContainer::Iterator pointsIter; mitk::PointSet::PointDataContainer::Iterator pointDataIter; int j; // get and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); //input->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { return; } for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End() ; pointsIter++,j++) { vtkIdType cell[2] = {j-1,j}; itk::Point point1 = pointsIter->Value(); points->InsertPoint(j,point1[0],point1[1],point1[2]); if (j>0) polys->InsertNextCell(2,cell); } bool close; if (dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("close contour"), renderer) == NULL) close = false; else close = dynamic_cast(this->GetDataNode()->GetPropertyList()->GetProperty("close contour"), renderer)->GetValue(); if (close) { vtkIdType cell[2] = {j-1,0}; polys->InsertNextCell(2,cell); } vtkPolyData* contour = vtkPolyData::New(); contour->SetPoints(points); points->Delete(); contour->SetLines(polys); polys->Delete(); contour->Update(); vtkTubeFilter* tubeFilter = vtkTubeFilter::New(); tubeFilter->SetNumberOfSides( 12 ); tubeFilter->SetInput(contour); contour->Delete(); //check for property contoursize. m_ContourRadius = 0.5; mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast(this->GetDataNode()->GetProperty("contoursize") ); if (contourSizeProp.IsNotNull()) m_ContourRadius = contourSizeProp->GetValue(); tubeFilter->SetRadius( m_ContourRadius ); tubeFilter->Update(); //add to pipeline vtkContourPolyData->AddInput(tubeFilter->GetOutput()); tubeFilter->Delete(); vtkContourPolyDataMapper->SetInput(vtkContourPolyData->GetOutput()); vtkContourPolyData->Delete(); //create a new instance of the actor m_ContourActor->Delete(); m_ContourActor = vtkActor::New(); m_ContourActor->SetMapper(vtkContourPolyDataMapper); vtkContourPolyDataMapper->Delete(); m_PointsAssembly->AddPart(m_ContourActor); } void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); //red node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite ); - node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp index 17749d6ec4..34ecc6c89c 100644 --- a/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp +++ b/Modules/MitkExt/Rendering/mitkEnhancedPointSetVtkMapper3D.cpp @@ -1,439 +1,438 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkEnhancedPointSetVtkMapper3D.h" //#include #include #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkLookupTables.h" #include "mitkColorProperty.h" //#include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include const mitk::PointSet* mitk::EnhancedPointSetVtkMapper3D::GetInput() { return static_cast ( GetData() ); } mitk::EnhancedPointSetVtkMapper3D::EnhancedPointSetVtkMapper3D() { m_Contour = vtkActor::New(); m_ContourSource = vtkTubeFilter::New(); m_PropAssembly = vtkAssembly::New(); } vtkProp* mitk::EnhancedPointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer* /*renderer*/) { return m_PropAssembly; } mitk::EnhancedPointSetVtkMapper3D::~EnhancedPointSetVtkMapper3D() { m_Contour->Delete(); m_ContourSource->Delete(); m_PropAssembly->Delete(); // TODO: do cleanup correctly // Clean up all remaining actors and poly-data sources //std::for_each(m_PointActors.begin(), m_PointActors.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_SphereSources.begin(), m_SphereSources.end(), &mitk::EnhancedPointSetVtgkMapper3D::DeleteVtkObject); // std::for_each(m_CubeSources.begin(), m_CubeSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_ConeSources.begin(), m_ConeSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // std::for_each(m_CylinderSources.begin(), m_CylinderSources.end(), &mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject); // } void mitk::EnhancedPointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow * /*renWin*/) { // TODO: Do we have to call this for all actors?? //m_Actor->ReleaseGraphicsResources(renWin); } void mitk::EnhancedPointSetVtkMapper3D::UpdateVtkObjects() { // get and update the PointSet const mitk::PointSet* pointset = this->GetInput(); //pointset->Update(); int timestep = this->GetTimestep(); mitk::PointSet::DataType* itkPointSet = pointset->GetPointSet( timestep ); mitk::PointSet::PointsContainer* points = itkPointSet->GetPoints(); mitk::PointSet::PointDataContainer* pointData = itkPointSet->GetPointData(); assert(points->Size() == pointData->Size()); mitk::PointSet::PointsIterator pIt; mitk::PointSet::PointDataIterator pdIt; /* search removed points and delete the corresponding source/actor/mapper objects */ for (ActorMap::iterator it = m_PointActors.begin(); it != m_PointActors.end(); ) { PointIdentifier id = it->first; if (!points->IndexExists(id)) { this->RemoveEntryFromSourceMaps(id); m_PropAssembly->GetParts()->RemoveItem(it->second.first); // remove from prop assembly if (it->second.first != NULL) it->second.first->Delete(); // Delete actor, which deletes mapper too (reference count) ActorMap::iterator er = it; // save iterator for deleting ++it; // advance iterator to next object m_PointActors.erase(er); // erase element from map. This invalidates er, therefore we had to advance it before deletion. } else ++it; } /* iterate over each point in the pointset and create corresponding vtk objects */ for (pIt = points->Begin(), pdIt = pointData->Begin(); pIt != itkPointSet->GetPoints()->End(); ++pIt, ++pdIt) { PointIdentifier pointID = pIt->Index(); assert (pointID == pdIt->Index()); mitk::PointSet::PointType point = pIt->Value(); mitk::PointSet::PointDataType data = pdIt->Value(); ActorMap::iterator aIt = m_PointActors.find(pointID); // Does an actor exist for the point? /* Create/Update sources for the point */ vtkActor* a = NULL; bool newPoint = (aIt == m_PointActors.end()); // current point is new bool specChanged = (!newPoint && data.pointSpec != aIt->second.second); // point spec of current point has changed if (newPoint) // point did not exist before, we have to create vtk objects for it { // create actor and mapper for the new point a = vtkActor::New(); vtkPolyDataMapper* m = vtkPolyDataMapper::New(); a->SetMapper(m); m->UnRegister( NULL ); aIt = m_PointActors.insert(std::make_pair(pointID, std::make_pair(a, data.pointSpec))).first; // insert element and update actormap iterator to point to new element m_PropAssembly->AddPart(a); } else { a = aIt->second.first; if (specChanged) // point exists, but point spec has changed { this->RemoveEntryFromSourceMaps( pointID ); } } if ( newPoint || specChanged ) // new point OR existing point but point spec changed { vtkPolyDataAlgorithm* source = NULL; // works only in VTK 5+ switch (data.pointSpec) // add to new map { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID] = vtkCubeSource::New(); source = m_CubeSources[pointID]; break; case PTCORNER: //cone m_ConeSources[pointID] = vtkConeSource::New(); source = m_ConeSources[pointID]; break; case PTEDGE: // cylinder m_CylinderSources[pointID] = vtkCylinderSource::New(); source = m_CylinderSources[pointID]; break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID] = vtkSphereSource::New(); source = m_SphereSources[pointID]; break; } vtkPolyDataMapper* m = dynamic_cast(a->GetMapper()); assert(m != NULL); m->SetInput(source->GetOutput()); aIt->second.second = data.pointSpec; // update point spec in actormap } } // for each point } void mitk::EnhancedPointSetVtkMapper3D::GenerateData() { this->UpdateVtkObjects(); } void mitk::EnhancedPointSetVtkMapper3D::ApplyProperties( mitk::BaseRenderer * renderer ) { /* iterate over all points in pointset and apply properties to corresponding vtk objects */ // get and update the PointSet const mitk::PointSet* pointset = this->GetInput(); int timestep = this->GetTimestep(); mitk::PointSet::DataType* itkPointSet = pointset->GetPointSet( timestep ); mitk::PointSet::PointsContainer* points = itkPointSet->GetPoints(); mitk::PointSet::PointDataContainer* pointData = itkPointSet->GetPointData(); assert(points->Size() == pointData->Size()); mitk::PointSet::PointsIterator pIt; mitk::PointSet::PointDataIterator pdIt; mitk::DataNode* n = this->GetDataNode(); assert(n != NULL); for (pIt = points->Begin(), pdIt = pointData->Begin(); pIt != itkPointSet->GetPoints()->End(); ++pIt, ++pdIt) // for each point in the pointset { PointIdentifier pointID = pIt->Index(); assert (pointID == pdIt->Index()); mitk::PointSet::PointType point = pIt->Value(); mitk::PointSet::PointDataType data = pdIt->Value(); ActorMap::iterator aIt = m_PointActors.find(pointID); // Does an actor exist for the point? assert(aIt != m_PointActors.end()); // UpdateVtkObjects() must ensure that actor exists vtkActor* a = aIt->second.first; assert(a != NULL); SetVtkMapperImmediateModeRendering(a->GetMapper()); /* update properties */ // visibility bool pointVisibility = true; bool visValueFound = false; mitk::BaseProperty* visProp = n->GetProperty("visibility", renderer); mitk::BoolLookupTableProperty* visLTProp = dynamic_cast(visProp); if (visLTProp != NULL) { mitk::BoolLookupTable visLookupTable = visLTProp->GetValue(); //if (visLookupTable != NULL) //{ try { pointVisibility = visLookupTable.GetTableValue(pointID); visValueFound = true; } catch (...) { } //} } if (visValueFound == false) { pointVisibility = n->IsVisible(renderer, "show points"); // use BoolProperty instead } a->SetVisibility(pointVisibility); // opacity float opacity = 1.0; bool opValueFound = false; mitk::BaseProperty* opProp = n->GetProperty("opacity", renderer); mitk::FloatLookupTableProperty* opLTProp = dynamic_cast(opProp); if (opLTProp != NULL) { mitk::FloatLookupTable opLookupTable = opLTProp->GetValue(); //if (opLookupTable != NULL) //{ try { opacity = opLookupTable.GetTableValue(pointID); opValueFound = true; } catch (...) { } //} } if (opValueFound == false) { n->GetOpacity(opacity, renderer); } a->GetProperty()->SetOpacity(opacity); ////////////////////// continue here /////////////////// // pointsize & point position float pointSize = 1.0; n->GetFloatProperty( "pointsize", pointSize, renderer); switch (data.pointSpec) { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID]->SetXLength(pointSize); m_CubeSources[pointID]->SetYLength(pointSize); m_CubeSources[pointID]->SetZLength(pointSize); //m_CubeSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTCORNER: //cone m_ConeSources[pointID]->SetRadius(pointSize/2); m_ConeSources[pointID]->SetHeight(pointSize); m_ConeSources[pointID]->SetResolution(2); // two crossed triangles. Maybe introduce an extra property for //m_ConeSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTEDGE: // cylinder m_CylinderSources[pointID]->SetRadius(pointSize/2); m_CylinderSources[pointID]->SetHeight(pointSize); m_CylinderSources[pointID]->CappingOn(); m_CylinderSources[pointID]->SetResolution(6); //m_CylinderSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID]->SetRadius(pointSize/2); m_SphereSources[pointID]->SetThetaResolution(10); m_SphereSources[pointID]->SetPhiResolution(10); //m_SphereSources[pointID]->SetCenter(pos[0], pos[1], pos[2]); break; } // set position mitk::Point3D pos = pIt->Value(); aIt->second.first->SetPosition(pos[0], pos[1], pos[2]); // selectedcolor & color float color[3]; if (data.selected) { if(!n->GetColor(color, renderer, "selectedcolor")) n->GetColor(color, renderer); } else { mitk::BaseProperty* a = n->GetProperty("colorLookupTable", renderer); mitk::LookupTableProperty* b = dynamic_cast(a); if (b != NULL) { mitk::LookupTable::Pointer c = b->GetLookupTable(); vtkLookupTable *d = c->GetVtkLookupTable(); double *e=d->GetTableValue(pointID); color[0]=e[0]; color[1]=e[1]; color[2]=e[2]; } else { if(!n->GetColor(color, renderer, "unselectedcolor")) n->GetColor(color, renderer); } } // TODO: What about "color" property? 2D Mapper only uses unselected and selected color properties a->GetProperty()->SetColor(color[0], color[1], color[2]); // TODO: label property } //TODO test different pointSpec // TODO "line width" "show contour" "contourcolor" "contoursize" "close contour" "show label", "label" // TODO "show points" vs "visibility" - is visibility evaluated at all? in a superclass maybe? // TODO create lookup tables for all properties that should be evaluated per point. also create editor widgets for these lookup tables! // TODO check if property changes and pointset changes are reflected in the render window immediately. // TODO check behavior with large PointSets // TODO check for memory leaks on adding/deleting points } void mitk::EnhancedPointSetVtkMapper3D::GenerateData( mitk::BaseRenderer * renderer ) { ApplyProperties(renderer); } void mitk::EnhancedPointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/) { // TODO: apply new transform if time step changed //vtkLinearTransform * vtktransform = // this->GetDataNode()->GetVtkTransform(this->GetTimestep()); //m_SelectedActor->SetUserTransform(vtktransform); //m_UnselectedActor->SetUserTransform(vtktransform); //m_ContourActor->SetUserTransform(vtktransform); } void mitk::EnhancedPointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite); node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow for selected node->AddProperty( "unselectedcolor", mitk::ColorProperty::New(0.5f, 1.0f, 0.5f), renderer, overwrite); // middle green for unselected node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); // red as standard node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite ); - node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "show label", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "label", mitk::StringProperty::New("P"), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::EnhancedPointSetVtkMapper3D::DeleteVtkObject( vtkObject* o) { if (o != NULL) o->Delete(); } void mitk::EnhancedPointSetVtkMapper3D::RemoveEntryFromSourceMaps( mitk::PointSet::PointIdentifier pointID ) { ActorMap::iterator aIt = m_PointActors.find(pointID); if (aIt == m_PointActors.end()) return; switch (aIt->second.second) // erase in old map { //TODO: look up representation in a representationlookuptable case PTSTART: //cube m_CubeSources[pointID]->Delete(); m_CubeSources.erase(pointID); break; case PTCORNER: //cone m_ConeSources[pointID]->Delete(); m_ConeSources.erase(pointID); break; case PTEDGE: // cylinder m_CylinderSources[pointID]->Delete(); m_CylinderSources.erase(pointID); break; case PTUNDEFINED: // sphere case PTEND: default: m_SphereSources[pointID]->Delete(); m_SphereSources.erase(pointID); break; } }