[vtkusers] vtkImageSlice using UserTransform

Miro Drahos mdrahos at robodoc.com
Tue Nov 26 18:29:38 EST 2013


David,
Thank you very much for the valuable pointers that will make my code 
more robust.
I am quite confident that InteractionProp is what I think it is, as I 
change its properties (color, opacity) and see the changes in the scene. 
Also the surface model is being repositioned as it should, based on the 
UserMatrix that I set. I do have other objects in the scene, so I do 
have a test that checks that InteractionProp is indeed what it is.
The cameras are unlikely to be the culprit either, since I have the 
SliceAtFocalPointOff() and SliceFacesCameraOff() on the 
vtkImageResliceMappers. Also, I do have an orientation marker widget in 
the scene, so I see the orientation of the camera, and it doesn't 
change. There are also other objects in the scene, (another surface, 
markers) that don't change their relative position.
I wrote the picking callback class a couple months ago, with only minor 
changes since, it was well tested with the vtkResliceCursor and 
vtkResliceCursorLineRepresentation, so I thought there might be some 
internal link of vtkImageResliceMapper with the rendering pipeline that 
I don't see and you would recognize. Since that is not the case, I will 
dig deeper and try to investigate in further detail. Experience has 
taught me to hold the tendency to blame others' code and scrutinize mine 
in the first place :)
If I can't find the culprit, I will put together a compilable piece of 
code that would reproduce the issue.
Thanks again!
Miro



On 11/26/2013 03:01 PM, David Gobbi wrote:
> Hi Miro,
>
> The PokeMatrix() method is used internally by VTK during pick
> operations and render operations, so I advise against using it in your
> own code.  By doing so, you might interfere with VTK's own internal
> state machinery.  Also, all the PokeMatrix(matrix) does is cache the
> current actor state (i.e. position, orientation, UserMatrix, etc) and
> then replace the UserMatrix with the supplied matrix.   So for your
> purposes, you can just call SetUserMatrix() directly to achieve the
> same effect.  And, by calling SetUserMatrix() directly, you won't be
> disturbing the aforementioned actor state cache.
>
> Also, I recommend calling SetUserMatrix(NULL) instead of
> SetUserMatrix(identity).  Having the user matrix set to NULL allows
> the rendering machinery to enable certain optimizations.
> Incidentally, calling PokeMatrix(NULL) causes the actor to restore its
> state from its internal cache (i.e. this is what VTK's internally
> machinery does to restore the actor state, and this is why calling
> PokeMatrix() yourself can cause problems for VTK).
>
> With respect to vtkImageSlice moving unexpectedly, I suspect one of
> the following:
> 1) your interaction is actually moving the camera in addition to
> moving the mesh (or instead of moving the mesh)
> 2) your callbacks are setting the UserMatrix on the vtkImageSlice
> (i.e. what do you do to guarantee that  this->InteractionProp is never
> the vtkImageSlice?).
>
> So in general, if you haven't already done so, verify that your own
> callbacks are being called, and also verify that the mouse callbacks
> of VTK's own interactor style are _not_ being called.
>
>    - David
>
>
>
> On Tue, Nov 26, 2013 at 3:23 PM, Miro Drahos <mdrahos at robodoc.com> wrote:
>> Hi David,
>> thanks for the response.
>> I do not call SetUserMatrix(m) on vtkImageSlice, that's why I am quite
>> surprised to see it changing.
>> I am only manipulating the UserMatrix of vtkActor (of the surface model).
>> I was using actor->PokeMatrix(m) on each mouse move, let me illustrate with
>> some code:
>> //---------------------------------------------------
>> // triggered by means of vtkCommand::MouseMoveEvent
>> void PickImplantCallback::Pan()
>> {
>>      VTK_CREATE(vtkTransform, t);
>>      // ... build a transform based on interaction event positions
>>
>> this->InteractionProp->PokeMatrix(t->GetMatrix());
>>
>>      this->Render();
>> }
>>
>> //---------------------------------------------------
>> // triggered by means of vtkCommand::MouseButtonReleaseEvent
>> void PickImplantCallback::OnButtonUp()
>> {
>>      // transform the actual polydata
>>      VTK_CREATE(vtkTransform, t);
>> t->SetMatrix(this->InteractionProp->GetMatrix());
>>
>>      //... use vtkTransformPolyDataFilter to transform the vtkPolyData object
>>
>>      // reset the actor's matrix:
>>      VTK_CREATE(vtkMatrix4x4, identity);
>>      this->InteractionProp->PokeMatrix(identity);
>>
>>      // update the state vars, other cleanup
>>
>>      this->Render();
>> }
>>
>> This callback class doesn't even know about the vtkImageSlice, yet the
>> vtkImageSlice objects update their textures as the InteractionProp's matrix
>> is being updated, and then on button up reset the view that was before
>> interaction (as the InteractionProp's matrix is reset to identity).
>>
>> I have been using actor->PokeMatrix(m), which internally sets the
>> UserMatrix; I tried to change all actor->PokeMatrix(m) calls to
>> actor->SetUserMatrix(m) but that doesn't change anything.
>>
>> Best,
>> Miro
>>
>>
>>
>> On 11/26/2013 01:25 PM, David Gobbi wrote:
>>> Hi Miro,
>>>
>>> Let me see if I understand... you have a vtkImageSlice, and you have a
>>> vtkActor, and you have a matrix.  You call SetUserMatrix(matrix) on
>>> the vtkImageSlice, and you call SetUserMatrix(matrix) on the vtkActor.
>>>    Finally, you use the vtkRenderWindowInteractor to interact with the
>>> vtkActor.
>>>
>>> Why not call a DeepCopy on the original matrix, so that the
>>> vtkImageSlice and the vtkActor each has its own matrix?
>>>
>>> matrix2 = vtkMatrix4x4::New();
>>> matrix2->DeepCopy(matrix);
>>> imageSlice->SetUserMatrix(matrix2);
>>> actor->SetUserMatrix(matrix);
>>>
>>>     David
>>>
>>>
>>>
>>> On Mon, Nov 25, 2013 at 6:31 PM, Miro Drahos <mdrahos at robodoc.com> wrote:
>>>> Hi David,
>>>> I was hoping you could advise on an issue I am experiencing with
>>>> vtkImageSlice.
>>>> Together with the sliced image I am rendering a surface model in the
>>>> scene,
>>>> that the user needs to be able to pick and interact with. When the
>>>> surface
>>>> (~ 20000 vertices) is picked, I call SetUserMatrix() on its actor to
>>>> render
>>>> the translation or rotation that user is performing in real-time.
>>>> This, however has a side-effect that vtkImageSlice uses the matrix and so
>>>> the displayed slice is modified during the interaction.
>>>> Is there a way to tell vtkImageSlice not to use the UserMatrix? Or
>>>> perhaps
>>>> is there a better way to set the transformation matrix on the surface/its
>>>> actor to render the interaction?
>>>> I turned SliceAtFocalPointOff() and SliceFacesCameraOff() but that
>>>> doesn't
>>>> change this behavior.
>>>> Thank you!
>>>> Miro
>>>>



More information about the vtkusers mailing list