1111
(Tomonari Hayakawa )
August 10, 2019, 6:33am
1
Hi,
I want to display the slice plane selected by vtkImplicitPlaneWidget2 as a two-dimensional image while synchronizing in another window.
Can you tell me how to display while synchronizing?
The code to reslice was created as follows:
// Extract a slice in the desired orientation
vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceMatrix);
reslice->SetInterpolationModeToLinear();
reslice->SetOutputOrigin(0.0, 0.0, 0.0);
reslice->SetOutputExtent(0, n-1, 0, n-1, 0, 0);
reslice->SetOutputSpacing(s, s, s);
// Create a greyscale lookup table
vtkSmartPointer<vtkLookupTable> table =
vtkSmartPointer<vtkLookupTable>::New();
table->SetRange(0, 500); // image intensity range
table->SetValueRange(0.0, 1.0); // from black to white
table->SetSaturationRange(0.0, 0.0); // no color saturation
table->SetRampToLinear();
table->Build();
// Map the image through the lookup table
vtkSmartPointer<vtkImageMapToColors> Imagecolor =
vtkSmartPointer<vtkImageMapToColors>::New();
Imagecolor->SetLookupTable(table);
Imagecolor->SetInputConnection(reslice->GetOutputPort());
// Display the image
vtkSmartPointer<vtkImageActor> actor =
vtkSmartPointer<vtkImageActor>::New();
actor->GetMapper()->SetInputConnection(Imagecolor->GetOutputPort());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
vtkSmartPointer<vtkRenderWindow> window =
vtkSmartPointer<vtkRenderWindow>::New();
window->AddRenderer(renderer);
@dgobbi
dgobbi
(David Gobbi)
August 10, 2019, 7:28pm
2
Use a callback. The TestImplicitPlaneWidget2 example code will give you some ideas.
2 Likes
1111
(Tomonari Hayakawa )
August 11, 2019, 4:21am
3
Thank you for your reply.
I would like to refer to TestImplicitPlaneWidget2.
Does that mean you need to make the callback in vtkImplicitPlaneWidget2 also apply to vtkImageReslice?
@dgobbi
1111
(Tomonari Hayakawa )
August 20, 2019, 9:28am
4
Hi,
After manipulating in the window, I want to know the normal and center and adapt to a 4x4 matrix.
I’ve studied, but I don’t know how to update the normals and origins using callback.
Can you give me a hint if possible?
The code for the callback part is shown below.
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);
//this->Actor->VisibilityOn();
}
vtkIPWCallback():Plane(0),Actor(0) {}
vtkPlane *Plane;
vtkActor *Actor;
};
@dgobbi
dgobbi
(David Gobbi)
August 21, 2019, 3:59pm
5
The callback also needs `vtkImageReslice *Reslice;" as a member.
And the Execute() method must compute the ResliceAxes matrix and call Update().
(The Actor member is not needed, it can be removed).
Of course, the callback must be connected to the widget:
myCallback->Plane = plane;
myCallback->Reslice = reslice;
planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback);
1111
(Tomonari Hayakawa )
August 23, 2019, 2:03am
6
Thank you for your reply.
The callback also needs `vtkImageReslice *Reslice;" as a member.
Does this mean creating a new call back (vtkImageReslice * Reslice) in addition to vtkIPWCallback as follow?
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);
}
vtkIPWCallback():Plane(0) {}
vtkPlane *Plane;
};
class vtkIRCallback : public vtkCommand
{
public:
static vtkIRCallback *New()
{ return new vtkIRCallback; }
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkImageReslice *reslice =
reinterpret_cast<vtkImageReslice*>(caller);
}
vtkIRCallback():Reslice(0) {}
vtkImageReslice *Reslice;
};
dgobbi
(David Gobbi)
August 23, 2019, 2:23am
7
No, only one callback (the vtkIPWCallback).
The callback should get the Plane, create the matrix, and put the matrix into vtkImageReslice.
1111
(Tomonari Hayakawa )
August 23, 2019, 4:04am
8
Thank you.
I understand.
Do I need to include code to calculate a 4x4 matrix in Excute()?
dgobbi
(David Gobbi)
August 23, 2019, 12:43pm
9
Yes. Of course it would be best to write a function that computes the vtkMatrix4x4 from the vtkPlane, and to call that function from Execute.
1111
(Tomonari Hayakawa )
August 29, 2019, 5:05am
10
Thank you for reply.
I created Excute () including 4x4 matrix calculation.
Can you tell me if there are improvements in the code below?
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;
};
@dgobbi
dgobbi
(David Gobbi)
August 29, 2019, 12:44pm
11
In your example, where does Execute() start and where does it end?
1111
(Tomonari Hayakawa )
August 30, 2019, 2:19am
12
The edited version is shown below.
Can you give me some advice?
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;
};
dgobbi
(David Gobbi)
August 30, 2019, 2:47am
13
Yes, that should be okay.
Does Execute() also call Reslice->SetResliceAxes(matrix)?
1111
(Tomonari Hayakawa )
August 30, 2019, 3:16am
14
Does Execute() also call Reslice->SetResliceAxes(matrix)?
Does it mean to include Reslice-> SetResliceAxes (matrix) in Execute ()?
I’m sorry, can you tell me a little more?
@dgobbi
1111
(Tomonari Hayakawa )
September 4, 2019, 2:31am
15
Hi,
I want to adapt the computed 4x4 matrix to Reslice.
I am thinking about how to adapt the reslice by calling the calculated 4x4 matrix.
Therefore, the following code was added after the compute of the 4x4 matrix.
Please let me know if you have any improvements.
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)
vtkImageReslice *reslice = this->Reslice;
reslice->SetResliceAxes(resliceMatrix);
reslice->Update();
}
vtkIPWCallback():Plane(0) {}
vtkPlane *Plane;
vtkImageReslice *Reslice;
};
The code for Reslice is as follows:
vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceMatrix);
reslice->SetInterpolationModeToLinear();
reslice->SetOutputOrigin(0.0, 0.0, 0.0);
reslice->SetOutputExtent(0, n-1, 0, n-1, 0, 0);
reslice->SetOutputSpacing(s, s, s);
myCallback->Reslice = reslice;