.. _ogn_generation_script:

Generating OmniGraph Nodes
==========================
The OmniGraph nodes consist of code that is automatically generated from a .ogn file and one or more methods
defined by the node class. These interfaces consist of C++ code, Python code, a USDA file, and Python test scripts
For full details of what is generated automatically see the :ref:`ogn_user_guide`.

.. contents::

.. toctree::

    ogn_user_guide
    ogn_reference_guide
    attribute_types

Running The Script
------------------
The script to run to perform the conversion is *generate_node.py*. It is run with the
same version of Python included with the build in *tools/packman/python.bat* or *tools/packman.python.sh*.
The script `generate_node.py` reads in a node description file in order to automatically generate documentation,
tests, template files, anda simplified interface the node can use to implement its algorithm.

.. note::

    Although not required for using the .ogn format, if you are interested in what kind of code is generated from the
    descriptions see :ref:`ogn_node_architects_guide`.

Run *generate_node.py --help* to see all of the arguments that can be passed to the script, reproduced here. Each
flag has both a short and long form that are equivalent.

.. code-block:: text

    usage: generate_node.py [-h] [-cd DIR] [-c [DIR]] [-d [DIR]]
                            [-e EXTENSION_NAME] [-i [DIR]]
                            [-in [INTERMEDIATE_DIRECTORY]]
                            [-m [PYTHON_IMPORT_MODULE]] [-n [FILE.ogn]] [-p [DIR]]
                            [-s SETTING_NAME] [-t [DIR]] [-td FILE.json]
                            [-tp [DIR]] [-u] [-usd [DIR]] [-uw [DIR]] [-v]

    Parse a node interface description file and generate code or documentation

    optional arguments:
    -h, --help            show this help message and exit
    -cd DIR, --configDirectory DIR
                            the directory containing the code generator configuration files (default is current)
    -c [DIR], --cpp [DIR]
                            generate the C++ interface class into the specified directory (default is current)
    -d [DIR], --docs [DIR]
                            generate the node documentation into the specified directory (default is current)
    -e EXTENSION_NAME, --extension EXTENSION_NAME
                            name of the extension requesting the generation
    -i [DIR], --icons [DIR]
                            directory into which to install the icon, if one is found
    -in [INTERMEDIATE_DIRECTORY], --intermediate [INTERMEDIATE_DIRECTORY]
                            directory into which temporary build information is stored
    -m [PYTHON_IMPORT_MODULE], --module [PYTHON_IMPORT_MODULE]
                            Python module where the Python node files live
    -n [FILE.ogn], --nodeFile [FILE.ogn]
                            file containing the node description (use stdin if file name is omitted)
    -p [DIR], --python [DIR]
                            generate the Python interface class into the specified directory (default is current)
    -s SETTING_NAME, --settings SETTING_NAME
                            define one or more build-specific settings that can be used to change the generated code at runtime
    -t [DIR], --tests [DIR]
                            generate a file containing basic operational tests for this node
    -td FILE.json, --typeDefinitions FILE.json
                            file name containing the mapping to use from OGN type names to generated code types
    -tp [DIR], --template [DIR]
                            generate an annotated template for the C++ node class into the specified directory (default is current)
    -u, --unitTests       run the unit tests on this file
    -usd [DIR], --usdPath [DIR]
                            generate a file containing a USD template for nodes of this type
    -uw [DIR], --unwritable [DIR]
                            mark the generated directory as unwritable at runtime
    -v, --verbose         output the steps the script is performing as it performs them

    Available attribute types:
            any
            bool, bool[]
            bundle
            colord[3], colord[4], colord[3][], colord[4][]
            colorf[3], colorf[4], colorf[3][], colorf[4][]
            colorh[3], colorh[4], colorh[3][], colorh[4][]
            double, double[2], double[3], double[4], double[], double[2][], double[3][], double[4][]
            execution
            float, float[2], float[3], float[4], float[], float[2][], float[3][], float[4][]
            frame[4], frame[4][]
            half, half[2], half[3], half[4], half[], half[2][], half[3][], half[4][]
            int, int[2], int[3], int[4], int[], int[2][], int[3][], int[4][]
            int64, int64[]
            matrixd[2], matrixd[3], matrixd[4], matrixd[2][], matrixd[3][], matrixd[4][]
            normald[3], normald[3][]
            normalf[3], normalf[3][]
            normalh[3], normalh[3][]
            objectId, objectId[]
            path
            pointd[3], pointd[3][]
            pointf[3], pointf[3][]
            pointh[3], pointh[3][]
            quatd[4], quatd[4][]
            quatf[4], quatf[4][]
            quath[4], quath[4][]
            string
            texcoordd[2], texcoordd[3], texcoordd[2][], texcoordd[3][]
            texcoordf[2], texcoordf[3], texcoordf[2][], texcoordf[3][]
            texcoordh[2], texcoordh[3], texcoordh[2][], texcoordh[3][]
            timecode, timecode[]
            token, token[]
            transform[4], transform[4][]
            uchar, uchar[]
            uint, uint[]
            uint64, uint64[]
            vectord[3], vectord[3][]
            vectorf[3], vectorf[3][]
            vectorh[3], vectorh[3][]
            ["A", "B", "C"... = Any one of the listed types]

The main argument of interest is *--nodeFile MyFile.ogn*. That is how you specify the file for which interfaces are
to be generated. Another one of interest is *--verbose* which, when included, will dump debugging information
describing the operations being performed. Several other options describe which of the available outputs will be
generated.

.. note::

    There is also an environment variable controlling build flags. If you set **OGN_DEBUG** then the .ogn
    generator will use its *--verbose* option to dump information about the parsing of the file and generation
    of the code - worth remembering if you are running into code generation errors.

The usual method of running the script is through the build process, described in :ref:`ogn_tutorial_nodes`.

Other uses of the script are the following:

.. code-block:: bash

    # Generate the node using an alternate code path controlled by the value of CODE_SETTING
    python generate_node.py --nodeFile MYNODE.ogn --setting CODE_SETTING

    # Validate a .ogn file but do not produce any output
    python generate_node.py --schema --nodeFile MYNODE.ogn

    # Generate all of the interfaces
    python generate_node.py --cpp INCLUDE_DIR --python PYTHON_DIR --schema --namespace omni.MY.FEATURE --nodeFile MYNODE.ogn

.. note::

    Normally the generated directory is set up to regenerate its files on demand when the .ogn or .py implementation
    files change to facilitate hot reloading. When the nodes are installed from an extension through a distribution
    this is disabled by using the `--unwritable` flag to tag the generated directory to prevent that. This speeds up
    the extension loading and avoids potential write permission problems with installed directories.

.. note::

    The script is written to run on Python 3.6 or later. Earlier 3.x versions may work but are untested. It will always
    be guaranteed to run on the same version of Python as Kit.
