void mitk::AffineImageCropperInteractor::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return;

  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
  if(currentPickedDisplayPoint.EuclideanDistanceTo(m_InitialPickedDisplayPoint) < 1)
    return;

  vtkRenderer* currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();

  if ( currentVtkRenderer &&  currentVtkRenderer->GetActiveCamera())
  {
    double vpn[3];
    currentVtkRenderer->GetActiveCamera()->GetViewPlaneNormal( vpn );

    Vector3D rotationAxis;
    rotationAxis[0] = vpn[0];
    rotationAxis[1] = vpn[1];
    rotationAxis[2] = vpn[2];
    rotationAxis.Normalize();

    Vector2D move = currentPickedDisplayPoint - m_InitialPickedDisplayPoint;

    double rotationAngle = -57.3 * atan(move[0]/move[1]);
    if(move[1]<0) rotationAngle +=180;

    // Use center of data bounding box as center of rotation
    Point3D rotationCenter = m_OriginalGeometry->GetCenter();
    if(positionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D)
      rotationCenter = m_InitialPickedPoint;

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

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
  }
}
bool ShowSegmentationAsSmoothedSurface::ThreadedUpdateFunction()
{
  Image::Pointer image;
  GetPointerParameter("Input", image);

  float smoothing;
  GetParameter("Smoothing", smoothing);

  float decimation;
  GetParameter("Decimation", decimation);

  float closing;
  GetParameter("Closing", closing);

  int timeNr = 0;
  GetParameter("TimeNr", timeNr);

  if (image->GetDimension() == 4)
    MITK_INFO << "CREATING SMOOTHED POLYGON MODEL (t = " << timeNr << ')';
  else
    MITK_INFO << "CREATING SMOOTHED POLYGON MODEL";

  MITK_INFO << "  Smoothing  = " << smoothing;
  MITK_INFO << "  Decimation = " << decimation;
  MITK_INFO << "  Closing    = " << closing;

  Geometry3D::Pointer geometry = dynamic_cast<Geometry3D *>(image->GetGeometry()->Clone().GetPointer());

  // Make ITK image out of MITK image

  typedef itk::Image<unsigned char, 3> CharImageType;
  typedef itk::Image<unsigned short, 3> ShortImageType;
  typedef itk::Image<float, 3> FloatImageType;

  if (image->GetDimension() == 4)
  {
    ImageTimeSelector::Pointer imageTimeSelector = ImageTimeSelector::New();
    imageTimeSelector->SetInput(image);
    imageTimeSelector->SetTimeNr(timeNr);
    imageTimeSelector->UpdateLargestPossibleRegion();
    image = imageTimeSelector->GetOutput(0);
  }

  ImageToItk<CharImageType>::Pointer imageToItkFilter = ImageToItk<CharImageType>::New();

  try
  {
    imageToItkFilter->SetInput(image);
  }
  catch (const itk::ExceptionObject &e)
  {
    // Most probably the input image type is wrong. Binary images are expected to be
    // >unsigned< char images.
    MITK_ERROR << e.GetDescription() << endl;
    return false;
  }

  imageToItkFilter->Update();

  CharImageType::Pointer itkImage = imageToItkFilter->GetOutput();

  // Get bounding box and relabel

  MITK_INFO << "Extracting VOI...";

  int imageLabel = 1;
  bool roiFound = false;

  CharImageType::IndexType minIndex;
  minIndex.Fill(numeric_limits<CharImageType::IndexValueType>::max());

  CharImageType::IndexType maxIndex;
  maxIndex.Fill(numeric_limits<CharImageType::IndexValueType>::min());

  itk::ImageRegionIteratorWithIndex<CharImageType> iter(itkImage, itkImage->GetLargestPossibleRegion());

  for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter)
  {
    if (iter.Get() == imageLabel)
    {
      roiFound = true;
      iter.Set(1);

      CharImageType::IndexType currentIndex = iter.GetIndex();

      for (unsigned int dim = 0; dim < 3; ++dim)
      {
        minIndex[dim] = min(currentIndex[dim], minIndex[dim]);
        maxIndex[dim] = max(currentIndex[dim], maxIndex[dim]);
      }
    }
    else
    {
      iter.Set(0);
    }
  }

  if (!roiFound)
  {
    ProgressBar::GetInstance()->Progress(8);
    MITK_ERROR << "Didn't found segmentation labeled with " << imageLabel << "!" << endl;
    return false;
  }

  ProgressBar::GetInstance()->Progress(1);

  // Extract and pad bounding box

  typedef itk::RegionOfInterestImageFilter<CharImageType, CharImageType> ROIFilterType;

  ROIFilterType::Pointer roiFilter = ROIFilterType::New();
  CharImageType::RegionType region;
  CharImageType::SizeType size;

  for (unsigned int dim = 0; dim < 3; ++dim)
  {
    size[dim] = maxIndex[dim] - minIndex[dim] + 1;
  }

  region.SetIndex(minIndex);
  region.SetSize(size);

  roiFilter->SetInput(itkImage);
  roiFilter->SetRegionOfInterest(region);
  roiFilter->ReleaseDataFlagOn();
  roiFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::ConstantPadImageFilter<CharImageType, CharImageType> PadFilterType;

  PadFilterType::Pointer padFilter = PadFilterType::New();
  const PadFilterType::SizeValueType pad[3] = { 10, 10, 10 };

  padFilter->SetInput(roiFilter->GetOutput());
  padFilter->SetConstant(0);
  padFilter->SetPadLowerBound(pad);
  padFilter->SetPadUpperBound(pad);
  padFilter->ReleaseDataFlagOn();
  padFilter->ReleaseDataBeforeUpdateFlagOn();
  padFilter->Update();

  CharImageType::Pointer roiImage = padFilter->GetOutput();

  roiImage->DisconnectPipeline();
  roiFilter = nullptr;
  padFilter = nullptr;

  // Correct origin of real geometry (changed by cropping and padding)

  typedef Geometry3D::TransformType TransformType;

  TransformType::Pointer transform = TransformType::New();
  TransformType::OutputVectorType translation;

  for (unsigned int dim = 0; dim < 3; ++dim)
    translation[dim] = (int)minIndex[dim] - (int)pad[dim];

  transform->SetIdentity();
  transform->Translate(translation);
  geometry->Compose(transform, true);

  ProgressBar::GetInstance()->Progress(1);

  // Median

  MITK_INFO << "Median...";

  typedef itk::BinaryMedianImageFilter<CharImageType, CharImageType> MedianFilterType;

  MedianFilterType::Pointer medianFilter = MedianFilterType::New();
  CharImageType::SizeType radius = { 0 };

  medianFilter->SetRadius(radius);
  medianFilter->SetBackgroundValue(0);
  medianFilter->SetForegroundValue(1);
  medianFilter->SetInput(roiImage);
  medianFilter->ReleaseDataFlagOn();
  medianFilter->ReleaseDataBeforeUpdateFlagOn();
  medianFilter->Update();

  ProgressBar::GetInstance()->Progress(1);

  // Intelligent closing

  MITK_INFO << "Intelligent closing...";

  unsigned int surfaceRatio = (unsigned int)((1.0f - closing) * 100.0f);

  typedef itk::IntelligentBinaryClosingFilter<CharImageType, ShortImageType> ClosingFilterType;

  ClosingFilterType::Pointer closingFilter = ClosingFilterType::New();

  closingFilter->SetInput(medianFilter->GetOutput());
  closingFilter->ReleaseDataFlagOn();
  closingFilter->ReleaseDataBeforeUpdateFlagOn();
  closingFilter->SetSurfaceRatio(surfaceRatio);
  closingFilter->Update();

  ShortImageType::Pointer closedImage = closingFilter->GetOutput();

  closedImage->DisconnectPipeline();
  roiImage = nullptr;
  medianFilter = nullptr;
  closingFilter = nullptr;

  ProgressBar::GetInstance()->Progress(1);

  // Gaussian blur

  MITK_INFO << "Gauss...";

  typedef itk::BinaryThresholdImageFilter<ShortImageType, FloatImageType> BinaryThresholdToFloatFilterType;

  BinaryThresholdToFloatFilterType::Pointer binThresToFloatFilter = BinaryThresholdToFloatFilterType::New();

  binThresToFloatFilter->SetInput(closedImage);
  binThresToFloatFilter->SetLowerThreshold(1);
  binThresToFloatFilter->SetUpperThreshold(1);
  binThresToFloatFilter->SetInsideValue(100);
  binThresToFloatFilter->SetOutsideValue(0);
  binThresToFloatFilter->ReleaseDataFlagOn();
  binThresToFloatFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::DiscreteGaussianImageFilter<FloatImageType, FloatImageType> GaussianFilterType;

  // From the following line on, IntelliSense (VS 2008) is broken. Any idea how to fix it?
  GaussianFilterType::Pointer gaussFilter = GaussianFilterType::New();

  gaussFilter->SetInput(binThresToFloatFilter->GetOutput());
  gaussFilter->SetUseImageSpacing(true);
  gaussFilter->SetVariance(smoothing);
  gaussFilter->ReleaseDataFlagOn();
  gaussFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::BinaryThresholdImageFilter<FloatImageType, CharImageType> BinaryThresholdFromFloatFilterType;

  BinaryThresholdFromFloatFilterType::Pointer binThresFromFloatFilter = BinaryThresholdFromFloatFilterType::New();

  binThresFromFloatFilter->SetInput(gaussFilter->GetOutput());
  binThresFromFloatFilter->SetLowerThreshold(50);
  binThresFromFloatFilter->SetUpperThreshold(255);
  binThresFromFloatFilter->SetInsideValue(1);
  binThresFromFloatFilter->SetOutsideValue(0);
  binThresFromFloatFilter->ReleaseDataFlagOn();
  binThresFromFloatFilter->ReleaseDataBeforeUpdateFlagOn();
  binThresFromFloatFilter->Update();

  CharImageType::Pointer blurredImage = binThresFromFloatFilter->GetOutput();

  blurredImage->DisconnectPipeline();
  closedImage = nullptr;
  binThresToFloatFilter = nullptr;
  gaussFilter = nullptr;

  ProgressBar::GetInstance()->Progress(1);

  // Fill holes

  MITK_INFO << "Filling cavities...";

  typedef itk::ConnectedThresholdImageFilter<CharImageType, CharImageType> ConnectedThresholdFilterType;

  ConnectedThresholdFilterType::Pointer connectedThresFilter = ConnectedThresholdFilterType::New();

  CharImageType::IndexType corner;

  corner[0] = 0;
  corner[1] = 0;
  corner[2] = 0;

  connectedThresFilter->SetInput(blurredImage);
  connectedThresFilter->SetSeed(corner);
  connectedThresFilter->SetLower(0);
  connectedThresFilter->SetUpper(0);
  connectedThresFilter->SetReplaceValue(2);
  connectedThresFilter->ReleaseDataFlagOn();
  connectedThresFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> BinaryThresholdFilterType;

  BinaryThresholdFilterType::Pointer binThresFilter = BinaryThresholdFilterType::New();

  binThresFilter->SetInput(connectedThresFilter->GetOutput());
  binThresFilter->SetLowerThreshold(0);
  binThresFilter->SetUpperThreshold(0);
  binThresFilter->SetInsideValue(50);
  binThresFilter->SetOutsideValue(0);
  binThresFilter->ReleaseDataFlagOn();
  binThresFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::AddImageFilter<CharImageType, CharImageType, CharImageType> AddFilterType;

  AddFilterType::Pointer addFilter = AddFilterType::New();

  addFilter->SetInput1(blurredImage);
  addFilter->SetInput2(binThresFilter->GetOutput());
  addFilter->ReleaseDataFlagOn();
  addFilter->ReleaseDataBeforeUpdateFlagOn();
  addFilter->Update();

  ProgressBar::GetInstance()->Progress(1);

  // Surface extraction

  MITK_INFO << "Surface extraction...";

  Image::Pointer filteredImage = Image::New();
  CastToMitkImage(addFilter->GetOutput(), filteredImage);

  filteredImage->SetGeometry(geometry);

  ImageToSurfaceFilter::Pointer imageToSurfaceFilter = ImageToSurfaceFilter::New();

  imageToSurfaceFilter->SetInput(filteredImage);
  imageToSurfaceFilter->SetThreshold(50);
  imageToSurfaceFilter->SmoothOn();
  imageToSurfaceFilter->SetDecimate(ImageToSurfaceFilter::NoDecimation);

  m_Surface = imageToSurfaceFilter->GetOutput(0);

  ProgressBar::GetInstance()->Progress(1);

  // Mesh decimation

  if (decimation > 0.0f && decimation < 1.0f)
  {
    MITK_INFO << "Quadric mesh decimation...";

    vtkQuadricDecimation *quadricDecimation = vtkQuadricDecimation::New();
    quadricDecimation->SetInputData(m_Surface->GetVtkPolyData());
    quadricDecimation->SetTargetReduction(decimation);
    quadricDecimation->AttributeErrorMetricOn();
    quadricDecimation->GlobalWarningDisplayOff();
    quadricDecimation->Update();

    vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
    cleaner->SetInputConnection(quadricDecimation->GetOutputPort());
    cleaner->PieceInvariantOn();
    cleaner->ConvertLinesToPointsOn();
    cleaner->ConvertStripsToPolysOn();
    cleaner->PointMergingOn();
    cleaner->Update();

    m_Surface->SetVtkPolyData(cleaner->GetOutput());
  }

  ProgressBar::GetInstance()->Progress(1);

  // Compute Normals

  vtkPolyDataNormals* computeNormals = vtkPolyDataNormals::New();
  computeNormals->SetInputData(m_Surface->GetVtkPolyData());
  computeNormals->SetFeatureAngle(360.0f);
  computeNormals->FlipNormalsOff();
  computeNormals->Update();

  m_Surface->SetVtkPolyData(computeNormals->GetOutput());

  return true;
}
mitk::ProportionalTimeGeometry::Pointer mitk::ProportionalTimeGeometryToXML::FromXML(TiXmlElement *timeGeometryElement)
{
  if (!timeGeometryElement)
  {
    MITK_ERROR << "Cannot deserialize ProportionalTimeGeometry from nullptr.";
    return nullptr;
  }

  int numberOfTimeSteps = 0;

  if (TIXML_SUCCESS != timeGeometryElement->QueryIntAttribute("NumberOfTimeSteps", &numberOfTimeSteps))
  {
    MITK_WARN << "<ProportionalTimeGeometry> found without NumberOfTimeSteps attribute. Counting...";
  }

  // might be missing!
  TimePointType firstTimePoint;
  std::string firstTimePoint_s;
  TimePointType stepDuration;
  std::string stepDuration_s;
  try
  {
    if (TIXML_SUCCESS == timeGeometryElement->QueryStringAttribute("FirstTimePoint", &firstTimePoint_s))
    {
      firstTimePoint = boost::lexical_cast<double>(firstTimePoint_s);
    }
    else
    {
      firstTimePoint = -std::numeric_limits<TimePointType>::max();
    }

    if (TIXML_SUCCESS == timeGeometryElement->QueryStringAttribute("StepDuration", &stepDuration_s))
    {
      stepDuration = boost::lexical_cast<double>(stepDuration_s);
    }
    else
    {
      stepDuration = std::numeric_limits<TimePointType>::infinity();
    }
  }
  catch (boost::bad_lexical_cast &e)
  {
    MITK_ERROR << "Could not parse string as number: " << e.what();
    return nullptr;
  }

  // list of all geometries with their time steps
  std::multimap<TimeStepType, BaseGeometry::Pointer> allReadGeometries;

  int indexForUnlabeledTimeStep(-1);
  for (TiXmlElement *currentElement = timeGeometryElement->FirstChildElement(); currentElement != nullptr;
       currentElement = currentElement->NextSiblingElement())
  {
    // different geometries could have been inside a ProportionalTimeGeometry.
    // By now, we only support Geometry3D
    std::string tagName = currentElement->Value();
    if (tagName == "Geometry3D")
    {
      Geometry3D::Pointer restoredGeometry = Geometry3DToXML::FromXML(currentElement);
      if (restoredGeometry.IsNotNull())
      {
        int timeStep(-1);
        if (TIXML_SUCCESS != currentElement->QueryIntAttribute("TimeStep", &timeStep))
        {
          timeStep = indexForUnlabeledTimeStep--; // decrement index for next one
          MITK_WARN << "Found <Geometry3D> without 'TimeStep' attribute in <ProportionalTimeGeometry>. No guarantees "
                       "on order anymore.";
        }

        if (allReadGeometries.count(static_cast<TimeStepType>(timeStep)) > 0)
        {
          MITK_WARN << "Found <Geometry3D> tags with identical 'TimeStep' attribute in <ProportionalTimeGeometry>. No "
                       "guarantees on order anymore.";
        }

        allReadGeometries.insert(std::make_pair(static_cast<TimeStepType>(timeStep), restoredGeometry.GetPointer()));
      }
    }
    else
    {
      MITK_WARN << "Found unsupported tag <" << tagName << "> inside <ProportionalTimeGeometry>. Ignoring.";
    }
  }

  // now add all BaseGeometries that were read to a new instance
  // of ProportionalTimeGeometry
  ProportionalTimeGeometry::Pointer newTimeGeometry = ProportionalTimeGeometry::New();
  newTimeGeometry->SetFirstTimePoint(firstTimePoint);
  newTimeGeometry->SetStepDuration(stepDuration);
  newTimeGeometry->ReserveSpaceForGeometries(allReadGeometries.size());

  TimeStepType t(0);
  for (auto entry : allReadGeometries)
  {
    // We add items with newly assigned time steps.
    // This avoids great confusion when a file contains
    // bogus numbers.
    newTimeGeometry->SetTimeStepGeometry(entry.second, t++);
  }

  // Need to re-calculate global bounding box.
  // This is neither stored in a file, nor done by SetTimeStepGeometry
  newTimeGeometry->UpdateBoundingBox();

  return newTimeGeometry;
}
std::vector<itk::SmartPointer<mitk::BaseData>> mitk::GeometryDataReaderService::Read()
{
  // Switch the current locale to "C"
  LocaleSwitch localeSwitch("C");

  std::vector<itk::SmartPointer<BaseData>> result;

  InputStream stream(this);

  TiXmlDocument doc;
  stream >> doc;
  if (!doc.Error())
  {
    TiXmlHandle docHandle(&doc);

    for (TiXmlElement *geomDataElement = docHandle.FirstChildElement("GeometryData").ToElement();
         geomDataElement != nullptr;
         geomDataElement = geomDataElement->NextSiblingElement())
    {
      for (TiXmlElement *currentElement = geomDataElement->FirstChildElement(); currentElement != nullptr;
           currentElement = currentElement->NextSiblingElement())
      {
        // different geometries could have been serialized from a GeometryData
        // object:
        std::string tagName = currentElement->Value();
        if (tagName == "Geometry3D")
        {
          Geometry3D::Pointer restoredGeometry = Geometry3DToXML::FromXML(currentElement);
          if (restoredGeometry.IsNotNull())
          {
            GeometryData::Pointer newGeometryData = GeometryData::New();
            newGeometryData->SetGeometry(restoredGeometry);
            result.push_back(newGeometryData.GetPointer());
          }
          else
          {
            MITK_ERROR << "Invalid <Geometry3D> tag encountered. Skipping.";
          }
        }
        else if (tagName == "ProportionalTimeGeometry")
        {
          ProportionalTimeGeometry::Pointer restoredTimeGeometry =
            ProportionalTimeGeometryToXML::FromXML(currentElement);
          if (restoredTimeGeometry.IsNotNull())
          {
            GeometryData::Pointer newGeometryData = GeometryData::New();
            newGeometryData->SetTimeGeometry(restoredTimeGeometry);
            result.push_back(newGeometryData.GetPointer());
          }
          else
          {
            MITK_ERROR << "Invalid <ProportionalTimeGeometry> tag encountered. Skipping.";
          }
        }
      } // for child of <GeometryData>
    }   // for <GeometryData>
  }
  else
  {
    mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc();
  }

  if (result.empty())
  {
    mitkThrow() << "Did not read a single GeometryData object from input.";
  }

  return result;
}
bool
RenderingManager
::InitializeViews( const Geometry3D * dataGeometry, RequestType type, bool preserveRoughOrientationInWorldSpace )
{
    MITK_DEBUG << "initializing views";

    bool boundingBoxInitialized = false;

    Geometry3D::ConstPointer geometry = dataGeometry;

    if (dataGeometry && preserveRoughOrientationInWorldSpace)
    {

        // clone the input geometry
        Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
        assert(modifiedGeometry.IsNotNull());

        // construct an affine transform from it
        AffineGeometryFrame3D::TransformType::Pointer transform = AffineGeometryFrame3D::TransformType::New();
        assert( modifiedGeometry->GetIndexToWorldTransform() );
        transform->SetMatrix( modifiedGeometry->GetIndexToWorldTransform()->GetMatrix() );
        transform->SetOffset( modifiedGeometry->GetIndexToWorldTransform()->GetOffset() );

        // get transform matrix
        AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& oldMatrix =
            const_cast< AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& > ( transform->GetMatrix().GetVnlMatrix() );
        AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType newMatrix(oldMatrix);

        // get offset and bound
        Vector3D offset = modifiedGeometry->GetIndexToWorldTransform()->GetOffset();
        Geometry3D::BoundsArrayType oldBounds = modifiedGeometry->GetBounds();
        Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds();

        // get rid of rotation other than pi/2 degree
        for ( unsigned int i = 0; i < 3; ++i )
        {

            // i-th column of the direction matrix
            Vector3D currentVector;
            currentVector[0] = oldMatrix(0,i);
            currentVector[1] = oldMatrix(1,i);
            currentVector[2] = oldMatrix(2,i);

            // matchingRow will store the row that holds the biggest
            // value in the column
            unsigned int matchingRow = 0;

            // maximum value in the column
            float max = std::numeric_limits<float>::min();

            // sign of the maximum value (-1 or 1)
            int sign = 1;

            // iterate through the column vector
            for (unsigned int dim = 0; dim < 3; ++dim)
            {
                if ( fabs(currentVector[dim]) > max )
                {
                    matchingRow = dim;
                    max = fabs(currentVector[dim]);
                    if(currentVector[dim]<0)
                        sign = -1;
                    else
                        sign = 1;
                }
            }

            // in case we found a negative maximum,
            // we negate the column and adjust the offset
            // (in order to run through the dimension in the opposite direction)
            if(sign == -1)
            {
                currentVector *= sign;
                offset += modifiedGeometry->GetAxisVector(i);
            }


            // matchingRow is now used as column index to place currentVector
            // correctly in the new matrix
            vnl_vector<ScalarType> newMatrixColumn(3);
            newMatrixColumn[0] = currentVector[0];
            newMatrixColumn[1] = currentVector[1];
            newMatrixColumn[2] = currentVector[2];
            newMatrix.set_column( matchingRow, newMatrixColumn );

            // if a column is moved, we also have to adjust the bounding
            // box accordingly, this is done here
            newBounds[2*matchingRow  ] = oldBounds[2*i  ];
            newBounds[2*matchingRow+1] = oldBounds[2*i+1];
        }

        // set the newly calculated bounds array
        modifiedGeometry->SetBounds(newBounds);

        // set new offset and direction matrix
        AffineGeometryFrame3D::TransformType::MatrixType newMatrixITK( newMatrix );
        transform->SetMatrix( newMatrixITK );
        transform->SetOffset( offset );
        modifiedGeometry->SetIndexToWorldTransform( transform );
        geometry = modifiedGeometry;

    }

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

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

    if (geometry.IsNotNull() )
    {   // make sure bounding box has an extent bigger than zero in any direction
        // clone the input geometry
        Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
        assert(modifiedGeometry.IsNotNull());
        Geometry3D::BoundsArrayType newBounds = modifiedGeometry->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;
            }
        }

        // set the newly calculated bounds array
        modifiedGeometry->SetBounds(newBounds);

        geometry = modifiedGeometry;
    }

    RenderWindowList::iterator it;
    for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
    {
        mitk::BaseRenderer *baseRenderer =
            mitk::BaseRenderer::GetInstance( it->first );

        baseRenderer->GetDisplayGeometry()->SetConstrainZoomingAndPanning(m_ConstrainedPaddingZooming);

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

    if ( m_TimeNavigationController != NULL )
    {
        if ( boundingBoxInitialized )
        {
            m_TimeNavigationController->SetInputWorldGeometry( geometry );
        }
        m_TimeNavigationController->Update();
    }

    this->RequestUpdateAll( type );

    vtkObject::SetGlobalWarningDisplay( warningLevel );

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


    return boundingBoxInitialized;
}
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< Geometry3D * >(
        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 );
          Geometry3D::Pointer newGeometry = static_cast< Geometry3D * >(
            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;
}
Example #7
0
std::vector<itk::SmartPointer<mitk::BaseData>> mitk::PointSetReaderService::Read()
{
    // Switch the current locale to "C"
    LocaleSwitch localeSwitch("C");

    std::vector<itk::SmartPointer<mitk::BaseData>> result;

    InputStream stream(this);

    TiXmlDocument doc;
    stream >> doc;
    if (!doc.Error())
    {
        TiXmlHandle docHandle(&doc);
        // unsigned int pointSetCounter(0);
        for (TiXmlElement *currentPointSetElement =
                    docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement();
                currentPointSetElement != NULL;
                currentPointSetElement = currentPointSetElement->NextSiblingElement())
        {
            mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();

            // time geometry assembled for addition after all points
            // else the SetPoint method would already transform the points that we provide it
            mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New();

            if (currentPointSetElement->FirstChildElement("time_series") != NULL)
            {
                for (TiXmlElement *currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement();
                        currentTimeSeries != NULL;
                        currentTimeSeries = currentTimeSeries->NextSiblingElement())
                {
                    unsigned int currentTimeStep(0);
                    TiXmlElement *currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id");

                    currentTimeStep = atoi(currentTimeSeriesID->GetText());

                    timeGeometry->Expand(currentTimeStep + 1); // expand (default to identity) in any case
                    TiXmlElement *geometryElem = currentTimeSeries->FirstChildElement("Geometry3D");
                    if (geometryElem)
                    {
                        Geometry3D::Pointer geometry = Geometry3DToXML::FromXML(geometryElem);
                        if (geometry.IsNotNull())
                        {
                            timeGeometry->SetTimeStepGeometry(geometry, currentTimeStep);
                        }
                        else
                        {
                            MITK_ERROR << "Could not deserialize Geometry3D element.";
                        }
                    }
                    else
                    {
                        MITK_WARN << "Fallback to legacy behavior: defining PointSet geometry as identity";
                    }

                    newPointSet = this->ReadPoints(newPointSet, currentTimeSeries, currentTimeStep);
                }
            }
            else
            {
                newPointSet = this->ReadPoints(newPointSet, currentPointSetElement, 0);
            }

            newPointSet->SetTimeGeometry(timeGeometry);

            result.push_back(newPointSet.GetPointer());
        }
    }
    else
    {
        mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc();
    }

    return result;
}
Example #8
0
mitk::BaseGeometry::Pointer mitk::PointSetReaderService::ReadGeometry(TiXmlElement *parentElement)
{
    TiXmlElement *geometryElem = parentElement->FirstChildElement("geometry3d");
    if (!geometryElem)
        return nullptr;

    // data to generate
    AffineTransform3D::MatrixType matrix;
    AffineTransform3D::OffsetType offset;
    bool isImageGeometry(false);
    unsigned int frameOfReferenceID(0);
    BaseGeometry::BoundsArrayType bounds;

    bool somethingMissing(false);

    // find data in xml structure
    TiXmlElement *imageGeometryElem = geometryElem->FirstChildElement("image_geometry");
    if (imageGeometryElem)
    {
        std::string igs = imageGeometryElem->GetText();
        isImageGeometry = igs == "true" || igs == "TRUE" || igs == "1";
    }
    else
        somethingMissing = true;

    TiXmlElement *frameOfReferenceElem = geometryElem->FirstChildElement("frame_of_reference_id");
    if (frameOfReferenceElem)
    {
        frameOfReferenceID = atoi(frameOfReferenceElem->GetText());
    }
    else
        somethingMissing = true;

    TiXmlElement *indexToWorldElem = geometryElem->FirstChildElement("index_to_world");
    if (indexToWorldElem)
    {
        TiXmlElement *matrixElem = indexToWorldElem->FirstChildElement("matrix3x3");
        TiXmlElement *offsetElem = indexToWorldElem->FirstChildElement("offset");
        if (indexToWorldElem && offsetElem)
        {
            TiXmlElement *col0 = matrixElem->FirstChildElement("column_0");
            TiXmlElement *col1 = matrixElem->FirstChildElement("column_1");
            TiXmlElement *col2 = matrixElem->FirstChildElement("column_2");

            if (col0 && col1 && col2)
            {
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("x", &matrix[0][0]);
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("y", &matrix[1][0]);
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("z", &matrix[2][0]);

                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("x", &matrix[0][1]);
                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("y", &matrix[1][1]);
                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("z", &matrix[2][1]);

                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("x", &matrix[0][2]);
                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("y", &matrix[1][2]);
                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("z", &matrix[2][2]);
            }
            else
                somethingMissing = true;

            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("x", &offset[0]);
            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("y", &offset[1]);
            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("z", &offset[2]);
        }
        else
            somethingMissing = true;

        TiXmlElement *boundsElem = geometryElem->FirstChildElement("bounds");
        if (boundsElem)
        {
            TiXmlElement *minBoundsElem = boundsElem->FirstChildElement("min");
            TiXmlElement *maxBoundsElem = boundsElem->FirstChildElement("max");

            if (minBoundsElem && maxBoundsElem)
            {
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("x", &bounds[0]);
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("y", &bounds[2]);
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("z", &bounds[4]);

                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("x", &bounds[1]);
                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("y", &bounds[3]);
                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("z", &bounds[5]);
            }
            else
                somethingMissing = true;
        }
        else
            somethingMissing = true;
    }
    else
        somethingMissing = true;

    if (somethingMissing)
    {
        MITK_ERROR << "XML structure of geometry inside a PointSet file broken. Refusing to build Geometry3D";
        return nullptr;
    }
    else
    {
        Geometry3D::Pointer g = Geometry3D::New();
        g->SetImageGeometry(isImageGeometry);
        g->SetFrameOfReferenceID(frameOfReferenceID);
        g->SetBounds(bounds);

        AffineTransform3D::Pointer transform = AffineTransform3D::New();
        transform->SetMatrix(matrix);
        transform->SetOffset(offset);

        g->SetIndexToWorldTransform(transform);

        return g.GetPointer();
    }
}
void mitk::AffineBaseDataInteractor3D::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return;

  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
  Point3D currentWorldPoint = positionEvent->GetPositionInWorld();

  vtkCamera* camera = NULL;
  vtkRenderer* currentVtkRenderer = NULL;

  if ((interactionEvent->GetSender()) != NULL)
  {
    camera = interactionEvent->GetSender()->GetVtkRenderer()->GetActiveCamera();
    currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();
  }
  if ( camera && currentVtkRenderer)
  {
    double vpn[3];
    camera->GetViewPlaneNormal( vpn );

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

    Vector3D interactionMove;
    interactionMove[0] = currentWorldPoint[0] - m_InitialPickedWorldPoint[0];
    interactionMove[1] = currentWorldPoint[1] - m_InitialPickedWorldPoint[1];
    interactionMove[2] = currentWorldPoint[2] - m_InitialPickedWorldPoint[2];

    if (interactionMove[0] == 0 && interactionMove[1] == 0  && interactionMove[2] == 0)
      return;

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

    int* size = currentVtkRenderer->GetSize();
    double l2 =
        (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) *
        (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) +
        (currentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) *
        (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();

    int timeStep = 0;
    if ((interactionEvent->GetSender()) != NULL)
      timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData());

    // Reset current Geometry3D to original state (pre-interaction) and
    // apply rotation
    RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle );
    Geometry3D::Pointer newGeometry = static_cast<Geometry3D*>(m_OriginalGeometry->Clone().GetPointer());
    newGeometry->ExecuteOperation( &op );
    mitk::TimeGeometry::Pointer timeGeometry = this->GetDataNode()->GetData()->GetTimeGeometry();
    if (timeGeometry.IsNotNull())
      timeGeometry->SetTimeStepGeometry(newGeometry, timeStep);

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
  }
}
bool mitk::SurfaceDeformationDataInteractor3D::ColorizeSurface(vtkPolyData* polyData, int timeStep, const Point3D &pickedPoint, int mode, double scalar)
{
  if (polyData == NULL)
    return false;

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

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

  if (mode == COLORIZATION_GAUSS)
  {
    // Get picked point and transform into local coordinates
    Point3D localPickedPoint;
    Geometry3D::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 (unsigned int 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 (unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i)
    {
      scalars->SetComponent(i, 0, scalar);
    }
  }

  polyData->Modified();
  pointData->Update();

  return true;
}
bool mitk::SurfaceDeformationDataInteractor3D::DeformObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  const InteractionPositionEvent* positionEvent = dynamic_cast<const InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return false;

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

  Point3D currentPickedPoint = positionEvent->GetPositionInWorld();

  // Calculate mouse move in 3D space
  Vector3D interactionMove;
  interactionMove[0] = currentPickedPoint[0] - m_InitialPickedPoint[0];
  interactionMove[1] = currentPickedPoint[1] - m_InitialPickedPoint[1];
  interactionMove[2] = currentPickedPoint[2] - m_InitialPickedPoint[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 (unsigned int 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();
  return true;
}
Example #12
0
mitk::Geometry3D::Pointer mitk::Geometry3DToXML::FromXML( TiXmlElement* geometryElement )
{
  if (!geometryElement)
  {
    MITK_ERROR << "Cannot deserialize Geometry3D from nullptr.";
    return nullptr;
  }

  AffineTransform3D::MatrixType matrix;
  AffineTransform3D::OffsetType offset;
  bool isImageGeometry(false);
  unsigned int frameOfReferenceID(0);
  BaseGeometry::BoundsArrayType bounds;

  if ( TIXML_SUCCESS != geometryElement->QueryUnsignedAttribute("FrameOfReferenceID", &frameOfReferenceID) )
  {
    MITK_WARN << "Missing FrameOfReference for Geometry3D.";
  }

  if ( TIXML_SUCCESS != geometryElement->QueryBoolAttribute("ImageGeometry", &isImageGeometry) )
  {
    MITK_WARN << "Missing bool ImageGeometry for Geometry3D.";
  }

  // matrix
  if ( TiXmlElement* matrixElem = geometryElement->FirstChildElement("IndexToWorld")->ToElement() )
  {
    bool matrixComplete = true;
    for ( unsigned int r = 0; r < 3; ++r )
    {
      for ( unsigned int c = 0; c < 3; ++c )
      {
        std::stringstream element_namer;
        element_namer << "m_" << r << "_" << c;

        std::string string_value;
        if (TIXML_SUCCESS == matrixElem->QueryStringAttribute(element_namer.str().c_str(),
                                                              &string_value))
        {
          try
          {
            matrix[r][c] = boost::lexical_cast<double>(string_value);
          }
          catch (boost::bad_lexical_cast& e)
          {
            MITK_ERROR << "Could not parse '" << string_value << "' as number: " << e.what();
            return nullptr;
          }
        }
        else
        {
          matrixComplete = false;
        }
      }
    }

    if ( !matrixComplete )
    {
      MITK_ERROR << "Could not parse all Geometry3D matrix coefficients!";
      return nullptr;
    }
  } else
  {
    MITK_ERROR << "Parse error: expected Matrix3x3 child below Geometry3D node";
    return nullptr;
  }

  // offset
  if ( TiXmlElement* offsetElem = geometryElement->FirstChildElement("Offset")->ToElement() )
  {
    bool vectorComplete = true;
    std::string offset_string[3];
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("x", &offset_string[0]);
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("y", &offset_string[1]);
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("z", &offset_string[2]);

    if ( !vectorComplete )
    {
      MITK_ERROR << "Could not parse complete Geometry3D offset!";
      return nullptr;
    }

    for ( unsigned int d = 0; d < 3; ++d )
      try
      {
        offset[d] = boost::lexical_cast<double>(offset_string[d]);
      }
      catch ( boost::bad_lexical_cast& e )
      {
        MITK_ERROR << "Could not parse '" << offset_string[d] << "' as number: " << e.what();
        return nullptr;
      }
  }
  else
  {
    MITK_ERROR << "Parse error: expected Offset3D child below Geometry3D node";
    return nullptr;
  }

  // bounds
  if ( TiXmlElement* boundsElem = geometryElement->FirstChildElement("Bounds")->ToElement() )
  {
    bool vectorsComplete(true);
    std::string bounds_string[6];
    if ( TiXmlElement* minElem = boundsElem->FirstChildElement("Min")->ToElement() )
    {
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("x", &bounds_string[0]);
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("y", &bounds_string[2]);
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("z", &bounds_string[4]);
    } else
    {
      vectorsComplete = false;
    }

    if ( TiXmlElement* maxElem = boundsElem->FirstChildElement("Max")->ToElement() )
    {
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("x", &bounds_string[1]);
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("y", &bounds_string[3]);
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("z", &bounds_string[5]);
    } else
    {
      vectorsComplete = false;
    }

    if ( !vectorsComplete )
    {
      MITK_ERROR << "Could not parse complete Geometry3D bounds!";
      return nullptr;
    }

    for (unsigned int d = 0; d < 6; ++d)
      try
      {
        bounds[d] = boost::lexical_cast<double>(bounds_string[d]);
      }
      catch (boost::bad_lexical_cast& e)
      {
        MITK_ERROR << "Could not parse '" << bounds_string[d] << "' as number: " << e.what();
        return nullptr;
      }
}

  // build GeometryData from matrix/offset
  AffineTransform3D::Pointer newTransform = AffineTransform3D::New();
  newTransform->SetMatrix(matrix);
  newTransform->SetOffset(offset);

  Geometry3D::Pointer newGeometry = Geometry3D::New();
  newGeometry->SetFrameOfReferenceID(frameOfReferenceID);
  newGeometry->SetImageGeometry(isImageGeometry);

  newGeometry->SetIndexToWorldTransform(newTransform);

  newGeometry->SetBounds(bounds);

  return newGeometry;
}