[vtkusers] vtkImageSlice using UserTransform
Miro Drahos
mdrahos at robodoc.com
Wed Nov 27 19:36:11 EST 2013
Hi David,
I will have a look at the vtkFollowerPlane after the holidays.
I am quite sure that there are useful things there for me to learn from.
Thank you!
Miro
On 11/26/2013 07:14 PM, David Gobbi wrote:
> 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