<commit_before>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/summed_area_table.h"
#include "./placement/to_gray.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    frustumOptimizer(nodes)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<Graphics::FrameBufferObject>(
      new Graphics::FrameBufferObject());
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");

  fbo->initialize(gl, width, height);
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  distanceTransformTexture =
      std::make_shared<Graphics::StandardTexture2d>(width, height, GL_RGBA32F);
  distanceTransformTexture->initialize(gl);
}

void Scene::cleanup()
{
  colorTextureMapper.reset();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  frustumOptimizer.update(camera.getViewMatrix());
  camera.updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  // doPick();

  fbo->unbind();

  if (!colorTextureMapper.get())
  {
    colorTextureMapper = std::shared_ptr<CudaTextureMapper>(
        CudaTextureMapper::createReadWriteMapper(fbo->getRenderTextureId(),
                                                 width, height));
  }

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  ToGray(colorTextureMapper).runKernel();
  Eigen::Affine3f transformation(
      Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  fbo->bindDepthTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  fbo->bindPositionTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(positionQuad, transformation.matrix());

  glAssert(gl->glEnable(GL_DEPTH_TEST));
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  fbo->bindColorTexture(GL_TEXTURE0);

  renderQuad(quad, Eigen::Matrix4f::Identity());
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  pickingPosition = position;
  performPicking = true;
  pickingLabelId = id;
}

void Scene::doPick()
{
  if (!performPicking)
    return;

  float depth = -2.0f;

  fbo->bindDepthTexture(GL_TEXTURE0);

  glAssert(gl->glReadPixels(pickingPosition.x(),
                            height - pickingPosition.y() - 1, 1, 1,
                            GL_DEPTH_COMPONENT, GL_FLOAT, &depth));
  Eigen::Vector4f positionNDC(pickingPosition.x() * 2.0f / width - 1.0f,
                              pickingPosition.y() * -2.0f / height + 1.0f,
                              depth * 2.0f - 1.0f, 1.0f);

  Eigen::Matrix4f viewProjection =
      camera.getProjectionMatrix() * camera.getViewMatrix();
  Eigen::Vector4f positionWorld = viewProjection.inverse() * positionNDC;
  positionWorld = positionWorld / positionWorld.w();

  qWarning() << "picked:" << positionWorld;

  performPicking = false;
  auto label = labels->getById(pickingLabelId);
  label.anchorPosition = toVector3f(positionWorld);

  labels->update(label);
}

<commit_msg>Add mappers for debugging.<commit_after>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/summed_area_table.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    frustumOptimizer(nodes)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<Graphics::FrameBufferObject>(
      new Graphics::FrameBufferObject());
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");

  fbo->initialize(gl, width, height);
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  distanceTransformTexture =
      std::make_shared<Graphics::StandardTexture2d>(width, height, GL_R32F);
  distanceTransformTexture->initialize(gl);
}

