There you go. My version also has a property to show edges on the
surface, but it doesn't come into play unless you set the property
"material.edgeVisibility" to true, so don't worry about this.
Rostislav.
On 08/06/2015 11:00, Pukhlikov Mikhail wrote:
Thank you, may you show the specific code for "mitkSurfaceVtkMapper3D
to apply a yellow color if the "selected" flag was set for the
surface" implementation
------------------------------------------------------------------------
Date: Mon, 8 Jun 2015 09:09:28 +0100
From: [email protected]
To: [email protected]
Subject: Re: [mitk-users] Draw contour around model
Hi Mikhail,
I think that displaying a selected data object is the data object's
mapper job. For surfaces, I modified the mitkSurfaceVtkMapper3D to
apply a yellow color if the "selected" flag was set for the surface.
Alternatively, you can just manually set the color once a node is
selected - but the mapper way is more robust.
Regarding the dependencies - it's pretty easy to pull dependencies to
your plugin - just add "PACKAGE_DEPENDS VTK" to the
MACRO_CREATE_MITK_CTK_PLUGIN in the CMakeLists.txt of your plugin and
the dependency will be there - i.e. all headers will be available and
libraries will be linked with your plugin. Also, what you're trying to
do looks more like VTK's job rather than ITK's.
Rostislav.
On 08/06/2015 07:11, Pukhlikov Mikhail wrote:
Hello,
Is there fast way to draw a contour around the model. I'm trying
to implement locally selection mechanism and I think about fast
way to display selection on 3D multiwidgety view. I was thinking
about applieng some ITK filters maybe but it's way to slow and
complicated since I need to get ITK deps into display interactor
for doing it and it will work slow. May you suggest fast way how
can I show selection of specific data node (model) in 3D view of
multiwidget?
Thank you
------------------------------------------------------------------------------
_______________________________________________
mitk-users mailing list
[email protected] <mailto:[email protected]>
https://lists.sourceforge.net/lists/listinfo/mitk-users
------------------------------------------------------------------------------
_______________________________________________ mitk-users mailing
list [email protected]
https://lists.sourceforge.net/lists/listinfo/mitk-users
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkSurfaceVtkMapper3D.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkVtkRepresentationProperty.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkScalarModeProperty.h"
#include "mitkClippingProperty.h"
#include "mitkSmartPointerProperty.h"
//#include "mitkShaderProperty.h"
#include "mitkIShaderRepository.h"
#include <mitkExtractSliceFilter.h>
#include <mitkImageSliceSelector.h>
#include <mitkCoreServices.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkIPropertyDescriptions.h>
#include <mitkIPropertyAliases.h>
//VTK
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkPointData.h>
#include <vtkPlaneCollection.h>
#include <vtkSmartPointer.h>
const mitk::Surface* mitk::SurfaceVtkMapper3D::GetInput()
{
return static_cast<const mitk::Surface * > ( GetDataNode()->GetData() );
}
mitk::SurfaceVtkMapper3D::SurfaceVtkMapper3D()
{
// m_Prop3D = vtkActor::New();
m_GenerateNormals = false;
}
mitk::SurfaceVtkMapper3D::~SurfaceVtkMapper3D()
{
// m_Prop3D->Delete();
}
void mitk::SurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer*
renderer)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
bool visible = true;
GetDataNode()->GetVisibility(visible, renderer, "visible");
if(!visible)
{
ls->m_Actor->VisibilityOff();
return;
}
//
// set the input-object at time t for the mapper
//
mitk::Surface::Pointer input = const_cast< mitk::Surface* >(
this->GetInput() );
vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() );
if(polydata == NULL)
{
ls->m_Actor->VisibilityOff();
return;
}
if ( m_GenerateNormals )
{
ls->m_VtkPolyDataNormals->SetInputData( polydata );
ls->m_VtkPolyDataMapper->SetInputConnection(
ls->m_VtkPolyDataNormals->GetOutputPort() );
}
else
{
bool depthsorting = false;
GetDataNode()->GetBoolProperty("Depth Sorting", depthsorting);
if (depthsorting)
{
ls->m_DepthSort->SetInputData( polydata );
ls->m_DepthSort->SetCamera( renderer->GetVtkRenderer()->GetActiveCamera()
);
ls->m_DepthSort->SetDirectionToBackToFront();
ls->m_DepthSort->Update();
ls->m_VtkPolyDataMapper->SetInputConnection(ls->m_DepthSort->GetOutputPort());
}
else
{
ls->m_VtkPolyDataMapper->SetInputData( polydata );
}
}
//
// apply properties read from the PropertyList
//
ApplyAllProperties(renderer, ls->m_Actor);
if(visible)
ls->m_Actor->VisibilityOn();
}
void mitk::SurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer )
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
ls->m_Actor->VisibilityOff();
}
void mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode
*node, vtkProperty* property, mitk::BaseRenderer* renderer)
{
// Backface culling
{
mitk::BoolProperty::Pointer p;
node->GetProperty(p, "Backface Culling", renderer);
bool useCulling = false;
if(p.IsNotNull())
useCulling = p->GetValue();
property->SetBackfaceCulling(useCulling);
}
// Colors
{
double ambient [3] = { 0.5,0.5,0.0 };
double diffuse [3] = { 0.5,0.5,0.0 };
double specular[3] = { 1.0,1.0,1.0 };
float coeff_ambient = 0.5f;
float coeff_diffuse = 0.5f;
float coeff_specular= 0.5f;
float power_specular=10.0f;
// Color
{
mitk::ColorProperty::Pointer colorProperty;
if (node->IsSelected()) {
node->GetProperty(colorProperty, "color.selected", renderer);
}
if (colorProperty.IsNull()) {
// If not selected or failed to obtain selected color
node->GetProperty(colorProperty, "color", renderer);
}
if(colorProperty.IsNotNull())
{
mitk::Color c = colorProperty->GetColor();
ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue();
diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue();
// Setting specular color to the same, make physically no real sense,
however vtk rendering slows down, if these colors are different.
specular[0]=c.GetRed(); specular[1]=c.GetGreen();
specular[2]=c.GetBlue();
}
}
// Ambient
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.ambientColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue();
}
}
// Diffuse
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.diffuseColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue();
}
}
// Specular
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.specularColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
specular[0]=c.GetRed(); specular[1]=c.GetGreen();
specular[2]=c.GetBlue();
}
}
// Ambient coeff
{
node->GetFloatProperty("material.ambientCoefficient", coeff_ambient,
renderer);
}
// Diffuse coeff
{
node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse,
renderer);
}
// Specular coeff
{
node->GetFloatProperty("material.specularCoefficient", coeff_specular,
renderer);
}
// Specular power
{
node->GetFloatProperty("material.specularPower", power_specular,
renderer);
}
property->SetAmbient( coeff_ambient );
property->SetDiffuse( coeff_diffuse );
property->SetSpecular( coeff_specular );
property->SetSpecularPower( power_specular );
property->SetAmbientColor(ambient);
property->SetDiffuseColor( diffuse );
property->SetSpecularColor( specular );
}
// Render mode
{
// Opacity
{
float opacity = 1.0f;
if( node->GetOpacity(opacity,renderer) )
property->SetOpacity( opacity );
}
// Wireframe line width
{
float lineWidth = 1;
node->GetFloatProperty("material.wireframeLineWidth", lineWidth,
renderer);
property->SetLineWidth( lineWidth );
}
// Representation
{
mitk::VtkRepresentationProperty::Pointer p;
node->GetProperty(p, "material.representation", renderer);
if(p.IsNotNull())
property->SetRepresentation( p->GetVtkRepresentation() );
}
// Edge visibility
{
bool edgesVisible = false;
node->GetBoolProperty("material.edgeVisibility", edgesVisible,
renderer);
property->SetEdgeVisibility((int)edgesVisible);
}
// Edge color
{
double edgeColor[3] = { 0.5, 0.5, 0.5 };
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.edgeColor", renderer);
if (p.IsNotNull())
{
mitk::Color c = p->GetColor();
edgeColor[0] = c.GetRed(); edgeColor[1] = c.GetGreen();
edgeColor[2] = c.GetBlue();
}
property->SetEdgeColor(edgeColor);
}
// Interpolation
{
mitk::VtkInterpolationProperty::Pointer p;
node->GetProperty(p, "material.interpolation", renderer);
if(p.IsNotNull())
property->SetInterpolation( p->GetVtkInterpolation() );
}
}
}
void mitk::SurfaceVtkMapper3D::ApplyAllProperties( mitk::BaseRenderer*
renderer, vtkActor* /*actor*/)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
// Applying shading properties
//Superclass::ApplyColorAndOpacityProperties( renderer, ls->m_Actor ) ;
this->ApplyShaderProperties(renderer);
// VTK Properties
ApplyMitkPropertiesToVtkProperty( this->GetDataNode(),
ls->m_Actor->GetProperty(), renderer );
mitk::TransferFunctionProperty::Pointer transferFuncProp;
this->GetDataNode()->GetProperty(transferFuncProp,
"Surface.TransferFunction", renderer);
if (transferFuncProp.IsNotNull() )
{
ls->m_VtkPolyDataMapper->SetLookupTable(transferFuncProp->GetValue()->GetColorTransferFunction());
}
mitk::LookupTableProperty::Pointer lookupTableProp;
this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
if (lookupTableProp.IsNotNull() )
{
ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable());
}
mitk::LevelWindow levelWindow;
if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow"))
{
ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound());
}
else
if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer))
{
ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound());
}
bool scalarVisibility = false;
this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility);
ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) );
if(scalarVisibility)
{
mitk::VtkScalarModeProperty* scalarMode;
if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode());
else
ls->m_VtkPolyDataMapper->SetScalarModeToDefault();
bool colorMode = false;
this->GetDataNode()->GetBoolProperty("color mode", colorMode);
ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) );
double scalarsMin = 0;
this->GetDataNode()->GetDoubleProperty("ScalarsRangeMinimum", scalarsMin,
renderer);
double scalarsMax = 1.0;
this->GetDataNode()->GetDoubleProperty("ScalarsRangeMaximum", scalarsMax,
renderer);
ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax);
}
mitk::SmartPointerProperty::Pointer imagetextureProp =
dynamic_cast< mitk::SmartPointerProperty *
>(GetDataNode()->GetProperty("Surface.Texture", renderer));
if(imagetextureProp.IsNotNull())
{
mitk::Image* miktTexture = dynamic_cast< mitk::Image* >(
imagetextureProp->GetSmartPointer().GetPointer() );
vtkSmartPointer<vtkTexture> vtkTxture =
vtkSmartPointer<vtkTexture>::New();
//Either select the first slice of a volume
if(miktTexture->GetDimension(2) > 1)
{
MITK_WARN << "3D Textures are not supported by VTK and MITK. The first
slice of the volume will be used instead!";
mitk::ImageSliceSelector::Pointer sliceselector =
mitk::ImageSliceSelector::New();
sliceselector->SetSliceNr(0);
sliceselector->SetChannelNr(0);
sliceselector->SetTimeNr(0);
sliceselector->SetInput(miktTexture);
sliceselector->Update();
vtkTxture->SetInputData(sliceselector->GetOutput()->GetVtkImageData());
}
else //or just use the 2D image
{
vtkTxture->SetInputData(miktTexture->GetVtkImageData());
}
//pass the texture to the actor
ls->m_Actor->SetTexture(vtkTxture);
if(ls->m_VtkPolyDataMapper->GetInput()->GetPointData()->GetTCoords() ==
NULL)
{
MITK_ERROR << "Surface.Texture property was set, but there are no
texture coordinates. Please provide texture coordinates for the vtkPolyData via
vtkPolyData->GetPointData()->SetTCoords().";
}
// if no texture is set, this will also remove a previously used texture
// and reset the actor to it's default behaviour
} else {
ls->m_Actor->SetTexture(0);
}
// deprecated settings
bool deprecatedUseCellData = false;
this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring",
deprecatedUseCellData);
bool deprecatedUsePointData = false;
this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring",
deprecatedUsePointData);
if (deprecatedUseCellData)
{
ls->m_VtkPolyDataMapper->SetColorModeToDefault();
ls->m_VtkPolyDataMapper->SetScalarRange(0,255);
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
ls->m_Actor->GetProperty()->SetInterpolationToPhong();
}
else if (deprecatedUsePointData)
{
float scalarsMin = 0;
if (dynamic_cast<mitk::FloatProperty
*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL)
scalarsMin =
dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue();
float scalarsMax = 0.1;
if (dynamic_cast<mitk::FloatProperty
*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL)
scalarsMax =
dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue();
ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax);
ls->m_VtkPolyDataMapper->SetColorModeToMapScalars();
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
ls->m_Actor->GetProperty()->SetInterpolationToPhong();
}
int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT;
if(this->GetDataNode()->GetIntProperty("deprecated scalar mode",
deprecatedScalarMode, renderer))
{
ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode);
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
//m_Actor->GetProperty()->SetInterpolationToPhong();
}
// Check whether one or more ClippingProperty objects have been defined for
// this node. Check both renderer specific and global property lists, since
// properties in both should be considered.
const PropertyList::PropertyMap *rendererProperties =
this->GetDataNode()->GetPropertyList( renderer )->GetMap();
const PropertyList::PropertyMap *globalProperties =
this->GetDataNode()->GetPropertyList( NULL )->GetMap();
// Add clipping planes (if any)
ls->m_ClippingPlaneCollection->RemoveAllItems();
PropertyList::PropertyMap::const_iterator it;
for ( it = rendererProperties->begin(); it != rendererProperties->end();
++it )
{
this->CheckForClippingProperty( renderer,(*it).second.GetPointer() );
}
for ( it = globalProperties->begin(); it != globalProperties->end(); ++it )
{
this->CheckForClippingProperty( renderer,(*it).second.GetPointer() );
}
if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 )
{
ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection
);
}
else
{
ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes();
}
}
vtkProp *mitk::SurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
return ls->m_Actor;
}
void mitk::SurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer*
renderer, mitk::BaseProperty *property )
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
// m_Prop3D = ls->m_Actor;
ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >(
property );
if ( (clippingProperty != NULL)
&& (clippingProperty->GetClippingEnabled()) )
{
const Point3D &origin = clippingProperty->GetOrigin();
const Vector3D &normal = clippingProperty->GetNormal();
vtkPlane *clippingPlane = vtkPlane::New();
clippingPlane->SetOrigin( origin[0], origin[1], origin[2] );
clippingPlane->SetNormal( normal[0], normal[1], normal[2] );
ls->m_ClippingPlaneCollection->AddItem( clippingPlane );
clippingPlane->UnRegister( NULL );
}
}
void
mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode*
node, mitk::BaseRenderer* renderer, bool overwrite)
{
// Shading
{
node->AddProperty( "material.wireframeLineWidth",
mitk::FloatProperty::New(1.0f) , renderer, overwrite );
node->AddProperty( "material.ambientCoefficient" ,
mitk::FloatProperty::New(0.05f) , renderer, overwrite );
node->AddProperty( "material.diffuseCoefficient" ,
mitk::FloatProperty::New(0.9f) , renderer, overwrite );
node->AddProperty( "material.specularCoefficient",
mitk::FloatProperty::New(1.0f) , renderer, overwrite );
node->AddProperty( "material.specularPower" ,
mitk::FloatProperty::New(16.0f) , renderer, overwrite );
//node->AddProperty( "material.ambientColor" ,
mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
//node->AddProperty( "material.diffuseColor" ,
mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
//node->AddProperty( "material.specularColor" ,
mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
node->AddProperty( "material.representation" ,
mitk::VtkRepresentationProperty::New() , renderer, overwrite );
node->AddProperty( "material.interpolation" ,
mitk::VtkInterpolationProperty::New() , renderer, overwrite );
node->AddProperty("material.edgeVisibility",
mitk::BoolProperty::New(false), renderer, overwrite);
node->AddProperty("material.edgeColor", mitk::ColorProperty::New(0.5f,
0.5f, 0.5f), renderer, overwrite);
}
// Shaders
IShaderRepository* shaderRepo = CoreServices::GetShaderRepository();
if (shaderRepo)
{
shaderRepo->AddDefaultProperties(node, renderer, overwrite);
}
}
void mitk::SurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node,
mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty("color", mitk::ColorProperty::New(1.0f,1.0f,1.0f),
renderer, overwrite );
node->AddProperty("color.selected", mitk::ColorProperty::New(1.0f, 1.0f,
0.0f), renderer, overwrite);
node->AddProperty("opacity", mitk::FloatProperty::New(1.0), renderer,
overwrite);
mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite);
// Shading
node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false),
renderer, overwrite );
node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer,
overwrite );
node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(),
renderer, overwrite );
mitk::Surface::Pointer surface = dynamic_cast<Surface*>(node->GetData());
if(surface.IsNotNull())
{
if((surface->GetVtkPolyData() != 0) &&
(surface->GetVtkPolyData()->GetPointData() != NULL) &&
(surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0))
{
node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true),
renderer, overwrite );
node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer,
overwrite );
}
}
// Backface culling
node->AddProperty( "Backface Culling", mitk::BoolProperty::New(false),
renderer, overwrite );
node->AddProperty( "Depth Sorting", mitk::BoolProperty::New(false), renderer,
overwrite );
mitk::CoreServices::GetPropertyDescriptions()->AddDescription( "Depth
Sorting", "Enables correct rendering for transparent objects by ordering
polygons according to the distance to the camera. It is not recommended to
enable this property for large surfaces (rendering might be slow).");
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
------------------------------------------------------------------------------
_______________________________________________
mitk-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mitk-users