00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkGL.h"
00020 #include "mitkGeometry2DDataMapper2D.h"
00021 #include "mitkBaseRenderer.h"
00022 #include "mitkPlaneGeometry.h"
00023 #include "mitkColorProperty.h"
00024 #include "mitkProperties.h"
00025 #include "mitkSmartPointerProperty.h"
00026 #include "mitkPlaneOrientationProperty.h"
00027 #include "mitkGeometry2DDataToSurfaceFilter.h"
00028 #include "mitkSurfaceGLMapper2D.h"
00029 #include "mitkLine.h"
00030 #include "mitkNodePredicateDataType.h"
00031
00032
00033 mitk::Geometry2DDataMapper2D::Geometry2DDataMapper2D()
00034 : m_SurfaceMapper( NULL ), m_DataStorage(NULL), m_ParentNode(NULL),
00035 m_OtherGeometry2Ds(), m_RenderOrientationArrows( false ),
00036 m_ArrowOrientationPositive( true )
00037 {
00038 }
00039
00040
00041 mitk::Geometry2DDataMapper2D::~Geometry2DDataMapper2D()
00042 {
00043 }
00044
00045
00046 const mitk::Geometry2DData* mitk::Geometry2DDataMapper2D::GetInput(void)
00047 {
00048 return static_cast<const Geometry2DData * > ( GetData() );
00049 }
00050
00051
00052 void mitk::Geometry2DDataMapper2D::GenerateData()
00053 {
00054
00055 m_OtherGeometry2Ds.clear();
00056 if (m_DataStorage.IsNull())
00057 return;
00058
00059 mitk::NodePredicateDataType::Pointer p = mitk::NodePredicateDataType::New("Geometry2DData");
00060 mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetDerivations(m_ParentNode, p, false);
00061 for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
00062 {
00063 if(it->Value().IsNull())
00064 continue;
00065
00066 BaseData* data = it->Value()->GetData();
00067 if (data == NULL)
00068 continue;
00069
00070 Geometry2DData* geometry2dData = dynamic_cast<Geometry2DData*>(data);
00071 if(geometry2dData == NULL)
00072 continue;
00073
00074 PlaneGeometry* planegeometry = dynamic_cast<PlaneGeometry*>(geometry2dData->GetGeometry2D());
00075 if (planegeometry != NULL)
00076 m_OtherGeometry2Ds.push_back(it->Value());
00077 }
00078 }
00079
00080
00081 void mitk::Geometry2DDataMapper2D::Paint(BaseRenderer *renderer)
00082 {
00083 if ( !this->IsVisible(renderer) )
00084 {
00085 return;
00086 }
00087
00088 Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput());
00089
00090
00091 if ( input.IsNull() || (this->GetInput()->GetGeometry2D() ==
00092 renderer->GetCurrentWorldGeometry2D()) )
00093 {
00094 return;
00095 }
00096
00097 const PlaneGeometry *inputPlaneGeometry =
00098 dynamic_cast< const PlaneGeometry * >( input->GetGeometry2D() );
00099
00100 const PlaneGeometry *worldPlaneGeometry =
00101 dynamic_cast< const PlaneGeometry* >(
00102 renderer->GetCurrentWorldGeometry2D() );
00103
00104 if ( worldPlaneGeometry && inputPlaneGeometry
00105 && inputPlaneGeometry->GetReferenceGeometry() )
00106 {
00107 DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
00108 assert( displayGeometry );
00109
00110 const Geometry3D *referenceGeometry =
00111 inputPlaneGeometry->GetReferenceGeometry();
00112
00113
00114
00115 Point2D lineFrom, lineTo;
00116
00117 typedef Geometry3D::TransformType TransformType;
00118 const TransformType *transform = dynamic_cast< const TransformType * >(
00119 referenceGeometry->GetIndexToWorldTransform() );
00120
00121 TransformType::Pointer inverseTransform = TransformType::New();
00122 transform->GetInverse( inverseTransform );
00123
00124 Line3D crossLine, otherCrossLine;
00125
00126
00127 if ( worldPlaneGeometry->IntersectionLine(
00128 inputPlaneGeometry, crossLine ) )
00129 {
00130 BoundingBox::PointType boundingBoxMin, boundingBoxMax;
00131 boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum();
00132 boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum();
00133 if(referenceGeometry->GetImageGeometry())
00134 {
00135 for(unsigned int i = 0; i < 3; ++i)
00136 {
00137 boundingBoxMin[i]-=0.5;
00138 boundingBoxMax[i]-=0.5;
00139 }
00140 }
00141
00142 crossLine.Transform( *inverseTransform );
00143 Point3D point1, point2;
00144
00145
00146
00147 if ( crossLine.BoxLineIntersection(
00148 boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2],
00149 boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2],
00150 crossLine.GetPoint(), crossLine.GetDirection(),
00151 point1, point2 ) == 2 )
00152 {
00153
00154
00155 worldPlaneGeometry->Map(
00156 transform->TransformPoint( point1 ), lineFrom );
00157 worldPlaneGeometry->Map(
00158 transform->TransformPoint( point2 ), lineTo );
00159
00160 Line< ScalarType, 2 > line, otherLine;
00161 line.SetPoints( lineFrom, lineTo );
00162
00163 displayGeometry->WorldToDisplay( lineFrom, lineFrom );
00164 displayGeometry->WorldToDisplay( lineTo, lineTo );
00165
00166 ScalarType lengthInDisplayUnits = (lineTo - lineFrom).GetNorm();
00167
00168
00169
00170
00171 std::vector< ScalarType > lineParams;
00172 lineParams.reserve( m_OtherGeometry2Ds.size() + 2 );
00173 lineParams.push_back( 0.0 );
00174 lineParams.push_back( 1.0 );
00175
00176 Vector2D d, dOrth;
00177
00178
00179
00180
00181
00182 NodesVectorType::iterator otherPlanesIt = m_OtherGeometry2Ds.begin();
00183 NodesVectorType::iterator otherPlanesEnd = m_OtherGeometry2Ds.end();
00184 while ( otherPlanesIt != otherPlanesEnd )
00185 {
00186 PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >(
00187 static_cast< Geometry2DData * >(
00188 (*otherPlanesIt)->GetData() )->GetGeometry2D() );
00189
00190
00191
00192 if ( (otherPlane != inputPlaneGeometry)
00193 && worldPlaneGeometry->IntersectionLine(
00194 otherPlane, otherCrossLine ) )
00195 {
00196
00197
00198 otherCrossLine.Transform( *inverseTransform );
00199 if ( otherCrossLine.BoxLineIntersection(
00200 boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2],
00201 boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2],
00202 otherCrossLine.GetPoint(), otherCrossLine.GetDirection(),
00203 point1, point2 ) == 2 )
00204 {
00205 worldPlaneGeometry->Map(
00206 transform->TransformPoint( point1 ), lineFrom );
00207 worldPlaneGeometry->Map(
00208 transform->TransformPoint( point2 ), lineTo );
00209
00210
00211
00212 otherLine.SetPoints( lineFrom, lineTo );
00213 d = otherLine.GetDirection();
00214 dOrth[0] = -d[1]; dOrth[1] = d[0];
00215
00216 ScalarType t, norm;
00217 t = ( otherLine.GetPoint1() - line.GetPoint1() ) * dOrth;
00218 norm = line.GetDirection() * dOrth;
00219
00220 if ( fabs( norm ) > eps )
00221 {
00222 t /= norm;
00223 if ( (t > 0.0) && (t < 1.0) )
00224 {
00225 lineParams.push_back(t);
00226 }
00227 }
00228 }
00229 }
00230 ++otherPlanesIt;
00231 }
00232
00233
00234 this->ApplyProperties( renderer );
00235
00236 ScalarType gapSizeInPixel = 10.0;
00237 ScalarType gapSizeInParamUnits =
00238 1.0 / lengthInDisplayUnits * gapSizeInPixel;
00239
00240 std::sort( lineParams.begin(), lineParams.end() );
00241
00242 Point2D p1, p2;
00243 ScalarType p1Param, p2Param;
00244
00245 p1Param = lineParams[0];
00246 p1 = line.GetPoint( p1Param );
00247 displayGeometry->WorldToDisplay( p1, p1 );
00248
00249
00250
00251 unsigned int i, preLastLineParam = lineParams.size() - 1;
00252 for ( i = 1; i < preLastLineParam; ++i )
00253 {
00254 p2Param = lineParams[i] - gapSizeInParamUnits * 0.5;
00255 p2 = line.GetPoint( p2Param );
00256
00257 if ( p2Param > p1Param )
00258 {
00259
00260
00261 displayGeometry->WorldToDisplay( p2, p2 );
00262
00263
00264 glBegin (GL_LINES);
00265 glVertex2f(p1[0],p1[1]);
00266 glVertex2f(p2[0],p2[1]);
00267 glEnd ();
00268
00269 if ( (i == 1) && (m_RenderOrientationArrows) )
00270 {
00271
00272 this->DrawOrientationArrow( p1, p2,
00273 inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
00274 m_ArrowOrientationPositive );
00275 }
00276 }
00277
00278 p1Param = p2Param + gapSizeInParamUnits;
00279 p1 = line.GetPoint( p1Param );
00280 displayGeometry->WorldToDisplay( p1, p1 );
00281 }
00282
00283
00284 p2Param = lineParams[i];
00285 p2 = line.GetPoint( p2Param );
00286 displayGeometry->WorldToDisplay( p2, p2 );
00287 glBegin( GL_LINES );
00288 glVertex2f( p1[0], p1[1] );
00289 glVertex2f( p2[0], p2[1] );
00290 glEnd();
00291
00292
00293
00294 if ( m_RenderOrientationArrows )
00295 {
00296 this->DrawOrientationArrow( p2, p1,
00297 inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
00298 m_ArrowOrientationPositive );
00299 if ( preLastLineParam < 2 )
00300 {
00301
00302 this->DrawOrientationArrow( p1, p2,
00303 inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
00304 m_ArrowOrientationPositive );
00305 }
00306 }
00307 }
00308 }
00309 }
00310 else
00311 {
00312 Geometry2DDataToSurfaceFilter::Pointer surfaceCreator;
00313 SmartPointerProperty::Pointer surfacecreatorprop;
00314 surfacecreatorprop = dynamic_cast< SmartPointerProperty * >(
00315 GetDataNode()->GetProperty(
00316 "surfacegeometry", renderer));
00317
00318 if( (surfacecreatorprop.IsNull()) ||
00319 (surfacecreatorprop->GetSmartPointer().IsNull()) ||
00320 ((surfaceCreator = dynamic_cast< Geometry2DDataToSurfaceFilter * >(
00321 surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull())
00322 )
00323 {
00324 surfaceCreator = Geometry2DDataToSurfaceFilter::New();
00325 surfacecreatorprop = SmartPointerProperty::New(surfaceCreator);
00326 surfaceCreator->PlaceByGeometryOn();
00327 GetDataNode()->SetProperty( "surfacegeometry", surfacecreatorprop );
00328 }
00329
00330 surfaceCreator->SetInput( input );
00331
00332
00333 if ( input->GetGeometry2D()->HasReferenceGeometry() )
00334 {
00335 surfaceCreator->SetBoundingBox(
00336 input->GetGeometry2D()->GetReferenceGeometry()->GetBoundingBox()
00337 );
00338 }
00339
00340 int res;
00341 bool usegeometryparametricbounds = true;
00342 if ( GetDataNode()->GetIntProperty("xresolution", res, renderer))
00343 {
00344 surfaceCreator->SetXResolution(res);
00345 usegeometryparametricbounds=false;
00346 }
00347 if (GetDataNode()->GetIntProperty("yresolution", res, renderer))
00348 {
00349 surfaceCreator->SetYResolution(res);
00350 usegeometryparametricbounds=false;
00351 }
00352 surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds);
00353
00354
00355 surfaceCreator->Update();
00356
00357 if (m_SurfaceMapper.IsNull())
00358 {
00359 m_SurfaceMapper=SurfaceGLMapper2D::New();
00360 }
00361 m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput());
00362 m_SurfaceMapper->SetDataNode(GetDataNode());
00363
00364 m_SurfaceMapper->Paint(renderer);
00365 }
00366 }
00367
00368 void mitk::Geometry2DDataMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint,
00369 const mitk::PlaneGeometry *planeGeometry,
00370 const mitk::PlaneGeometry *rendererPlaneGeometry,
00371 const mitk::DisplayGeometry *displayGeometry,
00372 bool positiveOrientation )
00373 {
00374
00375
00376 Vector2D v1 = innerPoint - outerPoint;
00377 v1.Normalize();
00378 v1 *= 7.0;
00379
00380
00381 Vector2D v2;
00382 v2[0] = v1[1];
00383 v2[1] = -v1[0];
00384
00385
00386
00387 Point2D worldPoint2D;
00388 Point3D worldPoint;
00389 displayGeometry->DisplayToWorld( outerPoint + v1 + v2, worldPoint2D );
00390 rendererPlaneGeometry->Map( worldPoint2D, worldPoint );
00391
00392
00393
00394 Point2D p1 = outerPoint + v1 * 2.0;
00395 Point2D p2 = outerPoint + v1
00396 + ((positiveOrientation ^ planeGeometry->IsAbove( worldPoint ))
00397 ? v2 : -v2);
00398
00399
00400 glBegin( GL_TRIANGLES );
00401 glVertex2f( outerPoint[0], outerPoint[1] );
00402 glVertex2f( p1[0], p1[1] );
00403 glVertex2f( p2[0], p2[1] );
00404 glEnd();
00405 }
00406
00407
00408 void mitk::Geometry2DDataMapper2D::ApplyProperties( BaseRenderer *renderer )
00409 {
00410 Superclass::ApplyProperties(renderer);
00411
00412 PlaneOrientationProperty* decorationProperty;
00413 this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer );
00414 if ( decorationProperty != NULL )
00415 {
00416 if ( decorationProperty->GetPlaneDecoration() ==
00417 PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION )
00418 {
00419 m_RenderOrientationArrows = true;
00420 m_ArrowOrientationPositive = true;
00421 }
00422 else if ( decorationProperty->GetPlaneDecoration() ==
00423 PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION )
00424 {
00425 m_RenderOrientationArrows = true;
00426 m_ArrowOrientationPositive = false;
00427 }
00428 else
00429 {
00430 m_RenderOrientationArrows = false;
00431 }
00432 }
00433 }
00434
00435
00436 void mitk::Geometry2DDataMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent )
00437 {
00438 if (ds.IsNotNull())
00439 {
00440 m_DataStorage = ds;
00441 }
00442 if (parent.IsNotNull())
00443 {
00444 m_ParentNode = parent;
00445 }
00446 }