vtkSplineWidget with undo/redo buttons

Hello!

I’m working with vtkSplineWidget based on the example vtk.js.

My task is to draw a figure on a 3D image and being able to delete and return a deleted point during the drawing process (undo/redo buttons). Everything worked well until I noticed that when I first press undo (remove the point), and then redo (return this point which saved in a variable back), and then hovering over this point to be able to move it (I set resetAfterPointPlacement: false) I get the following error:

At the same time, if I don’t use the undo and redo buttons, then everything works as it should. Buttons code:

const undo = () => {
    const { splineWidgetManager, renderWindow } = context.current

    const coordinatesList = splineWidgetManager
      .getWidgets()
      [splineWidgetManager.getWidgets().length - 1].getWidgetState()
      .getState().handleList

    const currentWidget = splineWidgetManager
      .getWidgets()
      [splineWidgetManager.getWidgets().length - 1].getWidgetState()

    setRemovedCoordinate(coordinatesList[coordinatesList.length - 1])

    currentWidget.removeHandle(coordinatesList.length - 1)

    renderWindow.render()
  }
  const redo = () => {
    const { splineWidgetManager, renderWindow } = context.current

    const currentWidget = splineWidgetManager
      .getWidgets()
      [splineWidgetManager.getWidgets().length - 1].getWidgetState()

    currentWidget.addHandle(removedCoordinate)

    renderWindow.render()
  }

I also noticed that if I use the undo/redo scenario while drawing, then in the widgetManager the coordinate that was deleted and returned will not have a handleOrigin property inside manipulator object when the drawing of the figure is completed.

Coordinate which was just drawn:

Coordinate which was drawn, deleted and returned:

So, what can cause these errors?

Calling getState() will serialize your widget state. When you go add it back, it doesn’t get serialized. I would just use getWidgetState().getHandleList(), unless you need to serialize the widget state.

Currently most widgets assume to be controlled uniquely by the mouse events and not programatically. If you look at SplineWidget/behavior.js you will notice that setOrigin() (and other important calls) is called on each new handle.
addPoint() should probably made public so that your undo/redo mechanism could call it (and it could correctly initialize each created handle.

Thanks for your reply.

It turns out that within the current version of vtk.js the behavior described by me cannot be implemented with the functions of the vtkSplineWidget that comes out of the box?

And then question arises: for what purposes is the addHandle() function needed and what use cases might it have if interaction with the mouse is necessary to correctly add a point?

I would also like to know if it is possible to control the position of the drawn figure on the 3D image so that the drawing happen on the side that is facing the camera. For example, considering this example vtk.js the line always appears strictly inside and in the center of the cube, regardless the side of cube that is facing the camera. So, is it possible to do it like this:

taking into account that if the cube is turned with the opposite side towards the camera, the next new drawing will appear exactly on that side?

It turns out that within the current version of vtk.js the behavior described by me cannot be implemented with the functions of the vtkSplineWidget that comes out of the box?

From what you describe, it seems that your statement is correct. Small VTK.js internal changes are required.

And then question arises: for what purposes is the addHandle() function needed and what use cases might it have if interaction with the mouse is necessary to correctly add a point?

addHandle() is a low-level function (to modify the Model in the ModelViewController paradigm), however there must be other configuration required (the Controller part in the ModelViewController paradigm).

I would also like to know if it is possible to control the position of the drawn figure on the 3D image so that the drawing happen on the side that is facing the camera. For example, considering this example vtk.js the line always appears strictly inside and in the center of the cube, regardless the side of cube that is facing the camera. So, is it possible to do it like this:

It should be possible. This depends on the type of manipulator. You should use a PickerManipulator instead of a PlaneManipulator.