void Scene::cleanup()
{
  colorTextureMapper.reset();
  depthTextureMapper.reset();
  distanceTransformTextureMapper.reset();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  frustumOptimizer.update(camera.getViewMatrix());
  camera.updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  // doPick();

  fbo->unbind();

  if (!colorTextureMapper.get())
  {
    colorTextureMapper = std::shared_ptr<CudaTextureMapper>(
        CudaTextureMapper::createReadWriteMapper(fbo->getRenderTextureId(),
                                                 width, height));
    depthTextureMapper = std::shared_ptr<CudaTextureMapper>(
        CudaTextureMapper::createReadOnlyMapper(fbo->getPositionTextureId(),
                                                width, height));
    distanceTransformTextureMapper = std::shared_ptr<CudaTextureMapper>(
        CudaTextureMapper::createReadWriteDiscardMapper(
            distanceTransformTexture->getId(), width, height));
  }

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  ToGray(colorTextureMapper).runKernel();
  Eigen::Affine3f transformation(
      Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  fbo->bindDepthTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  fbo->bindPositionTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(positionQuad, transformation.matrix());

  glAssert(gl->glEnable(GL_DEPTH_TEST));
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  fbo->bindColorTexture(GL_TEXTURE0);

  renderQuad(quad, Eigen::Matrix4f::Identity());
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  pickingPosition = position;
  performPicking = true;
  pickingLabelId = id;
}

void Scene::doPick()
{
  if (!performPicking)
    return;

  float depth = -2.0f;

  fbo->bindDepthTexture(GL_TEXTURE0);

  glAssert(gl->glReadPixels(pickingPosition.x(),
                            height - pickingPosition.y() - 1, 1, 1,
                            GL_DEPTH_COMPONENT, GL_FLOAT, &depth));
  Eigen::Vector4f positionNDC(pickingPosition.x() * 2.0f / width - 1.0f,
                              pickingPosition.y() * -2.0f / height + 1.0f,
                              depth * 2.0f - 1.0f, 1.0f);

  Eigen::Matrix4f viewProjection =
      camera.getProjectionMatrix() * camera.getViewMatrix();
  Eigen::Vector4f positionWorld = viewProjection.inverse() * positionNDC;
  positionWorld = positionWorld / positionWorld.w();

  qWarning() << "picked:" << positionWorld;

  performPicking = false;
  auto label = labels->getById(pickingLabelId);
  label.anchorPosition = toVector3f(positionWorld);

  labels->update(label);
}

<|endoftext|>


<commit_before>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(),
      textureMapperManager->getDistanceTransformTextureMapper(),
      textureMapperManager->getApolloniusTextureMapper(),
      textureMapperManager->getConstraintTextureMapper(), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  // frustumOptimizer.update(camera->getViewMatrix());
  // camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
  //                                frustumOptimizer.getFar());
  // haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
  //                                  frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  fbo->bindDepthTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOccupancyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  fbo->bindColorTexture(GL_TEXTURE0);

  renderQuad(quad, Eigen::Matrix4f::Identity());
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

<commit_msg>Show first render texture instead of depth buffer in debugging views.<commit_after>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(),
      textureMapperManager->getDistanceTransformTextureMapper(),
      textureMapperManager->getApolloniusTextureMapper(),
      textureMapperManager->getConstraintTextureMapper(), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  // frustumOptimizer.update(camera->getViewMatrix());
  // camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
  //                                frustumOptimizer.getFar());
  // haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
  //                                  frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  fbo->bindColorTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOccupancyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  fbo->bindColorTexture2(GL_TEXTURE0);

  renderQuad(quad, Eigen::Matrix4f::Identity());
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

<|endoftext|>


<commit_before>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(0),
      textureMapperManager->getDistanceTransformTextureMapper(0),
      textureMapperManager->getApolloniusTextureMapper(0),
      textureMapperManager->getConstraintTextureMapper(0), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindColorTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, -0.4, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindDepthTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, 0.8, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  fbo->bindDepthTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  int layerIndex = 0;
  textureMapperManager->bindOccupancyTexture(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(0, GL_TEXTURE0);
    fbo->bindColorTexture(1, GL_TEXTURE1);
    fbo->bindColorTexture(2, GL_TEXTURE2);
    fbo->bindColorTexture(3, GL_TEXTURE3);

    screenQuad->getShaderProgram()->setUniform("layer1", 0);
    screenQuad->getShaderProgram()->setUniform("layer2", 1);
    screenQuad->getShaderProgram()->setUniform("layer3", 2);
    screenQuad->getShaderProgram()->setUniform("layer4", 3);
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else
  {
    fbo->bindColorTexture(activeLayerNumber - 1, GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<commit_msg>Render debugging views of active layer.<commit_after>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./labelling/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/to_gray.h"
#include "./placement/distance_transform.h"
#include "./placement/occupancy.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./placement/constraint_updater.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> forcesLabeller,
             std::shared_ptr<Placement::Labeller> placementLabeller,
             std::shared_ptr<TextureMapperManager> textureMapperManager)

  : nodes(nodes), labels(labels), forcesLabeller(forcesLabeller),
    placementLabeller(placementLabeller), frustumOptimizer(nodes),
    textureMapperManager(textureMapperManager)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>();
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  auto drawer = std::make_shared<Graphics::BufferDrawer>(
      textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize(), gl, managers->getShaderManager());

  auto constraintUpdater = std::make_shared<ConstraintUpdater>(
      drawer, textureMapperManager->getBufferSize(),
      textureMapperManager->getBufferSize());

  placementLabeller->initialize(
      textureMapperManager->getOccupancyTextureMapper(0),
      textureMapperManager->getDistanceTransformTextureMapper(0),
      textureMapperManager->getApolloniusTextureMapper(0),
      textureMapperManager->getConstraintTextureMapper(0), constraintUpdater);
}

void Scene::cleanup()
{
  placementLabeller->cleanup();
  textureMapperManager->cleanup();
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  auto camera = getCamera();

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  /*
  auto newPositions = forcesLabeller->update(LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));
      */
  auto newPositions = placementLabeller->getLastPlacementResult();
  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  if (camera->needsResizing())
    camera->resize(width, height);

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData = createRenderData();

  renderNodesWithHABufferIntoFBO(renderData);

  glAssert(gl->glDisable(GL_DEPTH_TEST));
  renderScreenQuad();

  textureMapperManager->update();

  constraintBufferObject->bind();

  placementLabeller->update(LabellerFrameData(
      frameTime, camera->getProjectionMatrix(), camera->getViewMatrix()));

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  nodes->renderLabels(gl, managers, renderData);
}

void Scene::renderNodesWithHABufferIntoFBO(const RenderData &renderData)
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  picker->doPick(renderData.projectionMatrix * renderData.viewMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindColorTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, -0.4, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    fbo->bindDepthTexture(i, GL_TEXTURE0);
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8 + 0.4 * i, 0.8, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
    renderQuad(quad, transformation.matrix());
  }

  fbo->bindDepthTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  int layerIndex = activeLayerNumber == 0 ? 0 : activeLayerNumber - 1;
  textureMapperManager->bindOccupancyTexture(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(-0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindDistanceTransform(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  textureMapperManager->bindApollonius(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8, -0.8, 0)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2, 0.2, 1)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(0, GL_TEXTURE0);
    fbo->bindColorTexture(1, GL_TEXTURE1);
    fbo->bindColorTexture(2, GL_TEXTURE2);
    fbo->bindColorTexture(3, GL_TEXTURE3);

    screenQuad->getShaderProgram()->setUniform("layer1", 0);
    screenQuad->getShaderProgram()->setUniform("layer2", 1);
    screenQuad->getShaderProgram()->setUniform("layer3", 2);
    screenQuad->getShaderProgram()->setUniform("layer4", 3);
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else
  {
    fbo->bindColorTexture(activeLayerNumber - 1, GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  placementLabeller->resize(width, height);

  shouldResize = true;

  forcesLabeller->resize(width, height);
}

RenderData Scene::createRenderData()
{
  RenderData renderData;
  auto camera = getCamera();
  renderData.projectionMatrix = camera->getProjectionMatrix();
  renderData.viewMatrix = camera->getViewMatrix();
  renderData.cameraPosition = camera->getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();
  renderData.windowPixelSize = Eigen::Vector2f(width, height);

  return renderData;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<|endoftext|>


<commit_before>#ifndef _SCENE_HPP
#define _SCENE_HPP

#include <vector>
#include <string>

#include "shape.hpp"
#include "light.hpp"
#include "camera.hpp"

class Scene {

protected:
    // Storage for shapes in scene
    std::vector<Shape*> shapes;
    std::vector<LightSource*> lights;
    Camera camera;

public:
    Scene();
    Scene(std::string fileName);
    ~Scene();

    /**
     * Asks the camera for a ray
     * @return The camera's ray
     */
    Ray get_camera_ray(float x, float y) const;

};

#endif
<commit_msg>Added Scene::scene().<commit_after>#ifndef _SCENE_HPP
#define _SCENE_HPP

#include <vector>
#include <string>

#include "shape.hpp"
#include "light.hpp"
#include "camera.hpp"

class Scene {

protected:
    // Storage for shapes in scene
    std::vector<Shape*> shapes;
    std::vector<LightSource*> lights;
    Camera camera;

public:
    /**
     * Default constructor for objects of class Scene().
     * Creates a default scene layout for testing purposes,
     * with a minimal number of objects and lights.
     */
    Scene();

    /**
     * Constructor for objects of class Scene().
     * Loads a scene from a file using JSON and OpenCTM file formats.
     */
    Scene(std::string fileName);

    /**
     * Given an object and the ray representing the intersection point,
     * returns the expected color given the local illumination calculation.
     *
     * @param obj The object which a ray intersected.
     * @param hit The ray representing the normal vector and point of intersection.
     * @return The color at the given point.
     */
    Color shade(Shape obj, Ray hit);

    ~Scene();

    /**
     * Asks the camera for a ray
     * @return The camera's ray
     */
    Ray get_camera_ray(float x, float y) const;

};

#endif
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH

#include <memory>
#include <sstream>
#include <type_traits>
#include <vector>
#include <array>

#include <boost/numeric/conversion/cast.hpp>

#include <dune/grid/sgrid.hh>
#include <dune/grid/yaspgrid.hh>
#if HAVE_ALUGRID
# include <dune/grid/alugrid.hh>
#endif

#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/memory.hh>
#include <dune/stuff/grid/structuredgridfactory.hh>

#include "default.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Providers {
namespace internal {

template< typename GridType >
struct ElementVariant;

template< typename GridType >
struct ElementVariant
{
  static const int id = 2;
};

template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::SGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

#if HAVE_ALUGRID

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUCubeGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::conforming > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::nonconforming > >
{
  static const int id = 1;
};

#endif // HAVE_ALUGRID

} // namespace internal

#if HAVE_DUNE_GRID

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = internal::ElementVariant< GridImp >::id >
class Cube
  : public ProviderInterface< GridImp >
{
  typedef ProviderInterface< GridImp > BaseType;
  typedef Cube< GridImp, variant > ThisType;
public:
  using typename BaseType::GridType;
  static const size_t dimDomain = BaseType::dimDomain;
  using typename BaseType::DomainFieldType;
  using typename BaseType::DomainType;

  static const std::string static_id()
  {
    return BaseType::static_id() + ".cube";
  }

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    Common::Configuration config;
    config["lower_left"] = "[0.0 0.0 0.0 0.0]";
    config["upper_right"] = "[1.0 1.0 1.0 1.0]";
    config["num_elements"] = "[8 8 8 8]";
    config["num_refinements"] = "0";
    if (sub_name.empty())
      return config;
    else {
      Common::Configuration tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(),
                                            const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::Configuration default_cfg = default_config();
    return Common::make_unique< ThisType >(
          cfg.get("lower_left", default_cfg.get< DomainType >("lower_left")),
          cfg.get("upper_right", default_cfg.get< DomainType >("upper_right")),
          cfg.get("num_elements", default_cfg.get< std::vector< unsigned int > >("num_elements"), dimDomain),
          cfg.get("num_refinements", default_cfg.get< size_t >("num_refinements")));
  } // ... create(...)

  /**
   *  \brief      Creates a cube.
   *  \param[in]  lower_left
   *              Used as a lower left corner (in each dimension, if scalar).
   *  \param[in]  upper_right
   *              Used as an upper right corner (in each dimension, if scalar).
   *  \param[in]  num_elements (optional)
   *              Number of elements.
   **/
  explicit Cube(const DomainFieldType lower_left = default_config().get< DomainFieldType >("lower_left"),
       const DomainFieldType upper_right = default_config().get< DomainFieldType >("upper_right"),
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(DomainType(lower_left),
                            DomainType(upper_right),
                            parse_array(num_elements),
                            num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const std::vector< unsigned int > num_elements
          = default_config().get< std::vector< unsigned int > >("num_elements"),
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  virtual GridType& grid() override
  {
    return *grid_ptr_;
  }

  virtual const GridType& grid() const override
  {
    return *grid_ptr_;
  }

  std::shared_ptr< GridType > grid_ptr()
  {
    return grid_ptr_;
  }

  const std::shared_ptr< const GridType >& grid_ptr() const
  {
    return grid_ptr_;
  }

private:
  static std::array< unsigned int, dimDomain > parse_array(const unsigned int in)
  {
    std::array< unsigned int, dimDomain > ret;
    std::fill(ret.begin(), ret.end(), in);
    return ret;
  } // ... parse_array(...)

  static std::array< unsigned int, dimDomain > parse_array(const std::vector< unsigned int >& in)
  {
    if (in.size() < dimDomain)
      DUNE_THROW(Exceptions::wrong_input_given,
                 "Given vector is too short: should be " << dimDomain << ", is " << in.size() << "!");
    std::array< unsigned int, dimDomain > ret;
    for (size_t ii = 0; ii < dimDomain; ++ii)
      ret[ii] = in[ii];
    return ret;
  } // ... parse_array(...)

  static std::shared_ptr< GridType > create_grid(DomainType lower_left,
                                                 DomainType upper_right,
                                                 const std::array< unsigned int, dimDomain >& num_elements,
                                                 const size_t num_refinements)
  {
    static_assert(variant == 1 || variant == 2, "variant has to be 1 or 2!");
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      if (!(lower_left[dd] < upper_right[dd]))
        DUNE_THROW(Exceptions::wrong_input_given,
                   "lower_left has to be elementwise smaller than upper_right!\n\n"
                   << lower_left[dd] << " vs. " << upper_right[dd]);
    }
    std::shared_ptr< GridType > grd_ptr(nullptr);
    switch (variant) {
      case 1:
        grd_ptr = Dune::StructuredGridFactory< GridType >::createCubeGrid(lower_left, upper_right, num_elements);
        break;
      case 2:
    default:
        grd_ptr = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lower_left, upper_right, num_elements);
        break;
    }
    grd_ptr->globalRefine(boost::numeric_cast< int >(num_refinements));
    return grd_ptr;
  } // ... create_grid(...)

  std::shared_ptr< GridType > grid_ptr_;
}; // class Cube

#else // HAVE_DUNE_GRID

template< typename GridImp, int variant = 1 >
class Cube
{
  static_assert(AlwaysFalse< GridImp >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Providers
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
<commit_msg>[tests] fixes test fail w/o dune-grid present<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH

#include <memory>
#include <sstream>
#include <type_traits>
#include <vector>
#include <array>

#include <boost/numeric/conversion/cast.hpp>

#if HAVE_DUNE_GRID
# include <dune/grid/sgrid.hh>
# include <dune/grid/yaspgrid.hh>
# if HAVE_ALUGRID
#   include <dune/grid/alugrid.hh>
# endif
# include <dune/stuff/grid/structuredgridfactory.hh>
#endif

#include <dune/stuff/common/fvector.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/memory.hh>

#include "default.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Providers {
namespace internal {

template< typename GridType >
struct ElementVariant;

template< typename GridType >
struct ElementVariant
{
  static const int id = 2;
};

template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::SGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

#if HAVE_ALUGRID

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUCubeGrid< dimGrid, dimWorld > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::conforming > >
{
  static const int id = 1;
};

template< int dimGrid, int dimWorld >
struct ElementVariant< Dune::ALUGrid< dimGrid, dimWorld, Dune::cube, Dune::nonconforming > >
{
  static const int id = 1;
};

#endif // HAVE_ALUGRID

} // namespace internal

#if HAVE_DUNE_GRID

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = internal::ElementVariant< GridImp >::id >
class Cube
  : public ProviderInterface< GridImp >
{
  typedef ProviderInterface< GridImp > BaseType;
  typedef Cube< GridImp, variant > ThisType;
public:
  using typename BaseType::GridType;
  static const size_t dimDomain = BaseType::dimDomain;
  using typename BaseType::DomainFieldType;
  using typename BaseType::DomainType;

  static const std::string static_id()
  {
    return BaseType::static_id() + ".cube";
  }

  static Common::Configuration default_config(const std::string sub_name = "")
  {
    Common::Configuration config;
    config["lower_left"] = "[0.0 0.0 0.0 0.0]";
    config["upper_right"] = "[1.0 1.0 1.0 1.0]";
    config["num_elements"] = "[8 8 8 8]";
    config["num_refinements"] = "0";
    if (sub_name.empty())
      return config;
    else {
      Common::Configuration tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::Configuration config = default_config(),
                                            const std::string sub_name = static_id())
  {
    // get correct config
    const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    const Common::Configuration default_cfg = default_config();
    return Common::make_unique< ThisType >(
          cfg.get("lower_left", default_cfg.get< DomainType >("lower_left")),
          cfg.get("upper_right", default_cfg.get< DomainType >("upper_right")),
          cfg.get("num_elements", default_cfg.get< std::vector< unsigned int > >("num_elements"), dimDomain),
          cfg.get("num_refinements", default_cfg.get< size_t >("num_refinements")));
  } // ... create(...)

  /**
   *  \brief      Creates a cube.
   *  \param[in]  lower_left
   *              Used as a lower left corner (in each dimension, if scalar).
   *  \param[in]  upper_right
   *              Used as an upper right corner (in each dimension, if scalar).
   *  \param[in]  num_elements (optional)
   *              Number of elements.
   **/
  explicit Cube(const DomainFieldType lower_left = default_config().get< DomainFieldType >("lower_left"),
       const DomainFieldType upper_right = default_config().get< DomainFieldType >("upper_right"),
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(DomainType(lower_left),
                            DomainType(upper_right),
                            parse_array(num_elements),
                            num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const unsigned int num_elements = default_config().get< std::vector< unsigned int > >("num_elements")[0],
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  Cube(const DSC::FieldVector< DomainFieldType, dimDomain >& lower_left,
       const DSC::FieldVector< DomainFieldType, dimDomain >& upper_right,
       const std::vector< unsigned int > num_elements
          = default_config().get< std::vector< unsigned int > >("num_elements"),
       const size_t num_refinements = default_config().get< size_t >("num_refinements"))
    : grid_ptr_(create_grid(lower_left, upper_right, parse_array(num_elements), num_refinements))
  {}

  virtual GridType& grid() override
  {
    return *grid_ptr_;
  }

  virtual const GridType& grid() const override
  {
    return *grid_ptr_;
  }

  std::shared_ptr< GridType > grid_ptr()
  {
    return grid_ptr_;
  }

  const std::shared_ptr< const GridType >& grid_ptr() const
  {
    return grid_ptr_;
  }

private:
  static std::array< unsigned int, dimDomain > parse_array(const unsigned int in)
  {
    std::array< unsigned int, dimDomain > ret;
    std::fill(ret.begin(), ret.end(), in);
    return ret;
  } // ... parse_array(...)

  static std::array< unsigned int, dimDomain > parse_array(const std::vector< unsigned int >& in)
  {
    if (in.size() < dimDomain)
      DUNE_THROW(Exceptions::wrong_input_given,
                 "Given vector is too short: should be " << dimDomain << ", is " << in.size() << "!");
    std::array< unsigned int, dimDomain > ret;
    for (size_t ii = 0; ii < dimDomain; ++ii)
      ret[ii] = in[ii];
    return ret;
  } // ... parse_array(...)

  static std::shared_ptr< GridType > create_grid(DomainType lower_left,
                                                 DomainType upper_right,
                                                 const std::array< unsigned int, dimDomain >& num_elements,
                                                 const size_t num_refinements)
  {
    static_assert(variant == 1 || variant == 2, "variant has to be 1 or 2!");
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      if (!(lower_left[dd] < upper_right[dd]))
        DUNE_THROW(Exceptions::wrong_input_given,
                   "lower_left has to be elementwise smaller than upper_right!\n\n"
                   << lower_left[dd] << " vs. " << upper_right[dd]);
    }
    std::shared_ptr< GridType > grd_ptr(nullptr);
    switch (variant) {
      case 1:
        grd_ptr = Dune::StructuredGridFactory< GridType >::createCubeGrid(lower_left, upper_right, num_elements);
        break;
      case 2:
    default:
        grd_ptr = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lower_left, upper_right, num_elements);
        break;
    }
    grd_ptr->globalRefine(boost::numeric_cast< int >(num_refinements));
    return grd_ptr;
  } // ... create_grid(...)

  std::shared_ptr< GridType > grid_ptr_;
}; // class Cube

#else // HAVE_DUNE_GRID

template< typename GridImp, int variant = 1 >
class Cube
{
  static_assert(AlwaysFalse< GridImp >::value, "You are missing dune-grid!");
};

#endif // HAVE_DUNE_GRID

} // namespace Providers
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRIDS_PROVIDER_CUBE_HH
<|endoftext|>


<commit_before>#include <PeerNet.h>
#pragma comment(lib, "PeerNet.lib")

#include <iostream>
#include <string>

int main()
{
	std::string ConsoleInput;
	printf("[Example Peer]\nHelp commands->\n");
	printf("\tinit - Initialize PeerNet\n");
	printf("\tdeinit - Deinitialize PeerNet\n");
	printf("\tquit - Exit application\n");
	printf("\topen - Create new socket from IP and PORT\n");
	printf("\tclose - Delete the last created socket\n");
	printf("\tdiscover - Discover new peer from IP and PORT\n");
	printf("\tforget - Forget a discovered peer\n");
	printf("\tr - Send reliable packet to discovered peer\n");
	printf("\tur - Send unreliable packet to discovered peer\n");
	printf("\n");

	PeerNet::NetSocket* Socket = nullptr;
	std::shared_ptr<PeerNet::NetPeer> Peer;
	while (std::getline(std::cin, ConsoleInput))
	{
		if (ConsoleInput == "init")	{
			PeerNet::Initialize();
		}
		else if (ConsoleInput == "deinit") {
			PeerNet::Deinitialize();
		}
		if (ConsoleInput == "quit")	{
			break;
		}
		else if (ConsoleInput == "open") {
			if (Socket == nullptr)
			{
				printf("IP Address: ");
				std::string InputIP;
				std::getline(std::cin, InputIP);
				printf("Port: ");
				std::string InputPort;
				std::getline(std::cin, InputPort);
				Socket = PeerNet::CreateSocket(InputIP.c_str(), InputPort.c_str());
			}
		}
		else if (ConsoleInput == "close")
		{
			if (Socket != nullptr)
			{
				PeerNet::DeleteSocket(Socket);
				Socket = nullptr;
			}
		}
		else if (ConsoleInput == "discover")
		{
			if (Peer == nullptr)
			{
				printf("IP Address: ");
				std::string InputIP;
				std::getline(std::cin, InputIP);
				printf("Port: ");
				std::string InputPort;
				std::getline(std::cin, InputPort);
				Peer = Socket->DiscoverPeer(InputIP.c_str(), InputPort.c_str());
			}
		}
		else if (ConsoleInput == "forget")
		{
			if (Peer != nullptr)
			{
				Peer.reset(); // release our shared_ptr to Peer
				Peer = nullptr;
			}
		}
		else if (ConsoleInput == "r")
		{
			if (Peer != nullptr)
			{
				auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Reliable);
				NewPacket->WriteData<std::string>("I'm about to be serialized and I'm reliable!!");
				Peer->SendPacket(NewPacket);
			}
		}
		else if (ConsoleInput == "u")
		{
			if (Peer != nullptr)
			{
				auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Unreliable);
				NewPacket->WriteData<std::string>("I'm about to be serialized and I'm unreliable..");
				Peer->SendPacket(NewPacket);
			}
		}
		else if (ConsoleInput == "ul")
		{
			if (Peer != nullptr)
			{
				unsigned int i = 0;
				while (i < 1000)
				{
					auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Unreliable);
					NewPacket->WriteData<std::string>("I'm about to be serialized and I'm unreliable..");
					Peer->SendPacket(NewPacket);
					i++;
				}
			}
		}
		else if (ConsoleInput == "rl")
		{
			if (Peer != nullptr)
			{
				unsigned int i = 0;
				while (i < 1000)
				{
					auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Reliable);
					NewPacket->WriteData<std::string>("I'm about to be serialized and I'm reliable!!");
					Peer->SendPacket(NewPacket);
					i++;
				}
			}
		}
	}
	std::system("PAUSE");
	return 0;
}<commit_msg>fixing appveyor<commit_after>#include "PeerNet.h"
#pragma comment(lib, "PeerNet.lib")

#include <iostream>
#include <string>

int main()
{
	std::string ConsoleInput;
	printf("[Example Peer]\nHelp commands->\n");
	printf("\tinit - Initialize PeerNet\n");
	printf("\tdeinit - Deinitialize PeerNet\n");
	printf("\tquit - Exit application\n");
	printf("\topen - Create new socket from IP and PORT\n");
	printf("\tclose - Delete the last created socket\n");
	printf("\tdiscover - Discover new peer from IP and PORT\n");
	printf("\tforget - Forget a discovered peer\n");
	printf("\tr - Send reliable packet to discovered peer\n");
	printf("\tur - Send unreliable packet to discovered peer\n");
	printf("\n");

	PeerNet::NetSocket* Socket = nullptr;
	std::shared_ptr<PeerNet::NetPeer> Peer;
	while (std::getline(std::cin, ConsoleInput))
	{
		if (ConsoleInput == "init")	{
			PeerNet::Initialize();
		}
		else if (ConsoleInput == "deinit") {
			PeerNet::Deinitialize();
		}
		if (ConsoleInput == "quit")	{
			break;
		}
		else if (ConsoleInput == "open") {
			if (Socket == nullptr)
			{
				printf("IP Address: ");
				std::string InputIP;
				std::getline(std::cin, InputIP);
				printf("Port: ");
				std::string InputPort;
				std::getline(std::cin, InputPort);
				Socket = PeerNet::CreateSocket(InputIP.c_str(), InputPort.c_str());
			}
		}
		else if (ConsoleInput == "close")
		{
			if (Socket != nullptr)
			{
				PeerNet::DeleteSocket(Socket);
				Socket = nullptr;
			}
		}
		else if (ConsoleInput == "discover")
		{
			if (Peer == nullptr)
			{
				printf("IP Address: ");
				std::string InputIP;
				std::getline(std::cin, InputIP);
				printf("Port: ");
				std::string InputPort;
				std::getline(std::cin, InputPort);
				Peer = Socket->DiscoverPeer(InputIP.c_str(), InputPort.c_str());
			}
		}
		else if (ConsoleInput == "forget")
		{
			if (Peer != nullptr)
			{
				Peer.reset(); // release our shared_ptr to Peer
				Peer = nullptr;
			}
		}
		else if (ConsoleInput == "r")
		{
			if (Peer != nullptr)
			{
				auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Reliable);
				NewPacket->WriteData<std::string>("I'm about to be serialized and I'm reliable!!");
				Peer->SendPacket(NewPacket);
			}
		}
		else if (ConsoleInput == "u")
		{
			if (Peer != nullptr)
			{
				auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Unreliable);
				NewPacket->WriteData<std::string>("I'm about to be serialized and I'm unreliable..");
				Peer->SendPacket(NewPacket);
			}
		}
		else if (ConsoleInput == "ul")
		{
			if (Peer != nullptr)
			{
				unsigned int i = 0;
				while (i < 1000)
				{
					auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Unreliable);
					NewPacket->WriteData<std::string>("I'm about to be serialized and I'm unreliable..");
					Peer->SendPacket(NewPacket);
					i++;
				}
			}
		}
		else if (ConsoleInput == "rl")
		{
			if (Peer != nullptr)
			{
				unsigned int i = 0;
				while (i < 1000)
				{
					auto NewPacket = PeerNet::CreateNewPacket(PeerNet::PacketType::PN_Reliable);
					NewPacket->WriteData<std::string>("I'm about to be serialized and I'm reliable!!");
					Peer->SendPacket(NewPacket);
					i++;
				}
			}
		}
	}
	std::system("PAUSE");
	return 0;
}<|endoftext|>


<commit_before>/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * hir_typeck/impl_ref.cpp
 * - Reference to a trait implementation (either a bound or a impl block)
 */
#include "impl_ref.hpp"
#include <hir/hir.hpp>
#include "static.hpp"   // for monomorphise_type_with

bool ImplRef::more_specific_than(const ImplRef& other) const
{
    TU_MATCH(Data, (this->m_data), (te),
    (TraitImpl,
        if( te.impl == nullptr ) {
            return false;
        }
        TU_MATCH(Data, (other.m_data), (oe),
        (TraitImpl,
            if( oe.impl == nullptr ) {
                return true;
            }
            return te.impl->more_specific_than( *oe.impl );
            ),
        (BoundedPtr,
            return false;
            ),
        (Bounded,
            return false;
            )
        )
        ),
    (BoundedPtr,
        return true;
        ),
    (Bounded,
        return true;
        )
    )
    throw "";
}
bool ImplRef::type_is_specialisable(const char* name) const
{
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            // No impl yet? This type is specialisable.
            return true;
        }
        //TODO(Span(), "type_is_specializable - Impl = " << *this << ", Type = " << name);
        auto it = e.impl->m_types.find(name);
        if( it == e.impl->m_types.end() ) {
            TODO(Span(), "Handle missing type in " << *this << ", name = " << name);
            return false;
        }
        return it->second.is_specialisable;
        ),
    (BoundedPtr,
        return false;
        ),
    (Bounded,
        return false;
        )
    )
    throw "";
}
::HIR::TypeRef ImplRef::get_impl_type() const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }
        return monomorphise_type_with(sp, e.impl->m_type, [&e](const auto& t)->const auto& {
            const auto& ge = t.m_data.as_Generic();
            return *e.params.at(ge.binding);
            });
        ),
    (BoundedPtr,
        return e.type->clone();
        ),
    (Bounded,
        return e.type.clone();
        )
    )
    throw "";
}
::HIR::PathParams ImplRef::get_trait_params() const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }
        return monomorphise_path_params_with(sp, e.impl->m_trait_args, [&e](const auto& t)->const auto& {
            const auto& ge = t.m_data.as_Generic();
            return *e.params.at(ge.binding);
            }, true);
        ),
    (BoundedPtr,
        return e.trait_args->clone();
        ),
    (Bounded,
        return e.trait_args.clone();
        )
    )
    throw "";
}
::HIR::TypeRef ImplRef::get_trait_ty_param(unsigned int idx) const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }
        if( idx >= e.impl->m_trait_args.m_types.size() )
            return ::HIR::TypeRef();
        return monomorphise_type_with(sp, e.impl->m_trait_args.m_types[idx], [&e](const auto& t)->const auto& {
            const auto& ge = t.m_data.as_Generic();
            return *e.params.at(ge.binding);
            }, true);
        ),
    (BoundedPtr,
        if( idx >= e.trait_args->m_types.size() )
            return ::HIR::TypeRef();
        return e.trait_args->m_types.at(idx).clone();
        ),
    (Bounded,
        if( idx >= e.trait_args.m_types.size() )
            return ::HIR::TypeRef();
        return e.trait_args.m_types.at(idx).clone();
        )
    )
    throw "";
    TODO(Span(), "");
}
::HIR::TypeRef ImplRef::get_type(const char* name) const
{
    if( !name[0] )
        return ::HIR::TypeRef();
    static Span  sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        DEBUG("name=" << name << " " << *this);
        auto it = e.impl->m_types.find(name);
        if( it == e.impl->m_types.end() )
            return ::HIR::TypeRef();
        const ::HIR::TypeRef& tpl_ty = it->second.data;
        if( monomorphise_type_needed(tpl_ty) ) {
            auto cb_monomorph = [&](const auto& gt)->const auto& {
                const auto& ge = gt.m_data.as_Generic();
                assert(ge.binding < 256);
                assert(ge.binding < e.params.size());
                if( e.params[ge.binding] ) {
                    return *e.params[ge.binding];
                }
                else if( e.params_ph.size() && e.params_ph[ge.binding] != ::HIR::TypeRef() ) {
                    return e.params_ph[ge.binding];
                }
                else {
                    BUG(Span(), "Param #" << ge.binding << " " << ge.name << " isn't constrained for " << *this);
                }
                };
            return monomorphise_type_with(sp, tpl_ty, cb_monomorph);
        }
        else {
            return tpl_ty.clone();
        }
        ),
    (BoundedPtr,
        auto it = e.assoc->find(name);
        if(it == e.assoc->end())
            return ::HIR::TypeRef();
        return it->second.clone();
        ),
    (Bounded,
        auto it = e.assoc.find(name);
        if(it == e.assoc.end())
            return ::HIR::TypeRef();
        return it->second.clone();
        )
    )
    return ::HIR::TypeRef();
}

