00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkSlicedGeometry3D.h"
00019 #include "mitkPlaneGeometry.h"
00020 #include "mitkRotationOperation.h"
00021 #include "mitkPlaneOperation.h"
00022 #include "mitkInteractionConst.h"
00023 #include "mitkSliceNavigationController.h"
00024
00025
00026 mitk::SlicedGeometry3D::SlicedGeometry3D()
00027 : m_EvenlySpaced( true ),
00028 m_Slices( 0 ),
00029 m_ReferenceGeometry( NULL ),
00030 m_SliceNavigationController( NULL )
00031 {
00032 this->Initialize( m_Slices );
00033 }
00034
00035
00036 mitk::SlicedGeometry3D::~SlicedGeometry3D()
00037 {
00038 }
00039
00040
00041 mitk::Geometry2D *
00042 mitk::SlicedGeometry3D::GetGeometry2D( int s ) const
00043 {
00044 mitk::Geometry2D::Pointer geometry2D = NULL;
00045
00046 if ( this->IsValidSlice(s) )
00047 {
00048 geometry2D = m_Geometry2Ds[s];
00049
00050
00051
00052
00053
00054
00055 if ( (m_EvenlySpaced) && (geometry2D.IsNull()) )
00056 {
00057 PlaneGeometry *firstSlice = dynamic_cast< PlaneGeometry * > (
00058 m_Geometry2Ds[0].GetPointer() );
00059
00060 if ( firstSlice != NULL )
00061 {
00062 if ( (m_DirectionVector[0] == 0.0)
00063 && (m_DirectionVector[1] == 0.0)
00064 && (m_DirectionVector[2] == 0.0) )
00065 {
00066 m_DirectionVector = firstSlice->GetNormal();
00067 m_DirectionVector.Normalize();
00068 }
00069
00070 Vector3D direction;
00071 direction = m_DirectionVector * m_Spacing[2];
00072
00073 mitk::PlaneGeometry::Pointer requestedslice;
00074 requestedslice = static_cast< mitk::PlaneGeometry * >(
00075 firstSlice->Clone().GetPointer() );
00076
00077 requestedslice->SetOrigin(
00078 requestedslice->GetOrigin() + direction * s );
00079
00080 geometry2D = requestedslice;
00081 m_Geometry2Ds[s] = geometry2D;
00082 }
00083 }
00084 return geometry2D;
00085 }
00086 else
00087 {
00088 return NULL;
00089 }
00090 }
00091
00092 const mitk::BoundingBox *
00093 mitk::SlicedGeometry3D::GetBoundingBox() const
00094 {
00095 assert(m_BoundingBox.IsNotNull());
00096 return m_BoundingBox.GetPointer();
00097 }
00098
00099
00100 bool
00101 mitk::SlicedGeometry3D::SetGeometry2D( mitk::Geometry2D *geometry2D, int s )
00102 {
00103 if ( this->IsValidSlice(s) )
00104 {
00105 m_Geometry2Ds[s] = geometry2D;
00106 m_Geometry2Ds[s]->SetReferenceGeometry( m_ReferenceGeometry );
00107 return true;
00108 }
00109 return false;
00110 }
00111
00112
00113 void
00114 mitk::SlicedGeometry3D::Initialize( unsigned int slices )
00115 {
00116 Superclass::Initialize();
00117 m_Slices = slices;
00118
00119 Geometry2D::Pointer gnull = NULL;
00120 m_Geometry2Ds.assign( m_Slices, gnull );
00121
00122 Vector3D spacing;
00123 spacing.Fill( 1.0 );
00124 this->SetSpacing( spacing );
00125
00126 m_DirectionVector.Fill( 0 );
00127 }
00128
00129
00130 void
00131 mitk::SlicedGeometry3D::InitializeEvenlySpaced(
00132 mitk::Geometry2D* geometry2D, unsigned int slices, bool flipped )
00133 {
00134 assert( geometry2D != NULL );
00135 this->InitializeEvenlySpaced(
00136 geometry2D, geometry2D->GetExtentInMM(2)/geometry2D->GetExtent(2),
00137 slices, flipped );
00138 }
00139
00140
00141 void
00142 mitk::SlicedGeometry3D::InitializeEvenlySpaced(
00143 mitk::Geometry2D* geometry2D, mitk::ScalarType zSpacing,
00144 unsigned int slices, bool flipped )
00145 {
00146 assert( geometry2D != NULL );
00147 assert( geometry2D->GetExtent(0) > 0 );
00148 assert( geometry2D->GetExtent(1) > 0 );
00149
00150 geometry2D->Register();
00151
00152 Superclass::Initialize();
00153 m_Slices = slices;
00154
00155 BoundingBox::BoundsArrayType bounds = geometry2D->GetBounds();
00156 bounds[4] = 0;
00157 bounds[5] = slices;
00158
00159
00160 Geometry2D::Pointer gnull = NULL;
00161 m_Geometry2Ds.assign( m_Slices, gnull );
00162
00163 Vector3D directionVector = geometry2D->GetAxisVector(2);
00164 directionVector.Normalize();
00165 directionVector *= zSpacing;
00166
00167 if ( flipped == false )
00168 {
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 m_IndexToWorldTransform = const_cast< AffineTransform3D * >(
00181 geometry2D->GetIndexToWorldTransform() );
00182 }
00183 else
00184 {
00185 directionVector *= -1.0;
00186 m_IndexToWorldTransform = AffineTransform3D::New();
00187 m_IndexToWorldTransform->SetMatrix(
00188 geometry2D->GetIndexToWorldTransform()->GetMatrix() );
00189
00190 AffineTransform3D::OutputVectorType scaleVector;
00191 FillVector3D(scaleVector, 1.0, 1.0, -1.0);
00192 m_IndexToWorldTransform->Scale(scaleVector, true);
00193 m_IndexToWorldTransform->SetOffset(
00194 geometry2D->GetIndexToWorldTransform()->GetOffset() );
00195 }
00196
00197 mitk::Vector3D spacing;
00198 FillVector3D( spacing,
00199 geometry2D->GetExtentInMM(0) / bounds[1],
00200 geometry2D->GetExtentInMM(1) / bounds[3],
00201 zSpacing );
00202
00203
00204
00205 m_Spacing[2] = zSpacing - 1;
00206
00207 this->SetDirectionVector( directionVector );
00208 this->SetBounds( bounds );
00209 this->SetGeometry2D( geometry2D, 0 );
00210 this->SetSpacing( spacing );
00211 this->SetEvenlySpaced();
00212 this->SetTimeBounds( geometry2D->GetTimeBounds() );
00213
00214 assert(m_IndexToWorldTransform.GetPointer()
00215 != geometry2D->GetIndexToWorldTransform());
00216
00217 this->SetFrameOfReferenceID( geometry2D->GetFrameOfReferenceID() );
00218 this->SetImageGeometry( geometry2D->GetImageGeometry() );
00219
00220 geometry2D->UnRegister();
00221 }
00222
00223
00224 void
00225 mitk::SlicedGeometry3D::InitializePlanes(
00226 const mitk::Geometry3D *geometry3D,
00227 mitk::PlaneGeometry::PlaneOrientation planeorientation,
00228 bool top, bool frontside, bool rotated )
00229 {
00230 m_ReferenceGeometry = const_cast< Geometry3D * >( geometry3D );
00231
00232 PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
00233 planeGeometry->InitializeStandardPlane(
00234 geometry3D, top, planeorientation, frontside, rotated );
00235
00236 ScalarType viewSpacing = 1;
00237 unsigned int slices = 1;
00238
00239 switch ( planeorientation )
00240 {
00241 case PlaneGeometry::Transversal:
00242 viewSpacing = geometry3D->GetSpacing()[2];
00243 slices = (unsigned int) geometry3D->GetExtent( 2 );
00244 break;
00245
00246 case PlaneGeometry::Frontal:
00247 viewSpacing = geometry3D->GetSpacing()[1];
00248 slices = (unsigned int) geometry3D->GetExtent( 1 );
00249 break;
00250
00251 case PlaneGeometry::Sagittal:
00252 viewSpacing = geometry3D->GetSpacing()[0];
00253 slices = (unsigned int) geometry3D->GetExtent( 0 );
00254 break;
00255
00256 default:
00257 itkExceptionMacro("unknown PlaneOrientation");
00258 }
00259
00260 mitk::Vector3D normal = this->AdjustNormal( planeGeometry->GetNormal() );
00261
00262
00263 ScalarType directedExtent =
00264 fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
00265 + fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
00266 + fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
00267
00268 if ( directedExtent >= viewSpacing )
00269 {
00270 slices = static_cast< int >(directedExtent / viewSpacing + 0.5);
00271 }
00272 else
00273 {
00274 slices = 1;
00275 }
00276
00277 bool flipped = (top == false);
00278
00279 if ( frontside == false )
00280 {
00281 flipped = !flipped;
00282 }
00283 if ( planeorientation == PlaneGeometry::Frontal )
00284 {
00285 flipped = !flipped;
00286 }
00287
00288 this->InitializeEvenlySpaced( planeGeometry, viewSpacing, slices, flipped );
00289 }
00290
00291
00292 void
00293 mitk::SlicedGeometry3D
00294 ::ReinitializePlanes( const Point3D ¢er, const Point3D &referencePoint )
00295 {
00296
00297 if ( !m_ReferenceGeometry )
00298 {
00299 return;
00300 }
00301
00302
00303 PlaneGeometry *firstPlane =
00304 dynamic_cast< PlaneGeometry * >( m_Geometry2Ds[0].GetPointer() );
00305
00306
00307 if ( firstPlane == NULL )
00308 {
00309 return;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 mitk::Vector3D axis0 = firstPlane->GetAxisVector(0);
00319 mitk::Vector3D axis1 = firstPlane->GetAxisVector(1);
00320 mitk::Vector3D normal = firstPlane->GetNormal();
00321 normal.Normalize();
00322
00323 Vector3D spacing;
00324 spacing[0] = this->CalculateSpacing( axis0 );
00325 spacing[1] = this->CalculateSpacing( axis1 );
00326 spacing[2] = this->CalculateSpacing( normal );
00327
00328 Superclass::SetSpacing( spacing );
00329
00330
00331
00332
00333
00334
00335
00336 ScalarType directedExtent =
00337 fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
00338 + fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
00339 + fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
00340
00341 if ( directedExtent >= spacing[2] )
00342 {
00343 m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
00344 }
00345 else
00346 {
00347 m_Slices = 1;
00348 }
00349
00350
00351
00352
00353
00354 double centerOfRotationDistance =
00355 firstPlane->SignedDistanceFromPlane( center );
00356
00357 if ( centerOfRotationDistance > 0 )
00358 {
00359 firstPlane->SetOrigin( firstPlane->GetOrigin()
00360 + normal * (centerOfRotationDistance - directedExtent / 2.0)
00361 );
00362 m_DirectionVector = normal;
00363 }
00364 else
00365 {
00366 firstPlane->SetOrigin( firstPlane->GetOrigin()
00367 + normal * (directedExtent / 2.0 + centerOfRotationDistance)
00368 );
00369 m_DirectionVector = -normal;
00370 }
00371
00372
00373
00374
00375 double referencePointDistance =
00376 firstPlane->SignedDistanceFromPlane( referencePoint );
00377
00378 int referencePointSlice = static_cast< int >(
00379 referencePointDistance / spacing[2]);
00380
00381 double alignmentValue =
00382 referencePointDistance / spacing[2] - referencePointSlice;
00383
00384 firstPlane->SetOrigin(
00385 firstPlane->GetOrigin() + normal * alignmentValue * spacing[2] );
00386
00387
00388
00389
00390 m_Geometry2Ds.assign( m_Slices, Geometry2D::Pointer( NULL ) );
00391
00392 if ( m_Slices > 0 )
00393 {
00394 m_Geometry2Ds[0] = firstPlane;
00395 }
00396
00397
00398 m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );
00399
00400 this->Modified();
00401 }
00402
00403
00404 double
00405 mitk::SlicedGeometry3D::CalculateSpacing( const mitk::Vector3D &d ) const
00406 {
00407
00408 if ( !m_ReferenceGeometry )
00409 {
00410 return 1.0;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420 const mitk::Vector3D &spacing = m_ReferenceGeometry->GetSpacing();
00421
00422 double scaling = d[0]*d[0] / (spacing[0] * spacing[0])
00423 + d[1]*d[1] / (spacing[1] * spacing[1])
00424 + d[2]*d[2] / (spacing[2] * spacing[2]);
00425
00426 scaling = sqrt( scaling );
00427
00428 return ( sqrt( d[0]*d[0] + d[1]*d[1] + d[2]*d[2] ) / scaling );
00429 }
00430
00431 mitk::Vector3D
00432 mitk::SlicedGeometry3D::AdjustNormal( const mitk::Vector3D &normal ) const
00433 {
00434 Geometry3D::TransformType::Pointer inverse = Geometry3D::TransformType::New();
00435 m_ReferenceGeometry->GetIndexToWorldTransform()->GetInverse( inverse );
00436
00437 Vector3D transformedNormal = inverse->TransformVector( normal );
00438
00439 transformedNormal.Normalize();
00440 return transformedNormal;
00441 }
00442
00443
00444 void
00445 mitk::SlicedGeometry3D::SetImageGeometry( const bool isAnImageGeometry )
00446 {
00447 Superclass::SetImageGeometry( isAnImageGeometry );
00448
00449 mitk::Geometry3D* geometry;
00450
00451 unsigned int s;
00452 for ( s = 0; s < m_Slices; ++s )
00453 {
00454 geometry = m_Geometry2Ds[s];
00455 if ( geometry!=NULL )
00456 {
00457 geometry->SetImageGeometry( isAnImageGeometry );
00458 }
00459 }
00460 }
00461
00462 bool
00463 mitk::SlicedGeometry3D::IsValidSlice( int s ) const
00464 {
00465 return ((s >= 0) && (s < (int)m_Slices));
00466 }
00467
00468 void
00469 mitk::SlicedGeometry3D::SetReferenceGeometry( Geometry3D *referenceGeometry )
00470 {
00471 m_ReferenceGeometry = referenceGeometry;
00472
00473 std::vector<Geometry2D::Pointer>::iterator it;
00474
00475 for ( it = m_Geometry2Ds.begin(); it != m_Geometry2Ds.end(); ++it )
00476 {
00477 (*it)->SetReferenceGeometry( referenceGeometry );
00478 }
00479 }
00480
00481 void
00482 mitk::SlicedGeometry3D::SetSpacing( const mitk::Vector3D &aSpacing )
00483 {
00484 bool hasEvenlySpacedPlaneGeometry = false;
00485 mitk::Point3D origin;
00486 mitk::Vector3D rightDV, bottomDV;
00487 BoundingBox::BoundsArrayType bounds;
00488
00489 assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);
00490
00491
00492
00493 if ((m_EvenlySpaced) && (m_Geometry2Ds.size() > 0))
00494 {
00495 mitk::Geometry2D::ConstPointer firstGeometry =
00496 m_Geometry2Ds[0].GetPointer();
00497
00498 const PlaneGeometry *planeGeometry =
00499 dynamic_cast< const PlaneGeometry * >( firstGeometry.GetPointer() );
00500
00501 if (planeGeometry != NULL )
00502 {
00503 this->WorldToIndex( planeGeometry->GetOrigin(), origin );
00504 this->WorldToIndex( planeGeometry->GetOrigin(),
00505 planeGeometry->GetAxisVector(0), rightDV );
00506 this->WorldToIndex( planeGeometry->GetOrigin(),
00507 planeGeometry->GetAxisVector(1), bottomDV );
00508
00509 bounds = planeGeometry->GetBounds();
00510 hasEvenlySpacedPlaneGeometry = true;
00511 }
00512 }
00513
00514 Superclass::SetSpacing(aSpacing);
00515
00516 mitk::Geometry2D::Pointer firstGeometry;
00517
00518
00519
00520 if ( hasEvenlySpacedPlaneGeometry )
00521 {
00522
00523 this->IndexToWorld( origin, origin );
00524 this->IndexToWorld( origin, rightDV, rightDV );
00525 this->IndexToWorld( origin, bottomDV, bottomDV );
00526
00527 mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
00528
00529 planeGeometry->SetReferenceGeometry( m_ReferenceGeometry );
00530 planeGeometry->InitializeStandardPlane(
00531 rightDV.Get_vnl_vector(), bottomDV.Get_vnl_vector(), &m_Spacing );
00532 planeGeometry->SetOrigin(origin);
00533 planeGeometry->SetBounds(bounds);
00534
00535 firstGeometry = planeGeometry;
00536 }
00537 else if ( (m_EvenlySpaced) && (m_Geometry2Ds.size() > 0) )
00538 {
00539 firstGeometry = m_Geometry2Ds[0].GetPointer();
00540 }
00541
00542
00543 Geometry2D::Pointer gnull=NULL;
00544 m_Geometry2Ds.assign(m_Slices, gnull);
00545
00546 if ( m_Slices > 0 )
00547 {
00548 m_Geometry2Ds[0] = firstGeometry;
00549 }
00550
00551 this->Modified();
00552 }
00553
00554
00555 void
00556 mitk::SlicedGeometry3D
00557 ::SetSliceNavigationController( SliceNavigationController *snc )
00558 {
00559 m_SliceNavigationController = snc;
00560 }
00561
00562
00563 mitk::SliceNavigationController *
00564 mitk::SlicedGeometry3D::GetSliceNavigationController()
00565 {
00566 return m_SliceNavigationController;
00567 }
00568
00569 void
00570 mitk::SlicedGeometry3D::SetEvenlySpaced(bool on)
00571 {
00572 if(m_EvenlySpaced!=on)
00573 {
00574 m_EvenlySpaced=on;
00575 this->Modified();
00576 }
00577 }
00578
00579
00580 void
00581 mitk::SlicedGeometry3D
00582 ::SetDirectionVector( const mitk::Vector3D& directionVector )
00583 {
00584 Vector3D diff = m_DirectionVector - directionVector;
00585
00586 if ( (m_DirectionVector.GetSquaredNorm() == 0.0)
00587 || (diff.GetNorm() >= vnl_math::float_eps) )
00588 {
00589 m_DirectionVector = directionVector;
00590 m_DirectionVector.Normalize();
00591 this->Modified();
00592 }
00593 }
00594
00595
00596 void
00597 mitk::SlicedGeometry3D::SetTimeBounds( const mitk::TimeBounds& timebounds )
00598 {
00599 Superclass::SetTimeBounds( timebounds );
00600
00601 unsigned int s;
00602 for ( s = 0; s < m_Slices; ++s )
00603 {
00604 if(m_Geometry2Ds[s].IsNotNull())
00605 {
00606 m_Geometry2Ds[s]->SetTimeBounds( timebounds );
00607 }
00608 }
00609 m_TimeBounds = timebounds;
00610 }
00611
00612
00613 mitk::AffineGeometryFrame3D::Pointer
00614 mitk::SlicedGeometry3D::Clone() const
00615 {
00616 Self::Pointer newGeometry = Self::New();
00617 newGeometry->Initialize(m_Slices);
00618 InitializeGeometry(newGeometry);
00619 return newGeometry.GetPointer();
00620 }
00621
00622
00623 void
00624 mitk::SlicedGeometry3D::InitializeGeometry( Self *newGeometry ) const
00625 {
00626 Superclass::InitializeGeometry( newGeometry );
00627
00628 newGeometry->SetEvenlySpaced( m_EvenlySpaced );
00629 newGeometry->SetSpacing( this->GetSpacing() );
00630 newGeometry->SetDirectionVector( this->GetDirectionVector() );
00631
00632 newGeometry->SetSliceNavigationController( m_SliceNavigationController );
00633 newGeometry->m_ReferenceGeometry = m_ReferenceGeometry;
00634
00635 if ( m_EvenlySpaced )
00636 {
00637 AffineGeometryFrame3D::Pointer geometry = m_Geometry2Ds[0]->Clone();
00638 Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
00639 assert(geometry2D!=NULL);
00640 newGeometry->SetGeometry2D(geometry2D, 0);
00641 }
00642 else
00643 {
00644 unsigned int s;
00645 for ( s = 0; s < m_Slices; ++s )
00646 {
00647 if ( m_Geometry2Ds[s].IsNull() )
00648 {
00649 assert(m_EvenlySpaced);
00650 }
00651 else
00652 {
00653 AffineGeometryFrame3D::Pointer geometry = m_Geometry2Ds[s]->Clone();
00654 Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
00655 assert(geometry2D!=NULL);
00656 newGeometry->SetGeometry2D(geometry2D, s);
00657 }
00658 }
00659 }
00660 }
00661
00662
00663 void
00664 mitk::SlicedGeometry3D::PrintSelf( std::ostream& os, itk::Indent indent ) const
00665 {
00666 Superclass::PrintSelf(os,indent);
00667 os << indent << " EvenlySpaced: " << m_EvenlySpaced << std::endl;
00668 if ( m_EvenlySpaced )
00669 {
00670 os << indent << " DirectionVector: " << m_DirectionVector << std::endl;
00671 }
00672 os << indent << " Slices: " << m_Slices << std::endl;
00673
00674 os << std::endl;
00675 os << indent << " GetGeometry2D(0): ";
00676 if ( this->GetGeometry2D(0) == NULL )
00677 {
00678 os << "NULL" << std::endl;
00679 }
00680 else
00681 {
00682 this->GetGeometry2D(0)->Print(os, indent);
00683 }
00684 }
00685
00686 void
00687 mitk::SlicedGeometry3D::ExecuteOperation(Operation* operation)
00688 {
00689 switch ( operation->GetOperationType() )
00690 {
00691 case OpNOTHING:
00692 break;
00693
00694 case OpROTATE:
00695 if ( m_EvenlySpaced )
00696 {
00697
00698 if ( m_ReferenceGeometry )
00699 {
00700
00701
00702
00703
00704 Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];
00705
00706 RotationOperation *rotOp = dynamic_cast< RotationOperation * >( operation );
00707
00708
00709
00710
00711
00712 Point3D center = m_ReferenceGeometry->GetCenter();
00713
00714 RotationOperation centeredRotation(
00715 rotOp->GetOperationType(),
00716 center,
00717 rotOp->GetVectorOfRotation(),
00718 rotOp->GetAngleOfRotation()
00719 );
00720
00721
00722 geometry2D->ExecuteOperation( ¢eredRotation );
00723
00724
00725
00726
00727 this->ReinitializePlanes( center, rotOp->GetCenterOfRotation() );
00728
00729 if ( m_SliceNavigationController )
00730 {
00731 m_SliceNavigationController->SelectSliceByPoint(
00732 rotOp->GetCenterOfRotation() );
00733 m_SliceNavigationController->AdjustSliceStepperRange();
00734 }
00735
00736 Geometry3D::ExecuteOperation( ¢eredRotation );
00737 }
00738 }
00739 else
00740 {
00741
00742 for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
00743 iter != m_Geometry2Ds.end();
00744 ++iter)
00745 {
00746 (*iter)->ExecuteOperation(operation);
00747 }
00748 }
00749 break;
00750
00751 case OpORIENT:
00752 if ( m_EvenlySpaced )
00753 {
00754
00755 Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];
00756
00757 PlaneGeometry *planeGeometry = dynamic_cast< PlaneGeometry * >(
00758 geometry2D.GetPointer() );
00759
00760 PlaneOperation *planeOp = dynamic_cast< PlaneOperation * >( operation );
00761
00762
00763
00764 if ( m_ReferenceGeometry && planeGeometry && planeOp )
00765 {
00766
00767
00768
00769
00770
00771 Point3D center = m_ReferenceGeometry->GetCenter();
00772
00773 const mitk::Vector3D ¤tNormal = planeGeometry->GetNormal();
00774 const mitk::Vector3D &newNormal = planeOp->GetNormal();
00775
00776 Vector3D rotationAxis = itk::CrossProduct( newNormal, currentNormal );
00777
00778 vtkFloatingPointType rotationAngle = - atan2(
00779 (double) rotationAxis.GetNorm(),
00780 (double) (newNormal * currentNormal) );
00781
00782 rotationAngle *= 180.0 / vnl_math::pi;
00783
00784 RotationOperation centeredRotation(
00785 mitk::OpROTATE,
00786 center,
00787 rotationAxis,
00788 rotationAngle
00789 );
00790
00791
00792 geometry2D->ExecuteOperation( ¢eredRotation );
00793
00794
00795
00796 this->ReinitializePlanes( center, planeOp->GetPoint() );
00797
00798 if ( m_SliceNavigationController )
00799 {
00800 m_SliceNavigationController->SelectSliceByPoint( planeOp->GetPoint() );
00801 m_SliceNavigationController->AdjustSliceStepperRange();
00802 }
00803
00804 Geometry3D::ExecuteOperation( ¢eredRotation );
00805 }
00806 }
00807 else
00808 {
00809
00810 for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
00811 iter != m_Geometry2Ds.end();
00812 ++iter)
00813 {
00814 (*iter)->ExecuteOperation(operation);
00815 }
00816 }
00817 break;
00818 }
00819
00820 this->Modified();
00821 }
00822