# Advanced Example

A more complex example demonstrating different ways of populating the blocks. For instance a node block (`NodeBlock`) can be populated with either setting all nodes at once with `setNodes()` or setting them one at a time using `addNode()`.

This example contains two parts, two states, a scalar result, a vector result and a displacement result.

It also uses properties for the following features:

- Show Part 1 as lines
- Show scalar result as fringes. Set legend range 1.0 to 5.0.
- Show vector result. Color vector arrows by fringes.
- Set initial camera position

This example can be overwhelming to start with, but is a very good reference for more practiced users.

Source file

    const bool allAtOnce = 0;

    //--------------------------------------------------------------------------------------------------
    // Writes the given nodes to the VTFx file
    //--------------------------------------------------------------------------------------------------
    bool writeNodes(int blockId, cee::vtfx::Database* database, const std::vector<float> nodes, const std::vector<int> nodeIds)
    {
        // Create the node block
        cee::PtrRef<cee::vtfx::NodeBlock> nodeBlock = new cee::vtfx::NodeBlock(blockId, !nodeIds.empty());

        // Set the node data (Note: Express Writer expects interleaved node coordinates (xyzxyzxyz...))
        // -------------------------------------------------------------------------
        if (allAtOnce)
        {
            // Alt 1: Supply all nodes at once
            if (!nodeBlock->setNodes(nodes, nodeIds))
            {
                return false;
            }
        }
        else
        {
            // Alt 2: Add each node individually, using pre-allocation
            if (!nodeBlock->allocateNodes(nodes.size()))
            {
                return false;
            }

            for (size_t i = 0; i < nodes.size() / 3; i++)
            {
                if (!nodeIds.empty())
                {
                    nodeBlock->addNode(nodes[i * 3], nodes[i * 3 + 1], nodes[i * 3 + 2], nodeIds[i]);
                }
                else
                {
                    nodeBlock->addNode(nodes[i * 3], nodes[i * 3 + 1], nodes[i * 3 + 2]);
                }
            }
        }

        // Write the block
        // -------------------------------------------------------------------------
        if (!database->writeBlock(nodeBlock.get()))
        {
            return false;
        }

        return true;
    }

    //--------------------------------------------------------------------------------------------------
    // Writes the given elements to the VTFx file
    //--------------------------------------------------------------------------------------------------
    bool writeElements(int blockId, cee::vtfx::Database* database, std::vector<int> elementNodes, cee::vtfx::ElementBlock::ElementType elementType, int nodeBlockId, std::vector<int> elementIds)
    {
        // Create the element block, using index mapping for the nodes
        cee::PtrRef<cee::vtfx::ElementBlock> elementBlock = new cee::vtfx::ElementBlock(blockId, !elementIds.empty(), false);

        // Set the element data
        // -------------------------------------------------------------------------
        if (allAtOnce)
        {
            // Set all elements at once (most efficient)
            if (!elementBlock->addElements(elementType, elementNodes, elementIds))
            {
                return false;
            }
        }
        else
        {
            // Add elements individually (requires frequent re-allocations)

            int numElementNodes = static_cast<int>(cee::vtfx::ElementBlock::nodesPerElement(elementType));
            int numElements = static_cast<int>(elementNodes.size()) / numElementNodes;
            for (int i = 0; i < numElements; i++)
            {
                std::vector<int> currentElementNodes;
                currentElementNodes.assign(elementNodes.begin() + (i*numElementNodes), elementNodes.begin() + ((i + 1)*numElementNodes));
                if (!elementBlock->addElement(elementType, currentElementNodes, elementIds.empty() ? -1 : elementIds[i]))
                {
                    return false;
                }
            }
        }

        elementBlock->setNodeBlockId(nodeBlockId);

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

        return true;
    }

    //--------------------------------------------------------------------------------------------------
    // Writes the given geometry to the VTFx file
    //--------------------------------------------------------------------------------------------------
    bool writeGeometry(cee::vtfx::Database* database, const std::vector<int>& elementParts)
    {
        cee::PtrRef<cee::vtfx::GeometryBlock> geoBlock = new cee::vtfx::GeometryBlock(1); // Only one geometry per state

        size_t geoIndex = 0;

        // Set the element data
        // -------------------------------------------------------------------------
        if (!geoBlock->setElementBlocks(geoIndex, elementParts, elementParts)) // There's one part for each element block. Use same id array for simplicity.
        {
            return false;
        }

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

        // Set info
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::GeometryInfoBlock> infoBlock = new cee::vtfx::GeometryInfoBlock(1); // Only one geometry per state
        for (size_t i = 0; i < elementParts.size(); i++)
        {
            infoBlock->addPartInfo(geoIndex, elementParts[i], cee::Str("Part %1").arg((int)i));
        }

        if (!database->writeBlock(infoBlock.get()))
        {
            return false;
        }

        return true;
    }

    //--------------------------------------------------------------------------------------------------
    // Writes 1D/3D result values for one part to the file
    //--------------------------------------------------------------------------------------------------
    bool writeResult(int blockId, cee::vtfx::Database* database, const std::vector<float>& resultValues, int mapToBlock, cee::vtfx::Block::BlockType mapToBlockType, cee::vtfx::ResultValuesBlock::ResultValueDimension dimension)
    {
        // Create the result values block
        cee::PtrRef<cee::vtfx::ResultValuesBlock> resultValuesBlock = new cee::vtfx::ResultValuesBlock(blockId, dimension, false);
        resultValuesBlock->setMapToBlockId(mapToBlock, mapToBlockType);

        // Set the result values
        // -------------------------------------------------------------------------
        if (allAtOnce)
        {
            // Alt 1: Set data directly
            if (!resultValuesBlock->setResultValues(resultValues))
            {
                return false;
            }
        }
        else
        {
            // Alt 2: Add each result value individually (using pre-allocation)
            if (dimension == cee::vtfx::ResultValuesBlock::SCALAR1D)
            {
                if (!resultValuesBlock->allocateResultValues(static_cast<int>(resultValues.size())))
                {
                    return false;
                }

                for (size_t i = 0; i < resultValues.size(); i++)
                {
                    resultValuesBlock->addResultValue1d(resultValues[i]);
                }
            }
            else // assuming dimension VECTOR3D
            {
                if (!resultValuesBlock->allocateResultValues(static_cast<int>(resultValues.size()) / 3))
                {
                    return false;
                }

                for (size_t i = 0; i < resultValues.size() / 3; i++)
                {
                    resultValuesBlock->addResultValue3d(resultValues[3 * i], resultValues[3 * i + 1], resultValues[3 * i + 2]);
                }
            }
        }

        // Write the block
        // -------------------------------------------------------------------------
        if (!database->writeBlock(resultValuesBlock.get()))
        {
            return false;
        }

        return true;
    }

    //--------------------------------------------------------------------------------------------------
    // Creates case properties
    //--------------------------------------------------------------------------------------------------
    bool createProperties(cee::vtfx::Case* currentCase)
    {
        cee::PtrRef<cee::PropertySetCollection> vtfxProps = new cee::PropertySetCollection;

        cee::PtrRef<cee::PropertySet> partSettings = new cee::PropertySet("part_settings");
        partSettings->setValue("context_geometry_index", static_cast<unsigned int>(0));
        partSettings->setValue("context_part_id", 1);
        partSettings->setValue("draw_style", "line");
        vtfxProps->addPropertySet(partSettings.get());

        cee::PtrRef<cee::PropertySet> scalarSelection = new cee::PropertySet("result_selection");
        scalarSelection->setValue("fringes_result_id", 1);
        vtfxProps->addPropertySet(scalarSelection.get());

        cee::PtrRef<cee::PropertySet> colorMapper = new cee::PropertySet("color_mapper_filled_contours_uniform");
        colorMapper->setValue("context_result_id", 1);
        colorMapper->setValue("range_min", 1.0);
        colorMapper->setValue("range_max", 5.0);
        vtfxProps->addPropertySet(colorMapper.get());

        cee::PtrRef<cee::PropertySet> vectorSelection = new cee::PropertySet("result_selection");
        std::vector<cee::Variant> vectorIds;
        vectorIds.push_back(1);
        vectorSelection->setValue("vector_result_ids", vectorIds);
        vtfxProps->addPropertySet(vectorSelection.get());

        cee::PtrRef<cee::PropertySet> vectorSettings = new cee::PropertySet("vector_settings");
        vectorSettings->setValue("context_result_id", 1);
        vectorSettings->setValue("color_mode", "color_by_fringes");
        vtfxProps->addPropertySet(vectorSettings.get());

        cee::PtrRef<cee::PropertySet> camera = new cee::PropertySet("camera");
        camera->setValue("eye", cee::Vec3d(2.0, -7.5, 1-0));
        camera->setValue("vrp", cee::Vec3d(2.0, -5.5, 1.0));
        camera->setValue("vup", cee::Vec3d(0.0, 0.0, 1.0));
        vtfxProps->addPropertySet(camera.get());

        // Write the block
        if (!currentCase->setProperties(vtfxProps.get()))
        {
            return false;
        }

        return true;
    }

    cee::PtrRef<cee::Instance>  g_componentInstance;

    //--------------------------------------------------------------------------------------------------
    // Main function, program entry point
    //--------------------------------------------------------------------------------------------------
    int main()
    {
        // Initialize components and set up logging to console
        // -------------------------------------------------------------------------
        g_componentInstance = cee::CoreComponent::initialize(HOOPS_LICENSE);
        cee::vtfx::VTFxComponent::initialize(g_componentInstance.get());

        cee::PtrRef<cee::LogDestinationConsole> log = new cee::LogDestinationConsole();
        cee::CoreComponent::logManager()->setDestination(log.get());
        cee::CoreComponent::logManager()->setLevel("", 3);               // Log errors, warnings and info

        const cee::Str fileName = "Example1.vtfx";

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

        // Create VTFx file settings struct
        // -------------------------------------------------------------------------
        cee::vtfx::FileSettings fileSettings;
        fileSettings.binary = true;
        fileSettings.compressionLevel = 5; // 0 to 9
        fileSettings.applicationName = "VTFx: VTFxExample";
        fileSettings.vendorName = "My Company AS";
        fileSettings.createDigitalSignature = false;

        // Let the API create the VTFx file
        if (!file->create(fileName, fileSettings))
        {
            return EXIT_FAILURE;
        }

        // Create a single database (could have many)
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::Database> singleDatabase = new cee::vtfx::Database(file.get(), "Single Database", 1); // database id 1

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

        // Part 1
        // -------------------------------------------------------------------------
        // Write nodes
        std::vector<float> nodesPart1(NODES_PART_1, NODES_PART_1 + sizeof(NODES_PART_1) / sizeof(float));
        std::vector<int> nodesPart1Ids(NODES_PART_1_IDS, NODES_PART_1_IDS + sizeof(NODES_PART_1_IDS) / sizeof(int));
        if (!writeNodes(1, singleDatabase.get(), nodesPart1, nodesPart1Ids))
        {
            return EXIT_FAILURE;
        }

        // Write elements
        std::vector<int> connectsPart1(CONNECTS_PART_1, CONNECTS_PART_1 + sizeof(CONNECTS_PART_1) / sizeof(int));
        std::vector<int> elementPart1(ELEMENTS_PART_1_IDS, ELEMENTS_PART_1_IDS + sizeof(ELEMENTS_PART_1_IDS) / sizeof(int));
        if (!writeElements(1, singleDatabase.get(), connectsPart1, elementTypePart1, 1, elementPart1))
        {
            return EXIT_FAILURE;
        }

        // Part 2
        // -------------------------------------------------------------------------
        // Write nodes
        std::vector<float> nodesPart2(NODES_PART_2, NODES_PART_2 + sizeof(NODES_PART_2) / sizeof(float));
        std::vector<int> nodesPart2Ids(NODES_PART_2_IDS, NODES_PART_2_IDS + sizeof(NODES_PART_2_IDS) / sizeof(int));
        if (!writeNodes(2, singleDatabase.get(), nodesPart2, nodesPart2Ids))
        {
            return EXIT_FAILURE;
        }

        // Write elements
        std::vector<int> connectsPart2(CONNECTS_PART_2, CONNECTS_PART_2 + sizeof(CONNECTS_PART_2) / sizeof(int));
        std::vector<int> elementPart2(ELEMENTS_PART_2_IDS, ELEMENTS_PART_2_IDS + sizeof(ELEMENTS_PART_2_IDS) / sizeof(int));
        if (!writeElements(2, singleDatabase.get(), connectsPart2, elementTypePart2, 2, elementPart2))
        {
            return EXIT_FAILURE;
        }

        // Write Geometry definition
        // -------------------------------------------------------------------------
        std::vector<int> elementParts(ELEMENT_PARTS, ELEMENT_PARTS + sizeof(ELEMENT_PARTS) / sizeof(int));
        if (!writeGeometry(singleDatabase.get(), elementParts))
        {
            return EXIT_FAILURE;
        }

        // Write the scalar result values
        // -------------------------------------------------------------------------
        // Write result values for each part for each step (here 2 parts, 2 steps)
        std::vector<float> result1P1S1(RESULT1_P1_S1, RESULT1_P1_S1 + sizeof(RESULT1_P1_S1) / sizeof(int));
        if (!writeResult(1, singleDatabase.get(), result1P1S1, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::SCALAR1D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result1P1S2(RESULT1_P1_S2, RESULT1_P1_S2 + sizeof(RESULT1_P1_S2) / sizeof(int));
        if (!writeResult(11, singleDatabase.get(), result1P1S2, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::SCALAR1D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result1P2S1(RESULT1_P2_S1, RESULT1_P2_S1 + sizeof(RESULT1_P2_S1) / sizeof(int));
        if (!writeResult(2, singleDatabase.get(), result1P2S1, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::SCALAR1D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result1P2S2(RESULT1_P2_S2, RESULT1_P2_S2 + sizeof(RESULT1_P2_S2) / sizeof(int));
        if (!writeResult(12, singleDatabase.get(), result1P2S2, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::SCALAR1D))
        {
            return EXIT_FAILURE;
        }

        // Write the scalar result definition
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::ResultBlock> scalarResult = new cee::vtfx::ResultBlock(1, cee::vtfx::ResultBlock::SCALAR, cee::vtfx::ResultBlock::NODE_MAPPING);
        if (!scalarResult->addResultValuesBlock(1, 1)  || // Assign the result values blocks to state IDs. Order is not significant.
            !scalarResult->addResultValuesBlock(11, 2) ||
            !scalarResult->addResultValuesBlock(2, 1)  ||
            !scalarResult->addResultValuesBlock(12, 2))
        {
            return EXIT_FAILURE;
        }

        scalarResult->setResultId(1);
        scalarResult->setName("My scalar result");
        scalarResult->setUnit("m^2");

        if (!singleDatabase->writeBlock(scalarResult.get()))
        {
            return EXIT_FAILURE;
        }

        // Write the vector result values
        // -------------------------------------------------------------------------
        // Write result values for each part for each step (here 2 parts, 2 steps)
        std::vector<float> result2P1S1(RESULT2_P1_S1, RESULT2_P1_S1 + sizeof(RESULT2_P1_S1) / sizeof(float));
        if (!writeResult(101, singleDatabase.get(), result2P1S1, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result2P1S2(RESULT2_P1_S2, RESULT2_P1_S2 + sizeof(RESULT2_P1_S2) / sizeof(float));
        if (!writeResult(111, singleDatabase.get(), result2P1S2, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result2P2S1(RESULT2_P2_S1, RESULT2_P2_S1 + sizeof(RESULT2_P2_S1) / sizeof(float));
        if (!writeResult(102, singleDatabase.get(), result2P2S1, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result2P2S2(RESULT2_P2_S2, RESULT2_P2_S2 + sizeof(RESULT2_P2_S2) / sizeof(float));
        if (!writeResult(112, singleDatabase.get(), result2P2S2, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        // Write the vector result definition
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::ResultBlock> vectorResult = new cee::vtfx::ResultBlock(2, cee::vtfx::ResultBlock::VECTOR, cee::vtfx::ResultBlock::NODE_MAPPING);
        if (!vectorResult->addResultValuesBlock(101, 1) || // Assign the result values blocks to state IDs. Order is not significant.
            !vectorResult->addResultValuesBlock(111, 2) ||
            !vectorResult->addResultValuesBlock(102, 1) ||
            !vectorResult->addResultValuesBlock(112, 2))
        {
            return EXIT_FAILURE;
        }
        vectorResult->setResultId(1);
        vectorResult->setName("My vector result");

        if (!singleDatabase->writeBlock(vectorResult.get()))
        {
            return EXIT_FAILURE;
        }

        // Write the Displacement result values
        // -------------------------------------------------------------------------
        // Write result values for each part for each step (here 2 parts, 2 steps)
        std::vector<float> result3P1S1(RESULT3_P1_S1, RESULT3_P1_S1 + sizeof(RESULT3_P1_S1) / sizeof(float));
        if (!writeResult(201, singleDatabase.get(), result3P1S1, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result3P1S2(RESULT3_P1_S2, RESULT3_P1_S2 + sizeof(RESULT3_P1_S2) / sizeof(float));
        if (!writeResult(211, singleDatabase.get(), result3P1S2, 1, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result3P2S1(RESULT3_P2_S1, RESULT3_P2_S1 + sizeof(RESULT3_P2_S1) / sizeof(float));
        if (!writeResult(202, singleDatabase.get(), result3P2S1, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        std::vector<float> result3P2S2(RESULT3_P2_S2, RESULT3_P2_S2 + sizeof(RESULT3_P2_S2) / sizeof(float));
        if (!writeResult(212, singleDatabase.get(), result3P2S2, 2, cee::vtfx::Block::NODES, cee::vtfx::ResultValuesBlock::VECTOR3D))
        {
            return EXIT_FAILURE;
        }

        // Write the displacement result definition
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::ResultBlock> displacementResult = new cee::vtfx::ResultBlock(3, cee::vtfx::ResultBlock::DISPLACEMENT, cee::vtfx::ResultBlock::NODE_MAPPING);
        if (!displacementResult->addResultValuesBlock(201, 1) || // Assign the result values blocks to state ids. Order is not significant.
            !displacementResult->addResultValuesBlock(211, 2) ||
            !displacementResult->addResultValuesBlock(202, 1) ||
            !displacementResult->addResultValuesBlock(212, 2))
        {
            return EXIT_FAILURE;
        }
        displacementResult->setResultId(1);
        displacementResult->setName("My displacement result");

        if (!singleDatabase->writeBlock(displacementResult.get()))
        {
            return EXIT_FAILURE;
        }

        // Write state information info (here we have two "steps" of a time series)
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::vtfx::StateInfoBlock> stepInfo = new cee::vtfx::StateInfoBlock;

        if (!stepInfo->addStateInfo(1, "First step", 1.0f, cee::vtfx::StateInfoBlock::TIME) ||
            !stepInfo->addStateInfo(2, "Second and last step", 5.0f, cee::vtfx::StateInfoBlock::TIME))
        {
            return EXIT_FAILURE;
        }

        if (!singleDatabase->writeBlock(stepInfo.get()))
        {
            return EXIT_FAILURE;
        }

        // Create properties
        // -------------------------------------------------------------------------
        if (!createProperties(singleCase.get()))
        {
            return EXIT_FAILURE;
        }

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

        std::cout << "Exported successfully to file: " << fileName.toStdString() << std::endl;
        std::cout << std::endl << "Press enter to exit..." << std::endl;
        std::cin.ignore();

        return EXIT_SUCCESS;
    }

Header file

    // Part 1
    // -----------------------------------------------------------------------------
    // Nodes for part 1
    const float NODES_PART_1[] =
    {
        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,
        0.0f, 0.0f, 2.0f,
        1.0f, 0.0f, 2.0f,
        1.0f, 1.0f, 2.0f,
        0.0f, 1.0f, 2.0f
    };

    const int NODES_PART_1_IDS[] =
    {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
    };

    // Elements for part 1
    const int CONNECTS_PART_1[] =
    {
        0, 1, 2, 3, 4, 5, 6, 7,
        4, 5, 6, 7, 8, 9, 10, 11
    };
    const cee::vtfx::ElementBlock::ElementType elementTypePart1 = cee::vtfx::ElementBlock::HEXAHEDRONS;

    const int ELEMENTS_PART_1_IDS[] =
    {
        1, 2
    };

    // Part 2
    // -----------------------------------------------------------------------------
    // Nodes for part 2
    const float NODES_PART_2[] =
    {
        2.0f, 0.0f, 0.0f,
        3.0f, 0.0f, 0.0f,
        3.0f, 1.0f, 0.0f,
        2.0f, 1.0f, 0.0f,
        4.0f, 0.0f, 0.0f,
        4.0f, 1.0f, 0.0f
    };

    const int NODES_PART_2_IDS[] =
    {
        101, 102, 103, 104, 105, 106
    };

    // Elements for part 2
    const int CONNECTS_PART_2[] =
    {
        0, 1, 2, 3,
        1, 4, 5, 2
    };
    const cee::vtfx::ElementBlock::ElementType elementTypePart2 = cee::vtfx::ElementBlock::QUADS;

    const int ELEMENTS_PART_2_IDS[] =
    {
        3, 4
    };

    // Geometry definition
    // -----------------------------------------------------------------------------
    const int ELEMENT_PARTS[] =
    {
        1, 2
    };

    // Time step 1 - Scalar Result 1
    // -----------------------------------------------------------------------------
    const float RESULT1_P1_S1[] =
    {
        0.0,
        0.5,
        1.5,
        2.0,
        3.0,
        4.0,
        5.0,
        6.0,
        6.5,
        7.0,
        7.5,
        8.0
    };
    const float RESULT1_P2_S1[] =
    {
        1.0,
        5.0,
        3.0,
        2.0,
        5.0,
        1.0
    };

    // Time step 2 - Scalar Result 1
    // -----------------------------------------------------------------------------
    const float RESULT1_P1_S2[] =
    {
        8.1f,
        9.6f,
        5.8f,
        3.5f,
        7.4f,
        9.7f,
        2.7f,
        6.5f,
        3.2f,
        4.6f,
        3.7f,
        2.2f
    };
    const float RESULT1_P2_S2[] =
    {
        1.5f,
        2.1f,
        4.5f,
        5.5f,
        2.1f,
        1.1f
    };

    // Time step 1 - Vector Result 1
    // -----------------------------------------------------------------------------
    const float RESULT2_P1_S1[] =
    {
        0.0, 0.0, 0.0,
        1.0, 0.0, 0.0,
        1.0, 1.0, 0.0,
        0.0, 1.0, 0.0,
        0.0, 0.0, 1.0,
        1.0, 0.0, 1.0,
        1.0, 1.0, 1.0,
        0.0, 1.0, 1.0,
        0.0, 0.0, 2.0,
        1.0, 0.0, 2.0,
        1.0, 1.0, 2.0,
        0.0, 1.0, 2.0
    };
    const float RESULT2_P2_S1[] =
    {
        2.0, 0.0, 0.0,
        3.0, 0.0, 0.0,
        3.0, 1.0, 0.0,
        2.0, 1.0, 0.0,
        4.0, 0.0, 0.0,
        4.0, 1.0, 0.0,
    };

    // Time step 2 - Vector Result 2
    // -----------------------------------------------------------------------------
    const float RESULT2_P1_S2[] =
    {
        1.0, 8.0, 1.0,
        3.0, 2.0, 5.0,
        5.0, 8.0, 7.0,
        3.0, 4.0, 9.0,
        5.0, 2.0, 3.0,
        7.0, 1.0, 2.0,
        2.0, 7.0, 1.0,
        5.0, 6.0, 5.0,
        7.0, 5.0, 8.0,
        6.0, 4.0, 0.0,
        4.0, 2.0, 0.0,
        1.0, 2.0, 2.0
    };
    const float RESULT2_P2_S2[] =
    {
        1.0, 4.0, 2.0,
        6.0, 8.0, 5.0,
        8.0, 7.0, 7.0,
        3.0, 3.0, 8.0,
        7.0, 5.0, 2.0,
        3.0, 3.0, 1.0,
    };

    // Time step 1 - Displacement Result 1
    // -----------------------------------------------------------------------------
    const float RESULT3_P1_S1[] =
    {
        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,
        0.0f, 0.0f, 2.0f,
        1.0f, 0.0f, 2.0f,
        1.0f, 1.0f, 2.0f,
        0.0f, 1.0f, 2.0f
    };
    const float RESULT3_P2_S1[] =
    {
        2.0, 0.0, 0.0,
        3.0, 0.0, 0.0,
        3.0, 1.0, 0.0,
        2.0, 1.0, 0.0,
        4.0, 0.0, 0.0,
        4.0, 1.0, 0.0,
    };

    // Time step 2 - Displacement Result 1
    // -----------------------------------------------------------------------------
    const float RESULT3_P1_S2[] =
    {
        0.0f, 0.0f, 0.0f,
        1.5f, 0.0f, 0.0f,
        1.5f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f,
        1.5f, 0.0f, 1.0f,
        1.5f, 1.0f, 1.0f,
        0.0f, 1.0f, 1.0f,
        0.0f, 0.0f, 2.0f,
        1.5f, 0.0f, 2.0f,
        1.5f, 1.0f, 2.0f,
        0.0f, 1.0f, 2.0f
    };
    const float RESULT3_P2_S2[] =
    {
        2.0, 0.0, 0.0,
        3.0, 0.0, 0.0,
        3.0, 1.0, 0.0,
        2.0, 1.0, 0.0,
        4.0, 0.0, 0.5,
        4.0, 1.0, 0.5,
    };

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...