UnstructGrid: Create a Custom DataReader to Add Support for Your File Format

This example shows how to get your own analysis results into the cee::ug::UnstructGridModel by creating a cee::ug::DataReader.

../_images/tut_custom_datareader.png
class SingleHexReader : public cee::ug::DataReader
{
public:
    bool isSupportedFileFormat(const cee::Str& /*filename*/)
    {
        return true;
    }

    bool open(const cee::Str& /*filename*/, cee::ug::Error* /*error*/)
    {
        return true;
    }

    void close()
    {
    }

    size_t geometryCount() const
    {
        return 1;
    }

    bool initializeDirectory(cee::ug::DataSourceDirectory* directory, cee::ug::Error* /*error*/)
    {
        directory->setPartInfo(0, cee::ug::PartInfo(1, "First part"));
        directory->setStateInfo(cee::ug::StateInfo(1, "First state", 0.0));
        directory->setResultInfo(cee::ug::ResultInfo(cee::ug::SCALAR, 10, "Per node result", cee::ug::PER_NODE));
		directory->setResultInfo(cee::ug::ResultInfo(cee::ug::VECTOR, 10, "Per node result", cee::ug::PER_NODE));
        directory->setResultInfo(cee::ug::ResultInfo(cee::ug::DISPLACEMENT, 10, "Displacement result", cee::ug::PER_NODE));
		directory->setTransformationResult(true);

        return true;
    }

    bool readGeometry(int /*stateId*/, size_t /*geometryIndex*/, cee::ug::DataGeometry* geometry, cee::ug::Error* /*error*/)
    {
        cee::PtrRef<cee::ug::DataPart> part = new cee::ug::DataPart(1);
        cee::PtrRef<cee::ug::DataElements> elements = new cee::ug::DataElements(false, 0);
        cee::PtrRef<cee::ug::DataNodes> nodes = new cee::ug::DataNodes(false);
        part->setElements(elements.get());
        part->setNodes(nodes.get());
        nodes->resize(8);
        nodes->setNode(0, cee::Vec3d(0,0,0));
        nodes->setNode(1, cee::Vec3d(1,0,0));
        nodes->setNode(2, cee::Vec3d(1,1,0));
        nodes->setNode(3, cee::Vec3d(0,1,0));
        nodes->setNode(4, cee::Vec3d(0,0,1));
        nodes->setNode(5, cee::Vec3d(1,0,1));
        nodes->setNode(6, cee::Vec3d(1,1,1));
        nodes->setNode(7, cee::Vec3d(0,1,1));

        std::vector<unsigned int> elementIndices;
        for (unsigned int i = 0; i < 8; ++i) elementIndices.push_back(i);
        elements->addElement(cee::ug::Element::HEXAHEDRONS, elementIndices);

        geometry->addPart(part.get());

        return true;
    }

    bool readScalarResult(int /*stateId*/, size_t /*geometryIndex*/, int /*resultId*/, cee::ug::DataResultScalar* scalarResult, cee::ug::Error* /*error*/)
    {
        std::vector<double> values;
        for (size_t i = 0; i < 8; ++i) values.push_back(static_cast<double>(i));

        cee::PtrRef<cee::ug::DataPartScalar> part = new cee::ug::DataPartScalar;
        part->setValues(values);
        scalarResult->addPart(part.get());

        return true;
    }

    bool readVectorResult(int /*stateId*/, size_t /*geometryIndex*/, int /*resultId*/, cee::ug::DataResultVector* vectorResult, cee::ug::Error* /*error*/)
    {
        std::vector<cee::Vec3d> values;
        for (size_t i = 0; i < 8; ++i) values.push_back(cee::Vec3d(0.2*static_cast<double>(i), 0, 0));

        cee::PtrRef<cee::ug::DataPartVector> part = new cee::ug::DataPartVector;
        part->setValues(values);
        vectorResult->addPart(part.get());

        return true;
    }

    bool readDisplacementResult(int /*stateId*/, size_t /*geometryIndex*/, int /*resultId*/, cee::ug::DataResultDisplacement* displacementResult, cee::ug::Error* /*error*/)
    {
        std::vector<cee::Vec3d> values;
        values.push_back(cee::Vec3d(0,0,0));
        values.push_back(cee::Vec3d(1.1,0,0));
        values.push_back(cee::Vec3d(1,1.2,0));
        values.push_back(cee::Vec3d(0,1,0));
        values.push_back(cee::Vec3d(0,0,1));
        values.push_back(cee::Vec3d(1,0,1));
        values.push_back(cee::Vec3d(1,1.1,1));
        values.push_back(cee::Vec3d(0,1.2,1));

        cee::PtrRef<cee::ug::DataPartDisplacement> part = new cee::ug::DataPartDisplacement;
        part->setValues(values);

        displacementResult->addPart(part.get());

        return true;
    }

    bool readTransformationResult(int /*stateId*/, size_t /*geometryIndex*/, cee::ug::DataResultTransformation* transformationResult, cee::ug::Error* /*error*/)
    {
        cee::Mat4d partMatrix = cee::Mat4d::fromRotation(cee::Vec3d(1,1,1), 0.4);
        transformationResult->addPart(partMatrix);

        return true;
    }
};


//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void TutorialRunnerMainWindow::createCustomDataReader()
{
    //--------------------------------------------------------------------------
    // Set up the model and the data source with our custom reader
    //--------------------------------------------------------------------------

    // Create model and data source
    cee::PtrRef<cee::ug::UnstructGridModel> ugModel = new cee::ug::UnstructGridModel();
    cee::PtrRef<cee::ug::DataSourceReader> dataSource = new cee::ug::DataSourceReader(1, new SingleHexReader);
    ugModel->setDataSource(dataSource.get());
    
    // "Open" the file
    dataSource->open("AnyFileWillDo.xyz");

    // Get info about what is available from the reader
    const cee::ug::DataSourceDirectory* dir = dataSource->directory();
    std::vector<cee::ug::StateInfo>  stateInfos  = dir->stateInfos();
    std::vector<cee::ug::ResultInfo> scalarInfos = dir->scalarResultInfos();
    std::vector<cee::ug::ResultInfo> vectorInfos = dir->vectorResultInfos();
    std::vector<cee::ug::ResultInfo> displacementInfos = dir->displacementResultInfos();
    std::vector<cee::ug::PartInfo>   partInfos  = dir->partInfos(0);

    // Specify what to show
    ugModel->modelSpec().setStateId(stateInfos[0].id());
    ugModel->modelSpec().setFringesResultId(scalarInfos[0].id());
    ugModel->modelSpec().setVectorResultId(vectorInfos[0].id());
    ugModel->modelSpec().setDisplacementResultId(displacementInfos[0].id());
    ugModel->modelSpec().setTransformationResult(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();