00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <mitkGL.h>
00020
00021 #include "mitkSurfaceGLMapper2D.h"
00022 #include "mitkBaseRenderer.h"
00023 #include "mitkPlaneGeometry.h"
00024 #include "mitkSurface.h"
00025 #include "mitkColorProperty.h"
00026 #include "mitkProperties.h"
00027 #include "mitkVtkScalarModeProperty.h"
00028 #include "mitkAbstractTransformGeometry.h"
00029 #include "mitkLookupTableProperty.h"
00030
00031 #include <vtkPolyData.h>
00032 #include <vtkPlane.h>
00033 #include <vtkCutter.h>
00034 #include <vtkPoints.h>
00035 #include <vtkCellArray.h>
00036 #include <vtkLookupTable.h>
00037 #include <vtkPointData.h>
00038 #include <vtkCellData.h>
00039 #include <vtkDataArray.h>
00040 #include <vtkLinearTransform.h>
00041 #include <vtkAbstractMapper.h>
00042 #include <vtkPKdTree.h>
00043 #include <vtkStripper.h>
00044
00045
00046 mitk::SurfaceGLMapper2D::SurfaceGLMapper2D()
00047 : m_Plane( vtkPlane::New() ),
00048 m_Cutter( vtkCutter::New() ),
00049 m_LUT( vtkLookupTable::New() ),
00050 m_PointLocator( vtkPKdTree::New() ),
00051 m_Stripper( vtkStripper::New() ),
00052 m_DrawNormals(false),
00053 m_FrontNormalLengthInPixels(10.0),
00054 m_BackNormalLengthInPixels(10.0)
00055 {
00056
00057 m_FrontSideColor[0] = 0.0;
00058 m_FrontSideColor[1] = 1.0;
00059 m_FrontSideColor[2] = 0.0;
00060 m_FrontSideColor[3] = 1.0;
00061
00062
00063 m_BackSideColor[0] = 1.0;
00064 m_BackSideColor[1] = 0.0;
00065 m_BackSideColor[2] = 0.0;
00066 m_BackSideColor[3] = 1.0;
00067
00068
00069 m_LineColor[0] = 1.0;
00070 m_LineColor[1] = 1.0;
00071 m_LineColor[2] = 0.0;
00072 m_LineColor[3] = 1.0;
00073
00074 m_Cutter->SetCutFunction(m_Plane);
00075 m_Cutter->GenerateValues(1,0,1);
00076
00077 m_LUT->SetTableRange(0,255);
00078 m_LUT->SetNumberOfColors(255);
00079 m_LUT->SetRampToLinear();
00080 m_LUT->Build();
00081 }
00082
00083 mitk::SurfaceGLMapper2D::~SurfaceGLMapper2D()
00084 {
00085 m_Plane->Delete();
00086 m_Cutter->Delete();
00087 m_LUT->Delete();
00088 m_PointLocator->Delete();
00089 m_Stripper->Delete();
00090 }
00091
00092 const mitk::Surface *mitk::SurfaceGLMapper2D::GetInput(void)
00093 {
00094 if(m_Surface.IsNotNull())
00095 return m_Surface;
00096
00097 return static_cast<const Surface * > ( GetData() );
00098 }
00099
00100 void mitk::SurfaceGLMapper2D::SetDataNode( mitk::DataNode::Pointer node )
00101 {
00102 Superclass::SetDataNode( node );
00103
00104 bool useCellData;
00105 if (dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring")) == NULL)
00106 useCellData = false;
00107 else
00108 useCellData = dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring"))->GetValue();
00109
00110 if (!useCellData)
00111 {
00112
00113 vtkFloatingPointType dataRange[2] = {0,0};
00114 vtkFloatingPointType range[2];
00115
00116 Surface::Pointer input = const_cast< Surface* >(dynamic_cast<const Surface*>( this->GetDataNode()->GetData() ));
00117 if(input.IsNull()) return;
00118 const TimeSlicedGeometry::Pointer inputTimeGeometry = input->GetTimeSlicedGeometry();
00119 if(( inputTimeGeometry.IsNull() ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) return;
00120 for (unsigned int timestep=0; timestep<inputTimeGeometry->GetTimeSteps(); timestep++)
00121 {
00122 vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
00123 if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) continue;
00124 vtkDataArray *vpointscalars = vtkpolydata->GetPointData()->GetScalars();
00125 if (vpointscalars) {
00126 vpointscalars->GetRange( range, 0 );
00127 if (dataRange[0]==0 && dataRange[1]==0) {
00128 dataRange[0] = range[0];
00129 dataRange[1] = range[1];
00130 }
00131 else {
00132 if (range[0] < dataRange[0]) dataRange[0] = range[0];
00133 if (range[1] > dataRange[1]) dataRange[1] = range[1];
00134 }
00135 }
00136 }
00137 if (dataRange[1] - dataRange[0] > 0) {
00138 m_LUT->SetTableRange( dataRange );
00139 m_LUT->Build();
00140 }
00141 }
00142 }
00143
00144
00145 void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer)
00146 {
00147 if(IsVisible(renderer)==false) return;
00148
00149 Surface::Pointer input = const_cast<Surface*>(this->GetInput());
00150
00151 if(input.IsNull())
00152 return;
00153
00154
00155
00156
00157 const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry();
00158 if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) )
00159 return;
00160
00161 if (dynamic_cast<IntProperty *>(this->GetDataNode()->GetProperty("line width")) == NULL)
00162 m_LineWidth = 1;
00163 else
00164 m_LineWidth = dynamic_cast<IntProperty *>(this->GetDataNode()->GetProperty("line width"))->GetValue();
00165
00166
00167
00168
00169 Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
00170 assert( worldGeometry.IsNotNull() );
00171
00172 ScalarType time = worldGeometry->GetTimeBounds()[ 0 ];
00173 int timestep=0;
00174
00175 if( time > ScalarTypeNumericTraits::NonpositiveMin() )
00176 timestep = inputTimeGeometry->MSToTimeStep( time );
00177
00178
00179
00180 if( inputTimeGeometry->IsValidTime( timestep ) == false )
00181 return;
00182
00183 vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
00184 if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 ))
00185 return;
00186
00187 PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>(worldGeometry.GetPointer());
00188
00189
00190 ApplyProperties(renderer);
00191
00192 if (m_DrawNormals)
00193 {
00194 m_PointLocator->SetDataSet( vtkpolydata );
00195 m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() );
00196 }
00197
00198 if(vtkpolydata!=NULL)
00199 {
00200 Point3D point;
00201 Vector3D normal;
00202
00203
00204 vtkFloatingPointType* scalarLimits = m_LUT->GetTableRange();
00205 vtkFloatingPointType scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1];
00206
00207 vtkLookupTable *lut;
00208
00209 LookupTableProperty::Pointer lookupTableProp;
00210 this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
00211 if (lookupTableProp.IsNotNull() )
00212 {
00213 lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable();
00214
00215 if (dynamic_cast<FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL)
00216 scalarsMin = dynamic_cast<FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue();
00217 if (dynamic_cast<FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL)
00218 scalarsMax = dynamic_cast<FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue();
00219
00220
00221 double* oldRange = lut->GetTableRange();
00222 if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax )
00223 {
00224 lut->SetTableRange(scalarsMin, scalarsMax);
00225 lut->Build();
00226 }
00227 }
00228 else
00229 {
00230 lut = m_LUT;
00231 }
00232
00233 vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep);
00234 if(worldPlaneGeometry.IsNotNull())
00235 {
00236
00237 point=worldPlaneGeometry->GetOrigin();
00238 normal=worldPlaneGeometry->GetNormal(); normal.Normalize();
00239 m_Plane->SetTransform((vtkAbstractTransform*)NULL);
00240 }
00241 else
00242 {
00243 AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D());
00244 if(worldAbstractGeometry.IsNotNull())
00245 {
00246 AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(input->GetTimeSlicedGeometry()->GetGeometry3D(0));
00247 if(surfaceAbstractGeometry.IsNotNull())
00248 {
00249 PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut);
00250 return;
00251 }
00252 else
00253 {
00254
00255 return;
00256
00257 point=const_cast<BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
00258 FillVector3D(normal, 0, 0, 1);
00259 m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
00260 }
00261 }
00262 else
00263 return;
00264 }
00265
00266 vtkFloatingPointType vp[3], vnormal[3];
00267
00268 vnl2vtk(point.Get_vnl_vector(), vp);
00269 vnl2vtk(normal.Get_vnl_vector(), vnormal);
00270
00271
00272
00273
00274
00275 vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();
00276 inversetransform->TransformPoint(vp, vp);
00277 inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal);
00278
00279 m_Plane->SetOrigin(vp);
00280 m_Plane->SetNormal(vnormal);
00281
00282
00283 m_Cutter->SetInput(vtkpolydata);
00284 m_Cutter->Update();
00285
00286
00287
00288 if (m_DrawNormals)
00289 {
00290 m_Stripper->SetInput( m_Cutter->GetOutput() );
00291
00292 m_Stripper->Update();
00293 PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
00294 }
00295 else
00296 {
00297 PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
00298 }
00299 }
00300 }
00301
00302 void mitk::SurfaceGLMapper2D::PaintCells(mitk::BaseRenderer* renderer, vtkPolyData* contour,
00303 const Geometry2D* worldGeometry,
00304 const DisplayGeometry* displayGeometry,
00305 vtkLinearTransform * vtktransform,
00306 vtkLookupTable *lut,
00307 vtkPolyData* original3DObject)
00308 {
00309
00310 bool usePointData = false;
00311
00312 bool useCellData = false;
00313 this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", useCellData);
00314
00315 bool scalarVisibility = false;
00316 this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility);
00317
00318 if(scalarVisibility)
00319 {
00320 VtkScalarModeProperty* scalarMode;
00321 if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
00322 {
00323 if( (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA) ||
00324 (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT) )
00325 {
00326 usePointData = true;
00327 }
00328 if(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA)
00329 {
00330 useCellData = true;
00331 }
00332 }
00333 else
00334 {
00335 usePointData = true;
00336 }
00337 }
00338
00339 vtkPoints *vpoints = contour->GetPoints();
00340 vtkDataArray *vpointscalars = contour->GetPointData()->GetScalars();
00341
00342 vtkCellArray *vlines = contour->GetLines();
00343 vtkDataArray* vcellscalars = contour->GetCellData()->GetScalars();
00344
00345 Point3D p; Point2D p2d, last;
00346 int i, j;
00347 int numberOfLines = vlines->GetNumberOfCells();
00348
00349 glLineWidth( m_LineWidth );
00350 glBegin (GL_LINES);
00351
00352 glColor4fv(m_LineColor);
00353
00354 double distanceSinceLastNormal(0.0);
00355
00356 vlines->InitTraversal();
00357 for(i=0;i<numberOfLines;++i)
00358 {
00359 vtkIdType *cell(NULL);
00360 vtkIdType cellSize(0);
00361 vtkFloatingPointType vp[3];
00362
00363 vlines->GetNextCell(cellSize, cell);
00364
00365 vpoints->GetPoint(cell[0], vp);
00366
00367 vtktransform->TransformPoint(vp, vp);
00368 vtk2itk(vp, p);
00369
00370
00371 worldGeometry->Map(p, p2d);
00372
00373
00374 displayGeometry->WorldToDisplay(p2d, p2d);
00375 last=p2d;
00376
00377 for(j=1; j<cellSize; ++j)
00378 {
00379 vpoints->GetPoint(cell[j], vp);
00380 Point3D originalPoint;
00381 vtk2itk(vp, originalPoint);
00382
00383 vtktransform->TransformPoint(vp, vp);
00384 vtk2itk(vp, p);
00385
00386
00387 worldGeometry->Map(p, p2d);
00388
00389
00390 displayGeometry->WorldToDisplay(p2d, p2d);
00391
00392 vtkFloatingPointType color[3];
00393 if (useCellData && vcellscalars != NULL )
00394 {
00395
00396 lut->GetColor( vcellscalars->GetComponent(i,0),color);
00397 glColor3f(color[0],color[1],color[2]);
00398 glVertex2f(last[0], last[1]);
00399 glVertex2f(p2d[0], p2d[1]);
00400 }
00401 else if (usePointData && vpointscalars != NULL )
00402 {
00403 lut->GetColor( vpointscalars->GetComponent(cell[j-1],0),color);
00404 glColor3f(color[0],color[1],color[2]);
00405 glVertex2f(last[0], last[1]);
00406 lut->GetColor( vpointscalars->GetComponent(cell[j],0),color);
00407 glColor3f(color[0],color[1],color[2]);
00408 glVertex2f(p2d[0], p2d[1]);
00409 }
00410 else
00411 {
00412 glVertex2f(last[0], last[1]);
00413 glVertex2f(p2d[0], p2d[1]);
00414
00415
00416 if (m_DrawNormals && original3DObject)
00417 {
00418 distanceSinceLastNormal += sqrt((p2d[0]-last[0])*(p2d[0]-last[0]) + (p2d[1]-last[1])*(p2d[1]-last[1]));
00419 if (distanceSinceLastNormal >= 5.0)
00420 {
00421 distanceSinceLastNormal = 0.0;
00422
00423 vtkPointData* pointData = original3DObject->GetPointData();
00424 if (!pointData) break;
00425
00426 vtkDataArray* normalsArray = pointData->GetNormals();
00427 if (!normalsArray) break;
00428
00429
00430 double distance(0.0);
00431 vtkIdType closestPointId = m_PointLocator->FindClosestPoint(originalPoint[0], originalPoint[1], originalPoint[2], distance);
00432 if (closestPointId >= 0)
00433 {
00434
00435 double* normal = normalsArray->GetTuple3(closestPointId);
00436 double transformedNormal[3];
00437 vtktransform->TransformNormal(normal, transformedNormal);
00438
00439 Vector3D normalITK;
00440 vtk2itk(transformedNormal, normalITK);
00441 normalITK.Normalize();
00442
00443
00444 Point3D tip3D = p + normalITK;
00445
00446
00447 Point2D tip2D;
00448 worldGeometry->Map(tip3D, tip2D);
00449
00450 displayGeometry->WorldToDisplay(tip2D, tip2D);
00451
00452
00453 Vector2D tipVectorGLFront = tip2D - p2d;
00454 tipVectorGLFront.Normalize();
00455 tipVectorGLFront *= m_FrontNormalLengthInPixels;
00456
00457 Vector2D tipVectorGLBack = p2d - tip2D;
00458 tipVectorGLBack.Normalize();
00459 tipVectorGLBack *= m_BackNormalLengthInPixels;
00460
00461 Point2D tipPoint2D = p2d + tipVectorGLFront;
00462 Point2D backTipPoint2D = p2d + tipVectorGLBack;
00463
00464
00465 glColor4f(m_BackSideColor[0], m_BackSideColor[1], m_BackSideColor[2], m_BackSideColor[3]);
00466 glVertex2f(p2d[0], p2d[1]);
00467 glVertex2f(tipPoint2D[0], tipPoint2D[1]);
00468 glColor4f(m_FrontSideColor[0], m_FrontSideColor[1], m_FrontSideColor[2], m_FrontSideColor[3]);
00469 glVertex2f(p2d[0], p2d[1]);
00470 glVertex2f(backTipPoint2D[0], backTipPoint2D[1]);
00471 glColor4fv(m_LineColor);
00472 }
00473 }
00474 }
00475 }
00476 last=p2d;
00477 }
00478 }
00479
00480 glEnd();
00481 glLineWidth(1.0);
00482 }
00483
00484 void mitk::SurfaceGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
00485 {
00486 node->AddProperty( "line width", IntProperty::New(2), renderer, overwrite );
00487 node->AddProperty( "scalar mode", VtkScalarModeProperty::New(), renderer, overwrite );
00488 node->AddProperty( "draw normals 2D", BoolProperty::New(false), renderer, overwrite );
00489 node->AddProperty( "invert normals", BoolProperty::New(false), renderer, overwrite );
00490 node->AddProperty( "front color", ColorProperty::New(0.0, 1.0, 0.0), renderer, overwrite );
00491 node->AddProperty( "back color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite );
00492 node->AddProperty( "front normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
00493 node->AddProperty( "back normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
00494 node->AddProperty( "layer", mitk::IntProperty::New(100), renderer, overwrite);
00495 Superclass::SetDefaultProperties(node, renderer, overwrite);
00496 }
00497
00498 void mitk::SurfaceGLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer)
00499 {
00500 Superclass::ApplyProperties(renderer);
00501
00502 GetDataNode()->GetBoolProperty("draw normals 2D", m_DrawNormals, renderer);
00503
00504
00505 GetColor(m_LineColor, renderer );
00506 GetOpacity(m_LineColor[3], renderer );
00507
00508 bool invertNormals(false);
00509 if (DataNode* node = GetDataNode())
00510 {
00511 node->GetBoolProperty("invert normals", invertNormals, renderer);
00512 }
00513
00514 if (!invertNormals)
00515 {
00516 GetColor(m_FrontSideColor, renderer, "front color");
00517 GetOpacity(m_FrontSideColor[3], renderer);
00518
00519 GetColor(m_BackSideColor, renderer, "back color");
00520 GetOpacity(m_BackSideColor[3], renderer);
00521
00522 if (DataNode* node = GetDataNode())
00523 {
00524 node->GetFloatProperty( "front normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
00525 node->GetFloatProperty( "back normal lenth (px)", m_BackNormalLengthInPixels, renderer );
00526 }
00527 }
00528 else
00529 {
00530 GetColor(m_FrontSideColor, renderer, "back color");
00531 GetOpacity(m_FrontSideColor[3], renderer);
00532
00533 GetColor(m_BackSideColor, renderer, "front color");
00534 GetOpacity(m_BackSideColor[3], renderer);
00535
00536 if (DataNode* node = GetDataNode())
00537 {
00538 node->GetFloatProperty( "back normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
00539 node->GetFloatProperty( "front normal lenth (px)", m_BackNormalLengthInPixels, renderer );
00540 }
00541 }
00542 }
00543