How to import a .vtu file programmatically?

Hi,

When I import a VTU file (e.g. the example file data/mesh/3d/nickel_superalloy.vtu) in CMB, it loads it successfully, displaying the following message in the Output Messages window:

INFO: smtk::session::vtk::Import: operation succeeded

However, when I want to do it programmatically in C++ using

// Create a read operator
auto readOp = smtk::session::vtk::Import::create();
if (!readOp) {
    std::cerr << "No read operator\n";
    return 1;
}

// Set the file path
std::cout << "readOp parameters: " << readOp->parameters() << std::endl;
readOp->parameters()->findFile("filename")->setValue(modelPath);

// Execute the operation
smtk::operation::Operation::Result readOpResult = readOp->operate();

it fails with

Exodus Library Warning/Error: [vtkexodusII_exi_check_file_type]
        ERROR: Could not recognize /home/zc/CMB_build/superbuild/smtk/src/data/mesh/3d/nickel_superalloy.vtu as a valid Exodus/NetCDF file variant.  Magic value is '<?xm'
        Integer sizes must match for input and output file in ex_copy.

Exodus Library Warning/Error: [vtkexodusII_ex_open_int]
        ERROR: failed to open /home/zc/CMB_build/superbuild/smtk/src/data/mesh/3d/nickel_superalloy.vtu of type 0 for reading.
        Either the file does not exist,
        or there is a permission or file format issue.
        NetCDF: Unknown file format
2025-11-24 11:15:36.765 (  52.775s) [    7FFFEC722180]  vtkExodusIIReader.cxx:3858   ERR| vtkExodusIIReaderPrivate (0x5555556938e0): Unable to open "/home/zc/CMB_build/superbuild/smtk/src/data/mesh/3d/nickel_superalloy.vtu" for reading
2025-11-24 11:15:36.765 (  52.775s) [    7FFFEC722180]  vtkExodusIIReader.cxx:5509   ERR| vtkExodusIIReader (0x555555693240): Unable to open file "/home/zc/CMB_build/superbuild/smtk/src/data/mesh/3d/nickel_superalloy.vtu" to read metadata
2025-11-24 11:15:36.765 (  52.775s) [    7FFFEC722180]       vtkExecutive.cxx:729    ERR| vtkCompositeDataPipeline (0x5555556958f0): Algorithm vtkExodusIIReader (0x555555693240) returned failure for request: vtkInformation (0x555555696c20)
  Debug: Off
  Modified Time: 98
  Reference Count: 1
  Registered Events: (none)
  Request: REQUEST_INFORMATION
  ALGORITHM_AFTER_FORWARD: 1
  FORWARD_DIRECTION: 0

The cause of the problem is that the .vtu extension is not supported, so the default Exodus reader is called. This function calls importExodusInternal, where the failure happens, resulting in the logged message above. It makes sense that trying to import a .vtu file with the Exodus importer fails. But then what does CMB do differently that it can import a .vtu file with smtk::session::vtk::Import?

I tries various methods.

  • I set in ToolsLog Viewer the verbosity level to TRACE to try to figure out what happens behind the scenes in CMB. Unfortunately, it only displays ParaView-related information (pipeline update, rendering info, etc.), not showing a detailed SMTK log.
  • I was looking for examples that import .vtu files, but found none (the closest I found was session/vtk/testing/cxx/ImportMultipleFiles.cxx).
  • I tried to attach a debugger to the running CMB instance to follow what it does. To which .so file should I attach the debugger. I am sure that this approach will work because I compiled SMTK and CMB in debug mode, moreover I can successfully attach GDB to my custom reader plugin. I just don’t know which .so – and the corresponding C++ source files – is responsible for importing a file in the CMB GUI.

By the way, in the user doc, does the discrete session correspond to the smtk::session::vtk namespace in SMTK?

Partial success: I found out that it is libsmtkVTKSession.so that I need to attach the debugger. Moreover, I need to import the .vtu file with smtk::markup::Import, which in turn calls smtk::extension::vtk::io::ImportAsVTKData. So the following questions remain:

  1. Is there a way to print (or log) what SMTK operations are executed in CMB?
  2. Why can’t I import a .vtu file with smtk::session::vtk::Import, but with smtk::markup::Import?
  3. Should I use smtk::markup::Import or directly smtk::extension::vtk::io::ImportAsVTKData?

@CsatiZoltan Sorry for the slow reply; I’ve been snowed under.

Yes, you can record traces in python using the Tools→Start Trace menu item.

We just haven’t had a need for that feature yet; the funding source for the markup resource did not need VTU support.

You could modify an existing import operation in SMTK (either markup or the VTK session) and submit a patch (or maintain it yourself). Each resource has its own way of modeling discrete data. The markup resource is newer and more flexible that the VTK session.

However, in addition to adding support for VTU files to an existing operation, you can add a new operation to either the markup resource or the VTK session to import data in VTU format. SMTK has a feature (and corresponding class) called an operation group. Operations that accomplish the same work and with similar parameters (but may vary in other ways) are added to an operation group. Then, applications can use any operation in the group to perform the same work. SMTK has an ImporterGroup for operations that import data from a non-native format into a resource. All importers must have a filename parameter (the file to be imported) with a list of supported filetype extensions. Applications can find an operation in the group that promises to handle the given filetype extension and set the filename parameter without needing to know more about the operation.

I have a merge request up that makes adding a python importer for the markup resource possible and I’ll try to provide an example for it over the weekend. The markup resource’s UnstructuredData component can present VTK data (polydata or an unstructured grid) as a discrete model via its setShapeData() method. This method allows you to indicate that point- and/or cell-IDs between components are shared, but you likely don’t care about that yet. The idea is that a volumetric mesh might be one component in the resource while portions of its boundary could be a collection of other components that share point IDs on the boundary.