
.. _vtfx-writer-tutorial:

#########################
Tutorial: My First VTFx
#########################

.. image:: ../../../images/vtfx/tut_vtfxwriter.png
    :height: 300
    :align: center

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 :class:`FileSettings <cee::vtfx::FileSettings>` 
for other available settings.

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 51-65

**Create database and case**

The database collects all data blocks (:class:`NodeBlock <cee::vtfx::NodeBlock>`, 
:class:`ElementBlock <cee::vtfx::ElementBlock>`, :class:`GeometryBlock <cee::vtfx::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 :class:`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.

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 67-71

**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 :class:`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.

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 77-97

**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 
:func:`setNodeBlockId(1) <cee::vtfx::ElementBlock::setNodeBlockId>` 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 :any:`ElementBlock::ElementType <cee::vtfx::ElementBlock::ElementType>` or a full list of supported element types.)

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 110-130

**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 :class:`GeometryBlock <cee::vtfx::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 
:class:`GeometryBlock <cee::tfx::GeometryBlock>` above).
Add a meta data for a part specifying part id used in the geometry block and a part name.

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 137-163

**Add a state**

Create a :class:`StateInfoBlock <cee::vtfx::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.

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 170-181

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

.. literalinclude:: ../../../../../../EnvisionDesktop/Examples/VTFx/VTFxMinimal/VTFxMinimal.cpp
    :language: cpp
    :lines: 183-187

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 :ref:`Logging page <logging-page>` for more information on how to set up 
logging.

**See the complete source code here:**

:ref:`minimal-example`
