[vtkusers] vtkImageSlice using UserTransform
David Gobbi
david.gobbi at gmail.com
Tue Nov 26 22:14:50 EST 2013
Hi Miro,
I'm glad that you found the cause of the issue. I'm not sure
if this will be useful in your case, but I wrote a class called
vtkFollowerPlane, which is a plane that is always oriented
and positioned relative to the "followed" plane by a vtkTransform:
http://github.com/dgobbi/ToolCursor/blob/master/vtkFollowerPlane.h
David
On Tue, Nov 26, 2013 at 7:48 PM, Miro Drahos <mdrahos at robodoc.com> wrote:
> Hi David,
> so I found out my issue with transformation of the reslice planes.
> There were other actors that were being updated with the surface model
> transform, to keep them all in sync when user interacts. One of the actors
> to use this was drawing an intersection of the surface model and the reslice
> plane using vtkCutter, to provide a visual highlight of the intersection. I
> was indirectly updating the reslice plane through the cutter input, like:
>
> for (int i=0; i<3; i++)
> {
> vtkAlgorithm * alg =
> this->cutterActor[i]->GetMapper()->GetInputConnection(0, 0)->GetProducer();
> vtkCutter * cutter = vtkCutter::SafeDownCast(alg);
> if (cutter)
> {
> cutter->GetCutFunction()->SetTransform(t);
> cutter->Update();
> }
> }
>
> Which, of course, modified the reslice plane. Duh! Mystery solved...
> Thanks again for your response.
> Regards,
> Miro
>
>
>
> On 11/26/2013 03:29 PM, Miro Drahos wrote:
>>
>> 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
>>>>>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the VTK FAQ at:
>> http://www.vtk.org/Wiki/VTK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.vtk.org/mailman/listinfo/vtkusers
>
>
More information about the vtkusers
mailing list