# Tutorial: My First VTFx

This tutorial shows how to write your own VTFx file from scratch.

This tutorial describes how to create a minimal VTFx file containing one database with a single cube, one state (i.e. time step) and one case.

Create and configure the File instance

Create the file instance and specify the output filename and the file settings for this file. To keep it simple, just specify an application name and vendor name. See `FileSettings` for other available settings.

        // Create the VTFx file
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::File> file = new cee::vtfx::File;

        // Create VTFx file settings struct
        cee::vtfx::FileSettings fileSettings;
        fileSettings.applicationName = "VTFx: VTFxMinimal";
        fileSettings.vendorName = "My Company AS";

        // Let the API create the VTFx file
        const cee::Str fileName = "ExampleMinimal.vtfx";
        if (!file->create(fileName, fileSettings))
        {
            return EXIT_FAILURE;
        }

Create database and case

The database collects all data blocks (`NodeBlock`, `ElementBlock`, `GeometryBlock`, …) for a file. The case represents one configuration of the visualization of a VTFx database. Several cases can use the same database but with a different set of properties describing the actual visualization.

A `cee::vtfx::File` can have several databases and cases, but for this simple example we will only create one database (with id = 1) and one case (with id = 1) referencing the database. The database and case take the file instance as a parameter upon construction.

        // Create a single database (could have many)
        cee::PtrRef<cee::vtfx::Database> database = new cee::vtfx::Database(file.get(), "Only Database", 1, cee::vtfx::Database::SIMULATION_TYPE_STRUCTURAL, cee::vtfx::Database::SOLUTION_TYPE_TRANSIENT, "Database description"); // database id 1

        // Create a single case (could have many)
        cee::PtrRef<cee::vtfx::Case> singleCase = new cee::vtfx::Case(file.get(), "Only Case", 1, 1); // case id 1 using database with id 1

Add nodes

The node block is a block that stores node coordinates. Node ids can also be specified, but for this simple tutorial, we will only be using node indexes.

Create the node block (with id = 1) with withNodeIds set to false.

This part is a cube so we add eight nodes. The node coordinates can either be added as an array of `cee::Vec3f` or as an interleaved float array (x,y,z,x,y,z,x,y,z,…).

When done, we write this block to the database instance.

        // Create the node block
        cee::PtrRef<cee::vtfx::NodeBlock> nodeBlock = new cee::vtfx::NodeBlock(1, false); // node block id 1, not using node ids

        // Set the node data (Note: The VTFx component expects interleaved node coordinates (xyzxyzxyz...))
        const float NODES_PART[] =
        {
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            1.0f, 1.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 1.0f,
            1.0f, 1.0f, 1.0f,
            0.0f, 1.0f, 1.0f
        };

        std::vector<float> nodesPart(NODES_PART, NODES_PART + sizeof(NODES_PART) / sizeof(NODES_PART[0]));
        if (!nodeBlock->setNodes(nodesPart))
        {
            return EXIT_FAILURE;
        }

Add elements

An element block describes the connectivity table for the elements. The nodes in the table can be referred to by index or id.

First we create an element block (with id = 1). Since we created the node block above without using ids, we will not reference nodes by ids so we set referNodesByIds in the constructor to false. The node block used to define the elements is specified by `setNodeBlockId(1)` which is the node block id.

This tutorial only has one hexahedron element. An element is described by the nodes that define it. For a single hexahedron element, it takes eight nodes. (See `ElementBlock::ElementType` or a full list of supported element types.)

        // Create the element block
        cee::PtrRef<cee::vtfx::ElementBlock> elementBlock = new cee::vtfx::ElementBlock(1, false, false); // element block id 1, not using element ids, referring nodes by index
        elementBlock->setNodeBlockId(1); // Use node block with id = 1

        // Set the element data
        const int CONNECTS_PART[] =
        {
            0, 1, 2, 3, 4, 5, 6, 7
        };

        std::vector<int> elementNodes(CONNECTS_PART, CONNECTS_PART + sizeof(CONNECTS_PART) / sizeof(CONNECTS_PART[0]));
        if (!elementBlock->addElements(cee::vtfx::ElementBlock::HEXAHEDRONS, elementNodes))
        {
            return EXIT_FAILURE;
        }

        // Write the element block
        if (!database->writeBlock(elementBlock.get()))
        {
            return EXIT_FAILURE;
        }

Add geometry

The geometry block bundles all elements contained in this geometry.

First, create the geometry block. Each database can - and must - have only one geometry block. In the `GeometryBlock` constructor, set number of geometries per state to 1. In most cases, a single geometry containing all element blocks will fulfill your needs.

Add the elements to the geometry block by using the element block ids. For this file, there’s only one element block (with id = 1), itself containing a single element. Specify an id (for instance, id = 1) for the part that uses this element block. A part can only contain one element block.

You also need to add meta data about the geometry using a geometry info block. Create the geometry info block and set the geometries per state to 1 (same as for the `GeometryBlock` above). Add a meta data for a part specifying part id used in the geometry block and a part name.

        // Create geometry block
        cee::PtrRef<cee::vtfx::GeometryBlock> geoBlock = new cee::vtfx::GeometryBlock(1); // Only one geometry per state

        size_t geoIndex = 0;
        int partId = 1;

        // Set to use element block with id 1
        if (!geoBlock->addElementBlock(geoIndex, 1, partId)) // Element block with id = 1
        {
            return EXIT_FAILURE;
        }

        // Write the geometry block
        if (!database->writeBlock(geoBlock.get()))
        {
            return EXIT_FAILURE;
        }

        // Create geometry info block
        cee::PtrRef<cee::vtfx::GeometryInfoBlock> infoBlock = new cee::vtfx::GeometryInfoBlock(1); // Only one geometry per state
        infoBlock->addPartInfo(geoIndex, partId, cee::Str("Only part"));

        // Write the geometry info block
        if (!database->writeBlock(infoBlock.get()))
        {
            return EXIT_FAILURE;
        }

Add a state

Create a `StateInfoBlock` containing the meta data of states. There must be only one state info block in each database.

Add meta data for single state with id = 1 and give it a suitable name, reference value and define the reference value type.

        // Create state info block
        cee::PtrRef<cee::vtfx::StateInfoBlock> stepInfo = new cee::vtfx::StateInfoBlock;
        if (!stepInfo->addStateInfo(1, "Only step", 42.0f, cee::vtfx::StateInfoBlock::TIME))
        {
            return EXIT_FAILURE;
        }

        // Write the state info block
        if (!database->writeBlock(stepInfo.get()))
        {
            return EXIT_FAILURE;
        }

Finally, close the file and it will be written to disk.

        // Finally close the file
        if (!file->close())
        {
            return EXIT_FAILURE;
        }

If any error occurred when writing the file, a log message should have been created. Check the log for further information on what went wrong. See the Logging page for more information on how to set up logging.

See the complete source code here:

Minimal VTFx File

Conversation saved
HOOPSY BETA

### Hello! I'm HOOPSY

Your multilingual generative AI assistant for documentation. Ask me anything about HOOPS Envision for Desktop in your own language, or choose a sample question below to start a conversation:

What is HOOPS Envision for Desktop?
What are the latest release notes for HOOPS Envision for Desktop?
How do I start evaluating HOOPS Envision for Desktop?
How do I write my first sample application?
How can I get assistance?

HOOPSY may store conversations according to OpenAI's policy. Responses may not always be accurate.

HOOPSY is thinking...