Saving images with a key press

Hi,
I am creating a program to save raw data of slice plane by pressing “c” based on KeypressEvents.

I was able to create a part that saves the raw data by pressing a key, but I don’t know how to adapt the cutout plane in the callback(vtkIPWCallback).

How can I connect the updated plane in the vtkImplicitPlaneWidget2 to the key press operation?

Could you give me a hint if possible?

Below is the callback and key press code.

  virtual void Execute(vtkObject *caller, unsigned long, void*)
 {
   vtkImplicitPlaneWidget2 *planeWidget = reinterpret_cast<vtkImplicitPlaneWidget2*>(caller);
vtkImplicitPlaneRepresentation *rep =reinterpret_cast<vtkImplicitPlaneRepresentation*>(planeWidget->GetRepresentation());
 rep->GetPlane(this->Plane);

double normal[3];
Plane->GetNormal(normal);
double Origin[3];
Plane->GetOrigin(Origin);

// Set the slice orientation
vtkSmartPointer<vtkMatrix4x4> resliceMatrix =
vtkSmartPointer<vtkMatrix4x4>::New();

(Compute of the 4x4 matrix)
}
vtkIPWCallback():Plane(0) {}
vtkPlane *Plane;
vtkImageReslice *Reslice;
};

Part of keypress

 class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static KeyPressInteractorStyle* New();
vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);

virtual void OnKeyPress() override
{
  // Get the keypress
vtkRenderWindowInteractor *rwi = this->Interactor;
std::string key = rwi->GetKeySym();
 
vtkImageReslice *reslice = this->ImageReslice;

// Output the key that was pressed
std::cout << "Pressed " << key << std::endl;

// Handle a "normal" key
if(key == "c")
{
  std::cout << "The a key was pressed." << std::endl;
  // adapt path !
  std::string filePathRaw = "slice_512x512.raw";

  vtkSmartPointer<vtkImageCast> castFilter = 
   vtkSmartPointer<vtkImageCast>::New();
  castFilter->SetOutputScalarTypeToUnsignedChar();
  castFilter->SetInputConnection(reslice->GetOutputPort());
  castFilter->Update();

  vtkSmartPointer<vtkImageWriter> writer =
   vtkSmartPointer<vtkImageWriter>::New();
  writer->SetInputConnection(castFilter->GetOutputPort());
  writer->SetFileName(filePathRaw.c_str());
  writer->Write();
  }

// Forward events
vtkInteractorStyleTrackballCamera::OnKeyPress();
}

// Pointer to vtkImageReslice
 vtkImageReslice *ImageReslice;
};
vtkStandardNewMacro(KeyPressInteractorStyle);

@dgobbi

That is not necessary. Just make sure that Reslice in your callback and ImageReslice in your KeyPressInteractorStyle are the same object.

Thank you for your reply.

I understood that there is no need to connect.
Currently, the vtkImplicitPlaneWidget2 window automatically disappears when the “c” key is pressed.

Is this because of the incorrect code in the writer part?
Can you tell me where to improve if possible?

@dgobbi

The code for the writer looks fine. If you run your program in a debugger, it might be able to tell you why the window disappears. It isn’t a question that I can answer for you.

Thank you for your reply.

“Just make sure that Reslice in your callback and ImageReslice in your KeyPressInteractorStyle are the same object.”

I would like to confirm one,
Does this mean that the updated plane of the callback is adapted to the KeyPressInteractorStyle’s ImageReslice?

@dgobbi

No, I meant interactorstyle->ImageReslice == callback->Reslice. They are the same object.

I can understand that they are the same object.

The callback and key press parts are divided as follows:

  class vtkIPWCallback : public vtkCommand
 {
 public:
 static vtkIPWCallback *New()
{ return new vtkIPWCallback; }

virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkImplicitPlaneWidget2 *planeWidget = reinterpret_cast<vtkImplicitPlaneWidget2*>(caller);
vtkImplicitPlaneRepresentation *rep =reinterpret_cast<vtkImplicitPlaneRepresentation*>(planeWidget->GetRepresentation());
rep->GetPlane(this->Plane);
(Compute of the 4x4 matrix)
vtkImageReslice *reslice = this->Reslice;
reslice->SetResliceAxes(resliceMatrix);
reslice->Update();
}
vtkIPWCallback():Plane(0),Reslice(0){};
vtkPlane *Plane;
vtkImageReslice *Reslice;
 };

 class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static KeyPressInteractorStyle* New();
vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnKeyPress() override
{
  // Get the keypress
vtkRenderWindowInteractor *rwi = this->Interactor;
std::string key = rwi->GetKeySym();

vtkImageReslice *reslice = this->ImageReslice;

 // Output the key that was pressed
 std::cout << "Pressed " << key << std::endl;

// Handle a "normal" key
if(key == "c")
{
std::cout << "The a key was pressed." << std::endl;
// adapt path !
std::string filePathRaw = "slice_512x512.raw";

vtkSmartPointer<vtkImageCast> castFilter = 
vtkSmartPointer<vtkImageCast>::New();
castFilter->SetOutputScalarTypeToUnsignedChar();
castFilter->SetInputConnection(reslice->GetOutputPort());
castFilter->Update();

vtkSmartPointer<vtkImageWriter> writer =
vtkSmartPointer<vtkImageWriter>::New();
writer->SetInputConnection(castFilter->GetOutputPort());
writer->SetFileName(filePathRaw.c_str());
writer->Write();
}

// Forward events
vtkInteractorStyleTrackballCamera::OnKeyPress();
}

// Pointer to vtkImageReslice
vtkImageReslice *ImageReslice;
};
vtkStandardNewMacro(KeyPressInteractorStyle);

Callback and key press are separated.
Using the same object, I tried to adapt the “reslice” updated in the callback with the “writer” that presses the key.

Should the key press part be included in the callback?
I would be grateful if you could give me advice.

@dgobbi

I’m sorry many times.

I want to know if using this same object is right or wrong in my code.

I don’t know if it’s correct, I tried to adapt the “reslice” updated in the callback with the “castFilter” that presses the key.

I would be grateful if you could advise me if possible.

@dgobbi

If you post the whole code, not just parts of it, then I can look at it sometime this week.

Thank you for your support.
Forgive me for stealing your time.

Attach the code file below.
ImplictWidget2.cxx (11.8 KB)

I would be grateful if you could give me advice.

@dgobbi

There are two problems that I can see with the interator style.

First is that the “Reslice” of the interactor style is never set. You need code like this:

style->Reslice = reslice;

In order for the “style” and the “callback” to have the same reslice object, you must do myCallback->Reslice = reslice and style->Reslice = reslice.

Second, only one interactor style object is allowed, but you have two (the KeyPressInteractorStyle and the vtkInteractorStyleImage). To fix this problem, you should make your KeyPressInteractorStyle a subclass of vtkInteractorStyleImage.

Thank you for your help, I know you have a busy schedule.

I was able to understand how to adapt reslice to the interactor style.

I understood the need for subclassing.
But I don’t know what code to use for the subclass.
Can you tell me if possible?

@dgobbi

Instead of this:

class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera

Do this:

class KeyPressInteractorStyle : public vtkInteractorStyleImage

Sorry for my late reply.

Actual operation is now possible.
Thank you very much for your support.

Thank you in the future.