Append Data to VTFx

../../../_images/append2_example.png

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;
}