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(); } }
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; } }
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; }
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(); }