::std::ostream& operator<<(::std::ostream& os, const ImplRef& x)
{
    TU_MATCH(ImplRef::Data, (x.m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            os << "none";
        }
        else {
            os << "impl";
            os << "(" << e.impl << ")";
            if( e.impl->m_params.m_types.size() )
            {
                os << "<";
                for( unsigned int i = 0; i < e.impl->m_params.m_types.size(); i ++ )
                {
                    const auto& ty_d = e.impl->m_params.m_types[i];
                    os << ty_d.m_name;
                    os << ",";
                }
                os << ">";
            }
            os << " " << *e.trait_path << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds();
            os << " {";
            for( unsigned int i = 0; i < e.impl->m_params.m_types.size(); i ++ )
            {
                const auto& ty_d = e.impl->m_params.m_types[i];
                os << ty_d.m_name << " = ";
                if( e.params[i] ) {
                    os << *e.params[i];
                }
                else {
                    os << "?";
                }
                os << ",";
            }
            for(const auto& aty : e.impl->m_types)
            {
                os << "Self::" << aty.first << " = " << aty.second.data << ",";
            }
            os << "}";
        }
        ),
    (BoundedPtr,
        os << "bound (ptr) " << *e.type << " : ?" << *e.trait_args << " + {" << *e.assoc << "}";
        ),
    (Bounded,
        os << "bound " << e.type << " : ?" << e.trait_args << " + {"<<e.assoc<<"}";
        )
    )
    return os;
}
<commit_msg>HIR ImplRef - Clean up monomorphisation code<commit_after>/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * hir_typeck/impl_ref.cpp
 * - Reference to a trait implementation (either a bound or a impl block)
 */
