Howto wrap a class that does not subclass vtkObject

Hi there,

as far as I can tell, subclassing from vtkObject automatically includes the class in the wrapping process.
How do you tell the wrapper to also include additional classes that do not subclass vtkObject?

Best regards
Jens

Nothing special should be required to wrap these classes, except that they need to have a public copy constructor. Some very brief documentation is given here.

In order for the wrappers to see the header for the class, it must be placed in a module like this example.

Thanks for the answer and links, I’ll have a look.
Is there more information specific to java wrapping?

Ah, sorry. I thought you were asking about Python wrapping. For Java wrapping, only vtkObjectBase classes can be wrapped, and wrapping documentation is virtually non-existent. As far as I understand, java wrapping of external modules isn’t even supported in VTK 9. Only the classes within VTK itself are wrapped for java.

The macros should work to generate the code, but the inter-project dependencies are not there. So you can make a .jar, but loading it is a manual process.

What I am trying to do is not exactly external, vtkOBBTree has an internal data structure, vtkOBBNode, which we need java access for.

So I moved the nested class vtkOBBNode from vtkOBBTree to its own header and src files.
Now I am trying to get it to wrap for java without the need to subclass from vtkObject.
But having read your post, this approach does not work.
Now I try to subclass from vtkObject and hope that somehow works.

Note that you can derive from vtkObjectBase, which is more lightweight than vtkObject.

To convert vtkOBBNode into a vtkObjectBase, it will need

  1. vtkTypeMacro()” and and “static vtkOBBNode* New()” in its definition
  2. vtkStandardNewMacro(vtkOBBNode)” in its .cxx file

Its allocation/deletion in vtkOBBNode.cxx will probably also have to change. All “new vtkOBBNode” will have to become “vtkOBBNode::New()”. All deletions such as “delete this->Tree;” become “this->Tree->Delete();

Thank you for the hints!
You mean the usage of new vtkOBBNode and equivalents of delete this->Tree; have to change over the entire vtk codebase, e.g. in vtkOBBTree and in vtkOBBDicer and so on to
::New() and ->Delete()?

Note that I said “probably”. A proper vtkObject has a protected constructor/destructor and therefore must be constructed/destructed with New() and Delete(). But if you’re doing something purely for your own use, you might be able to leave the constructor/destructor public (but then vtkOBBNode wouldn’t participate in VTK’s garbage collection, and I’m not sure what the side-effects would be).

AFAIK, stack allocation of vtkObjectBase is not possible because what does this code do?

vtkNew<vtkObject> obj_heap;
{
    vtkObject obj_stack;
    obj.Register(obj_heap);
    // `obj_stack` is *definitely* going away, but its dtor will do "nothing" because it has reference counts, but access will be UB.
}

I’m afraid that vtkObjectBase is just incompatible with stack usage due to design decisions made 20+ years ago.

Fortunately vtkOBBNode is only ever allocated on the heap.

Since vtkOBBNode is a protected field in vtkOBBTree how do you intend to access it in your wrapper code?

Is the class needed only for the callback in vtkOBBTree::IntersectWithOBBTree? If so I suggest you redefine the callback passing double Corner[3] and double Axes[3][3] parameters for each node instead. Then overload the public methods of vtkOBBTree which require vtkOBBNode with the same parameters.

I created an new Method vtkOBBNode* GetRootOfTree(); to get the root node.

I don’t know exactly what my colleague needs yet so I exposed the entire OBBNode and created getters for its properties.

Yes, it worked with swapping new for ::New() and delete for ->Delete().
Thanks to all the commenters, your input was invaluable to solve this!