void mitk::SurfaceToImageFilter::Stencil3DImage(int time) { const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry(); const mitk::TimeGeometry *imageTimeGeometry = GetImage()->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 = ( (mitk::Surface*)GetInput() )->GetVtkPolyData( surfaceTimeStep ); vtkSmartPointer<vtkTransformPolyDataFilter> move=vtkTransformPolyDataFilter::New(); move->SetInputData(polydata); move->ReleaseDataFlagOn(); vtkSmartPointer<vtkTransform> transform=vtkTransform::New(); Geometry3D* geometry = surfaceTimeGeometry->GetGeometryForTimeStep( surfaceTimeStep ); geometry->TransferItkToVtkTransform(); 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. Geometry3D* imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time); imageGeometry->TransferItkToVtkTransform(); transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse()); move->SetTransform(transform); vtkSmartPointer<vtkPolyDataNormals> normalsFilter = vtkPolyDataNormals::New(); normalsFilter->SetFeatureAngle(50); normalsFilter->SetConsistency(1); normalsFilter->SetSplitting(1); normalsFilter->SetFlipNormals(0); normalsFilter->ReleaseDataFlagOn(); normalsFilter->SetInputConnection(move->GetOutputPort() ); vtkSmartPointer<vtkPolyDataToImageStencil> surfaceConverter = vtkPolyDataToImageStencil::New(); surfaceConverter->SetTolerance( 0.0 ); surfaceConverter->ReleaseDataFlagOn(); surfaceConverter->SetInputConnection( normalsFilter->GetOutputPort() ); mitk::Image::Pointer binaryImage = mitk::Image::New(); if (m_MakeOutputBinary) { binaryImage->Initialize(mitk::MakeScalarPixelType<unsigned char>(), *this->GetImage()->GetTimeGeometry()); unsigned int size = sizeof(unsigned char); for (unsigned int i = 0; i < binaryImage->GetDimension(); ++i) size *= binaryImage->GetDimension(i); mitk::ImageWriteAccessor accessor( binaryImage ); memset( accessor.GetData(), 1, size ); } vtkImageData *image = m_MakeOutputBinary ? binaryImage->GetVtkImageData(time) : const_cast<mitk::Image *>(this->GetImage())->GetVtkImageData(time); // Create stencil and use numerical minimum of pixel type as background value vtkSmartPointer<vtkImageStencil> stencil = vtkImageStencil::New(); stencil->SetInputData(image); stencil->ReverseStencilOff(); stencil->ReleaseDataFlagOn(); stencil->SetStencilConnection(surfaceConverter->GetOutputPort()); stencil->SetBackgroundValue(m_MakeOutputBinary ? 0 : m_BackgroundValue); stencil->Update(); mitk::Image::Pointer output = this->GetOutput(); output->SetVolume( stencil->GetOutput()->GetScalarPointer(), time ); MITK_INFO << "stencil ref count: " << stencil->GetReferenceCount() << std::endl; }
bool mitk::WiiMoteInteractor::FixedRotationAndTranslation(const mitk::WiiMoteAllDataEvent* wiiMoteEvent) { Geometry3D* geometry = this->TransformCurrentDataInGeometry3D(); m_OrientationX = wiiMoteEvent->GetOrientationX(); m_OrientationY = wiiMoteEvent->GetOrientationY(); m_OrientationZ = wiiMoteEvent->GetOrientationZ(); ScalarType pitchSpeed = wiiMoteEvent->GetPitchSpeed(); ScalarType rollSpeed = wiiMoteEvent->GetRollSpeed(); ScalarType yawSpeed = wiiMoteEvent->GetYawSpeed(); // angle x if(std::abs(pitchSpeed) < 200) pitchSpeed = 0; m_xAngle += (pitchSpeed / 1500); // angle y if(std::abs(rollSpeed) < 200) rollSpeed = 0; m_yAngle += (rollSpeed / 1500); // angle z if(std::abs(yawSpeed) < 200) yawSpeed = 0; m_zAngle += (yawSpeed / 1500); if( std::abs(pitchSpeed) > 200 || std::abs(rollSpeed) > 200 || std::abs(yawSpeed) > 200) { m_InRotation = true; //// depending on a combination of the //// orientation the angleX wil be altered //// because the range from roll is limited //// range: -90° to 90° by the wiimote //if(wiiMoteEvent->GetOrientationZ() < 0) //{ // // value is positive // if(wiiMoteEvent->GetOrientationX() > 0) // { // // the degree measured decreases after it reaches // // in the "real" world the 90 degree angle // // (rotation to the right side) // // therefore it needs to artificially increased // // measured value drops -> computated angle increases // angleX = 90 - angleX; // // now add the "new" angle to 90 degree threshold // angleX += 90; // } // // value is negative // else if(wiiMoteEvent->GetOrientationX() < 0) // { // // the degree measured increases after it reaches // // in the "real" world -90 degree // // (rotation to the left side) // // therefore it needs to be artificially decreased // // (example -90 -> -70, but -110 is needed) // // measured value increases -> computated angle decreases // angleX = 90 + angleX; // // invert the algebraic sign, because it is the "negative" // // side of the rotation // angleX = -angleX; // // now add the negative value to the -90 degree threshold // // to decrease the value further // angleX -= 90; // } // else if(wiiMoteEvent->GetOrientationX() == 0) // { // // i.e. wiimote is flipped upside down // angleX = 180; // } //} //rotation vtkTransform *vtkTransform = vtkTransform::New(); //copy m_vtkMatrix to m_VtkIndexToWorldTransform geometry->TransferItkToVtkTransform(); //////m_VtkIndexToWorldTransform as vtkLinearTransform* vtkTransform->SetMatrix(geometry->GetVtkTransform()->GetMatrix()); // rotation from center is different // from rotation while translated // hence one needs the center of the object Point3D center = geometry->GetOrigin(); vtkTransform->PostMultiply(); vtkTransform->Translate(-center[0], -center[1], -center[2]); //vtkTransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]); vtkTransform->RotateX(m_xAngle); vtkTransform->RotateY(m_zAngle); vtkTransform->RotateZ(m_yAngle); vtkTransform->Translate(center[0], center[1], center[2]); vtkTransform->PreMultiply(); geometry->SetIndexToWorldTransformByVtkMatrix(vtkTransform->GetMatrix()); geometry->Modified(); // indicate modification of data tree node m_DataNode->Modified(); vtkTransform->Delete(); //update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } else if(!m_InRotation) { float xValue = wiiMoteEvent->GetXAcceleration(); float yValue = wiiMoteEvent->GetYAcceleration(); float zValue = wiiMoteEvent->GetZAcceleration(); float pitch = wiiMoteEvent->GetPitch(); float roll = wiiMoteEvent->GetRoll(); // substracts the proportionate force // applied by gravity depending on the // orientation float sinP = sin(pitch/180.0 * M_PI); float cosP = cos(pitch/180.0 * M_PI); float sinR = sin(roll/180.0 * M_PI); float cosR = cos(roll/180.0 * M_PI); // x acceleration if(m_OrientationZ >= 0) xValue = xValue - sinR * cosP; else xValue = xValue + sinR * cosP; // against drift if(std::abs(xValue) < 0.2) xValue = 0; // y acceleration yValue = yValue + sinP; // against drift if(std::abs(yValue) < 0.2) yValue = 0; // z acceleration zValue = zValue - cosP * cosR; // against drift if(std::abs(zValue) < 0.3) zValue = 0; // simple integration over time // resulting in velocity switch(m_TranslationMode) { case 1: m_xVelocity -= xValue; m_yVelocity -= yValue; m_zVelocity += zValue; // 1 = movement to the right // initially starts with negative acceleration // 2 = movement to the left // initially starts with positive acceleration if( m_xVelocity > 0 && xValue > 0 // 1 || m_xVelocity < 0 && xValue < 0) // 2 { m_xVelocity += xValue; } else if( m_xVelocity > 0 && xValue < 0 // 1 || m_xVelocity < 0 && xValue > 0) // 2 { m_xVelocity -= xValue; } break; case 3: m_yVelocity -= yValue; break; case 4: // 1 = movement up // initially starts with positive acceleration // 2 = movement down // initially starts with negative acceleration if( m_zVelocity > 0 && zValue < 0 // 1 || m_zVelocity < 0 && zValue > 0) // 2 { m_zVelocity -= zValue; } else if(m_zVelocity > 0 && zValue > 0 // 1 || m_zVelocity < 0 && zValue < 0) // 2 { m_zVelocity += zValue; } break; } // sets the mode of the translation // depending on the initial velocity if( std::abs(m_xVelocity) > std::abs(m_yVelocity) && std::abs(m_xVelocity) > std::abs(m_zVelocity) ) { m_TranslationMode = 2; m_yVelocity = 0; m_zVelocity = 0; } else if( std::abs(m_yVelocity) > std::abs(m_xVelocity) && std::abs(m_yVelocity) > std::abs(m_zVelocity) ) { m_TranslationMode = 3; m_xVelocity = 0; m_zVelocity = 0; } else if(std::abs(m_zVelocity) > std::abs(m_xVelocity) && std::abs(m_zVelocity) > std::abs(m_yVelocity) ) { m_TranslationMode = 4; m_xVelocity = 0; m_yVelocity = 0; } // translation mitk::Vector3D movementVector; movementVector.SetElement(0,m_xVelocity); movementVector.SetElement(1,m_yVelocity); movementVector.SetElement(2,m_zVelocity); geometry->Translate(movementVector); // indicate modification of data tree node m_DataNode->Modified(); // update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } return false; }
void mitk::SurfaceToImageFilter::Stencil3DImage(int time) { const mitk::TimeSlicedGeometry *surfaceTimeGeometry = GetInput()->GetTimeSlicedGeometry(); const mitk::TimeSlicedGeometry *imageTimeGeometry = GetImage()->GetTimeSlicedGeometry(); // Convert time step from image time-frame to surface time-frame int surfaceTimeStep = surfaceTimeGeometry->TimeStepToTimeStep( imageTimeGeometry, time ); vtkPolyData * polydata = ( (mitk::Surface*)GetInput() )->GetVtkPolyData( surfaceTimeStep ); vtkTransformPolyDataFilter * move=vtkTransformPolyDataFilter::New(); move->SetInput(polydata); move->ReleaseDataFlagOn(); vtkTransform *transform=vtkTransform::New(); Geometry3D* geometry = surfaceTimeGeometry->GetGeometry3D( surfaceTimeStep ); geometry->TransferItkToVtkTransform(); 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. Geometry3D* imageGeometry = imageTimeGeometry->GetGeometry3D(time); imageGeometry->TransferItkToVtkTransform(); transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse()); move->SetTransform(transform); transform->Delete(); vtkPolyDataNormals * normalsFilter = vtkPolyDataNormals::New(); normalsFilter->SetFeatureAngle(50); normalsFilter->SetConsistency(1); normalsFilter->SetSplitting(1); normalsFilter->SetFlipNormals(0); normalsFilter->ReleaseDataFlagOn(); normalsFilter->SetInput( move->GetOutput() ); move->Delete(); vtkPolyDataToImageStencil * surfaceConverter = vtkPolyDataToImageStencil::New(); surfaceConverter->SetTolerance( 0.0 ); surfaceConverter->ReleaseDataFlagOn(); surfaceConverter->SetInput( normalsFilter->GetOutput() ); normalsFilter->Delete(); vtkImageData *image = const_cast< mitk::Image * >(this->GetImage())->GetVtkImageData( time ); // Create stencil and use numerical minimum of pixel type as background value vtkImageStencil * stencil = vtkImageStencil::New(); stencil->SetInput( image ); stencil->ReverseStencilOff(); stencil->ReleaseDataFlagOn(); stencil->SetStencil( surfaceConverter->GetOutput() ); surfaceConverter->Delete(); if (m_MakeOutputBinary) { stencil->SetBackgroundValue( image->GetScalarTypeMin() ); vtkImageThreshold * threshold = vtkImageThreshold::New(); threshold->SetInput( stencil->GetOutput() ); threshold->ThresholdByLower( image->GetScalarTypeMin() ); threshold->ReplaceInOn(); threshold->ReplaceOutOn(); threshold->SetInValue( 0 ); threshold->SetOutValue( 1 ); threshold->SetOutputScalarTypeToUnsignedChar(); threshold->Update(); mitk::Image::Pointer output = this->GetOutput(); output->SetVolume( threshold->GetOutput()->GetScalarPointer(), time ); threshold->Delete(); } else { stencil->SetBackgroundValue( m_BackgroundValue ); stencil->Update(); mitk::Image::Pointer output = this->GetOutput(); output->SetVolume( stencil->GetOutput()->GetScalarPointer(), time ); MITK_INFO << "stencil ref count: " << stencil->GetReferenceCount() << std::endl; } stencil->Delete(); }