#include "impl_ref.hpp"
#include <hir/hir.hpp>
#include "static.hpp"   // for monomorphise_type_with

bool ImplRef::more_specific_than(const ImplRef& other) const
{
    TU_MATCH(Data, (this->m_data), (te),
    (TraitImpl,
        if( te.impl == nullptr ) {
            return false;
        }
        TU_MATCH(Data, (other.m_data), (oe),
        (TraitImpl,
            if( oe.impl == nullptr ) {
                return true;
            }
            return te.impl->more_specific_than( *oe.impl );
            ),
        (BoundedPtr,
            return false;
            ),
        (Bounded,
            return false;
            )
        )
        ),
    (BoundedPtr,
        return true;
        ),
    (Bounded,
        return true;
        )
    )
    throw "";
}
bool ImplRef::type_is_specialisable(const char* name) const
{
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            // No impl yet? This type is specialisable.
            return true;
        }
        //TODO(Span(), "type_is_specializable - Impl = " << *this << ", Type = " << name);
        auto it = e.impl->m_types.find(name);
        if( it == e.impl->m_types.end() ) {
            TODO(Span(), "Handle missing type in " << *this << ", name = " << name);
            return false;
        }
        return it->second.is_specialisable;
        ),
    (BoundedPtr,
        return false;
        ),
    (Bounded,
        return false;
        )
    )
    throw "";
}

