Beispiel #1
0
void mitk::Surface::CalculateBoundingBox()
{
  TimeGeometry *timeGeometry = this->GetTimeGeometry();

  if (timeGeometry->CountTimeSteps() != m_PolyDatas.size())
    mitkThrow() << "Number of geometry time steps is inconsistent with number of poly data pointers.";

  for (unsigned int i = 0; i < m_PolyDatas.size(); ++i)
  {
    vtkPolyData *polyData = m_PolyDatas[i].GetPointer();
    double bounds[6] = {0};

    if (polyData != nullptr && polyData->GetNumberOfPoints() > 0)
    {
      //      polyData->Update(); //VTK6_TODO vtk pipeline
      polyData->ComputeBounds();
      polyData->GetBounds(bounds);
    }

    BaseGeometry::Pointer geometry = timeGeometry->GetGeometryForTimeStep(i);

    if (geometry.IsNull())
      mitkThrow() << "Time-sliced geometry is invalid (equals nullptr).";

    geometry->SetFloatBounds(bounds);
  }

  timeGeometry->Update();
  m_CalculateBoundingBox = false;
}
void mitk::ProportionalTimeGeometry::ReplaceTimeStepGeometries(const BaseGeometry* geometry)
{
  for (TimeStepType currentStep = 0; currentStep < this->CountTimeSteps(); ++currentStep)
  {
    BaseGeometry::Pointer clonedGeometry = geometry->Clone();
    this->SetTimeStepGeometry(clonedGeometry.GetPointer(), currentStep);
  }
}
void mitk::SurfaceDeformationDataInteractor3D::ColorizeSurface(vtkPolyData* polyData, int timeStep, const Point3D &pickedPoint, int mode, double scalar)
{
    if (polyData == NULL)
        return;

    vtkPoints* points = polyData->GetPoints();
    vtkPointData* pointData = polyData->GetPointData();
    if ( pointData == NULL )
        return;

    vtkDataArray* scalars = pointData->GetScalars();
    if (scalars == NULL)
        return;

    if (mode == COLORIZATION_GAUSS)
    {
        // Get picked point and transform into local coordinates
        Point3D localPickedPoint;
        BaseGeometry::Pointer geometry = this->GetDataNode()->GetData()->GetGeometry(timeStep);
        geometry->WorldToIndex( pickedPoint, localPickedPoint );

        Vector3D v1 = localPickedPoint.GetVectorFromOrigin();

        vtkDataArray* normal = polyData->GetPointData()->GetVectors("planeNormal");
        if (normal != NULL)
        {
            m_ObjectNormal[0] = normal->GetComponent(0, 0);
            m_ObjectNormal[1] = normal->GetComponent(0, 1);
            m_ObjectNormal[2] = normal->GetComponent(0, 2);
        }

        double denom = m_GaussSigma * m_GaussSigma * 2;
        for (vtkIdType i = 0; i < points->GetNumberOfPoints(); ++i)
        {
            // Get original point
            double* point = points->GetPoint(i);
            Vector3D v0;
            v0[0] = point[0];
            v0[1] = point[1];
            v0[2] = point[2];

            // Calculate distance of this point from line through picked point
            double d = itk::CrossProduct(m_ObjectNormal, (v1 - v0)).GetNorm();
            double t = exp(- d * d / denom);

            scalars->SetComponent(i, 0, t);
        }
    }
    else if (mode == COLORIZATION_CONSTANT)
    {
        for (vtkIdType i = 0; i < pointData->GetNumberOfTuples(); ++i)
        {
            scalars->SetComponent(i, 0, scalar);
        }
    }
    polyData->Modified();
    pointData->Update();
}
  void ItkImageIO::Write()
  {
    const mitk::Image *image = dynamic_cast<const mitk::Image *>(this->GetInput());

    if (image == NULL)
    {
      mitkThrow() << "Cannot write non-image data";
    }

    // Switch the current locale to "C"
    LocaleSwitch localeSwitch("C");

    // Clone the image geometry, because we might have to change it
    // for writing purposes
    BaseGeometry::Pointer geometry = image->GetGeometry()->Clone();

    // Check if geometry information will be lost
    if (image->GetDimension() == 2 && !geometry->Is2DConvertable())
    {
      MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might "
                   "consider using Convert2Dto3DImageFilter before saving.";

      // set matrix to identity
      mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
      affTrans->SetIdentity();
      mitk::Vector3D spacing = geometry->GetSpacing();
      mitk::Point3D origin = geometry->GetOrigin();
      geometry->SetIndexToWorldTransform(affTrans);
      geometry->SetSpacing(spacing);
      geometry->SetOrigin(origin);
    }

    LocalFile localFile(this);
    const std::string path = localFile.GetFileName();

    MITK_INFO << "Writing image: " << path << std::endl;

    try
    {
      // Implementation of writer using itkImageIO directly. This skips the use
      // of templated itkImageFileWriter, which saves the multiplexing on MITK side.

      const unsigned int dimension = image->GetDimension();
      const unsigned int *const dimensions = image->GetDimensions();
      const mitk::PixelType pixelType = image->GetPixelType();
      const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
      const mitk::Point3D mitkOrigin = geometry->GetOrigin();

      // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
      // though they are not supported in MITK
      itk::Vector<double, 4u> spacing4D;
      spacing4D[0] = mitkSpacing[0];
      spacing4D[1] = mitkSpacing[1];
      spacing4D[2] = mitkSpacing[2];
      spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here

      itk::Vector<double, 4u> origin4D;
      origin4D[0] = mitkOrigin[0];
      origin4D[1] = mitkOrigin[1];
      origin4D[2] = mitkOrigin[2];
      origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here

      // Set the necessary information for imageIO
      m_ImageIO->SetNumberOfDimensions(dimension);
      m_ImageIO->SetPixelType(pixelType.GetPixelType());
      m_ImageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
                                    static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
                                    itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
      m_ImageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents());

      itk::ImageIORegion ioRegion(dimension);

      for (unsigned int i = 0; i < dimension; i++)
      {
        m_ImageIO->SetDimensions(i, dimensions[i]);
        m_ImageIO->SetSpacing(i, spacing4D[i]);
        m_ImageIO->SetOrigin(i, origin4D[i]);

        mitk::Vector3D mitkDirection;
        mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
        itk::Vector<double, 4u> direction4D;
        direction4D[0] = mitkDirection[0];
        direction4D[1] = mitkDirection[1];
        direction4D[2] = mitkDirection[2];

        // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
        // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
        if (i == 3)
        {
          direction4D[3] = 1; // homogenous component
        }
        else
        {
          direction4D[3] = 0;
        }
        vnl_vector<double> axisDirection(dimension);
        for (unsigned int j = 0; j < dimension; j++)
        {
          axisDirection[j] = direction4D[j] / spacing4D[i];
        }
        m_ImageIO->SetDirection(i, axisDirection);

        ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i));
        ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i));
      }

      // use compression if available
      m_ImageIO->UseCompressionOn();

      m_ImageIO->SetIORegion(ioRegion);
      m_ImageIO->SetFileName(path);

      // Handle time geometry
      const ArbitraryTimeGeometry *arbitraryTG = dynamic_cast<const ArbitraryTimeGeometry *>(image->GetTimeGeometry());
      if (arbitraryTG)
      {
        itk::EncapsulateMetaData<std::string>(m_ImageIO->GetMetaDataDictionary(),
                                              PROPERTY_KEY_TIMEGEOMETRY_TYPE,
                                              ArbitraryTimeGeometry::GetStaticNameOfClass());

        std::stringstream stream;
        stream << arbitraryTG->GetTimeBounds(0)[0];
        for (TimeStepType pos = 0; pos < arbitraryTG->CountTimeSteps(); ++pos)
        {
          stream << " " << arbitraryTG->GetTimeBounds(pos)[1];
        }
        std::string data = stream.str();

        itk::EncapsulateMetaData<std::string>(
          m_ImageIO->GetMetaDataDictionary(), PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS, data);
      }

      // Handle properties
      mitk::PropertyList::Pointer imagePropertyList = image->GetPropertyList();

      for (const auto &property : *imagePropertyList->GetMap())
      {
        IPropertyPersistence::InfoResultType infoList =
          mitk::CoreServices::GetPropertyPersistence()->GetInfo(property.first, GetMimeType()->GetName(), true);

        if (infoList.empty())
        {
          continue;
        }

        std::string value = infoList.front()->GetSerializationFunction()(property.second);

        if (value == mitk::BaseProperty::VALUE_CANNOT_BE_CONVERTED_TO_STRING)
        {
          continue;
        }

        std::string key = infoList.front()->GetKey();

        itk::EncapsulateMetaData<std::string>(m_ImageIO->GetMetaDataDictionary(), key, value);
      }

      ImageReadAccessor imageAccess(image);
      m_ImageIO->Write(imageAccess.GetData());
    }
    catch (const std::exception &e)
    {
      mitkThrow() << e.what();
    }
  }
