UnstructGrid: Using DataElementSets to Filter the Model

../_images/tut_dataelementsets.png

Element sets can be used to specify which elements that should be visible at any given time in a data source within an unstruct grid model.

By creating a DataElementSet and adding DataElementSetItems to this you can filter the model based on any custom property, spacial position in world or window coordinates or any other criteria.

This tutorial shows how to create element sets and how to use the filtering to control which elements to show.

The demo file (30x30x30.vtf) contains a single part geometry with a synthetic scalar result.

Load the file and setup the model specification to show the result. For a more thorough explanation on creating a data source from a file interface and setup the model specification, see the Load VFT tutorial: UnstructGrid: Load Model from File and Set Up Model Specification

Note

This tutorial expect the application to have a correctly configured cee::vis::View in place. See the demo applications on how to set up a cee::vis::View in your application.

Load model

Create the model and a VTF file interface data source. Open the file and set the created data source in the model.

    cee::PtrRef<cee::ug::UnstructGridModel> ugModel = new cee::ug::UnstructGridModel();
    cee::PtrRef<cee::ug::DataSourceVTF> source = new cee::ug::DataSourceVTF(42);
    cee::Str vtfFile = TutorialUtils::testDataDir() + "30x30x30.vtf";
    if (!source->open(vtfFile))
    {
        return;
    }
    ugModel->setDataSource(source.get());

Set the first state as current in the model specification.

    std::vector<cee::ug::StateInfo> stateInfos = source->directory()->stateInfos();
    int stateId = stateInfos[0].id();
    ugModel->modelSpec().setStateId(stateId);

Find the id of the first scalar result from the data source’s directory.

    std::vector<cee::ug::ResultInfo> scalarResultInfos = source->directory()->scalarResultInfos();
    int scalarId = scalarResultInfos[0].id();
    ugModel->modelSpec().setFringesResultId(scalarId);

    // We need to update the visualization before we can generate any sets
    ugModel->updateVisualization();

Create the sets

We use the DataElementSetGenerator class to create the sets. This class provides methods for creating sets from an UnstructGridModel, either by world coordinates (as in this example) or in screen coordinates (with the createFromRegion()) method.

First, create a set with all elements above the first plane. We use the FRONT and ON criteria so we will add any element that is either intersected by the plane or in front of the plane.

    cee::ug::DataElementSetGenerator setGenerator(*ugModel, 0);
    cee::Plane plane1 = cee::Plane::createFromPointAndNormal(cee::Vec3d(10,10,10), cee::Vec3d(1, 1, 1));
    cee::PtrRef<cee::ug::DataElementSet> set1 = setGenerator.createFromPlane(1, plane1, cee::ug::DataElementSetGenerator::FRONT | cee::ug::DataElementSetGenerator::ON);

Then, create a second set with all elements below the second plane. We use the same criteria here.

    cee::Plane plane2 = cee::Plane::createFromPointAndNormal(cee::Vec3d(20,20,20), cee::Vec3d(1, 1, 1));
    cee::PtrRef<cee::ug::DataElementSet> set2 = setGenerator.createFromPlane(2, plane2, cee::ug::DataElementSetGenerator::BACK | cee::ug::DataElementSetGenerator::ON);

Do an intersection of the two sets to get the elements that are between the two planes (the elements presents in both sets).

    set1->intersect(*set2);

Now, add the complete DataElementSet to the DataSource of the UnstructGridModel.

    ugModel->dataSource()->addElementSet(set1.get());

Specify to use this set (with id = 1) as our visible set in the ModelSpec of the UnstructGridModel. This will filter the model so only the elements in the set will be visible. When we specify one or more set ids as visible sets, the element filtering will be enabled.

    ugModel->modelSpec().setVisibleSetId(1);

Set up the created model

Show all parts as surface mesh so we can see the elements.

    cee::ug::PartSettingsIterator it(ugModel.get());
    while (it.hasNext())
    {
        cee::ug::PartSettings* partSettings = it.next();
        partSettings->setDrawStyle(cee::ug::PartSettings::SURFACE_MESH);
    }

The model is ready to use and can be added to the view. Exactly where the view exists depends on the platform and solution. These examples uses Qt and the view is set up in a cee::qt::ViewerWidget.

    cee::vis::View* view = getTutorialView();
    view->removeAllModels();
    view->addModel(ugModel.get());

    ugModel->updateVisualization();

    cee::BoundingBox bb = view->boundingBox();
    view->camera().fitView(bb, cee::Vec3d(0, 0, -1), cee::Vec3d(0, 1, 0));
    view->camera().inputHandler()->setRotationPoint(bb.center());

    view->requestRedraw();

See the complete source code here:

UnstructGrid: Using DataElementSets to Filter the Model