namespace {
    // Returns a closure to monomorphise including placeholders (if present)
    ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> get_cb_monomorph_traitimpl(const Span& sp, const ImplRef& ir)
    {
        const auto& e = ir.m_data.as_TraitImpl();
        return [&e,&ir,&sp](const auto& gt)->const auto& {
            const auto& ge = gt.m_data.as_Generic();
            assert(ge.binding < 256);
            assert(ge.binding < e.params.size());
            if( e.params[ge.binding] ) {
                return *e.params[ge.binding];
            }
            else if( e.params_ph.size() && e.params_ph[ge.binding] != ::HIR::TypeRef() ) {
                return e.params_ph[ge.binding];
            }
            else {
                BUG(sp, "Param #" << ge.binding << " " << ge.name << " isn't constrained for " << ir);
            }
            };
    }
}

::HIR::TypeRef ImplRef::get_impl_type() const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }
        return monomorphise_type_with(sp, e.impl->m_type, get_cb_monomorph_traitimpl(sp, *this));
        ),
    (BoundedPtr,
        return e.type->clone();
        ),
    (Bounded,
        return e.type.clone();
        )
    )
    throw "";
}
::HIR::PathParams ImplRef::get_trait_params() const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }

        return monomorphise_path_params_with(sp, e.impl->m_trait_args, get_cb_monomorph_traitimpl(sp, *this), true);
        ),
    (BoundedPtr,
        return e.trait_args->clone();
        ),
    (Bounded,
        return e.trait_args.clone();
        )
    )
    throw "";
}
::HIR::TypeRef ImplRef::get_trait_ty_param(unsigned int idx) const
{
    Span    sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            BUG(Span(), "nullptr");
        }
        if( idx >= e.impl->m_trait_args.m_types.size() )
            return ::HIR::TypeRef();
        return monomorphise_type_with(sp, e.impl->m_trait_args.m_types[idx], get_cb_monomorph_traitimpl(sp, *this), true);
        ),
    (BoundedPtr,
        if( idx >= e.trait_args->m_types.size() )
            return ::HIR::TypeRef();
        return e.trait_args->m_types.at(idx).clone();
        ),
    (Bounded,
        if( idx >= e.trait_args.m_types.size() )
            return ::HIR::TypeRef();
        return e.trait_args.m_types.at(idx).clone();
        )
    )
    throw "";
    TODO(Span(), "");
}