Beispiel #5
0
void LabelSetImageIO::Write()
{
  ValidateOutputLocation();

  const LabelSetImage* input = static_cast<const LabelSetImage*>(this->GetInput());

  const std::string& locale = "C";
  const std::string& currLocale = setlocale( LC_ALL, NULL );

  if ( locale.compare(currLocale)!=0 )
  {
    try
    {
      setlocale(LC_ALL, locale.c_str());
    }
    catch(...)
    {
      mitkThrow() << "Could not set locale " << currLocale;
    }
  }

  mitk::Image::Pointer inputVector = mitk::LabelSetImageConverter::ConvertLabelSetImageToImage(input);

  // image write
  if ( inputVector.IsNull() )
  {
    mitkThrow() << "Cannot write non-image data";
  }

  itk::NrrdImageIO::Pointer nrrdImageIo = itk::NrrdImageIO::New();

  // Clone the image geometry, because we might have to change it
  // for writing purposes
  BaseGeometry::Pointer geometry = inputVector->GetGeometry()->Clone();

  // Check if geometry information will be lost
  if (inputVector->GetDimension() == 2 &&
    !geometry->Is2DConvertable())
  {
    MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might consider using Convert2Dto3DImageFilter before saving.";

    // set matrix to identity
    mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
    affTrans->SetIdentity();
    mitk::Vector3D spacing = geometry->GetSpacing();
    mitk::Point3D origin = geometry->GetOrigin();
    geometry->SetIndexToWorldTransform(affTrans);
    geometry->SetSpacing(spacing);
    geometry->SetOrigin(origin);
  }

  LocalFile localFile(this);
  const std::string path = localFile.GetFileName();

  MITK_INFO << "Writing image: " << path << std::endl;

  try
  {
    // Implementation of writer using itkImageIO directly. This skips the use
    // of templated itkImageFileWriter, which saves the multiplexing on MITK side.

    const unsigned int dimension = inputVector->GetDimension();
    const unsigned int* const dimensions = inputVector->GetDimensions();
    const mitk::PixelType pixelType = inputVector->GetPixelType();
    const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
    const mitk::Point3D mitkOrigin = geometry->GetOrigin();

    // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
    // though they are not supported in MITK
    itk::Vector<double, 4u> spacing4D;
    spacing4D[0] = mitkSpacing[0];
    spacing4D[1] = mitkSpacing[1];
    spacing4D[2] = mitkSpacing[2];
    spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here

    itk::Vector<double, 4u> origin4D;
    origin4D[0] = mitkOrigin[0];
    origin4D[1] = mitkOrigin[1];
    origin4D[2] = mitkOrigin[2];
    origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here

    // Set the necessary information for imageIO
    nrrdImageIo->SetNumberOfDimensions(dimension);
    nrrdImageIo->SetPixelType(pixelType.GetPixelType());
    nrrdImageIo->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
      static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
      itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
    nrrdImageIo->SetNumberOfComponents(pixelType.GetNumberOfComponents());

    itk::ImageIORegion ioRegion(dimension);

    for (unsigned int i = 0; i < dimension; i++)
    {
      nrrdImageIo->SetDimensions(i, dimensions[i]);
      nrrdImageIo->SetSpacing(i, spacing4D[i]);
      nrrdImageIo->SetOrigin(i, origin4D[i]);

      mitk::Vector3D mitkDirection;
      mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
      itk::Vector<double, 4u> direction4D;
      direction4D[0] = mitkDirection[0];
      direction4D[1] = mitkDirection[1];
      direction4D[2] = mitkDirection[2];

      // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
      // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
      if (i == 3)
      {
        direction4D[3] = 1; // homogenous component
      }
      else
      {
        direction4D[3] = 0;
      }
      vnl_vector<double> axisDirection(dimension);
      for (unsigned int j = 0; j < dimension; j++)
      {
        axisDirection[j] = direction4D[j] / spacing4D[i];
      }
      nrrdImageIo->SetDirection(i, axisDirection);

      ioRegion.SetSize(i, inputVector->GetLargestPossibleRegion().GetSize(i));
      ioRegion.SetIndex(i, inputVector->GetLargestPossibleRegion().GetIndex(i));
    }

    //use compression if available
    nrrdImageIo->UseCompressionOn();

    nrrdImageIo->SetIORegion(ioRegion);
    nrrdImageIo->SetFileName(path);

    // label set specific meta data
    char keybuffer[512];
    char valbuffer[512];

    sprintf(keybuffer, "modality");
    sprintf(valbuffer, "org.mitk.image.multilabel");
    itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));

    sprintf(keybuffer, "layers");
    sprintf(valbuffer, "%1d", input->GetNumberOfLayers());
    itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));

    for (unsigned int layerIdx = 0; layerIdx<input->GetNumberOfLayers(); layerIdx++)
    {
      sprintf(keybuffer, "layer_%03d", layerIdx); // layer idx
      sprintf(valbuffer, "%1d", input->GetNumberOfLabels(layerIdx)); // number of labels for the layer
      itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), std::string(valbuffer));

      mitk::LabelSet::LabelContainerConstIteratorType iter = input->GetLabelSet(layerIdx)->IteratorConstBegin();
      unsigned int count(0);
      while (iter != input->GetLabelSet(layerIdx)->IteratorConstEnd())
      {
        std::auto_ptr<TiXmlDocument> document;
        document.reset(new TiXmlDocument());

        TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", ""); // TODO what to write here? encoding? etc....
        document->LinkEndChild(decl);
        TiXmlElement * labelElem = GetLabelAsTiXmlElement(iter->second);
        document->LinkEndChild(labelElem);
        TiXmlPrinter printer;
        printer.SetIndent("");
        printer.SetLineBreak("");

        document->Accept(&printer);

        sprintf(keybuffer, "org.mitk.label_%03u_%05u", layerIdx, count);
        itk::EncapsulateMetaData<std::string>(nrrdImageIo->GetMetaDataDictionary(), std::string(keybuffer), printer.Str());
        ++iter;
        ++count;
      }
    }
    // end label set specific meta data

    ImageReadAccessor imageAccess(inputVector);
    nrrdImageIo->Write(imageAccess.GetData());
  }
  catch (const std::exception& e)
  {
    mitkThrow() << e.what();
  }
  // end image write

  try
  {
    setlocale(LC_ALL, currLocale.c_str());
  }
  catch(...)
  {
    mitkThrow() << "Could not reset locale " << currLocale;
  }
}
Beispiel #6
0
void mitk::Image::Initialize(const mitk::PixelType& type, const mitk::TimeGeometry& geometry, unsigned int channels, int tDim )
{
  unsigned int dimensions[5];
  dimensions[0] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(0)+0.5);
  dimensions[1] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(1)+0.5);
  dimensions[2] = (unsigned int)(geometry.GetGeometryForTimeStep(0)->GetExtent(2)+0.5);
  dimensions[3] = (tDim > 0) ? tDim : geometry.CountTimeSteps();
  dimensions[4] = 0;

  unsigned int dimension = 2;
  if ( dimensions[2] > 1 )
    dimension = 3;
  if ( dimensions[3] > 1 )
    dimension = 4;

  Initialize( type, dimension, dimensions, channels );
  if (geometry.CountTimeSteps() > 1)
  {
    TimeGeometry::Pointer cloned = geometry.Clone();
    SetTimeGeometry(cloned.GetPointer());

    // make sure the image geometry flag is properly set for all time steps
    for (TimeStepType step = 0; step < cloned->CountTimeSteps(); ++step)
    {

      if( ! cloned->GetGeometryCloneForTimeStep(step)->GetImageGeometry() )
      {
        MITK_WARN("Image.3DnT.Initialize") << " Attempt to initialize an image with a non-image geometry. Re-interpretting the initialization geometry for timestep " << step
                                           << " as image geometry, the original geometry remains unchanged.";
        cloned->GetGeometryForTimeStep(step)->ImageGeometryOn();
      }
    }
  }
  else
  {
    // make sure the image geometry coming from outside has proper value of the image geometry flag
    BaseGeometry::Pointer cloned = geometry.GetGeometryCloneForTimeStep(0)->Clone();
    if( ! cloned->GetImageGeometry() )
    {
      MITK_WARN("Image.Initialize") << " Attempt to initialize an image with a non-image geometry. Re-interpretting the initialization geometry as image geometry, the original geometry remains unchanged.";
      cloned->ImageGeometryOn();

    }

    Superclass::SetGeometry( cloned );
  }
