<commit_before>/**
 *  Copyright (C) 2015 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "repo_renderer_glc.h"
#include "../../workers/repo_worker_glc_export.h"
#include <repo/core/model/bson/repo_bson_factory.h>

//------------------------------------------------------------------------------
#include <GLC_UserInput>
#include <GLC_Context>
#include <GLC_Octree>
#include <GLC_State>
#include <glc_renderstatistics.h>
//------------------------------------------------------------------------------

using namespace repo::gui::renderer;

GLCRenderer::GLCRenderer()
    : AbstractRenderer()
    , glcLight()
    , glcViewport()
    , glcMoverController()
    , glc3DWidgetManager(&glcViewport)
    , renderingFlag(glc::ShadingFlag)
    , clippingPlaneWidgets({nullptr, nullptr, nullptr})
    , clippingPlaneReverse(false)
    , shaderID(0)
    , isWireframe(false)
    , currentlyHighLighted("")
{
    //--------------------------------------------------------------------------
    // GLC settings
    QColor repColor;
    repColor.setRgbF(1.0, 0.11372, 0.11372, 1.0); // Red colour
    glcMoverController = GLC_Factory::instance()->createDefaultMoverController(
                repColor, &glcViewport);

    glcViewport.setBackgroundColor(Qt::white);
    glcLight.setPosition(1.0, 1.0, 1.0);

    //--------------------------------------------------------------------------
    // Create XYZ axes overlay
    GLC_3DViewInstance line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::X_AXIS);
    line.geomAt(0)->setWireColor(Qt::red);
    glcUICollection.add(line);
    line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::Y_AXIS);
    line.geomAt(0)->setWireColor(Qt::darkGreen);
    glcUICollection.add(line);
    line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::Z_AXIS);
    line.geomAt(0)->setWireColor(Qt::blue);
    glcUICollection.add(line);

    //--------------------------------------------------------------------------


    QObject::connect(
                &glcMoverController, &GLC_MoverController::repaintNeeded,
                this, &AbstractRenderer::repaintNeeded);

    QObject::connect(
                &glcMoverController, &GLC_MoverController::repaintNeeded,
                this, &AbstractRenderer::notifyCameraChange);

    QObject::connect(&glcViewport, &GLC_Viewport::updateOpenGL,
                     this, &AbstractRenderer::repaintNeeded);
}

GLCRenderer::~GLCRenderer()
{
    glcWorld.clear();
}

CameraSettings GLCRenderer::convertToCameraSettings(GLC_Camera *cam)
{
    CameraSettings res;
    auto eye = cam->eye();
    auto target = cam->target();
    auto up = cam->upVector();

    res.eye.x = eye.x();
    res.eye.y = eye.y();
    res.eye.z = eye.z();

    res.target.x = target.x();
    res.target.y = target.y();
    res.target.z = target.z();

    res.up.x = up.x();
    res.up.y = up.y();
    res.up.z = up.z();

    return res;
}

void GLCRenderer::deleteShaders(QOpenGLContext *context)
{
    GLC_SelectionMaterial::deleteShader(context);
    for (int i = 0; i < shaders.size(); ++i)
        delete shaders[i];
    shaders.clear();
}

void GLCRenderer::extractMeshes(GLC_StructOccurrence * occurrence)
{
    if (occurrence)
    {
        // Store the occurrence in a hash map.
        QString occurrenceName = occurrence->name();

        if (occurrence->structInstance() &&
                occurrence->structInstance()->structReference())
        {
            GLC_StructReference * glcReference = occurrence->structInstance()->structReference();
            if (!glcReference->representationIsEmpty())
            {
                GLC_3DRep * pRep = dynamic_cast<GLC_3DRep*>
                        (glcReference->representationHandle());
                if (pRep)
                {
                    for (int i = 0; i < pRep->numberOfBody(); ++i)
                    {
                        GLC_Mesh * glcMesh = dynamic_cast<GLC_Mesh*>(pRep->geomAt(i));

                        if (glcMesh)
                        {
                            glcMesh->setColorPearVertex(true);
                            meshMap[glcMesh->name()] = glcMesh;
                            QList<GLuint> materialIds = glcMesh->materialIds();
                            for (const GLuint id : materialIds)
                            {
                                GLC_Material *mat = glcMesh->material(id);
                                if (mat)
                                {
                                    matMap[mat->name()] = mat;
                                }
                            }
                        }
                    }
                }
            }
        }

        //----------------------------------------------------------------------
        // Children
        QList<GLC_StructOccurrence*> children = occurrence->children();
        QList<GLC_StructOccurrence*>::iterator it;
        for (it = children.begin(); it != children.end(); ++it)
        {
            GLC_StructOccurrence *child = *it;
            extractMeshes(child);
        }
    }
}

CameraSettings GLCRenderer::getCurrentCamera()
{
    return convertToCameraSettings(glcViewport.cameraHandle());
}

void GLCRenderer::highlightMesh(
        const QString &meshId)
{
    if(currentlyHighLighted == meshId)
    {
        //currently highlighted, should unhighlight it
        revertMeshMaterial(meshId);
        currentlyHighLighted = "";
    }
    else
    {
        GLC_Material highlightMat;


        highlightMat.setAmbientColor(QColor::fromRgbF(1.0f, 0.5f, 0.0f, 0.2f));
        highlightMat.setDiffuseColor(QColor::fromRgbF(1.0f, 0.5f, 0.0f, 0.2f));
        highlightMat.setSpecularColor(QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f));
        highlightMat.setEmissiveColor(QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f));
        highlightMat.setShininess(100);
        highlightMat.setOpacity(0.7);

        changeMeshMaterial(meshId, highlightMat);
        currentlyHighLighted = meshId;
    }



}

void GLCRenderer::changeMeshMaterial(
        const QString &uuidString,
        const GLC_Material &newMat)
{
    auto meshIt = meshMap.find(uuidString);
    auto matIt = matMap.find(uuidString);
    GLC_Material *mat = nullptr;
    if (matIt != matMap.end())
    {
        mat = matIt->second;

    }
    else if(meshIt != meshMap.end())
    {
        GLC_Mesh *mesh = meshIt->second;
        if (mesh->materialCount())
        {
            //has material, alter the emissive color
            auto matIds = mesh->materialIds();
            mat = mesh->material(matIds[0]);
        }
        else<commit_msg>change opacity to 1<commit_after>/**
 *  Copyright (C) 2015 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "repo_renderer_glc.h"
#include "../../workers/repo_worker_glc_export.h"
#include <repo/core/model/bson/repo_bson_factory.h>

//------------------------------------------------------------------------------
#include <GLC_UserInput>
#include <GLC_Context>
#include <GLC_Octree>
#include <GLC_State>
#include <glc_renderstatistics.h>
//------------------------------------------------------------------------------

using namespace repo::gui::renderer;

GLCRenderer::GLCRenderer()
    : AbstractRenderer()
    , glcLight()
    , glcViewport()
    , glcMoverController()
    , glc3DWidgetManager(&glcViewport)
    , renderingFlag(glc::ShadingFlag)
    , clippingPlaneWidgets({nullptr, nullptr, nullptr})
    , clippingPlaneReverse(false)
    , shaderID(0)
    , isWireframe(false)
    , currentlyHighLighted("")
{
    //--------------------------------------------------------------------------
    // GLC settings
    QColor repColor;
    repColor.setRgbF(1.0, 0.11372, 0.11372, 1.0); // Red colour
    glcMoverController = GLC_Factory::instance()->createDefaultMoverController(
                repColor, &glcViewport);

    glcViewport.setBackgroundColor(Qt::white);
    glcLight.setPosition(1.0, 1.0, 1.0);

    //--------------------------------------------------------------------------
    // Create XYZ axes overlay
    GLC_3DViewInstance line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::X_AXIS);
    line.geomAt(0)->setWireColor(Qt::red);
    glcUICollection.add(line);
    line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::Y_AXIS);
    line.geomAt(0)->setWireColor(Qt::darkGreen);
    glcUICollection.add(line);
    line = GLC_Factory::instance()->createLine(GLC_Point3d(), glc::Z_AXIS);
    line.geomAt(0)->setWireColor(Qt::blue);
    glcUICollection.add(line);

    //--------------------------------------------------------------------------


    QObject::connect(
                &glcMoverController, &GLC_MoverController::repaintNeeded,
                this, &AbstractRenderer::repaintNeeded);

    QObject::connect(
                &glcMoverController, &GLC_MoverController::repaintNeeded,
                this, &AbstractRenderer::notifyCameraChange);

    QObject::connect(&glcViewport, &GLC_Viewport::updateOpenGL,
                     this, &AbstractRenderer::repaintNeeded);
}

GLCRenderer::~GLCRenderer()
{
    glcWorld.clear();
}

CameraSettings GLCRenderer::convertToCameraSettings(GLC_Camera *cam)
{
    CameraSettings res;
    auto eye = cam->eye();
    auto target = cam->target();
    auto up = cam->upVector();

    res.eye.x = eye.x();
    res.eye.y = eye.y();
    res.eye.z = eye.z();

    res.target.x = target.x();
    res.target.y = target.y();
    res.target.z = target.z();

    res.up.x = up.x();
    res.up.y = up.y();
    res.up.z = up.z();

    return res;
}

void GLCRenderer::deleteShaders(QOpenGLContext *context)
{
    GLC_SelectionMaterial::deleteShader(context);
    for (int i = 0; i < shaders.size(); ++i)
        delete shaders[i];
    shaders.clear();
}

void GLCRenderer::extractMeshes(GLC_StructOccurrence * occurrence)
{
    if (occurrence)
    {
        // Store the occurrence in a hash map.
        QString occurrenceName = occurrence->name();

        if (occurrence->structInstance() &&
                occurrence->structInstance()->structReference())
        {
            GLC_StructReference * glcReference = occurrence->structInstance()->structReference();
            if (!glcReference->representationIsEmpty())
            {
                GLC_3DRep * pRep = dynamic_cast<GLC_3DRep*>
                        (glcReference->representationHandle());
                if (pRep)
                {
                    for (int i = 0; i < pRep->numberOfBody(); ++i)
                    {
                        GLC_Mesh * glcMesh = dynamic_cast<GLC_Mesh*>(pRep->geomAt(i));

                        if (glcMesh)
                        {
                            glcMesh->setColorPearVertex(true);
                            meshMap[glcMesh->name()] = glcMesh;
                            QList<GLuint> materialIds = glcMesh->materialIds();
                            for (const GLuint id : materialIds)
                            {
                                GLC_Material *mat = glcMesh->material(id);
                                if (mat)
                                {
                                    matMap[mat->name()] = mat;
                                }
                            }
                        }
                    }
                }
            }
        }

        //----------------------------------------------------------------------
        // Children
        QList<GLC_StructOccurrence*> children = occurrence->children();
        QList<GLC_StructOccurrence*>::iterator it;
        for (it = children.begin(); it != children.end(); ++it)
        {
            GLC_StructOccurrence *child = *it;
            extractMeshes(child);
        }
    }
}

CameraSettings GLCRenderer::getCurrentCamera()
{
    return convertToCameraSettings(glcViewport.cameraHandle());
}

void GLCRenderer::highlightMesh(
        const QString &meshId)
{
    if(currentlyHighLighted == meshId)
    {
        //currently highlighted, should unhighlight it
        revertMeshMaterial(meshId);
        currentlyHighLighted = "";
    }
    else
    {
        GLC_Material highlightMat;


        highlightMat.setAmbientColor(QColor::fromRgbF(1.0f, 0.5f, 0.0f, 0.2f));
        highlightMat.setDiffuseColor(QColor::fromRgbF(1.0f, 0.5f, 0.0f, 0.2f));
        highlightMat.setSpecularColor(QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f));
        highlightMat.setEmissiveColor(QColor::fromRgbF(1.0f, 0.5f, 0.0f, 0.2f));
//        highlightMat.setShininess(100);
        highlightMat.setOpacity(1.0);

        changeMeshMaterial(meshId, highlightMat);
        currentlyHighLighted = meshId;
    }



}

void GLCRenderer::changeMeshMaterial(
        const QString &uuidString,
        const GLC_Material &newMat)
{
    auto meshIt = meshMap.find(uuidString);
    auto matIt = matMap.find(uuidString);
    GLC_Material *mat = nullptr;
    if (matIt != matMap.end())
    {
        mat = matIt->second;

    }
    else if(meshIt != meshMap.end())
    {
        GLC_Mesh *mesh = meshIt->second;
        if (mesh->materialCount())
        {
            //has material, alter the emissive color
            auto matIds = mesh->materialIds();
            mat = mesh->material(matIds[0]);
        }
        else
{'fraction_non_alphanumeric': 0.17667309281189755, 'fraction_numerical': 0.010947397411181493, 'mean_word_length': 1.8402424716464607, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2641143', 'n_tokens_mistral': 4412, 'n_tokens_neox': 4198, 'n_words': 810}