vtkSphereSource dragging inside 3D image

Hello everyone!

I have a 3D image with a regular vtkRenderWindowInteractor and vtkInteractorStyleTrackballCamera.

Additionally, I’ve added a vtkSphereSource inside:

My question is: how can I enable dragging this sphere with the left mouse button within the outline? (restricting dragging outside the outline is not mandatory for me) Also, is it possible to track the moment when the dragging is finished and, for instance, output something to the console upon the completion of this event?

Here is my vtkSphereSource code:

import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper'
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'
import { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants'
import vtkSphereSource from '@kitware/vtk.js/Filters/Sources/SphereSource'

const sphereSource = vtkSphereSource.newInstance()

const bds = imageSource.getBounds()

sphereSource.setThetaResolution(10)
sphereSource.setPhiResolution(10)
sphereSource.setRadius(30)
sphereSource.setCenter(
  0.5 * (bds[0] + bds[1]),
  0.5 * (bds[2] + bds[3]),
  0.5 * (bds[4] + bds[5])
)

const sphereMapper = vtkMapper.newInstance()
sphereMapper.setInputConnection(sphereSource.getOutputPort())
const sphereActor = vtkActor.newInstance()
sphereActor.setMapper(sphereMapper)
sphereActor.getProperty().set({
  representation: Representation.SURFACE,
})

imageRenderer.addActor(sphereActor)

Shall you just want to drag a sphere, you might want to consider using a vtkHandleWidget (sphere by default). You would then need to control the widget “manipulator” to prevent from moving outside the cube.

A more robust solution is to rely on a transform controller widget. It’s a bit of work, but would be a great addition.

For me, simply being able to drag the sphere around will be enough. But I can’t find vtkHandleWidget. I am using vtk.js v29.1.3 and it looks like it was in vtk.js before, but for now this widget has been removed, isn’t it?

I guess a vtkSeedWidget would do it (you would need to overwrite getRepresentationsForViewType() to return a vtkSphereHandleRepresentation instead of a vtkCubeHandleRepresentation)

Are you sure this might be suitable in my case? It is important for me that the example code that I gave above remains untouched, because I think that I cannot do things without vtkSphereSource.

In general, I’m trying to reproduce the functionality of streamlines in paraview and using vtkSphereSource I succeeded well. All that remains is to make this sphere draggable, as in ParaView:

It would also be very useful to be able to similarly drag a line (vtkLineSource) at both ends.

Is all this possible?

From what you describe (i.e. add streamlines), it seems that vtkSeedWidget and vtkLineWidget is what you need.

Do you think widgets are suitable for these purposes? I studied the difference between Source and Widget and it seems to me that widgets lack important methods that are in Source, for example, for vtkLineWidget I could not find:
– setResolution();
– setPoint1();
– setPoint2();
– getOutputPort();

but I am able to find it in vtkLineSource.

About the same with vtkSeedWidget/vtkSphereWidget.

Studying the VTK code in Python, I can conclude that the e.g. vtkLineWidget has methods that are described a little above, but in vtk.js it does not.

Of course, this is my opinion, based on this streamlines example: vtk.js where Source is used. Maybe there is a completely different way to do the same thing with Widgets, however, I need the widget to be drawn by itself from the start of the application (not by the user’s hands), but after that its position can be adjusted by the user’s hands.

Widgets are meant to be mouse interactive. They internally use sources. You can therefore customize the source properties to your needs.
(InteractorStyles are meant to control only the camera.)

You can place/initialize the widgets programmaticaly.

Alright, could you please provide some tips on how I can reach or customize the properties that I need using the widgets rather then the sources (for example getOutputPort() method). I am not sure that I have seen that mechanism before…

I’m not sure why you need to use getOutputPort().
You can customize properties use getRepresentations()[0 or 1 or 2...] on the widget.

1 Like

I think you meant getRepresentationsForViewType(), rather than getRepresentations().

So, with vtkSeedWidget.newInstance().getRepresentationsForViewType()[0].builder.newInstance() I get the bunch of additional methods and can I use them for more advanced functionality for vtkSeedWidget just accessing them via ...builder.newInstance()...?

By the way, there are still no some functions that were in Sources.

I meant getRepresentations() and not getRepresentationsForViewType() .

You are not supposed to call getRepresentationsForViewType() yourself. It will be done automatically by widgetManager.addWidget().

I don’t know what my mistake is, but I can’t find the getRepresentations() method in the body of vtkLineWidget.

I also want to ask, speaking of streamlines, is it possible to select Integration Direction in vtk.js? Same as in ParaView:

Thanks for the clarification, but I don’t see that we mentioned vtkAbstractWidget earlier. Moreover, I can’t even do vtkAbstractWidget.newInstance() because I get the error:

It is also important for me to get an answer from you on this issue:

vtkAbstractWidget is a pure abstract class, hence it can’t be instantiated directly. Subclasses can be subclasses.

Regarding streamlines, I do not know from the top of my head. I would need to check, which I can’t do it without a support contract. Sorry.

1 Like