model data structure in vtk.js, please explain please help

Please explain the vtk.js data structure, expecially how ‘model’ is used. For example, const range = imageData.getPointData().getScalars().getRange();
if you go through debugger, you can see imageData is a bunch of useless public APIs with no data provided,
if you step into getPointData() function, you will get this line
publicAPI[get${capitalize(field)} ] = () => model[field];
, I tried and tried but couldn’t understand where model[] is defined, and how does macro.js thing work, please help! Please give some tips, thank you!

is there a way to see the actual data structure of imageData within a debuger?

I am trying to understand the magic in macro.js, I am looking at

imageData.getPointData()

, and once I step into it with chrome I suddenly get this

export function get(publicAPI, model, fieldNames) {
fieldNames.forEach((field) => {
if (typeof field === ‘object’) {
publicAPI[get${capitalize(field.name)}] = () => model[field.name];
} else {
publicAPI[get${capitalize(field)}] = () => model[field];
}
});
}

I cannot find where model[] is defined, although it is used everywhere in macro.js. Why a function without any parameters suddenly becomes a function with three parameters. What technique was employed here, there is no comment in macro.js for its usage, any documentation to understand this huge jump in code logic?

Any tip would be great, thanks!

Anyway to see the actualy data in a vtk object, e.g, imageData? the data must be somewhere stored in ‘model’, but it seems completely hidden from the chrome debugger by the publicAPIs. it is frustrating not being able to check the actual data. The publicAPI properties does not tell you anything about the object. So if I want to printout the data in imageData, what should I do?

Finally found the solution, have to use the get() call to get the actual data (model). it’s cumbersome to check the entire object tree in this way but at least it can be checked in chrome now.

I still don’t understand why you need to have access to the model? If you want something specific get it from the API or a subset via get('a', 'b'). But normally even that should not be allowed. That is the point of having things private/protected.

I still couldn’t get it, why VTK data structure is designed this way, everything is a function, which means virtual and abstract. The real data is completely hidden from you and the chrome debugger.

No real documentation, the VTK textbook is really a computer graphic textbook, not a programmer’s manual.

The learning curve is HUGE, not just huge, there is no where to start to learn. No reasonable tutorial written or explained clearly can be found on the internet. For example, I want to understand what the actor/mapper actually do, then I got this

"
vtkMapper is an abstract class to specify interface between data and
graphics primitives. Subclasses of vtkMapper map data through a
lookuptable and control the creation of rendering primitives that
interface to the graphics library. The mapping can be controlled by
supplying a lookup table and specifying a scalar range to map data
…"

Everything is explained in an abstract way so a common people cannot understand.

Actually, only if the actual data were exposed I could have understood lots of things by checking the data structure and data content, but now I’m stuck… two things to learn from three.js, 1, no strange names, 2, I can actually check and exam the data with chrome debugger.

1 Like

For example, I want to check the size and the content of 2 vol3D object, here is what I finally had to do to get a look at the data.

vol3D[0].getMapper().getInputData().getPointData().get().arrays[0].data.get().size

I was able to do this because of the previous .get() tip you provided.

It would be so much easier to be able to check directly,
vol3D[0].mapper.inputData.pointData[0].size
, and this way you can also check it by clicking through in chrome debugger

Finding .getMapper() is the key, as there are 100+ functions in vol3D, still not sure what the actor/mapper does, seems mapper provides the input/actual data, then what is actor, in vol3D getActors() returns an empty array.

For a better understanding of the mappers and actors, you can read the VTK C++ books, we reuse the same idea in VTK.js.

Please note that we recently added some tutorials.

Finally, please note that we can do live training as well.

Another point is that all the data structures are protected by function so we can monitor changes and properly update the pieces that needs update (filter, rendering code, …) and only when truly required. If we were following the “all public fields” approach of usual JavaScript code, you will get JS dev scratching their head on why things are not working like it was supposed to.

To comment on your access pattern, if you followed the C++ guide explaining the various data structures (meshes[imagedata/polydata/…/dataset], pipeline[algorithm], rendering[renderwindow/renderer/actor/mapper]), you will notice that you could do:

const actor = vol3D[0];
const dataset = someActor.getMapper().getInputData();
console.log(dataset.getNumberOfPoints()); // That was probably what you were looking for

const dataArray = dataset.getPointData().getArray(0); // Usually we prefer getting the array by their name rather than index
console.log(dataArray.getName());
console.log(dataArray.getNumberOfTuples());
console.log(dataArray.getNumberOfComponents()); 
const typedArray = dataArray.getData(); // raw data array
console.log(typedArray.length)

Nobody is saying VTK is simple, but unfortunately there is a reason behind some of that complexity.

I agree that the documentation alone isn’t nearly sufficient for someone new to vtk to understand how to use vtk.js. I hope we can improve this. For now, a couple of tips that helped me learn:

  • A reasonable understanding of VTK concepts from C++ VTK is necessary to work with vtk.js. Otherwise it will be very difficult, because many of those concepts are assumed to be understood. The transition from C++ vtk to vtk.js is a lot more natural than the transition from another javascript graphics library to vtk.js.
  • Use the examples. Whenever I want to do something, I find a similar example and work from there. They are more useful than the documentation, for now at least.
  • To understand from the code how “classes” are being constructed, it’s good to look at what newInstance does in macros.js. I basically couldn’t debug anything until I understood how this works, and I don’t think we really document it anywhere…