# Append Data to VTFx

This example opens an existing VTFx file in append mode and adds a new state.

It will also add scalar result values for the appended state and update the existing case properties to include this new state in the animation.

The initial VTFx file has three states. The VTFx created by this example will also contain a fourth newly added state and new scalar results for this state. The first three states (with their result values) are identical to the initial VTFx file.

    //--------------------------------------------------------------------------------------------------
    // 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", "surface_mesh");
        vtfxProps->addPropertySet(partSettings.get());

        cee::PtrRef<cee::PropertySet> partSettings2 = new cee::PropertySet("part_settings");
        partSettings2->setValue("context_geometry_index", static_cast<unsigned int>(0));
        partSettings2->setValue("context_part_id", 2);
        partSettings2->setValue("opacity", 0.7f);
        vtfxProps->addPropertySet(partSettings2.get());

        // Set the properties
        return currentCase->setProperties(vtfxProps.get());
    }

    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

        // Create the VTFx file
        // -------------------------------------------------------------------------
        cee::Str fileName = "ExampleAppend2.vtfx";

        // Make copy original file
        std::ifstream src("../../DemoFiles/SimpleExample.vtfx", std::ios::binary);
        if (!src.good())
        {
            return EXIT_FAILURE;
        }
        std::ofstream dst(fileName.toStdString().c_str(), std::ios::binary);
        dst << src.rdbuf();
        src.close();
        dst.close();

        cee::PtrRef<cee::vtfx::File> file = new cee::vtfx::File;
        if (!file->openForAppend(fileName))
        {
            return EXIT_FAILURE;
        }

        // Get the first database from file
        cee::PtrRef<cee::vtfx::Database> db = file->database(0);

        // Add extra state
        {
            // Get state info block
            cee::PtrRef<cee::vtfx::Block> block = db->blockByIndex(cee::vtfx::Block::STATEINFO, 0);
            cee::vtfx::StateInfoBlock* stateInfoBlock = dynamic_cast<cee::vtfx::StateInfoBlock*>(block.get());

            if (!stateInfoBlock->addStateInfo(4, "Fourth state", 4.0f, cee::vtfx::StateInfoBlock::TIME))
            {
                return EXIT_FAILURE;
            }

            if (!db->writeBlock(stateInfoBlock))
            {
                return EXIT_FAILURE;
            }

        }

        // Add extra results for fourth state
        // Time step 4 - Scalar Result 1
        {
            // Part 1 (the cube)
            {
                // Result values for step 4
                cee::PtrRef<cee::vtfx::ResultValuesBlock> resultValuesBlockPart1Step4 = new cee::vtfx::ResultValuesBlock(14, cee::vtfx::ResultValuesBlock::SCALAR1D, false);
                {
                    if (!resultValuesBlockPart1Step4->setMapToBlockId(1, cee::vtfx::Block::NODES))
                    {
                        return EXIT_FAILURE;
                    }

                    const float RESULT_VALUES[] = { 0.0f, 0.0f, 1.5f, 2.0f, 2.0f, 2.0f, 3.0f, 4.0f };
                    std::vector<float> resultValues(RESULT_VALUES, RESULT_VALUES + sizeof(RESULT_VALUES) / sizeof(RESULT_VALUES[0]));
                    if (!resultValuesBlockPart1Step4->setResultValues(resultValues))
                    {
                        return EXIT_FAILURE;
                    }

                    if (!db->writeBlock(resultValuesBlockPart1Step4.get()))
                    {
                        return EXIT_FAILURE;
                    }
                }
            }

            // Part 2 (the pyramid)
            {
                // Result values for step 4
                cee::PtrRef<cee::vtfx::ResultValuesBlock> resultValuesBlockPart2Step4 = new cee::vtfx::ResultValuesBlock(24, cee::vtfx::ResultValuesBlock::SCALAR1D, false);
                {
                    if (!resultValuesBlockPart2Step4->setMapToBlockId(2, cee::vtfx::Block::NODES))
                    {
                        return EXIT_FAILURE;
                    }

                    const float RESULT_VALUES[] = { 0.0f, 0.0f, 0.5f, 0.5f, 4.0f };
                    std::vector<float> resultValues(RESULT_VALUES, RESULT_VALUES + sizeof(RESULT_VALUES) / sizeof(RESULT_VALUES[0]));
                    if (!resultValuesBlockPart2Step4->setResultValues(resultValues))
                    {
                        return EXIT_FAILURE;
                    }

                    if (!db->writeBlock(resultValuesBlockPart2Step4.get()))
                    {
                        return EXIT_FAILURE;
                    }
                }
            }

            // Get result block
            cee::PtrRef<cee::vtfx::Block> block = db->blockById(cee::vtfx::Block::RESULT, 1); // Result block id = 1
            cee::vtfx::ResultBlock* resultBlock = dynamic_cast<cee::vtfx::ResultBlock*>(block.get());

            // Add results for step 4 (cube)
            if (!resultBlock->addResultValuesBlock(14, 4))
            {
                return EXIT_FAILURE;
            }

            // Add results for step 4 (pyramid)
            if (!resultBlock->addResultValuesBlock(24, 4))
            {
                return EXIT_FAILURE;
            }

            if (!db->writeBlock(resultBlock))
            {
                return EXIT_FAILURE;
            }
        }

        // Write properties
        // -------------------------------------------------------------------------
        cee::PtrRef<cee::PropertySetCollection> vtfxProps = new cee::PropertySetCollection;
        {
            // Show result with id = 1 as fringes
            cee::PtrRef<cee::PropertySet> scalarSelection = new cee::PropertySet("result_selection");
            scalarSelection->setValue("fringes_result_id", 1);
            vtfxProps->addPropertySet(scalarSelection.get());

            // Set animation to run over all states
            cee::PtrRef<cee::PropertySet> stateSelection = new cee::PropertySet("state_selection");
            const cee::Variant STATE_IDS[] = { 1, 2, 3, 4};
            std::vector<cee::Variant> stateIds(STATE_IDS, STATE_IDS + sizeof(STATE_IDS) / sizeof(STATE_IDS[0]));
            stateSelection->setValue("state_ids", stateIds);
            vtfxProps->addPropertySet(stateSelection.get());

            // Start animation when opening file. Set frames per second to 3.0.
            cee::PtrRef<cee::PropertySet> viewer = new cee::PropertySet("viewer");
            viewer->setValue("animation_fps", 3.0);
            viewer->setValue("start_animation", true);
            vtfxProps->addPropertySet(viewer.get());

            // Set the camera to look at the model from negative y axis
            cee::PtrRef<cee::PropertySet> camera = new cee::PropertySet("camera");
            camera->setValue("eye", cee::Vec3d(2.0, -7.5, 0.5));
            camera->setValue("vrp", cee::Vec3d(2.0, -5.5, 0.5));
            camera->setValue("vup", cee::Vec3d(0.0, 0.0, 1.0));
            vtfxProps->addPropertySet(camera.get());

            // Write the block
            if (!file->fileCase(0)->setProperties(vtfxProps.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;
    }

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