::HIR::TypeRef ImplRef::get_type(const char* name) const
{
    if( !name[0] )
        return ::HIR::TypeRef();
    static Span  sp;
    TU_MATCH(Data, (this->m_data), (e),
    (TraitImpl,
        DEBUG("name=" << name << " " << *this);
        auto it = e.impl->m_types.find(name);
        if( it == e.impl->m_types.end() )
            return ::HIR::TypeRef();
        const ::HIR::TypeRef& tpl_ty = it->second.data;
        if( monomorphise_type_needed(tpl_ty) ) {
            return monomorphise_type_with(sp, tpl_ty, get_cb_monomorph_traitimpl(sp, *this));
        }
        else {
            return tpl_ty.clone();
        }
        ),
    (BoundedPtr,
        auto it = e.assoc->find(name);
        if(it == e.assoc->end())
            return ::HIR::TypeRef();
        return it->second.clone();
        ),
    (Bounded,
        auto it = e.assoc.find(name);
        if(it == e.assoc.end())
            return ::HIR::TypeRef();
        return it->second.clone();
        )
    )
    return ::HIR::TypeRef();
}

::std::ostream& operator<<(::std::ostream& os, const ImplRef& x)
{
    TU_MATCH(ImplRef::Data, (x.m_data), (e),
    (TraitImpl,
        if( e.impl == nullptr ) {
            os << "none";
        }
        else {
            os << "impl";
            os << "(" << e.impl << ")";
            if( e.impl->m_params.m_types.size() )
            {
                os << "<";
                for( unsigned int i = 0; i < e.impl->m_params.m_types.size(); i ++ )
                {
                    const auto& ty_d = e.impl->m_params.m_types[i];
                    os << ty_d.m_name;
                    os << ",";
                }
                os << ">";
            }
            os << " " << *e.trait_path << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds();
            os << " {";
            for( unsigned int i = 0; i < e.impl->m_params.m_types.size(); i ++ )
            {
                const auto& ty_d = e.impl->m_params.m_types[i];
                os << ty_d.m_name << " = ";
                if( e.params[i] ) {
                    os << *e.params[i];
                }
                else {
                    os << "?";
                }
                os << ",";
            }
            for(const auto& aty : e.impl->m_types)
            {
                os << "Self::" << aty.first << " = " << aty.second.data << ",";
            }
            os << "}";
        }
        ),
    (BoundedPtr,
        os << "bound (ptr) " << *e.type << " : ?" << *e.trait_args << " + {" << *e.assoc << "}";
        ),
    (Bounded,
        os << "bound " << e.type << " : ?" << e.trait_args << " + {"<<e.assoc<<"}";
        )
    )
    return os;
}
<|endoftext|>