예제 #1
0
  bool
    RenderingManager
    ::InitializeViews(const TimeGeometry * dataGeometry, RequestType type, bool /*preserveRoughOrientationInWorldSpace*/)
  {
    MITK_DEBUG << "initializing views";

    bool boundingBoxInitialized = false;

    TimeGeometry::ConstPointer timeGeometry = dataGeometry;
    TimeGeometry::Pointer modifiedGeometry = NULL;
    if (dataGeometry != NULL)
    {
      modifiedGeometry = dataGeometry->Clone();
    }

    int warningLevel = vtkObject::GetGlobalWarningDisplay();
    vtkObject::GlobalWarningDisplayOff();

    if ((timeGeometry.IsNotNull()) && (const_cast<mitk::BoundingBox *>(
      timeGeometry->GetBoundingBoxInWorld())->GetDiagonalLength2() > mitk::eps))
    {
      boundingBoxInitialized = true;
    }

    if (timeGeometry.IsNotNull())
    {// make sure bounding box has an extent bigger than zero in any direction
      // clone the input geometry
      //Old Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
      assert(modifiedGeometry.IsNotNull());
      for (TimeStepType step = 0; step < modifiedGeometry->CountTimeSteps(); ++step)
      {
        BaseGeometry::BoundsArrayType newBounds = modifiedGeometry->GetGeometryForTimeStep(step)->GetBounds();
        for (unsigned int dimension = 0; (2 * dimension) < newBounds.Size(); dimension++)
        {
          //check for equality but for an epsilon
          if (Equal(newBounds[2 * dimension], newBounds[2 * dimension + 1]))
          {
            newBounds[2 * dimension + 1] += 1;
            if( Equal( newBounds[ 2 * dimension ], newBounds[ 2 * dimension + 1 ] ) ) // newBounds will still be equal if values are beyond double precision
            {
              mitkThrow()<< "One dimension of object data has zero length, please make sure you're not using numbers beyond double precision as coordinates.";
            }
          }
        }
        modifiedGeometry->GetGeometryForTimeStep(step)->SetBounds(newBounds);
      }
    }

    timeGeometry = modifiedGeometry;
    RenderWindowList::const_iterator it;
    for (it = m_RenderWindowList.cbegin(); it != m_RenderWindowList.cend(); ++it)
    {
      mitk::BaseRenderer *baseRenderer =
        mitk::BaseRenderer::GetInstance(it->first);

      baseRenderer->SetConstrainZoomingAndPanning(m_ConstrainedPanningZooming);

      int id = baseRenderer->GetMapperID();
      if (((type == REQUEST_UPDATE_ALL)
        || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
        || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)))
        )
      {
        this->InternalViewInitialization(baseRenderer, timeGeometry,
          boundingBoxInitialized, id);
      }
    }

    if (boundingBoxInitialized)
    {
      m_TimeNavigationController->SetInputWorldTimeGeometry(timeGeometry);
    }
    m_TimeNavigationController->Update();

    this->RequestUpdateAll(type);

    vtkObject::SetGlobalWarningDisplay(warningLevel);

    // Inform listeners that views have been initialized
    this->InvokeEvent(mitk::RenderingManagerViewsInitializedEvent());

    return boundingBoxInitialized;
  }
  void SliceNavigationController::Update(SliceNavigationController::ViewDirection viewDirection,
                                         bool top,
                                         bool frontside,
                                         bool rotated)
  {
    TimeGeometry::ConstPointer worldTimeGeometry = m_InputWorldTimeGeometry;

    if (m_BlockUpdate || (m_InputWorldTimeGeometry.IsNull() && m_InputWorldGeometry3D.IsNull()) ||
        ((worldTimeGeometry.IsNotNull()) && (worldTimeGeometry->CountTimeSteps() == 0)))
    {
      return;
    }

    m_BlockUpdate = true;

    if (m_InputWorldTimeGeometry.IsNotNull() && m_LastUpdateTime < m_InputWorldTimeGeometry->GetMTime())
    {
      Modified();
    }
    if (m_InputWorldGeometry3D.IsNotNull() && m_LastUpdateTime < m_InputWorldGeometry3D->GetMTime())
    {
      Modified();
    }
    this->SetViewDirection(viewDirection);
    this->SetTop(top);
    this->SetFrontSide(frontside);
    this->SetRotated(rotated);

    if (m_LastUpdateTime < GetMTime())
    {
      m_LastUpdateTime = GetMTime();

      // initialize the viewplane
      SlicedGeometry3D::Pointer slicedWorldGeometry = SlicedGeometry3D::Pointer();
      BaseGeometry::ConstPointer currentGeometry = BaseGeometry::ConstPointer();
      if (m_InputWorldTimeGeometry.IsNotNull())
        if (m_InputWorldTimeGeometry->IsValidTimeStep(GetTime()->GetPos()))
          currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(GetTime()->GetPos());
        else
          currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(0);
      else
        currentGeometry = m_InputWorldGeometry3D;

      m_CreatedWorldGeometry = mitk::TimeGeometry::Pointer();
      switch (viewDirection)
      {
        case Original:
          if (worldTimeGeometry.IsNotNull())
          {
            m_CreatedWorldGeometry = worldTimeGeometry->Clone();

            worldTimeGeometry = m_CreatedWorldGeometry.GetPointer();

            slicedWorldGeometry = dynamic_cast<SlicedGeometry3D *>(
              m_CreatedWorldGeometry->GetGeometryForTimeStep(this->GetTime()->GetPos()).GetPointer());

            if (slicedWorldGeometry.IsNotNull())
            {
              break;
            }
          }
          else
          {
            const SlicedGeometry3D *worldSlicedGeometry =
              dynamic_cast<const SlicedGeometry3D *>(currentGeometry.GetPointer());

          if ( worldSlicedGeometry != nullptr )
            {
              slicedWorldGeometry = static_cast<SlicedGeometry3D *>(currentGeometry->Clone().GetPointer());
              break;
            }
          }
          slicedWorldGeometry = SlicedGeometry3D::New();
          slicedWorldGeometry->InitializePlanes(currentGeometry, PlaneGeometry::None, top, frontside, rotated);
          slicedWorldGeometry->SetSliceNavigationController(this);
          break;

        case Axial:
          slicedWorldGeometry = SlicedGeometry3D::New();
          slicedWorldGeometry->InitializePlanes(currentGeometry, PlaneGeometry::Axial, top, frontside, rotated);
          slicedWorldGeometry->SetSliceNavigationController(this);
          break;

        case Frontal:
          slicedWorldGeometry = SlicedGeometry3D::New();
          slicedWorldGeometry->InitializePlanes(currentGeometry, PlaneGeometry::Frontal, top, frontside, rotated);
          slicedWorldGeometry->SetSliceNavigationController(this);
          break;

        case Sagittal:
          slicedWorldGeometry = SlicedGeometry3D::New();
          slicedWorldGeometry->InitializePlanes(currentGeometry, PlaneGeometry::Sagittal, top, frontside, rotated);
          slicedWorldGeometry->SetSliceNavigationController(this);
          break;
        default:
          itkExceptionMacro("unknown ViewDirection");
      }

      m_Slice->SetPos(0);
      m_Slice->SetSteps((int)slicedWorldGeometry->GetSlices());

      if ( worldTimeGeometry.IsNull() )
      {
        auto createdTimeGeometry = ProportionalTimeGeometry::New();
        createdTimeGeometry->Initialize( slicedWorldGeometry, 1 );
        m_CreatedWorldGeometry = createdTimeGeometry;
      
        m_Time->SetSteps(0);
        m_Time->SetPos(0);
        m_Time->InvalidateRange();
      }
      else
      {
        m_BlockUpdate = true;
        m_Time->SetSteps(worldTimeGeometry->CountTimeSteps());
        m_Time->SetPos(0);

        const TimeBounds &timeBounds = worldTimeGeometry->GetTimeBounds();
        m_Time->SetRange(timeBounds[0], timeBounds[1]);

        m_BlockUpdate = false;

        const auto currentTemporalPosition = this->GetTime()->GetPos();
        assert( worldTimeGeometry->GetGeometryForTimeStep( currentTemporalPosition ).IsNotNull() );

      if ( dynamic_cast<const mitk::ProportionalTimeGeometry*>( worldTimeGeometry.GetPointer() ) != nullptr )
      {
        const TimePointType minimumTimePoint =
          worldTimeGeometry->TimeStepToTimePoint( currentTemporalPosition );
        
        const TimePointType stepDuration =
          worldTimeGeometry->TimeStepToTimePoint( currentTemporalPosition + 1 ) - minimumTimePoint;

        auto createdTimeGeometry = ProportionalTimeGeometry::New();
        createdTimeGeometry->Initialize( slicedWorldGeometry, worldTimeGeometry->CountTimeSteps() );
        createdTimeGeometry->SetFirstTimePoint( minimumTimePoint );
        createdTimeGeometry->SetStepDuration( stepDuration );

        m_CreatedWorldGeometry = createdTimeGeometry;
      }
      else
      {
        auto createdTimeGeometry = mitk::ArbitraryTimeGeometry::New();
        const TimeStepType numberOfTimeSteps = worldTimeGeometry->CountTimeSteps();
        createdTimeGeometry->ReserveSpaceForGeometries( numberOfTimeSteps );

        for ( TimeStepType i = 0; i < numberOfTimeSteps; ++i )
        {
          const BaseGeometry::Pointer clonedGeometry = slicedWorldGeometry->Clone().GetPointer();
          const auto bounds = worldTimeGeometry->GetTimeBounds( i );
          createdTimeGeometry->AppendNewTimeStep( clonedGeometry,
            bounds[0], bounds[1]);
        }
        createdTimeGeometry->Update();

        m_CreatedWorldGeometry = createdTimeGeometry;
      }
      }
    }

    // unblock update; we may do this now, because if m_BlockUpdate was already
    // true before this method was entered, then we will never come here.
    m_BlockUpdate = false;

    // Send the geometry. Do this even if nothing was changed, because maybe
    // Update() was only called to re-send the old geometry and time/slice data.
    this->SendCreatedWorldGeometry();
    this->SendSlice();
    this->SendTime();

    // Adjust the stepper range of slice stepper according to geometry
    this->AdjustSliceStepperRange();
  }
