UnstructGrid: A simple model with results

This example shows how to build a custom built 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 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
ugModel->setDataSource(dataSource.get());
// Create new state with one geometry
int stateId = 1;
dataSource->addState(state.get());
ugModel->modelSpec().setStateId(stateId);
// Create a geometry and set it in the state object
int geometryIndex = 0;
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.
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.
elements->addElement(cee::ug::Element::TRIANGLES, eltNodes1);
// Define part. Set nodes and elements into the part object.
int partId = 1;
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;
// Create the scalar result part
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;
// Create the vector result part
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;
// Create the displacement result part
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
// 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);
// 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->requestRedraw();