/* //Old //TODO_GOETZ Really necessary?
  mitk::BoundingBox::BoundsArrayType bounds = geometry.GetBoundingBoxInWorld()->GetBounds();
  if( (bounds[0] != 0.0) || (bounds[2] != 0.0) || (bounds[4] != 0.0) )
  {
    SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);

    mitk::Point3D origin; origin.Fill(0.0);
    slicedGeometry->IndexToWorld(origin, origin);

    bounds[1]-=bounds[0]; bounds[3]-=bounds[2]; bounds[5]-=bounds[4];
    bounds[0] = 0.0;      bounds[2] = 0.0;      bounds[4] = 0.0;
    this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension );
    slicedGeometry->SetBounds(bounds);
    slicedGeometry->GetIndexToWorldTransform()->SetOffset(origin.GetVnlVector().data_block());

    ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
    timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
    SetTimeGeometry(timeGeometry);
  }*/
}
bool AffineInteractor3D
::ExecuteAction( Action *action, StateEvent const *stateEvent )
{
  bool ok = false;

  // Get data object
  BaseData *data = m_DataNode->GetData();
  if ( data == NULL )
  {
    MITK_ERROR << "No data object present!";
    return ok;
  }

  // Get Event and extract renderer
  const Event *event = stateEvent->GetEvent();
  BaseRenderer *renderer = NULL;
  vtkRenderWindow *renderWindow = NULL;
  vtkRenderWindowInteractor *renderWindowInteractor = NULL;
  vtkRenderer *currentVtkRenderer = NULL;
  vtkCamera *camera = NULL;

  if ( event != NULL )
  {
    renderer = event->GetSender();
    if ( renderer != NULL )
    {
      renderWindow = renderer->GetRenderWindow();
      if ( renderWindow != NULL )
      {
        renderWindowInteractor = renderWindow->GetInteractor();
        if ( renderWindowInteractor != NULL )
        {
          currentVtkRenderer = renderWindowInteractor
            ->GetInteractorStyle()->GetCurrentRenderer();
          if ( currentVtkRenderer != NULL )
          {
            camera = currentVtkRenderer->GetActiveCamera();
          }
        }
      }
    }
  }

  // Check if we have a DisplayPositionEvent
  const DisplayPositionEvent *dpe =
    dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
  if ( dpe != NULL )
  {
    m_CurrentPickedPoint = dpe->GetWorldPosition();
    m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition();
  }

  // Get the timestep to also support 3D+t
  int timeStep = 0;
  ScalarType timeInMS = 0.0;
  if ( renderer != NULL )
  {
    timeStep = renderer->GetTimeStep( data );
    timeInMS = renderer->GetTime();
  }

  // If data is an mitk::Surface, extract it
  Surface *surface = dynamic_cast< Surface * >( data );
  vtkPolyData *polyData = NULL;
  if ( surface != NULL )
  {
    polyData = surface->GetVtkPolyData( timeStep );

    // Extract surface normal from surface (if existent, otherwise use default)
    vtkPointData *pointData = polyData->GetPointData();
    if ( pointData != NULL )
    {
      vtkDataArray *normal = polyData->GetPointData()->GetVectors( "planeNormal" );
      if ( normal != NULL )
      {
        m_ObjectNormal[0] = normal->GetComponent( 0, 0 );
        m_ObjectNormal[1] = normal->GetComponent( 0, 1 );
        m_ObjectNormal[2] = normal->GetComponent( 0, 2 );
      }
    }
  }

  // Get geometry object
  m_Geometry = data->GetGeometry( timeStep );


  // Make sure that the data (if time-resolved) has enough entries;
  // if not, create the required extra ones (empty)
  data->Expand( timeStep+1 );


  switch (action->GetActionId())
  {
  case AcDONOTHING:
    ok = true;
    break;


  case AcCHECKOBJECT:
    {
      // Re-enable VTK interactor (may have been disabled previously)
      if ( renderWindowInteractor != NULL )
      {
        renderWindowInteractor->Enable();
      }

      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      // Check if an object is present at the current mouse position
      DataNode *pickedNode = dpe->GetPickedObjectNode();
      StateEvent *newStateEvent;
      if ( pickedNode == m_DataNode )
      {
        // Yes: object will be selected
        newStateEvent = new StateEvent( EIDYES );
      }
      else
      {
        // No: back to start state
        newStateEvent = new StateEvent( EIDNO );
      }

      this->HandleEvent( newStateEvent );

      ok = true;
      break;
    }

  case AcDESELECTOBJECT:
    {
      // Color object white
      m_DataNode->SetColor( 1.0, 1.0, 1.0 );
      RenderingManager::GetInstance()->RequestUpdateAll();

      // Colorize surface / wireframe as inactive
      this->ColorizeSurface( polyData,
        m_CurrentPickedPoint, -1.0 );

      ok = true;
      break;
    }

  case AcSELECTPICKEDOBJECT:
    {
      // Color object red
      m_DataNode->SetColor( 1.0, 0.0, 0.0 );
      RenderingManager::GetInstance()->RequestUpdateAll();

      // Colorize surface / wireframe dependend on distance from picked point
      this->ColorizeSurface( polyData,
        m_CurrentPickedPoint, 0.0 );

      ok = true;
      break;
    }

  case AcINITMOVE:
    {
      // Disable VTK interactor until MITK interaction has been completed
      if ( renderWindowInteractor != NULL )
      {
        renderWindowInteractor->Disable();
      }

      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      //DataNode *pickedNode = dpe->GetPickedObjectNode();

      m_InitialPickedPoint = m_CurrentPickedPoint;
      m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint;

      if ( currentVtkRenderer != NULL )
      {
        vtkInteractorObserver::ComputeDisplayToWorld(
          currentVtkRenderer,
          m_InitialPickedDisplayPoint[0],
          m_InitialPickedDisplayPoint[1],
          0.0, //m_InitialInteractionPickedPoint[2],
          m_InitialPickedPointWorld );
      }


      // Make deep copy of current Geometry3D of the plane
      data->UpdateOutputInformation(); // make sure that the Geometry is up-to-date
      m_OriginalGeometry = static_cast< BaseGeometry * >(
        data->GetGeometry( timeStep )->Clone().GetPointer() );

      ok = true;
      break;
    }

  case AcMOVE:
    {
      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      if ( currentVtkRenderer != NULL )
      {
        vtkInteractorObserver::ComputeDisplayToWorld(
          currentVtkRenderer,
          m_CurrentPickedDisplayPoint[0],
          m_CurrentPickedDisplayPoint[1],
          0.0, //m_InitialInteractionPickedPoint[2],
          m_CurrentPickedPointWorld );
      }


      Vector3D interactionMove;
      interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0];
      interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1];
      interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2];

      if ( m_InteractionMode == INTERACTION_MODE_TRANSLATION )
      {
        Point3D origin = m_OriginalGeometry->GetOrigin();

        Vector3D transformedObjectNormal;
        data->GetGeometry( timeStep )->IndexToWorld(
          m_ObjectNormal, transformedObjectNormal );

        data->GetGeometry( timeStep )->SetOrigin(
          origin + transformedObjectNormal * (interactionMove * transformedObjectNormal) );
      }
      else if ( m_InteractionMode == INTERACTION_MODE_ROTATION )
      {
        if ( camera )
        {
          double vpn[3];
          camera->GetViewPlaneNormal( vpn );

          Vector3D viewPlaneNormal;
          viewPlaneNormal[0] = vpn[0];
          viewPlaneNormal[1] = vpn[1];
          viewPlaneNormal[2] = vpn[2];

          Vector3D rotationAxis =
            itk::CrossProduct( viewPlaneNormal, interactionMove );
          rotationAxis.Normalize();

          int *size = currentVtkRenderer->GetSize();
          double l2 =
            (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) *
            (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) +
            (m_CurrentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) *
            (m_CurrentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]);

          double rotationAngle = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));

          // Use center of data bounding box as center of rotation
          Point3D rotationCenter = m_OriginalGeometry->GetCenter();;

          // Reset current Geometry3D to original state (pre-interaction) and
          // apply rotation
          RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle );
          BaseGeometry::Pointer newGeometry = static_cast< BaseGeometry * >(
            m_OriginalGeometry->Clone().GetPointer() );
          newGeometry->ExecuteOperation( &op );
          data->SetClonedGeometry(newGeometry, timeStep);
        }
      }

      RenderingManager::GetInstance()->RequestUpdateAll();
      ok = true;
      break;
    }



  default:
    return Superclass::ExecuteAction( action, stateEvent );
  }

  return ok;
}
Beispiel #8
0
void ItkImageIO::Write()
{
  const mitk::Image* image = dynamic_cast<const mitk::Image*>(this->GetInput());

  if (image == NULL)
  {
    mitkThrow() << "Cannot write non-image data";
  }

  struct LocaleSwitch
  {
    LocaleSwitch(const std::string& newLocale)
      : m_OldLocale(std::setlocale(LC_ALL, NULL))
      , m_NewLocale(newLocale)
    {
      if (m_OldLocale == NULL)
      {
        m_OldLocale = "";
      }
      else if (m_NewLocale != m_OldLocale)
      {
        // set the locale
        if (std::setlocale(LC_ALL, m_NewLocale.c_str()) == NULL)
        {
          MITK_INFO << "Could not set locale " << m_NewLocale;
          m_OldLocale = NULL;
        }
      }
    }

    ~LocaleSwitch()
    {
      if (m_OldLocale != NULL && std::setlocale(LC_ALL, m_OldLocale) == NULL)
      {
        MITK_INFO << "Could not reset locale " << m_OldLocale;
      }
    }

  private:
    const char* m_OldLocale;
    const std::string m_NewLocale;
  };

  // Switch the current locale to "C"
  LocaleSwitch localeSwitch("C");

  // Clone the image geometry, because we might have to change it
  // for writing purposes
  BaseGeometry::Pointer geometry = image->GetGeometry()->Clone();

  // Check if geometry information will be lost
  if (image->GetDimension() == 2 &&
      !geometry->Is2DConvertable())
  {
    MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might consider using Convert2Dto3DImageFilter before saving.";

    // set matrix to identity
    mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
    affTrans->SetIdentity();
    mitk::Vector3D spacing = geometry->GetSpacing();
    mitk::Point3D origin = geometry->GetOrigin();
    geometry->SetIndexToWorldTransform(affTrans);
    geometry->SetSpacing(spacing);
    geometry->SetOrigin(origin);
  }

  LocalFile localFile(this);
  const std::string path = localFile.GetFileName();

  MITK_INFO << "Writing image: " << path << std::endl;

  try
  {
    // Implementation of writer using itkImageIO directly. This skips the use
    // of templated itkImageFileWriter, which saves the multiplexing on MITK side.

    const unsigned int dimension = image->GetDimension();
    const unsigned int* const dimensions = image->GetDimensions();
    const mitk::PixelType pixelType = image->GetPixelType();
    const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
    const mitk::Point3D mitkOrigin = geometry->GetOrigin();

    // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
    // though they are not supported in MITK
    itk::Vector<double, 4u> spacing4D;
    spacing4D[0] = mitkSpacing[0];
    spacing4D[1] = mitkSpacing[1];
    spacing4D[2] = mitkSpacing[2];
    spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here

    itk::Vector<double, 4u> origin4D;
    origin4D[0] = mitkOrigin[0];
    origin4D[1] = mitkOrigin[1];
    origin4D[2] = mitkOrigin[2];
    origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here

    // Set the necessary information for imageIO
    m_ImageIO->SetNumberOfDimensions(dimension);
    m_ImageIO->SetPixelType(pixelType.GetPixelType());
    m_ImageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
                                  static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
                                  itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
    m_ImageIO->SetNumberOfComponents( pixelType.GetNumberOfComponents() );

    itk::ImageIORegion ioRegion( dimension );

    for(unsigned int i = 0; i < dimension; i++)
    {
      m_ImageIO->SetDimensions(i, dimensions[i]);
      m_ImageIO->SetSpacing(i, spacing4D[i]);
      m_ImageIO->SetOrigin(i, origin4D[i]);

      mitk::Vector3D mitkDirection;
      mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
      itk::Vector<double, 4u> direction4D;
      direction4D[0] = mitkDirection[0];
      direction4D[1] = mitkDirection[1];
      direction4D[2] = mitkDirection[2];

      // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
      // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
      if (i == 3)
      {
        direction4D[3] = 1; // homogenous component
      }
      else
      {
        direction4D[3] = 0;
      }
      vnl_vector<double> axisDirection(dimension);
      for(unsigned int j = 0; j < dimension; j++)
      {
        axisDirection[j] = direction4D[j] / spacing4D[i];
      }
      m_ImageIO->SetDirection(i, axisDirection);

      ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i));
      ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i));
    }

    //use compression if available
    m_ImageIO->UseCompressionOn();

    m_ImageIO->SetIORegion(ioRegion);
    m_ImageIO->SetFileName(path);

    // ***** Remove const_cast after bug 17952 is fixed ****
    ImageReadAccessor imageAccess(const_cast<mitk::Image*>(image));
    m_ImageIO->Write(imageAccess.GetData());
  }
  catch (const std::exception& e)
  {
    mitkThrow() << e.what();
  }
}
void mitk::SurfaceStampImageFilter::SurfaceStamp(int time)
{
  mitk::Image::Pointer inputImage = this->GetInput();

  const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry();
  const mitk::TimeGeometry *imageTimeGeometry = inputImage->GetTimeGeometry();

  // Convert time step from image time-frame to surface time-frame
  mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time);
  mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint);

  vtkPolyData *polydata = m_Surface->GetVtkPolyData(surfaceTimeStep);
  if (!polydata)
    mitkThrow() << "Polydata is null.";

  vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformFilter->SetInputData(polydata);
  //  transformFilter->ReleaseDataFlagOn();

  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
  BaseGeometry::Pointer geometry = surfaceTimeGeometry->GetGeometryForTimeStep(surfaceTimeStep);

  transform->PostMultiply();
  transform->Concatenate(geometry->GetVtkTransform()->GetMatrix());
  // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below.
  BaseGeometry::Pointer imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time);

  transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse());
  transformFilter->SetTransform(transform);
  transformFilter->Update();

  polydata = transformFilter->GetOutput();

  if (!polydata || !polydata->GetNumberOfPoints())
    mitkThrow() << "Polydata retrieved from transformation is null or has no points.";

  MeshType::Pointer mesh = MeshType::New();
  mesh->SetCellsAllocationMethod(MeshType::CellsAllocatedDynamicallyCellByCell);
  unsigned int numberOfPoints = polydata->GetNumberOfPoints();
  mesh->GetPoints()->Reserve(numberOfPoints);

  vtkPoints *points = polydata->GetPoints();

  MeshType::PointType point;
  for (unsigned int i = 0; i < numberOfPoints; i++)
  {
    double *aux = points->GetPoint(i);
    point[0] = aux[0];
    point[1] = aux[1];
    point[2] = aux[2];
    mesh->SetPoint(i, point);
  }

  // Load the polygons into the itk::Mesh
  typedef MeshType::CellAutoPointer CellAutoPointerType;
  typedef MeshType::CellType CellType;
  typedef itk::TriangleCell<CellType> TriangleCellType;
  typedef MeshType::PointIdentifier PointIdentifierType;
  typedef MeshType::CellIdentifier CellIdentifierType;

  // Read the number of polygons
  CellIdentifierType numberOfPolygons = 0;
  numberOfPolygons = polydata->GetNumberOfPolys();

  PointIdentifierType numberOfCellPoints = 3;
  CellIdentifierType i = 0;

  for (i = 0; i < numberOfPolygons; i++)
  {
    vtkIdList *cellIds;
    vtkCell *vcell = polydata->GetCell(i);
    cellIds = vcell->GetPointIds();

    CellAutoPointerType cell;
    auto *triangleCell = new TriangleCellType;
    PointIdentifierType k;
    for (k = 0; k < numberOfCellPoints; k++)
    {
      triangleCell->SetPointId(k, cellIds->GetId(k));
    }

    cell.TakeOwnership(triangleCell);
    mesh->SetCell(i, cell);
  }

  if (!mesh->GetNumberOfPoints())
    mitkThrow() << "Generated itk mesh is empty.";

  if (m_MakeOutputBinary)
  {
    this->SurfaceStampBinaryOutputProcessing(mesh);
  }
  else
  {
    AccessFixedDimensionByItk_1(inputImage, SurfaceStampProcessing, 3, mesh);
  }
}
void mitk::SurfaceDeformationDataInteractor3D::DeformObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
    const InteractionPositionEvent* positionEvent = dynamic_cast<const InteractionPositionEvent*>(interactionEvent);
    if(positionEvent == NULL)
        return;

    int timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData());
    vtkPolyData* polyData = m_Surface->GetVtkPolyData(timeStep);
    BaseGeometry::Pointer geometry = this->GetDataNode()->GetData()->GetGeometry(timeStep);

    double currentWorldPoint[4];
    mitk::Point2D currentDisplayPoint = positionEvent->GetPointerPositionOnScreen();
    vtkInteractorObserver::ComputeDisplayToWorld(
        interactionEvent->GetSender()->GetVtkRenderer(),
        currentDisplayPoint[0],
        currentDisplayPoint[1],
        0.0, //m_InitialInteractionPickedPoint[2],
        currentWorldPoint);

    // Calculate mouse move in 3D space
    Vector3D interactionMove;
    interactionMove[0] = currentWorldPoint[0] - m_InitialPickedWorldPoint[0];
    interactionMove[1] = currentWorldPoint[1] - m_InitialPickedWorldPoint[1];
    interactionMove[2] = currentWorldPoint[2] - m_InitialPickedWorldPoint[2];

    // Transform mouse move into geometry space
    this->GetDataNode()->GetData()->UpdateOutputInformation();// make sure that the Geometry is up-to-date
    Vector3D interactionMoveIndex;
    geometry->WorldToIndex(interactionMove, interactionMoveIndex);

    // Get picked point and transform into local coordinates
    Point3D pickedPoint;
    geometry->WorldToIndex(m_InitialPickedPoint, pickedPoint);

    Vector3D v1 = pickedPoint.GetVectorFromOrigin();

    vtkDataArray* normal = polyData->GetPointData()->GetVectors("planeNormal");
    if (normal != NULL)
    {
        m_ObjectNormal[0] = normal->GetComponent(0, 0);
        m_ObjectNormal[1] = normal->GetComponent(0, 1);
        m_ObjectNormal[2] = normal->GetComponent(0, 2);
    }

    Vector3D v2 = m_ObjectNormal * (interactionMoveIndex * m_ObjectNormal);

    vtkPoints* originalPoints = m_OriginalPolyData->GetPoints();
    vtkPoints* deformedPoints = polyData->GetPoints();

    double denom = m_GaussSigma * m_GaussSigma * 2;
    double point[3];
    for (vtkIdType i = 0; i < deformedPoints->GetNumberOfPoints(); ++i)
    {
        // Get original point
        double* originalPoint = originalPoints->GetPoint( i );

        Vector3D v0;
        v0[0] = originalPoint[0];
        v0[1] = originalPoint[1];
        v0[2] = originalPoint[2];

        // Calculate distance of this point from line through picked point
        double d = itk::CrossProduct(m_ObjectNormal, (v1 - v0)).GetNorm();

        Vector3D t = v2 * exp(- d * d / denom);

        point[0] = originalPoint[0] + t[0];
        point[1] = originalPoint[1] + t[1];
        point[2] = originalPoint[2] + t[2];
        deformedPoints->SetPoint(i, point);
    }

    // Make sure that surface is colorized at initial picked position as long as we are in deformation state
    m_SurfaceColorizationCenter = m_InitialPickedPoint;

    polyData->Modified();
    m_Surface->Modified();

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
}