void
SliceNavigationController::Update(
  SliceNavigationController::ViewDirection viewDirection,
  bool top, bool frontside, bool rotated )
{
  TimeGeometry::ConstPointer worldTimeGeometry = m_InputWorldTimeGeometry;

  if( m_BlockUpdate ||
      ( m_InputWorldTimeGeometry.IsNull() && m_InputWorldGeometry3D.IsNull() ) ||
      ( (worldTimeGeometry.IsNotNull()) && (worldTimeGeometry->CountTimeSteps() == 0) )
    )
  {
    return;
  }

  m_BlockUpdate = true;

  if ( m_InputWorldTimeGeometry.IsNotNull() &&
    m_LastUpdateTime < m_InputWorldTimeGeometry->GetMTime() )
  {
    Modified();
  }
  if ( m_InputWorldGeometry3D.IsNotNull() &&
    m_LastUpdateTime < m_InputWorldGeometry3D->GetMTime() )
  {
    Modified();
  }
  this->SetViewDirection( viewDirection );
  this->SetTop( top );
  this->SetFrontSide( frontside );
  this->SetRotated( rotated );

  if ( m_LastUpdateTime < GetMTime() )
  {
    m_LastUpdateTime = GetMTime();

    // initialize the viewplane
    SlicedGeometry3D::Pointer slicedWorldGeometry = NULL;
    Geometry3D::ConstPointer currentGeometry = NULL;
    if (m_InputWorldTimeGeometry.IsNotNull())
      if (m_InputWorldTimeGeometry->IsValidTimeStep(GetTime()->GetPos()))
        currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(GetTime()->GetPos());
      else
        currentGeometry = m_InputWorldTimeGeometry->GetGeometryForTimeStep(0);
    else
      currentGeometry = m_InputWorldGeometry3D;

    m_CreatedWorldGeometry = NULL;
    switch ( viewDirection )
    {
    case Original:
      if ( worldTimeGeometry.IsNotNull())
      {
        m_CreatedWorldGeometry = worldTimeGeometry->Clone();

        worldTimeGeometry = m_CreatedWorldGeometry.GetPointer();

        slicedWorldGeometry = dynamic_cast< SlicedGeometry3D * >(
          m_CreatedWorldGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() ).GetPointer() );

        if ( slicedWorldGeometry.IsNotNull() )
        {
          break;
        }
      }
      else
      {
        const SlicedGeometry3D *worldSlicedGeometry =
          dynamic_cast< const SlicedGeometry3D * >(
            currentGeometry.GetPointer());

        if ( worldSlicedGeometry != NULL )
        {
          slicedWorldGeometry = static_cast< SlicedGeometry3D * >(
            currentGeometry->Clone().GetPointer());
          break;
        }
      }
      //else: use Axial: no "break" here!!

    case Axial:
      slicedWorldGeometry = SlicedGeometry3D::New();
      slicedWorldGeometry->InitializePlanes(
        currentGeometry, PlaneGeometry::Axial,
        top, frontside, rotated );
      slicedWorldGeometry->SetSliceNavigationController( this );
      break;

    case Frontal:
      slicedWorldGeometry = SlicedGeometry3D::New();
      slicedWorldGeometry->InitializePlanes( currentGeometry,
        PlaneGeometry::Frontal, top, frontside, rotated );
      slicedWorldGeometry->SetSliceNavigationController( this );
      break;

    case Sagittal:
      slicedWorldGeometry = SlicedGeometry3D::New();
      slicedWorldGeometry->InitializePlanes( currentGeometry,
        PlaneGeometry::Sagittal, top, frontside, rotated );
      slicedWorldGeometry->SetSliceNavigationController( this );
      break;
    default:
      itkExceptionMacro("unknown ViewDirection");
    }

    m_Slice->SetPos( 0 );
    m_Slice->SetSteps( (int)slicedWorldGeometry->GetSlices() );

    if ( m_CreatedWorldGeometry.IsNull() )
    {
      // initialize TimeGeometry
      m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
    }
    if ( worldTimeGeometry.IsNull())
    {
      m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
      dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->Initialize(slicedWorldGeometry, 1);
      m_Time->SetSteps( 0 );
      m_Time->SetPos( 0 );
      m_Time->InvalidateRange();
    }
    else
    {
      m_BlockUpdate = true;
      m_Time->SetSteps( worldTimeGeometry->CountTimeSteps() );
      m_Time->SetPos( 0 );

      const TimeBounds &timeBounds = worldTimeGeometry->GetTimeBounds();
      m_Time->SetRange( timeBounds[0], timeBounds[1] );

      m_BlockUpdate = false;

      assert( worldTimeGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() ).IsNotNull() );

      slicedWorldGeometry->SetTimeBounds(
        worldTimeGeometry->GetGeometryForTimeStep( this->GetTime()->GetPos() )->GetTimeBounds() );

      //@todo implement for non-evenly-timed geometry!
      m_CreatedWorldGeometry = ProportionalTimeGeometry::New();
      dynamic_cast<ProportionalTimeGeometry *>(m_CreatedWorldGeometry.GetPointer())->Initialize(slicedWorldGeometry, worldTimeGeometry->CountTimeSteps());
    }
  }

  // unblock update; we may do this now, because if m_BlockUpdate was already
  // true before this method was entered, then we will never come here.
  m_BlockUpdate = false;

  // Send the geometry. Do this even if nothing was changed, because maybe
  // Update() was only called to re-send the old geometry and time/slice data.
  this->SendCreatedWorldGeometry();
  this->SendSlice();
  this->SendTime();

  // Adjust the stepper range of slice stepper according to geometry
  this->AdjustSliceStepperRange();
}