# UnstructGrid: A Simple Model with Results

This example shows how to build a custom memory data source.

The geometry is a simple structure containing only a single triangle.

Three results are created and mapped to the triangle geometry:

- A node mapped scalar result
- A node mapped vector result
- A displacement result
- A transformation result

When a result has been created, it must be added to the current model specification to be visualized with the model. This example sets all four result types in the model specification. The scalar result is set to be shown as fringes.

Remember to toggle on result visibility in each part’s `cee::ug::PartSettings`.

        //--------------------------------------------------------------------------
        // Set up the model, state and geometry.
        // This model contains one triangle element
        //--------------------------------------------------------------------------

        // Create model and data source
        // The data source must be given a unique id and number of geometries upon construction
        cee::PtrRef<cee::ug::UnstructGridModel> ugModel = new cee::ug::UnstructGridModel();
        cee::PtrRef<cee::ug::DataSourceMemory> dataSource = new cee::ug::DataSourceMemory(1, 1);
        ugModel->setDataSource(dataSource.get());

        // Create new state with one geometry
        int stateId = 1;
        cee::PtrRef<cee::ug::DataState> state = new cee::ug::DataState(stateId, 1);
        dataSource->addState(state.get());
        ugModel->modelSpec().setStateId(stateId);

        // Create a geometry and set it in the state object
        int geometryIndex = 0;
        cee::PtrRef<cee::ug::DataGeometry> geo = new cee::ug::DataGeometry;
        state->setGeometry(geometryIndex, geo.get());

        // Add a part which consists of only one triangle

        // Define nodes
        // Add three nodes to node array. Remember to set the array size first.
        cee::PtrRef<cee::ug::DataNodes> nodes = new cee::ug::DataNodes(false);
        nodes->resize(3);
        nodes->setNode(0, cee::Vec3d(0,0,0));
        nodes->setNode(1, cee::Vec3d(1,0,0));
        nodes->setNode(2, cee::Vec3d(1,1,0));

        // Define elements
        // Connectivity array for a triangle
        int c[] = {0, 1, 2};
        std::vector<unsigned int> eltNodes1(c, c+3);    // First triangle

        // Add a triangle to the elements array.
        cee::PtrRef<cee::ug::DataElements> elements = new cee::ug::DataElements(false, 0);
        elements->addElement(cee::ug::Element::TRIANGLES, eltNodes1);

        // Define part. Set nodes and elements into the part object.
        int partId = 1;
        cee::PtrRef<cee::ug::DataPart> part = new cee::ug::DataPart(partId);
        part->setNodes(nodes.get());
        part->setElements(elements.get());

        // Add the part to the geometry
        geo->addPart(part.get());

        //--------------------------------------------------------------------------
        // Create a scalar result (node mapped)
        //--------------------------------------------------------------------------

        // Create a scalar result with node mapping
        int scalarResultId = 1;
        cee::PtrRef<cee::ug::DataResultScalar> scalarResult = new cee::ug::DataResultScalar(scalarResultId, cee::ug::PER_NODE);

        // Create the scalar result part
        cee::PtrRef<cee::ug::DataPartScalar> scalarPart = new cee::ug::DataPartScalar();
        scalarPart->resize(3);
        scalarPart->setValue(0, 1.0);
        scalarPart->setValue(1, 2.0);
        scalarPart->setValue(2, 3.0);

        // Number of parts in the DataResultScalar must match number of parts in the geometry.
        // Scalar values and mapping types must also fit the corresponding part in the geometry.
        // Here the part is a single triangle with three nodes, hence a results array with three values using node mappings will fit.
        scalarResult->addPart(scalarPart.get());

        // Add a scalar result to the state
        state->results(geo.get())->addScalar(scalarResult.get());

        //--------------------------------------------------------------------------
        // Create a vector result (node mapped)
        //--------------------------------------------------------------------------

        // Create a vector result with node mapping
        int vectorResultId = 1;
        cee::PtrRef<cee::ug::DataResultVector> vectorResult = new cee::ug::DataResultVector(vectorResultId, cee::ug::PER_NODE);

        // Create the vector result part
        cee::PtrRef<cee::ug::DataPartVector> vectorPart = new cee::ug::DataPartVector();
        vectorPart->resize(3);
        vectorPart->setValue(0, cee::Vec3d(1.0, 0.0, 0.0));
        vectorPart->setValue(1, cee::Vec3d(1.0, 1.0, 0.0));
        vectorPart->setValue(2, cee::Vec3d(0.0, 2.0, 0.0));

        // Number of parts in the DataResultVector must match number of parts in the geometry.
        // Vector values and mapping types must also fit the corresponding part in the geometry.
        // Here the part is a single triangle with three nodes, hence a results array with three
        // vectors using node mappings will fit.
        vectorResult->addPart(vectorPart.get());

        // Add a vector result to the state's result group
        state->results(geo.get())->addVector(vectorResult.get());

        //--------------------------------------------------------------------------
        // Create a displacement result
        //--------------------------------------------------------------------------

        // Create a displacement result
        int dispResultId = 1;
        cee::PtrRef<cee::ug::DataResultDisplacement> dispResult = new cee::ug::DataResultDisplacement(dispResultId);

        // Create the displacement result part
        cee::PtrRef<cee::ug::DataPartDisplacement> dispPart = new cee::ug::DataPartDisplacement();
        dispPart->resize(3);
        dispPart->setValue(0, cee::Vec3d(1.0, 0.0, 0.0));
        dispPart->setValue(1, cee::Vec3d(0.0, 0.0, 0.0));
        dispPart->setValue(2, cee::Vec3d(0.0, 1.0, 0.0));

        // Number of parts in the DataResultDisplacement must match number of parts in the geometry.
        // Displacement values must also fit the corresponding part in the geometry.
        // Here the part is a single triangle with three nodes, hence a results array with three vectors will fit.
        dispResult->addPart(dispPart.get());

        // Add a displacement result to the state
        state->results(geo.get())->addDisplacement(dispResult.get());

        //--------------------------------------------------------------------------
        // Create a transformation result
        //--------------------------------------------------------------------------

        // Create a transformation result
        cee::PtrRef<cee::ug::DataResultTransformation> transformationResult = new cee::ug::DataResultTransformation();

        // Create the part matrix
        cee::Mat4d partMatrix;
        partMatrix(0,3) = 1.0;
        partMatrix(1,3) = 1.0;

        // Number of parts in the DataResultTransformation must match number of parts in the geometry.
        transformationResult->addPart(partMatrix);

        // Add a transformation result to the state
        state->results(geo.get())->setTransformation(transformationResult.get());

        //--------------------------------------------------------------------------
        // Create corresponding meta data
        //--------------------------------------------------------------------------
        // When we're done creating the data source, we need to update the directory with the current
        // content
        // Set the part info
        cee::ug::PartInfo partInfo(partId, "My part");
        dataSource->directory()->setPartInfo(geometryIndex, partInfo);

        // Set the state info
        cee::ug::StateInfo stateInfo(stateId, "My state", 0.0);
        dataSource->directory()->setStateInfo(stateInfo);

        // Set the scalar result info
        cee::ug::ResultInfo scalarInfo(cee::ug::SCALAR, scalarResultId, "My scalar", cee::ug::PER_NODE);
        dataSource->directory()->setResultInfo(scalarInfo);

        // Set the vector result info
        cee::ug::ResultInfo vectorInfo(cee::ug::VECTOR, vectorResultId, "My vector", cee::ug::PER_NODE);
        dataSource->directory()->setResultInfo(vectorInfo);

        // Set the displacement result info
        cee::ug::ResultInfo displacementInfo(cee::ug::DISPLACEMENT, dispResultId, "My displacement", cee::ug::UNKNOWN_MAPPING);
        dataSource->directory()->setResultInfo(displacementInfo);

        // Set transformation result existence
        dataSource->directory()->setTransformationResult(true);

        // Set modelspec to show all results
        ugModel->modelSpec().setFringesResultId(scalarResultId);
        ugModel->modelSpec().setVectorResultId(vectorResultId);
        ugModel->modelSpec().setDisplacementResultId(dispResultId);
        ugModel->modelSpec().setTransformationResult(true);

        // Set show fringes/vectors/displacement for the part
        ugModel->partSettings(geometryIndex, partId)->setFringesVisible(true);
        ugModel->partSettings(geometryIndex, partId)->setVectorsVisible(true);
        ugModel->partSettings(geometryIndex, partId)->setDisplacementVisible(true);

        // Add model to view. Ensure that old models are removed first
        cee::vis::View* gcView = getTutorialView();
        gcView->removeAllModels();
        gcView->addModel(ugModel.get());

        ugModel->updateVisualization();

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

        gcView->requestRedraw();

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