<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbImageToLuminanceImageFilter.h"
#include "otbLuminanceToReflectanceImageFilter.h"
#include "otbReflectanceToSurfaceReflectanceImageFilter.h"
#include "otbMultiplyByScalarImageFilter.h"

namespace otb
{

enum
{
  Level_TOC,
  Level_TOA
};

enum
{
  Aerosol_NoAerosol,
  Aerosol_Continental,
  Aerosol_Maritime,
  Aerosol_Urban,
  Aerosol_Desertic,
};

namespace Wrapper
{

class OpticalCalibration : public Application
{

public:
/** Standard class typedefs. */
  typedef OpticalCalibration            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(OpticalCalibration, Application);

  typedef ImageToLuminanceImageFilter<UInt16VectorImageType,
                                      FloatVectorImageType>              ImageToLuminanceImageFilterType;

  typedef LuminanceToReflectanceImageFilter<FloatVectorImageType,
                                            FloatVectorImageType>        LuminanceToReflectanceImageFilterType;

  typedef otb::MultiplyByScalarImageFilter<FloatVectorImageType,
                                           UInt16VectorImageType>        ScaleFilterType;

  typedef ReflectanceToSurfaceReflectanceImageFilter<FloatVectorImageType,
                                                     FloatVectorImageType>          ReflectanceToSurfaceReflectanceImageFilterType;
  typedef ReflectanceToSurfaceReflectanceImageFilterType::FilterFunctionValuesType  FilterFunctionValuesType;
  typedef FilterFunctionValuesType::ValuesVectorType                                ValuesVectorType;
  typedef AtmosphericCorrectionParameters                                           AtmosphericCorrectionParametersType;
  typedef AtmosphericCorrectionParametersType::AerosolModelType                     AerosolModelType;

private:
  OpticalCalibration()
  {
    SetName("OpticalCalibration");
    SetDescription("Perform optical calibration TOA/TOC(Top Of Atmosphere/Top Of Canopy). Output image is in milli-reflectance.");
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",  "Input Image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out","Projected image");

    AddParameter(ParameterType_Choice,   "level", "Calibration Level");
    AddChoice("level.toa",     "TOA : Top Of Atmosphere");
    AddChoice("level.toc",     "TOC : Top Of Canopy");

    AddParameter(ParameterType_Filename,   "rsr", "Relative Spectral Response File");
    std::ostringstream oss;
    oss << "Sensor relative spectral response file"<<std::endl;
    oss << "By default the application gets these informations in the metadata";
    SetParameterDescription("rsr",oss.str());
    MandatoryOff("rsr");

    AddParameter(ParameterType_Choice,   "aerosol", "Aerosol Model");
    AddChoice("aerosol.noaersol",    "No Aerosol");
    AddChoice("aerosol.continental", "Continental");
    AddChoice("aerosol.maritime",    "Maritime");
    AddChoice("aerosol.urban",       "Urban");
    AddChoice("aerosol.desertic",    "Desertic");

    AddParameter(ParameterType_Float, "oz",   "Amount of Ozone");
    AddParameter(ParameterType_Float, "wa",   "Water Vapor Amount");
    AddParameter(ParameterType_Float, "atmo", "Atmospheric Pressure");
    AddParameter(ParameterType_Float, "opt",  "Aerosol Optical");

    SetParameterFloat("oz", 0.);
    SetParameterFloat("wa",  2.5);
    SetParameterFloat("atmo", 1030.);

    SetParameterFloat("opt", 0.2);
    MandatoryOff("oz");
    MandatoryOff("wa");
    MandatoryOff("atmo");
    MandatoryOff("opt");

    AddParameter(ParameterType_Filename,   "aeronet", "Aeronet File");
    SetParameterDescription("aeronet","Aeronet file to get atmospheric parameters");
    MandatoryOff("aeronet");
  }

  void DoUpdateParameters()
  {
    // Nothing to update
  }

  void DoExecute()
  {
    UInt16VectorImageType::Pointer inImage = GetParameterUInt16VectorImage("in");

    //Check if valid metadata informations are available to compute ImageToLuminance and LuminanceToReflectance
    itk::MetaDataDictionary             dict = inImage->GetMetaDataDictionary();
    OpticalImageMetadataInterface::Pointer lImageMetadataInterface = OpticalImageMetadataInterfaceFactory::CreateIMI(dict);

    // Test if needed data are available.
    try
      {
      // ImageToLuminance
      lImageMetadataInterface->GetPhysicalGain();
      lImageMetadataInterface->GetPhysicalBias();

      // LuminanceToReflectance
      lImageMetadataInterface->GetDay();
      lImageMetadataInterface->GetMonth();

      lImageMetadataInterface->GetSolarIrradiance();
      lImageMetadataInterface->GetSunElevation();
      }
    catch (itk::ExceptionObject& err)
      {
      itkGenericExceptionMacro("Invalid input image medadata. The parsing returns the following error");
      }

    m_ImageToLuminanceFilter                = ImageToLuminanceImageFilterType::New();
    m_LuminanceToReflectanceFilter          = LuminanceToReflectanceImageFilterType::New();
    m_ReflectanceToSurfaceReflectanceFilter = ReflectanceToSurfaceReflectanceImageFilterType::New();

    m_ImageToLuminanceFilter->SetInput(inImage);
    m_LuminanceToReflectanceFilter->SetInput(m_ImageToLuminanceFilter->GetOutput());
    m_ReflectanceToSurfaceReflectanceFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());

    m_ScaleFilter = ScaleFilterType::New();
    m_ScaleFilter->SetCoef(1000.);

    switch ( GetParameterInt("level") )
      {
      case Level_TOA:
      {
      m_AtmosphericParam = m_ReflectanceToSurfaceReflectanceFilter->GetCorrectionParameters();
      AerosolModelType aeroMod = AtmosphericCorrectionParametersType::NO_AEROSOL;

      switch ( GetParameterInt("aerosol") )
        {
        case Aerosol_Desertic:
        {
        // Aerosol_Desertic correspond to 4 in the enum but actually in
        // the class atmosphericParam it is known as parameter 5
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(5));
        }
        break;
        default:
        {
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(GetParameterInt("aerosol")));
        }
        break;
        }
      // Set the atmospheric param
      m_AtmosphericParam->SetOzoneAmount(GetParameterFloat("oz"));
      m_AtmosphericParam->SetWaterVaporAmount(GetParameterFloat("wa"));
      m_AtmosphericParam->SetAtmosphericPressure(GetParameterFloat("atmo"));
      m_AtmosphericParam->SetAerosolOptical(GetParameterFloat("opt"));

      // Relative Spectral Response File
      if (IsParameterEnabled("rsr"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionValuesFileName(GetParameterString("rsr"));
        }
      else
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionCoef(lImageMetadataInterface->GetSpectralSensitivity());
        }

      // Aeronet file
      if (IsParameterEnabled("aeronet"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetAeronetFileName(GetParameterString("AeronetFile"));
        }

      //
      AtmosphericRadiativeTerms::Pointer radTerms = AtmosphericRadiativeTerms::New();
      radTerms->ValuesInitialization(inImage->GetNumberOfComponentsPerPixel());
      m_ReflectanceToSurfaceReflectanceFilter->SetAtmosphericRadiativeTerms(radTerms);
      m_ReflectanceToSurfaceReflectanceFilter->SetIsSetAtmosphericRadiativeTerms(true);
      m_ReflectanceToSurfaceReflectanceFilter->GenerateAtmosphericRadiativeTerms();
      m_ReflectanceToSurfaceReflectanceFilter->GenerateParameters();
      m_ReflectanceToSurfaceReflectanceFilter->SetUseGenerateParameters(false);

      //rescale the surface reflectance in milli-reflectance
      m_ScaleFilter->SetInput(m_ReflectanceToSurfaceReflectanceFilter->GetOutput());
      }
      break;
      case Level_TOC:
      {
      m_ScaleFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());
      }
      break;
      }

    // Output Image
    SetParameterOutputImage("out", m_ScaleFilter->GetOutput());
  }
  ImageToLuminanceImageFilterType ::Pointer m_ImageToLuminanceFilter;
  LuminanceToReflectanceImageFilterType::Pointer m_LuminanceToReflectanceFilter;
  ReflectanceToSurfaceReflectanceImageFilterType::Pointer m_ReflectanceToSurfaceReflectanceFilter;
  ScaleFilterType::Pointer m_ScaleFilter;
  AtmosphericCorrectionParametersType::Pointer m_AtmosphericParam;
};

}// namespace Wrapper
} // namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::OpticalCalibration)

<commit_msg>ENH: making the object global attributes avoid errors<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbImageToLuminanceImageFilter.h"
#include "otbLuminanceToReflectanceImageFilter.h"
#include "otbReflectanceToSurfaceReflectanceImageFilter.h"
#include "otbMultiplyByScalarImageFilter.h"

namespace otb
{

enum
{
  Level_TOC,
  Level_TOA
};

enum
{
  Aerosol_NoAerosol,
  Aerosol_Continental,
  Aerosol_Maritime,
  Aerosol_Urban,
  Aerosol_Desertic,
};

namespace Wrapper
{

class OpticalCalibration : public Application
{

public:
/** Standard class typedefs. */
  typedef OpticalCalibration            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(OpticalCalibration, Application);

  typedef ImageToLuminanceImageFilter<UInt16VectorImageType,
                                      FloatVectorImageType>              ImageToLuminanceImageFilterType;

  typedef LuminanceToReflectanceImageFilter<FloatVectorImageType,
                                            FloatVectorImageType>        LuminanceToReflectanceImageFilterType;

  typedef otb::MultiplyByScalarImageFilter<FloatVectorImageType,
                                           UInt16VectorImageType>        ScaleFilterType;

  typedef ReflectanceToSurfaceReflectanceImageFilter<FloatVectorImageType,
                                                     FloatVectorImageType>          ReflectanceToSurfaceReflectanceImageFilterType;
  typedef ReflectanceToSurfaceReflectanceImageFilterType::FilterFunctionValuesType  FilterFunctionValuesType;
  typedef FilterFunctionValuesType::ValuesVectorType                                ValuesVectorType;
  typedef AtmosphericCorrectionParameters                                           AtmosphericCorrectionParametersType;
  typedef AtmosphericCorrectionParametersType::AerosolModelType                     AerosolModelType;

private:
  OpticalCalibration()
  {
    SetName("OpticalCalibration");
    std::ostringstream oss;
    oss << "Perform optical calibration TOA/TOC(Top Of Atmosphere/Top Of Canopy)"<<std::endl;
    oss << "Output image is in milli-reflectance.";
    SetDescription(oss.str());
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",  "Input Image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out","Projected image");

    AddParameter(ParameterType_Choice,   "level", "Calibration Level");
    AddChoice("level.toa",     "TOA : Top Of Atmosphere");
    AddChoice("level.toc",     "TOC : Top Of Canopy");

    AddParameter(ParameterType_Filename,   "rsr", "Relative Spectral Response File");
    std::ostringstream oss;
    oss << "Sensor relative spectral response file"<<std::endl;
    oss << "By default the application gets these informations in the metadata";
    SetParameterDescription("rsr",oss.str());
    MandatoryOff("rsr");

    AddParameter(ParameterType_Choice,   "aerosol", "Aerosol Model");
    AddChoice("aerosol.noaersol",    "No Aerosol");
    AddChoice("aerosol.continental", "Continental");
    AddChoice("aerosol.maritime",    "Maritime");
    AddChoice("aerosol.urban",       "Urban");
    AddChoice("aerosol.desertic",    "Desertic");

    AddParameter(ParameterType_Float, "oz",   "Amount of Ozone");
    AddParameter(ParameterType_Float, "wa",   "Water Vapor Amount");
    AddParameter(ParameterType_Float, "atmo", "Atmospheric Pressure");
    AddParameter(ParameterType_Float, "opt",  "Aerosol Optical");

    SetParameterFloat("oz", 0.);
    SetParameterFloat("wa",  2.5);
    SetParameterFloat("atmo", 1030.);

    SetParameterFloat("opt", 0.2);
    MandatoryOff("oz");
    MandatoryOff("wa");
    MandatoryOff("atmo");
    MandatoryOff("opt");

    AddParameter(ParameterType_Filename,   "aeronet", "Aeronet File");
    SetParameterDescription("aeronet","Aeronet file to get atmospheric parameters");
    MandatoryOff("aeronet");
  }

  void DoUpdateParameters()
  {
    // Nothing to update
  }

  void DoExecute()
  {
    UInt16VectorImageType::Pointer inImage = GetParameterUInt16VectorImage("in");

    //Check if valid metadata informations are available to compute ImageToLuminance and LuminanceToReflectance
    itk::MetaDataDictionary             dict = inImage->GetMetaDataDictionary();
    OpticalImageMetadataInterface::Pointer lImageMetadataInterface = OpticalImageMetadataInterfaceFactory::CreateIMI(dict);

    // Test if needed data are available.
    try
      {
      // ImageToLuminance
      lImageMetadataInterface->GetPhysicalGain();
      lImageMetadataInterface->GetPhysicalBias();

      // LuminanceToReflectance
      lImageMetadataInterface->GetDay();
      lImageMetadataInterface->GetMonth();

      lImageMetadataInterface->GetSolarIrradiance();
      lImageMetadataInterface->GetSunElevation();
      }
    catch (itk::ExceptionObject& err)
      {
      itkGenericExceptionMacro("Invalid input image medadata. The parsing returns the following error");
      }

    m_ImageToLuminanceFilter                = ImageToLuminanceImageFilterType::New();
    m_LuminanceToReflectanceFilter          = LuminanceToReflectanceImageFilterType::New();
    m_ReflectanceToSurfaceReflectanceFilter = ReflectanceToSurfaceReflectanceImageFilterType::New();

    m_ImageToLuminanceFilter->SetInput(inImage);
    m_LuminanceToReflectanceFilter->SetInput(m_ImageToLuminanceFilter->GetOutput());
    m_ReflectanceToSurfaceReflectanceFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());

    m_ScaleFilter = ScaleFilterType::New();
    m_ScaleFilter->SetCoef(1000.);

    switch ( GetParameterInt("level") )
      {
      case Level_TOA:
      {
      m_AtmosphericParam = m_ReflectanceToSurfaceReflectanceFilter->GetCorrectionParameters();
      AerosolModelType aeroMod = AtmosphericCorrectionParametersType::NO_AEROSOL;

      switch ( GetParameterInt("aerosol") )
        {
        case Aerosol_Desertic:
        {
        // Aerosol_Desertic correspond to 4 in the enum but actually in
        // the class atmosphericParam it is known as parameter 5
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(5));
        }
        break;
        default:
        {
        m_AtmosphericParam->SetAerosolModel(static_cast<AerosolModelType>(GetParameterInt("aerosol")));
        }
        break;
        }
      // Set the atmospheric param
      m_AtmosphericParam->SetOzoneAmount(GetParameterFloat("oz"));
      m_AtmosphericParam->SetWaterVaporAmount(GetParameterFloat("wa"));
      m_AtmosphericParam->SetAtmosphericPressure(GetParameterFloat("atmo"));
      m_AtmosphericParam->SetAerosolOptical(GetParameterFloat("opt"));

      // Relative Spectral Response File
      if (IsParameterEnabled("rsr"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionValuesFileName(GetParameterString("rsr"));
        }
      else
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetFilterFunctionCoef(lImageMetadataInterface->GetSpectralSensitivity());
        }

      // Aeronet file
      if (IsParameterEnabled("aeronet"))
        {
        m_ReflectanceToSurfaceReflectanceFilter->SetAeronetFileName(GetParameterString("AeronetFile"));
        }

      //
      AtmosphericRadiativeTerms::Pointer radTerms = AtmosphericRadiativeTerms::New();
      radTerms->ValuesInitialization(inImage->GetNumberOfComponentsPerPixel());
      m_ReflectanceToSurfaceReflectanceFilter->SetAtmosphericRadiativeTerms(radTerms);
      m_ReflectanceToSurfaceReflectanceFilter->SetIsSetAtmosphericRadiativeTerms(true);
      m_ReflectanceToSurfaceReflectanceFilter->GenerateAtmosphericRadiativeTerms();
      m_ReflectanceToSurfaceReflectanceFilter->GenerateParameters();
      m_ReflectanceToSurfaceReflectanceFilter->SetUseGenerateParameters(false);

      //rescale the surface reflectance in milli-reflectance
      m_ScaleFilter->SetInput(m_ReflectanceToSurfaceReflectanceFilter->GetOutput());
      }
      break;
      case Level_TOC:
      {
      m_ScaleFilter->SetInput(m_LuminanceToReflectanceFilter->GetOutput());
      }
      break;
      }

    // Output Image
    SetParameterOutputImage("out", m_ScaleFilter->GetOutput());
  }
  ImageToLuminanceImageFilterType ::Pointer m_ImageToLuminanceFilter;
  LuminanceToReflectanceImageFilterType::Pointer m_LuminanceToReflectanceFilter;
  ReflectanceToSurfaceReflectanceImageFilterType::Pointer m_ReflectanceToSurfaceReflectanceFilter;
  ScaleFilterType::Pointer m_ScaleFilter;
  AtmosphericCorrectionParametersType::Pointer m_AtmosphericParam;
};

}// namespace Wrapper
} // namespace otb

OTB_APPLICATION_EXPORT(otb::Wrapper::OpticalCalibration)

<|endoftext|>


<commit_before>#include "ChunkRenderer.h"

#include <glm/vec3.hpp>
#include <glm/gtc/noise.hpp>

#include <glbinding/gl/enum.h>

#include <globjects/Buffer.h>
#include <globjects/VertexArray.h>
#include <globjects/VertexAttributeBinding.h>
#include <globjects/globjects.h>
#include <globjects/Program.h>
#include <globjects/Texture.h>
#include <globjects/TransformFeedback.h>
#include <globjects/VertexAttributeBinding.h>

#include "LookUpData.h"
#include "Chunk.h"

using namespace gl;
using namespace glm;
using namespace globjects;

const ivec3 dimensions(32, 32, 32);
const int margin(1);

ChunkRenderer::ChunkRenderer()
    : m_densityPositions()
    , m_edgeConnectList()
    , m_positions()
    , m_transform()
{
    setupTransformFeedback();

    setupProgram();
    setupRendering();
    setupNoiseTextures();

}

ChunkRenderer::~ChunkRenderer() = default;

void ChunkRenderer::render(std::vector<ref_ptr<Chunk>> chunks)
{
    m_renderProgram->use();
    m_renderProgram->setUniform(m_transformLocation, m_transform);
    m_renderProgram->setUniform("a_dim", dimensions);
    m_renderProgram->setUniform("a_margin", margin);
    m_renderProgram->setUniform("a_caseToNumPolys", LookUpData::m_caseToNumPolys);
    m_renderProgram->setUniform("a_edgeToVertices", LookUpData::m_edgeToVertices);
    m_renderProgram->setUniform("densities", 0);

    // Setup uniform block for edge connect list

    auto ubo = m_renderProgram->uniformBlock("edgeConnectList");
    m_edgeConnectList->bindBase(GL_UNIFORM_BUFFER, 1);
    ubo->setBinding(1);

    m_renderingVao->bind();

    for (auto chunk : chunks)
    {
        m_renderProgram->setUniform("a_offset", chunk->offset());

        chunk->draw(m_renderingVao, m_positionsSize);
    }
    m_renderingVao->unbind();
    m_renderProgram->release();
}

void ChunkRenderer::setTransform(mat4x4 transform)
{
    m_transform = transform;
}

void ChunkRenderer::setupProgram()
{
    m_renderProgram = new Program{};
    m_renderProgram->attach(
        Shader::fromFile(GL_VERTEX_SHADER, "data/marchingcubes/marchingcubes.vert"),
        Shader::fromFile(GL_GEOMETRY_SHADER, "data/marchingcubes/marchingcubes.geom"),
        Shader::fromFile(GL_FRAGMENT_SHADER, "data/marchingcubes/marchingcubes.frag")
    );

    m_transformLocation = m_renderProgram->getUniformLocation("transform");
}

void ChunkRenderer::setupRendering()
{
    m_renderingVao = new VertexArray;

    // Setup edge connect list

    m_edgeConnectList = new Buffer();
    m_edgeConnectList->bind(GL_UNIFORM_BUFFER);
    m_edgeConnectList->setData(sizeof(ivec4) * LookUpData::m_edgeConnectList.size(), LookUpData::m_edgeConnectList.data(), GL_STATIC_DRAW);
    m_edgeConnectList->unbind(GL_UNIFORM_BUFFER);

    std::vector<vec3> positions;
    for (int z = 0; z < dimensions.z; ++z)
    {
        for (int y = 0; y < dimensions.y; ++y)
        {
            for (int x = 0; x < dimensions.x; ++x)
            {
                positions.push_back(vec3(x, y, z) / vec3(dimensions));
            }
        }
    }

    m_positionsSize = positions.size();

    m_positions = new Buffer();
    m_positions->setData(positions, GL_STATIC_DRAW);

    // Setup positions binding

    auto positionsBinding = m_renderingVao->binding(0);
    positionsBinding->setAttribute(0);
    positionsBinding->setBuffer(m_positions, 0, sizeof(vec3));
    positionsBinding->setFormat(3, GL_FLOAT, GL_FALSE, 0);
    m_renderingVao->enable(0);
}

void ChunkRenderer::setupTransformFeedback()
{
    // Setup the program

    m_transformFeedbackProgram = new Program();
    m_transformFeedbackProgram->attach(Shader::fromFile(GL_VERTEX_SHADER, "data/marchingcubes/transformfeedback.vert"));
    m_transformFeedbackProgram->link();

    // Setup the transform feedback itself

    m_transformFeedback = new TransformFeedback();
    m_transformFeedback->setVaryings(m_transformFeedbackProgram, { "out_density" }, GL_INTERLEAVED_ATTRIBS);

    // Fill positions buffer (with border!)

    std::vector<vec3> densityPositions;
    for (int z = -margin; z < dimensions.z + margin + 1; ++z)
    {
        for (int y = -margin; y < dimensions.y + margin + 1; ++y)
        {
            for (int x = -margin; x < dimensions.x + margin + 1; ++x)
            {
                densityPositions.push_back(vec3(x, y, z) / vec3(dimensions));
            }
        }
    }

    m_densityPositionsSize = densityPositions.size();

    m_densityPositions = new Buffer();
    m_densityPositions->setData(densityPositions, GL_STATIC_DRAW);

    // Setup positions binding

    m_densityPositionVao = new VertexArray();

    auto densityPositionsBinding = m_densityPositionVao->binding(0);
    densityPositionsBinding->setAttribute(0);
    densityPositionsBinding->setBuffer(m_densityPositions, 0, sizeof(vec3));
    densityPositionsBinding->setFormat(3, GL_FLOAT);
    m_densityPositionVao->enable(0);
}

void ChunkRenderer::setupNoiseTextures()
{
    // Random values as offsets
    m_noiseTexture1 = setupNoiseTexture(vec3(0, 0, 0));
    m_noiseTexture2 = setupNoiseTexture(vec3(42, 1, 5));
    m_noiseTexture3 = setupNoiseTexture(vec3(2, 3, 4));
    m_noiseTexture4 = setupNoiseTexture(vec3(1, 33, 7));
}

globjects::ref_ptr<globjects::Texture> ChunkRenderer::setupNoiseTexture(vec3 offset)
{
    static const int size(32);

    float data[size * size * size];

    int i = 0;
    for (int z = 0; z < size; ++z)
    {
        for (int y = 0; y < size; ++y)
        {
            for (int x = 0; x < size; ++x, ++i)
            {
                float val = perlin(vec3(x, y, z) / float(size) + offset);
                data[i] = val;
            }
        }
    }
    auto texture = Texture::createDefault(GL_TEXTURE_3D);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_S, GL_REPEAT);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_T, GL_REPEAT);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_R, GL_REPEAT);
    texture->image3D(0, GL_R32F, size, size, size, 0, GL_RED, GL_FLOAT, data);
    return texture;
}

void ChunkRenderer::runTransformFeedback(Chunk * chunk)
{
    chunk->setupTransformFeedback(m_densityPositionsSize);
    m_densityPositionVao->bind();
    m_noiseTexture1->bindActive(GL_TEXTURE1);
    m_noiseTexture2->bindActive(GL_TEXTURE2);
    m_noiseTexture3->bindActive(GL_TEXTURE3);
    m_noiseTexture4->bindActive(GL_TEXTURE4);
    m_transformFeedback->bind();
    m_transformFeedbackProgram->setUniform("a_offset", chunk->offset());
    m_transformFeedbackProgram->setUniform("noiseTexture1", 1);
    m_transformFeedbackProgram->setUniform("noiseTexture2", 2);
    m_transformFeedbackProgram->setUniform("noiseTexture3", 3);
    m_transformFeedbackProgram->setUniform("noiseTexture4", 4);
    chunk->densities()->bindBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

    glEnable(GL_RASTERIZER_DISCARD);

    m_transformFeedbackProgram->use();
    m_transformFeedback->begin(GL_POINTS);
    m_densityPositionVao->drawArrays(GL_POINTS, 0, m_densityPositionsSize);
    m_transformFeedback->end();
    m_transformFeedback->unbind();
    m_transformFeedbackProgram->release();

    glDisable(GL_RASTERIZER_DISCARD);

    m_noiseTexture1->unbind();
    m_noiseTexture2->unbind();
    m_noiseTexture3->unbind();
    m_noiseTexture4->unbind();
    m_densityPositionVao->unbind();

}
<commit_msg>Use mirrored repeat for noise texture<commit_after>#include "ChunkRenderer.h"

#include <glm/vec3.hpp>
#include <glm/gtc/noise.hpp>

#include <glbinding/gl/enum.h>

#include <globjects/Buffer.h>
#include <globjects/VertexArray.h>
#include <globjects/VertexAttributeBinding.h>
#include <globjects/globjects.h>
#include <globjects/Program.h>
#include <globjects/Texture.h>
#include <globjects/TransformFeedback.h>
#include <globjects/VertexAttributeBinding.h>

#include "LookUpData.h"
#include "Chunk.h"

using namespace gl;
using namespace glm;
using namespace globjects;

const ivec3 dimensions(32, 32, 32);
const int margin(1);

ChunkRenderer::ChunkRenderer()
    : m_densityPositions()
    , m_edgeConnectList()
    , m_positions()
    , m_transform()
{
    setupTransformFeedback();

    setupProgram();
    setupRendering();
    setupNoiseTextures();

}

ChunkRenderer::~ChunkRenderer() = default;

void ChunkRenderer::render(std::vector<ref_ptr<Chunk>> chunks)
{
    m_renderProgram->use();
    m_renderProgram->setUniform(m_transformLocation, m_transform);
    m_renderProgram->setUniform("a_dim", dimensions);
    m_renderProgram->setUniform("a_margin", margin);
    m_renderProgram->setUniform("a_caseToNumPolys", LookUpData::m_caseToNumPolys);
    m_renderProgram->setUniform("a_edgeToVertices", LookUpData::m_edgeToVertices);
    m_renderProgram->setUniform("densities", 0);

    // Setup uniform block for edge connect list

    auto ubo = m_renderProgram->uniformBlock("edgeConnectList");
    m_edgeConnectList->bindBase(GL_UNIFORM_BUFFER, 1);
    ubo->setBinding(1);

    m_renderingVao->bind();

    for (auto chunk : chunks)
    {
        m_renderProgram->setUniform("a_offset", chunk->offset());

        chunk->draw(m_renderingVao, m_positionsSize);
    }
    m_renderingVao->unbind();
    m_renderProgram->release();
}

void ChunkRenderer::setTransform(mat4x4 transform)
{
    m_transform = transform;
}

void ChunkRenderer::setupProgram()
{
    m_renderProgram = new Program{};
    m_renderProgram->attach(
        Shader::fromFile(GL_VERTEX_SHADER, "data/marchingcubes/marchingcubes.vert"),
        Shader::fromFile(GL_GEOMETRY_SHADER, "data/marchingcubes/marchingcubes.geom"),
        Shader::fromFile(GL_FRAGMENT_SHADER, "data/marchingcubes/marchingcubes.frag")
    );

    m_transformLocation = m_renderProgram->getUniformLocation("transform");
}

void ChunkRenderer::setupRendering()
{
    m_renderingVao = new VertexArray;

    // Setup edge connect list

    m_edgeConnectList = new Buffer();
    m_edgeConnectList->bind(GL_UNIFORM_BUFFER);
    m_edgeConnectList->setData(sizeof(ivec4) * LookUpData::m_edgeConnectList.size(), LookUpData::m_edgeConnectList.data(), GL_STATIC_DRAW);
    m_edgeConnectList->unbind(GL_UNIFORM_BUFFER);

    std::vector<vec3> positions;
    for (int z = 0; z < dimensions.z; ++z)
    {
        for (int y = 0; y < dimensions.y; ++y)
        {
            for (int x = 0; x < dimensions.x; ++x)
            {
                positions.push_back(vec3(x, y, z) / vec3(dimensions));
            }
        }
    }

    m_positionsSize = positions.size();

    m_positions = new Buffer();
    m_positions->setData(positions, GL_STATIC_DRAW);

    // Setup positions binding

    auto positionsBinding = m_renderingVao->binding(0);
    positionsBinding->setAttribute(0);
    positionsBinding->setBuffer(m_positions, 0, sizeof(vec3));
    positionsBinding->setFormat(3, GL_FLOAT, GL_FALSE, 0);
    m_renderingVao->enable(0);
}

void ChunkRenderer::setupTransformFeedback()
{
    // Setup the program

    m_transformFeedbackProgram = new Program();
    m_transformFeedbackProgram->attach(Shader::fromFile(GL_VERTEX_SHADER, "data/marchingcubes/transformfeedback.vert"));
    m_transformFeedbackProgram->link();

    // Setup the transform feedback itself

    m_transformFeedback = new TransformFeedback();
    m_transformFeedback->setVaryings(m_transformFeedbackProgram, { "out_density" }, GL_INTERLEAVED_ATTRIBS);

    // Fill positions buffer (with border!)

    std::vector<vec3> densityPositions;
    for (int z = -margin; z < dimensions.z + margin + 1; ++z)
    {
        for (int y = -margin; y < dimensions.y + margin + 1; ++y)
        {
            for (int x = -margin; x < dimensions.x + margin + 1; ++x)
            {
                densityPositions.push_back(vec3(x, y, z) / vec3(dimensions));
            }
        }
    }

    m_densityPositionsSize = densityPositions.size();

    m_densityPositions = new Buffer();
    m_densityPositions->setData(densityPositions, GL_STATIC_DRAW);

    // Setup positions binding

    m_densityPositionVao = new VertexArray();

    auto densityPositionsBinding = m_densityPositionVao->binding(0);
    densityPositionsBinding->setAttribute(0);
    densityPositionsBinding->setBuffer(m_densityPositions, 0, sizeof(vec3));
    densityPositionsBinding->setFormat(3, GL_FLOAT);
    m_densityPositionVao->enable(0);
}

void ChunkRenderer::setupNoiseTextures()
{
    // Random values as offsets
    m_noiseTexture1 = setupNoiseTexture(vec3(0, 0, 0));
    m_noiseTexture2 = setupNoiseTexture(vec3(42, 1, 5));
    m_noiseTexture3 = setupNoiseTexture(vec3(2, 3, 4));
    m_noiseTexture4 = setupNoiseTexture(vec3(1, 33, 7));
}

globjects::ref_ptr<globjects::Texture> ChunkRenderer::setupNoiseTexture(vec3 offset)
{
    static const int size(32);

    float data[size * size * size];

    int i = 0;
    for (int z = 0; z < size; ++z)
    {
        for (int y = 0; y < size; ++y)
        {
            for (int x = 0; x < size; ++x, ++i)
            {
                float val = perlin(vec3(x, y, z) / float(size) + offset);
                data[i] = val;
            }
        }
    }
    auto texture = Texture::createDefault(GL_TEXTURE_3D);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    texture->setParameter(GLenum::GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT);
    texture->image3D(0, GL_R32F, size, size, size, 0, GL_RED, GL_FLOAT, data);
    return texture;
}

void ChunkRenderer::runTransformFeedback(Chunk * chunk)
{
    chunk->setupTransformFeedback(m_densityPositionsSize);
    m_densityPositionVao->bind();
    m_noiseTexture1->bindActive(GL_TEXTURE1);
    m_noiseTexture2->bindActive(GL_TEXTURE2);
    m_noiseTexture3->bindActive(GL_TEXTURE3);
    m_noiseTexture4->bindActive(GL_TEXTURE4);
    m_transformFeedback->bind();
    m_transformFeedbackProgram->setUniform("a_offset", chunk->offset());
    m_transformFeedbackProgram->setUniform("noiseTexture1", 1);
    m_transformFeedbackProgram->setUniform("noiseTexture2", 2);
    m_transformFeedbackProgram->setUniform("noiseTexture3", 3);
    m_transformFeedbackProgram->setUniform("noiseTexture4", 4);
    chunk->densities()->bindBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

    glEnable(GL_RASTERIZER_DISCARD);

    m_transformFeedbackProgram->use();
    m_transformFeedback->begin(GL_POINTS);
    m_densityPositionVao->drawArrays(GL_POINTS, 0, m_densityPositionsSize);
    m_transformFeedback->end();
    m_transformFeedback->unbind();
    m_transformFeedbackProgram->release();

    glDisable(GL_RASTERIZER_DISCARD);

    m_noiseTexture1->unbind();
    m_noiseTexture2->unbind();
    m_noiseTexture3->unbind();
    m_noiseTexture4->unbind();
    m_densityPositionVao->unbind();

}
<|endoftext|>


<commit_before>// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Stefan Brugger <stefanbrugger@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "boundary_loop.h"
#include "slice.h"
#include "triangle_triangle_adjacency.h"
#include "vertex_triangle_adjacency.h"
#include "is_border_vertex.h"
#include <set>

template <typename DerivedF, typename Index>
IGL_INLINE void igl::boundary_loop(
    const Eigen::PlainObjectBase<DerivedF> & F,
    std::vector<std::vector<Index> >& L)
{
  using namespace std;
  using namespace Eigen;
  using namespace igl;

  MatrixXd Vdummy(F.maxCoeff(),1);
  MatrixXi TT,TTi;
  vector<std::vector<int> > VF, VFi;
  triangle_triangle_adjacency(Vdummy,F,TT,TTi);
  vertex_triangle_adjacency(Vdummy,F,VF,VFi);

  vector<bool> unvisited = is_border_vertex(Vdummy,F);
  set<int> unseen;
  for (int i = 0; i < unvisited.size(); ++i)
  {
    if (unvisited[i])
      unseen.insert(unseen.end(),i);
  }

  while (!unseen.empty())
  {
    vector<Index> l;

    // Get first vertex of loop
    int start = *unseen.begin();
    unseen.erase(unseen.begin());
    unvisited[start] = false;
    l.push_back(start);

    bool done = false;
    while (!done)
    {
      // Find next vertex
      bool newBndEdge = false;
      int v = l[l.size()-1];
      int next;
      for (int i = 0; i < (int)VF[v].size() && !newBndEdge; i++)
      {
        int fid = VF[v][i];

        if (TT.row(fid).minCoeff() < 0.) // Face contains boundary edge
        {
          int vLoc;
          if (F(fid,0) == v) vLoc = 0;
          if (F(fid,1) == v) vLoc = 1;
          if (F(fid,2) == v) vLoc = 2;

          int vNext = F(fid,(vLoc + 1) % F.cols());

          newBndEdge = false;
          if (unvisited[vNext] && TT(fid,vLoc) < 0)
          {
            next = vNext;
            newBndEdge = true;
          }
        }
      }

      if (newBndEdge)
      {
        l.push_back(next);
        unseen.erase(next);
        unvisited[next] = false;
      }
      else
        done = true;
    }
    L.push_back(l);
  }
}

template <typename DerivedF, typename Index>
IGL_INLINE void igl::boundary_loop(
  const Eigen::PlainObjectBase<DerivedF>& F,
  std::vector<Index>& L)
{
  using namespace Eigen;
  using namespace std;

  vector<vector<int> > Lall;
  boundary_loop(F,Lall);

  int idxMax = -1;
  int maxLen = 0;
  for (int i = 0; i < Lall.size(); ++i)
  {
    if (Lall[i].size() > maxLen)
    {
      maxLen = Lall[i].size();
      idxMax = i;
    }
  }

  L.resize(Lall[idxMax].size());
  for (int i = 0; i < Lall[idxMax].size(); ++i)
    L[i] = Lall[idxMax][i];
}

template <typename DerivedF, typename DerivedL>
IGL_INLINE void igl::boundary_loop(
  const Eigen::PlainObjectBase<DerivedF>& F,
  Eigen::PlainObjectBase<DerivedL>& L)
{
  using namespace Eigen;
  using namespace std;

  vector<int> Lvec;
  boundary_loop(F,Lvec);

  L.resize(Lvec.size());
  for (int i = 0; i < Lvec.size(); ++i)
    L(i) = Lvec[i];
}<commit_msg>fixed memory allocation bug<commit_after>// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Stefan Brugger <stefanbrugger@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "boundary_loop.h"
#include "slice.h"
#include "triangle_triangle_adjacency.h"
#include "vertex_triangle_adjacency.h"
#include "is_border_vertex.h"
#include <set>

template <typename DerivedF, typename Index>
IGL_INLINE void igl::boundary_loop(
    const Eigen::PlainObjectBase<DerivedF> & F,
    std::vector<std::vector<Index> >& L)
{
  using namespace std;
  using namespace Eigen;
  using namespace igl;

  MatrixXd Vdummy(F.maxCoeff()+1,1);
  MatrixXi TT,TTi;
  vector<std::vector<int> > VF, VFi;
  triangle_triangle_adjacency(Vdummy,F,TT,TTi);
  vertex_triangle_adjacency(Vdummy,F,VF,VFi);

  vector<bool> unvisited = is_border_vertex(Vdummy,F);
  set<int> unseen;
  for (int i = 0; i < unvisited.size(); ++i)
  {
    if (unvisited[i])
      unseen.insert(unseen.end(),i);
  }

  while (!unseen.empty())
  {
    vector<Index> l;

    // Get first vertex of loop
    int start = *unseen.begin();
    unseen.erase(unseen.begin());
    unvisited[start] = false;
    l.push_back(start);

    bool done = false;
    while (!done)
    {
      // Find next vertex
      bool newBndEdge = false;
      int v = l[l.size()-1];
      int next;
      for (int i = 0; i < (int)VF[v].size() && !newBndEdge; i++)
      {
        int fid = VF[v][i];

        if (TT.row(fid).minCoeff() < 0.) // Face contains boundary edge
        {
          int vLoc;
          if (F(fid,0) == v) vLoc = 0;
          if (F(fid,1) == v) vLoc = 1;
          if (F(fid,2) == v) vLoc = 2;

          int vNext = F(fid,(vLoc + 1) % F.cols());

          newBndEdge = false;
          if (unvisited[vNext] && TT(fid,vLoc) < 0)
          {
            next = vNext;
            newBndEdge = true;
          }
        }
      }

      if (newBndEdge)
      {
        l.push_back(next);
        unseen.erase(next);
        unvisited[next] = false;
      }
      else
        done = true;
    }
    L.push_back(l);
  }
}

template <typename DerivedF, typename Index>
IGL_INLINE void igl::boundary_loop(
  const Eigen::PlainObjectBase<DerivedF>& F,
  std::vector<Index>& L)
{
  using namespace Eigen;
  using namespace std;

  vector<vector<int> > Lall;
  boundary_loop(F,Lall);

  int idxMax = -1;
  int maxLen = 0;
  for (int i = 0; i < Lall.size(); ++i)
  {
    if (Lall[i].size() > maxLen)
    {
      maxLen = Lall[i].size();
      idxMax = i;
    }
  }

  L.resize(Lall[idxMax].size());
  for (int i = 0; i < Lall[idxMax].size(); ++i)
    L[i] = Lall[idxMax][i];
}

template <typename DerivedF, typename DerivedL>
IGL_INLINE void igl::boundary_loop(
  const Eigen::PlainObjectBase<DerivedF>& F,
  Eigen::PlainObjectBase<DerivedL>& L)
{
  using namespace Eigen;
  using namespace std;

  vector<int> Lvec;
  boundary_loop(F,Lvec);

  L.resize(Lvec.size());
  for (int i = 0; i < Lvec.size(); ++i)
    L(i) = Lvec[i];
}
<|endoftext|>


<commit_before><commit_msg>This should be bool.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: zforauto.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:52:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifdef PCH
#include "core_pch.hxx"
#endif

#pragma hdrstop

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

#include <svtools/zforlist.hxx>
#include <svtools/zformat.hxx>
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#include <tools/debug.hxx>

#include "zforauto.hxx"
#include "global.hxx"

static const sal_Char __FAR_DATA pStandardName[] = "Standard";

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

ScNumFormatAbbrev::ScNumFormatAbbrev() :
    eLnge           (LANGUAGE_SYSTEM),
    eSysLnge        (LANGUAGE_GERMAN),      // sonst passt "Standard" nicht
    sFormatstring   ( RTL_CONSTASCII_USTRINGPARAM( pStandardName ) )
{
}

ScNumFormatAbbrev::ScNumFormatAbbrev(const ScNumFormatAbbrev& aFormat) :
    eLnge           (aFormat.eLnge),
    eSysLnge        (aFormat.eSysLnge),
    sFormatstring   (aFormat.sFormatstring)
{
}

ScNumFormatAbbrev::ScNumFormatAbbrev(ULONG nFormat,
                                     SvNumberFormatter& rFormatter)
{
    PutFormatIndex(nFormat, rFormatter);
}

void ScNumFormatAbbrev::Load( SvStream& rStream, CharSet eByteStrSet )
{
    USHORT nSysLang, nLang;
    rStream.ReadByteString( sFormatstring, eByteStrSet );
    rStream >> nSysLang >> nLang;
    eLnge = (LanguageType) nLang;
    eSysLnge = (LanguageType) nSysLang;
    if ( eSysLnge == LANGUAGE_SYSTEM )          // old versions did write it
        eSysLnge = Application::GetSettings().GetLanguage();
}

void ScNumFormatAbbrev::Save( SvStream& rStream, CharSet eByteStrSet ) const
{
    rStream.WriteByteString( sFormatstring, eByteStrSet );
    rStream << (USHORT) eSysLnge << (USHORT) eLnge;
}

void ScNumFormatAbbrev::PutFormatIndex(ULONG nFormat,
                                       SvNumberFormatter& rFormatter)
{
    const SvNumberformat* pFormat = rFormatter.GetEntry(nFormat);
    if (pFormat)
    {
        eSysLnge = Application::GetSettings().GetLanguage();
        eLnge = pFormat->GetLanguage();
        sFormatstring = ((SvNumberformat*)pFormat)->GetFormatstring();
    }
    else
    {
        DBG_ERROR("SCNumFormatAbbrev:: unbekanntes Zahlformat");
        eLnge = LANGUAGE_SYSTEM;
        eSysLnge = LANGUAGE_GERMAN;     // sonst passt "Standard" nicht
        sFormatstring.AssignAscii( RTL_CONSTASCII_STRINGPARAM( pStandardName ) );
    }
}

ULONG ScNumFormatAbbrev::GetFormatIndex( SvNumberFormatter& rFormatter)
{
    //  #62389# leerer Formatstring (vom Writer) -> Standardformat
    if ( !sFormatstring.Len() )
        return rFormatter.GetStandardIndex( eLnge );

    if ( eLnge == LANGUAGE_SYSTEM && eSysLnge != Application::GetSettings().GetLanguage() )
    {
        ULONG nOrig = rFormatter.GetEntryKey( sFormatstring, eSysLnge );
        if ( nOrig != NUMBERFORMAT_ENTRY_NOT_FOUND )
            return rFormatter.GetFormatForLanguageIfBuiltIn( nOrig, Application::GetSettings().GetLanguage() );
        else
            return rFormatter.GetStandardIndex( eLnge );    // geht nicht -> Standard
    }

    xub_StrLen nCheckPos;
    short nType;
    ULONG nKey = rFormatter.GetEntryKey(sFormatstring, eLnge);
    if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
    {
        BOOL res = rFormatter.PutEntry(sFormatstring,
                                       nCheckPos, nType, nKey, eLnge);
        if (nCheckPos > 0)
            DBG_ERROR("SCNumFormatAbbrev:: unkorrekter Formatstring");
    }
    return nKey;
}

<commit_msg>INTEGRATION: CWS autocurrency (1.3.252); FILE MERGED 2005/05/17 14:46:18 er 1.3.252.1: #i40902# use SvNumberFormatter::GetIndexPuttingAndConverting; convert legacy 'automatic' currency formats to new fixed currency formats<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: zforauto.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-23 12:17:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <svtools/zforlist.hxx>
#include <svtools/zformat.hxx>
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#include <tools/debug.hxx>

#include "zforauto.hxx"
#include "global.hxx"

static const sal_Char __FAR_DATA pStandardName[] = "Standard";

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

ScNumFormatAbbrev::ScNumFormatAbbrev() :
    sFormatstring   ( RTL_CONSTASCII_USTRINGPARAM( pStandardName ) ),
    eLnge           (LANGUAGE_SYSTEM),
    eSysLnge        (LANGUAGE_GERMAN)       // sonst passt "Standard" nicht
{
}

ScNumFormatAbbrev::ScNumFormatAbbrev(const ScNumFormatAbbrev& aFormat) :
    sFormatstring   (aFormat.sFormatstring),
    eLnge           (aFormat.eLnge),
    eSysLnge        (aFormat.eSysLnge)
{
}

ScNumFormatAbbrev::ScNumFormatAbbrev(ULONG nFormat,
                                     SvNumberFormatter& rFormatter)
{
    PutFormatIndex(nFormat, rFormatter);
}

void ScNumFormatAbbrev::Load( SvStream& rStream, CharSet eByteStrSet )
{
    USHORT nSysLang, nLang;
    rStream.ReadByteString( sFormatstring, eByteStrSet );
    rStream >> nSysLang >> nLang;
    eLnge = (LanguageType) nLang;
    eSysLnge = (LanguageType) nSysLang;
    if ( eSysLnge == LANGUAGE_SYSTEM )          // old versions did write it
        eSysLnge = Application::GetSettings().GetLanguage();
}

void ScNumFormatAbbrev::Save( SvStream& rStream, CharSet eByteStrSet ) const
{
    rStream.WriteByteString( sFormatstring, eByteStrSet );
    rStream << (USHORT) eSysLnge << (USHORT) eLnge;
}

void ScNumFormatAbbrev::PutFormatIndex(ULONG nFormat,
                                       SvNumberFormatter& rFormatter)
{
    const SvNumberformat* pFormat = rFormatter.GetEntry(nFormat);
    if (pFormat)
    {
        eSysLnge = Application::GetSettings().GetLanguage();
        eLnge = pFormat->GetLanguage();
        sFormatstring = ((SvNumberformat*)pFormat)->GetFormatstring();
    }
    else
    {
        DBG_ERROR("SCNumFormatAbbrev:: unbekanntes Zahlformat");
        eLnge = LANGUAGE_SYSTEM;
        eSysLnge = LANGUAGE_GERMAN;     // sonst passt "Standard" nicht
        sFormatstring.AssignAscii( RTL_CONSTASCII_STRINGPARAM( pStandardName ) );
    }
}

ULONG ScNumFormatAbbrev::GetFormatIndex( SvNumberFormatter& rFormatter)
{
    short nType;
    BOOL bNewInserted;
    xub_StrLen nCheckPos;
    return rFormatter.GetIndexPuttingAndConverting( sFormatstring, eLnge,
            eSysLnge, nType, bNewInserted, nCheckPos);
}
<|endoftext|>


<commit_before>#include <plugin.hpp>
#include <output.hpp>
#include <workspace-manager.hpp>
#include <signal-definitions.hpp>

#include "tree-controller.hpp"

namespace wf
{
class tile_workspace_implementation_t : public wf::workspace_implementation_t
{
  public:
    bool view_movable(wayfire_view view) override
    {
        return wf::tile::view_node_t::get_node(view) == nullptr;
    }

    bool view_resizable(wayfire_view view) override
    {
        return wf::tile::view_node_t::get_node(view) == nullptr;
    }
};

class tile_plugin_t : public wf::plugin_interface_t
{
  private:
    std::vector<std::vector<std::unique_ptr<wf::tile::tree_node_t>>> roots;

    const wf::tile::split_direction_t default_split = wf::tile::SPLIT_VERTICAL;

    void initialize_roots()
    {
        auto wsize = output->workspace->get_workspace_grid_size();
        roots.resize(wsize.width);
        for (int i = 0; i < wsize.width; i++)
        {
            roots[i].resize(wsize.height);
            for (int j = 0; j < wsize.height; j++)
            {
                roots[i][j] =
                    std::make_unique<wf::tile::split_node_t>(default_split);
            }
        }

        update_root_size(output->workspace->get_workarea());
    }

    void update_root_size(wf_geometry workarea)
    {
        auto output_geometry = output->get_relative_geometry();
        auto wsize = output->workspace->get_workspace_grid_size();
        for (int i = 0; i < wsize.width; i++)
        {
            for (int j = 0; j < wsize.height; j++)
            {
                /* Set size */
                auto vp_geometry = workarea;
                vp_geometry.x += i * output_geometry.width;
                vp_geometry.y += j * output_geometry.height;
                roots[i][j]->set_geometry(vp_geometry);
            }
        }
    }

    void flatten_roots()
    {
        for (auto& col : roots)
        {
            for (auto& root : col)
                tile::flatten_tree(root);
        }
    }

    bool can_tile_view(wayfire_view view)
    {
        if (view->role != wf::VIEW_ROLE_TOPLEVEL)
            return false;

        if (view->parent)
            return false;

        return true;
    }

    static std::unique_ptr<wf::tile::tile_controller_t> get_default_controller()
    {
        return std::make_unique<wf::tile::tile_controller_t> ();
    }

    std::unique_ptr<wf::tile::tile_controller_t> controller =
        get_default_controller();

    /**
     * Translate coordinates from output-local coordinates to the coordinate
     * system of the tiling trees, depending on the current workspace
     */
    wf_point get_global_coordinates(wf_point local_coordinates)
    {
        auto vp = output->workspace->get_current_workspace();
        auto size = output->get_screen_size();
        local_coordinates.x += size.width * vp.x;
        local_coordinates.y += size.height * vp.y;

        return local_coordinates;
    }

    template<class Controller>
    void start_controller(wf_point grab)
    {
        auto vp = output->workspace->get_current_workspace();

        int count_fullscreen = 0;
        for_each_view(roots[vp.x][vp.y], [&] (wayfire_view view) {
            count_fullscreen += view->fullscreen;
        });

        /* No action possible in this case */
        if (count_fullscreen)
            return;

        if (output->activate_plugin(grab_interface))
        {
            if (grab_interface->grab())
            {
                controller = std::make_unique<Controller> (
                    roots[vp.x][vp.y], get_global_coordinates(grab));
            } else
            {
                output->deactivate_plugin(grab_interface);
            }
        }
    }

    void stop_controller(bool force_stop)
    {
        if (!output->is_plugin_active(grab_interface->name))
            return;

        if (!force_stop)
            controller->input_released();

        output->deactivate_plugin(grab_interface);
        controller = get_default_controller();
    }

    void attach_view(wayfire_view view)
    {
        if (!can_tile_view(view))
            return;

        stop_controller(true);

        auto vp = output->workspace->get_current_workspace();
        auto view_node = std::make_unique<wf::tile::view_node_t> (view);
        roots[vp.x][vp.y]->as_split_node()->add_child(std::move(view_node));

        tile::restack_output_workspace(output,
            output->workspace->get_current_workspace());
    }

    signal_callback_t on_view_attached = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        attach_view(view);
    };

    signal_callback_t on_view_unmapped = [=] (signal_data_t *data)
    {
        stop_controller(true);
    };

    /** Remove the given view from its tiling container */
    void detach_view(nonstd::observer_ptr<tile::view_node_t> view)
    {
        stop_controller(true);
        auto wview = view->view;

        view->parent->remove_child(view);
        /* View node is invalid now */
        flatten_roots();

        if (wview->fullscreen)
            wview->fullscreen_request(nullptr, false);
    }

    signal_callback_t on_view_detached = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        auto view_node = wf::tile::view_node_t::get_node(view);

        if (view_node)
            detach_view(view_node);
    };

    signal_callback_t on_workarea_changed = [=] (signal_data_t *data)
    {
        update_root_size(output->workspace->get_workarea());
    };

    signal_callback_t on_tile_request = [=] (signal_data_t *data)
    {
        auto ev = static_cast<view_tiled_signal*> (data);
        if (ev->carried_out || !tile::view_node_t::get_node(ev->view))
            return;

        // we ignore those requests because we manage the tiled state manually
        ev->carried_out = true;
    };

    void set_view_fullscreen(wayfire_view view, bool fullscreen)
    {
        /* Set fullscreen, and trigger resizing of the views */
        view->set_fullscreen(fullscreen);
        update_root_size(output->workspace->get_workarea());
    }

    signal_callback_t on_fullscreen_request = [=] (signal_data_t *data)
    {
        auto ev = static_cast<view_fullscreen_signal*> (data);
        if (ev->carried_out || !tile::view_node_t::get_node(ev->view))
            return;

        ev->carried_out = true;
        set_view_fullscreen(ev->view, ev->state);
    };

    signal_callback_t on_focus_changed = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        if (tile::view_node_t::get_node(view) && !view->fullscreen)
        {
            auto vp = output->workspace->get_current_workspace();
            for_each_view(roots[vp.x][vp.y], [&] (wayfire_view view) {
                if (view->fullscreen)
                    set_view_fullscreen(view, false);
            });
        }

        tile::restack_output_workspace(output,
            output->workspace->get_current_workspace());
    };

    key_callback on_toggle_fullscreen = [=] (uint32_t key)
    {
        auto view = output->get_active_view();
        if (!view || !tile::view_node_t::get_node(view))
            return;

        if (output->activate_plugin(grab_interface))
        {
            stop_controller(true);
            set_view_fullscreen(view, !view->fullscreen);
            output->deactivate_plugin(grab_interface);
        }
    };

    key_callback on_toggle_tiled_state = [=] (uint32_t key)
    {
        auto view = output->get_active_view();
        if (!view || !output->activate_plugin(grab_interface))
            return;

        auto existing_node = tile::view_node_t::get_node(view);
        if (existing_node) {
            detach_view(existing_node);
            view->tile_request(0);
        } else {
            attach_view(view);
        }

        output->deactivate_plugin(grab_interface);
    };

    button_callback on_retile_view = [=] (uint32_t button, int32_t x, int32_t y)
    {
        start_controller<tile::move_view_controller_t> ({x, y});
    };

    button_callback on_resize_view = [=] (uint32_t button, int32_t x, int32_t y)
    {
        start_controller<tile::resize_view_controller_t> ({x, y});
    };

  public:
    void init(wayfire_config *config) override
    {
        this->grab_interface->name = "simple-tile";
        /* TODO: change how grab interfaces work - plugins should do ifaces on
         * their own, and should be able to have more than one */
        this->grab_interface->capabilities = CAPABILITY_MANAGE_COMPOSITOR;

        initialize_roots();
        // TODO: check whether this was successful
        output->workspace->set_workspace_implementation(
            std::make_unique<tile_workspace_implementation_t> (), true);

        output->connect_signal("unmap-view", &on_view_unmapped);
        output->connect_signal("attach-view", &on_view_attached);
        output->connect_signal("detach-view", &on_view_detached);
        output->connect_signal("reserved-workarea", &on_workarea_changed);
        output->connect_signal("view-maximized-request", &on_tile_request);
        output->connect_signal("view-fullscreen-request",
            &on_fullscreen_request);
        output->connect_signal("focus-view", &on_focus_changed);

        auto button = new_static_option("<super> BTN_LEFT");
        output->add_button(button, &on_retile_view);

        auto rb = new_static_option("<super> BTN_RIGHT");
        output->add_button(rb, &on_resize_view);

        auto toggle = new_static_option("<super> KEY_M");
        output->add_key(toggle, &on_toggle_fullscreen);

        auto toggle_tile = new_static_option("<super> KEY_N");
        output->add_key(toggle_tile, &on_toggle_tiled_state);

        grab_interface->callbacks.pointer.button =
            [=] (uint32_t b, uint32_t state)
        {
            if (state == WLR_BUTTON_RELEASED)
                stop_controller(false);
        };

        grab_interface->callbacks.pointer.motion = [=] (int32_t x, int32_t y)
        {
            controller->input_motion(get_global_coordinates({x, y}));
        };
    }

    void fini() override
    {
        output->workspace->set_workspace_implementation(nullptr);

        output->disconnect_signal("unmap-view", &on_view_unmapped);
        output->disconnect_signal("attach-view", &on_view_attached);
        output->disconnect_signal("detach-view", &on_view_detached);
        output->disconnect_signal("reserved-workarea", &on_workarea_changed);
        output->disconnect_signal("view-maximized-request", &on_tile_request);
        output->disconnect_signal("view-fullscreen-request",
            &on_fullscreen_request);
        output->disconnect_signal("focus-view", &on_focus_changed);
    }
};
};

DECLARE_WAYFIRE_PLUGIN(wf::tile_plugin_t);
<commit_msg>tile: read options from the config file<commit_after>#include <plugin.hpp>
#include <output.hpp>
#include <workspace-manager.hpp>
#include <signal-definitions.hpp>

#include "tree-controller.hpp"

namespace wf
{
class tile_workspace_implementation_t : public wf::workspace_implementation_t
{
  public:
    bool view_movable(wayfire_view view) override
    {
        return wf::tile::view_node_t::get_node(view) == nullptr;
    }

    bool view_resizable(wayfire_view view) override
    {
        return wf::tile::view_node_t::get_node(view) == nullptr;
    }
};

class tile_plugin_t : public wf::plugin_interface_t
{
  private:
    wf_option tile_by_default;
    wf_option button_move, button_resize;
    wf_option key_toggle_tile, key_toggle_fullscreen;
  private:
    std::vector<std::vector<std::unique_ptr<wf::tile::tree_node_t>>> roots;

    const wf::tile::split_direction_t default_split = wf::tile::SPLIT_VERTICAL;

    void initialize_roots()
    {
        auto wsize = output->workspace->get_workspace_grid_size();
        roots.resize(wsize.width);
        for (int i = 0; i < wsize.width; i++)
        {
            roots[i].resize(wsize.height);
            for (int j = 0; j < wsize.height; j++)
            {
                roots[i][j] =
                    std::make_unique<wf::tile::split_node_t>(default_split);
            }
        }

        update_root_size(output->workspace->get_workarea());
    }

    void update_root_size(wf_geometry workarea)
    {
        auto output_geometry = output->get_relative_geometry();
        auto wsize = output->workspace->get_workspace_grid_size();
        for (int i = 0; i < wsize.width; i++)
        {
            for (int j = 0; j < wsize.height; j++)
            {
                /* Set size */
                auto vp_geometry = workarea;
                vp_geometry.x += i * output_geometry.width;
                vp_geometry.y += j * output_geometry.height;
                roots[i][j]->set_geometry(vp_geometry);
            }
        }
    }

    void flatten_roots()
    {
        for (auto& col : roots)
        {
            for (auto& root : col)
                tile::flatten_tree(root);
        }
    }

    bool can_tile_view(wayfire_view view)
    {
        if (view->role != wf::VIEW_ROLE_TOPLEVEL)
            return false;

        if (view->parent)
            return false;

        return true;
    }

    static std::unique_ptr<wf::tile::tile_controller_t> get_default_controller()
    {
        return std::make_unique<wf::tile::tile_controller_t> ();
    }

    std::unique_ptr<wf::tile::tile_controller_t> controller =
        get_default_controller();

    /**
     * Translate coordinates from output-local coordinates to the coordinate
     * system of the tiling trees, depending on the current workspace
     */
    wf_point get_global_coordinates(wf_point local_coordinates)
    {
        auto vp = output->workspace->get_current_workspace();
        auto size = output->get_screen_size();
        local_coordinates.x += size.width * vp.x;
        local_coordinates.y += size.height * vp.y;

        return local_coordinates;
    }

    template<class Controller>
    void start_controller(wf_point grab)
    {
        auto vp = output->workspace->get_current_workspace();

        int count_fullscreen = 0;
        for_each_view(roots[vp.x][vp.y], [&] (wayfire_view view) {
            count_fullscreen += view->fullscreen;
        });

        /* No action possible in this case */
        if (count_fullscreen)
            return;

        if (output->activate_plugin(grab_interface))
        {
            if (grab_interface->grab())
            {
                controller = std::make_unique<Controller> (
                    roots[vp.x][vp.y], get_global_coordinates(grab));
            } else
            {
                output->deactivate_plugin(grab_interface);
            }
        }
    }

    void stop_controller(bool force_stop)
    {
        if (!output->is_plugin_active(grab_interface->name))
            return;

        if (!force_stop)
            controller->input_released();

        output->deactivate_plugin(grab_interface);
        controller = get_default_controller();
    }

    void attach_view(wayfire_view view)
    {
        if (!can_tile_view(view))
            return;

        stop_controller(true);

        auto vp = output->workspace->get_current_workspace();
        auto view_node = std::make_unique<wf::tile::view_node_t> (view);
        roots[vp.x][vp.y]->as_split_node()->add_child(std::move(view_node));

        tile::restack_output_workspace(output,
            output->workspace->get_current_workspace());
    }

    signal_callback_t on_view_attached = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        attach_view(view);
    };

    signal_callback_t on_view_unmapped = [=] (signal_data_t *data)
    {
        stop_controller(true);
    };

    /** Remove the given view from its tiling container */
    void detach_view(nonstd::observer_ptr<tile::view_node_t> view)
    {
        stop_controller(true);
        auto wview = view->view;

        view->parent->remove_child(view);
        /* View node is invalid now */
        flatten_roots();

        if (wview->fullscreen)
            wview->fullscreen_request(nullptr, false);
    }

    signal_callback_t on_view_detached = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        auto view_node = wf::tile::view_node_t::get_node(view);

        if (view_node)
            detach_view(view_node);
    };

    signal_callback_t on_workarea_changed = [=] (signal_data_t *data)
    {
        update_root_size(output->workspace->get_workarea());
    };

    signal_callback_t on_tile_request = [=] (signal_data_t *data)
    {
        auto ev = static_cast<view_tiled_signal*> (data);
        if (ev->carried_out || !tile::view_node_t::get_node(ev->view))
            return;

        // we ignore those requests because we manage the tiled state manually
        ev->carried_out = true;
    };

    void set_view_fullscreen(wayfire_view view, bool fullscreen)
    {
        /* Set fullscreen, and trigger resizing of the views */
        view->set_fullscreen(fullscreen);
        update_root_size(output->workspace->get_workarea());
    }

    signal_callback_t on_fullscreen_request = [=] (signal_data_t *data)
    {
        auto ev = static_cast<view_fullscreen_signal*> (data);
        if (ev->carried_out || !tile::view_node_t::get_node(ev->view))
            return;

        ev->carried_out = true;
        set_view_fullscreen(ev->view, ev->state);
    };

    signal_callback_t on_focus_changed = [=] (signal_data_t *data)
    {
        auto view = get_signaled_view(data);
        if (tile::view_node_t::get_node(view) && !view->fullscreen)
        {
            auto vp = output->workspace->get_current_workspace();
            for_each_view(roots[vp.x][vp.y], [&] (wayfire_view view) {
                if (view->fullscreen)
                    set_view_fullscreen(view, false);
            });
        }

        tile::restack_output_workspace(output,
            output->workspace->get_current_workspace());
    };

    key_callback on_toggle_fullscreen = [=] (uint32_t key)
    {
        auto view = output->get_active_view();
        if (!view || !tile::view_node_t::get_node(view))
            return;

        if (output->activate_plugin(grab_interface))
        {
            stop_controller(true);
            set_view_fullscreen(view, !view->fullscreen);
            output->deactivate_plugin(grab_interface);
        }
    };

    key_callback on_toggle_tiled_state = [=] (uint32_t key)
    {
        auto view = output->get_active_view();
        if (!view || !output->activate_plugin(grab_interface))
            return;

        auto existing_node = tile::view_node_t::get_node(view);
        if (existing_node) {
            detach_view(existing_node);
            view->tile_request(0);
        } else {
            attach_view(view);
        }

        output->deactivate_plugin(grab_interface);
    };

    button_callback on_move_view = [=] (uint32_t button, int32_t x, int32_t y)
    {
        start_controller<tile::move_view_controller_t> ({x, y});
    };

    button_callback on_resize_view = [=] (uint32_t button, int32_t x, int32_t y)
    {
        start_controller<tile::resize_view_controller_t> ({x, y});
    };

    void load_options(wayfire_config *config)
    {
        auto section = config->get_section("simple-tile");

        tile_by_default = section->get_option("tile_by_default", "1");
        button_move = section->get_option("button_move", "<super> BTN_LEFT");
        button_resize =
            section->get_option("button_resize", "<super> BTN_RIGHT");

        key_toggle_tile = section->get_option("key_toggle", "<super> KEY_T");
        key_toggle_fullscreen =
            section->get_option("key_toggle_fullscreen", "<super> KEY_M");
    }

    void setup_callbacks()
    {
        output->add_button(button_move, &on_move_view);
        output->add_button(button_resize, &on_resize_view);
        output->add_key(key_toggle_tile, &on_toggle_fullscreen);
        output->add_key(key_toggle_fullscreen, &on_toggle_tiled_state);

        grab_interface->callbacks.pointer.button =
            [=] (uint32_t b, uint32_t state)
            {
                if (state == WLR_BUTTON_RELEASED)
                    stop_controller(false);
            };

        grab_interface->callbacks.pointer.motion = [=] (int32_t x, int32_t y)
        {
            controller->input_motion(get_global_coordinates({x, y}));
        };
    }

  public:
    void init(wayfire_config *config) override
    {
        this->grab_interface->name = "simple-tile";
        /* TODO: change how grab interfaces work - plugins should do ifaces on
         * their own, and should be able to have more than one */
        this->grab_interface->capabilities = CAPABILITY_MANAGE_COMPOSITOR;

        initialize_roots();
        // TODO: check whether this was successful
        output->workspace->set_workspace_implementation(
            std::make_unique<tile_workspace_implementation_t> (), true);

        output->connect_signal("unmap-view", &on_view_unmapped);
        output->connect_signal("attach-view", &on_view_attached);
        output->connect_signal("detach-view", &on_view_detached);
        output->connect_signal("reserved-workarea", &on_workarea_changed);
        output->connect_signal("view-maximized-request", &on_tile_request);
        output->connect_signal("view-fullscreen-request",
            &on_fullscreen_request);
        output->connect_signal("focus-view", &on_focus_changed);

        load_options(config);
        setup_callbacks();
    }

    void fini() override
    {
        output->workspace->set_workspace_implementation(nullptr, true);

        output->rem_binding(&on_move_view);
        output->rem_binding(&on_resize_view);
        output->rem_binding(&on_toggle_fullscreen);
        output->rem_binding(&on_toggle_tiled_state);

        output->disconnect_signal("unmap-view", &on_view_unmapped);
        output->disconnect_signal("attach-view", &on_view_attached);
        output->disconnect_signal("detach-view", &on_view_detached);
        output->disconnect_signal("reserved-workarea", &on_workarea_changed);
        output->disconnect_signal("view-maximized-request", &on_tile_request);
        output->disconnect_signal("view-fullscreen-request",
            &on_fullscreen_request);
        output->disconnect_signal("focus-view", &on_focus_changed);
    }
};
};

DECLARE_WAYFIRE_PLUGIN(wf::tile_plugin_t);
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RULE_CACHE_HPP
#define MAPNIK_RULE_CACHE_HPP

// mapnik
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>

// boost
#include <boost/foreach.hpp>

// stl
#include <vector>

namespace mapnik
{

class rule_cache
{
public:
    typedef std::vector<rule const*> rule_ptrs;
    rule_cache()
     : if_rules_(),
       else_rules_(),
       also_rules_() {}

    void add_rule(rule const& r)
    {
        if (r.has_else_filter())
        {
            else_rules_.push_back(&r);
        }
        else if (r.has_also_filter())
        {
            also_rules_.push_back(&r);
        }
        else
        {
            if_rules_.push_back(&r);
        }
    }

    rule_ptrs const& get_if_rules() const
    {
        return if_rules_;
    }

    rule_ptrs const& get_else_rules() const
    {
        return else_rules_;
    }

    rule_ptrs const& get_also_rules() const
    {
        return also_rules_;
    }

private:
    rule_ptrs if_rules_;
    rule_ptrs else_rules_;
    rule_ptrs also_rules_;
};

}

#endif // MAPNIK_RULE_CACHE_HPP
<commit_msg>make rule_cache noncopyable<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2013 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_RULE_CACHE_HPP
#define MAPNIK_RULE_CACHE_HPP

// mapnik
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/noncopyable.hpp>

// boost
#include <boost/foreach.hpp>

// stl
#include <vector>

namespace mapnik
{

class rule_cache : private noncopyable
{
public:
    typedef std::vector<rule const*> rule_ptrs;
    rule_cache()
     : if_rules_(),
       else_rules_(),
       also_rules_() {}

    void add_rule(rule const& r)
    {
        if (r.has_else_filter())
        {
            else_rules_.push_back(&r);
        }
        else if (r.has_also_filter())
        {
            also_rules_.push_back(&r);
        }
        else
        {
            if_rules_.push_back(&r);
        }
    }

    rule_ptrs const& get_if_rules() const
    {
        return if_rules_;
    }

    rule_ptrs const& get_else_rules() const
    {
        return else_rules_;
    }

    rule_ptrs const& get_also_rules() const
    {
        return also_rules_;
    }

private:
    rule_ptrs if_rules_;
    rule_ptrs else_rules_;
    rule_ptrs also_rules_;
};

}

#endif // MAPNIK_RULE_CACHE_HPP
<|endoftext|>


<commit_before>/*
Copyright 2015 Rogier van Dalen.

This file is part of Rogier van Dalen's Range library for C++.

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef RANGE_VIEW_SHARED_HPP_INCLUDED
#define RANGE_VIEW_SHARED_HPP_INCLUDED

#include <memory>
#include <type_traits>

#include "utility/returns.hpp"

#include "core.hpp"
#include "detail/underlying.hpp"

namespace range {

namespace operation { namespace view_shared_detail {

        struct make_view_of_shared;
        struct get_heavyweight_pointer;

}} // namespace operation::view_shared_detail

/**
Range that holds a std::shared_ptr, and also a view of the range.
All copies or derivatives of the range will hold a copy of the shared_ptr, and
the operations will effect only the view.
*/
template <class Heavyweight,
    class View = typename std::decay <typename std::result_of <
        callable::view (Heavyweight &)>::type>::type>
    struct view_of_shared
{
public:
    static_assert (std::is_same <Heavyweight, typename
        std::remove_reference <Heavyweight>::type>::value,
        "The heavyweight range should not be a reference type.");

    typedef Heavyweight heavyweight_type;
    typedef std::shared_ptr <Heavyweight> heavyweight_pointer;
    typedef View underlying_type;

private:
    heavyweight_pointer heavyweight_;
    underlying_type underlying_;

    friend class detail::callable::get_underlying;

public:
    view_of_shared (heavyweight_pointer heavyweight, View const & underlying)
    : heavyweight_ (std::move (heavyweight)), underlying_ (underlying) {}

    view_of_shared (heavyweight_pointer heavyweight, View && underlying)
    : heavyweight_ (std::move (heavyweight)),
        underlying_ (std::move (underlying)) {}

private:
    friend struct operation::view_shared_detail::make_view_of_shared;
    friend struct operation::view_shared_detail::get_heavyweight_pointer;

    heavyweight_pointer const & heavyweight() const { return heavyweight_; }
    heavyweight_pointer & heavyweight() { return heavyweight_; }

private:
    friend class operation::member_access;

    auto default_direction() const
    RETURNS (range::default_direction (underlying_));

    template <class Direction> typename
        result_of_or <range::callable::empty (
            Direction, underlying_type const &)
    >::type empty (Direction const & direction) const
    { return range::empty (direction, underlying_); }

    template <class Direction> typename
        result_of_or <range::callable::size (
            Direction, underlying_type const &)
    >::type size (Direction const & direction) const
    { return range::size (direction, underlying_); }

    template <class Direction> typename
        result_of_or <range::callable::chop_in_place (
            Direction, underlying_type &)
    >::type chop_in_place (Direction const & direction)
    { return range::chop_in_place (direction, underlying_); }
};

struct view_of_shared_tag;

template <class Heavyweight, class View>
    struct tag_of_qualified <view_of_shared <Heavyweight, View>>
{ typedef view_of_shared_tag type; };

namespace operation {

    namespace view_shared_detail {

        struct make_view_of_shared {
            template <class Heavyweight, class View>
                view_of_shared <Heavyweight, typename std::decay <View>::type>
                    operator() (std::shared_ptr <Heavyweight> heavyweight,
                        View && view) const
            {
                return view_of_shared <Heavyweight, View> (
                    std::move (heavyweight), std::forward <View> (view));
            }
        };

        struct get_heavyweight_pointer {
            template <class Range>
                typename Range::heavyweight_pointer && operator() (
                    Range && range) const
            { return std::move (range.heavyweight()); }

            template <class Range>
                typename Range::heavyweight_pointer const & operator() (
                    Range const & range) const
            { return range.heavyweight(); }
        };

    } // namespace view_shared_detail

    template <class Direction, class Range>
        struct first <view_of_shared_tag, Direction, Range, typename
            boost::enable_if <has <
                callable::first (Direction, typename underlying <Range>::type)
            >>::type>
    {
        auto operator() (Direction const & direction, Range && range) const
        RETURNS (range::first (direction, range::detail::get_underlying (
            std::forward <Range> (range))));
    };

    template <class Direction, class Increment, class Range>
        struct drop <view_of_shared_tag, Direction, Increment, Range, typename
            boost::enable_if <has <
                callable::drop (Direction, Increment,
                    typename underlying <Range>::type)
            >>::type>
    {
        auto operator() (Direction const & direction,
            Increment const & increment, Range && range) const
        RETURNS (view_shared_detail::make_view_of_shared() (
            view_shared_detail::get_heavyweight_pointer() (
                std::forward <Range> (range)),
            range::drop (direction, increment,
            range::detail::get_underlying (std::forward <Range> (range)))));
    };

    template <class Direction, class Range>
        struct chop <view_of_shared_tag, Direction, Range, typename
            boost::enable_if <has <
                callable::chop (Direction,
                    typename underlying <Range>::type)
            >>::type>
    {
        typedef typename result_of <callable::chop (Direction,
            typename underlying <Range>::type)>::type underlying_chopped_type;
        typedef typename underlying_chopped_type::first_type first_type;
        typedef typename underlying_chopped_type::rest_type
            underlying_rest_type;

        typedef typename std::decay <Range>::type::heavyweight_type
            heavyweight_type;

        typedef chopped <first_type,
                view_of_shared <heavyweight_type, underlying_rest_type>>
            result_type;

        result_type operator() (Direction const & direction, Range && range)
            const
        {
            auto underlying_chopped = range::chop (direction,
                range::detail::get_underlying (std::forward <Range> (range)));
            return result_type (underlying_chopped.move_first(),
                view_shared_detail::make_view_of_shared() (
                    view_shared_detail::get_heavyweight_pointer() (
                        std::forward <Range> (range)),
                    underlying_chopped.move_rest()));
        }
    };

} // namespace operation

namespace callable {

    struct view_shared {

        /* With MakeView. */

        template <class Heavyweight, class MakeView,
            class View = typename std::decay <typename std::result_of <
                MakeView (Heavyweight &)>::type>::type,
            class Enable = typename boost::enable_if <is_range <Heavyweight>
                >::type>
        view_of_shared <Heavyweight, View>
            operator() (std::shared_ptr <Heavyweight> heavyweight,
                MakeView const & make_view) const
        {
            Heavyweight & h = *heavyweight;
            return view_of_shared <Heavyweight, View> (
                std::move (heavyweight), make_view (h));
        }

        template <class Heavyweight, class MakeView,
            class View = typename std::decay <typename std::result_of <
                MakeView (Heavyweight &)>::type>::type,
            class Enable = typename boost::enable_if <is_range <Heavyweight>
                >::type>
        view_of_shared <typename std::decay <Heavyweight>::type, View>
            operator() (Heavyweight && heavyweight, MakeView const & make_view)
            const
        {
            auto heavyweight_pointer =
                std::make_shared <typename std::decay <Heavyweight>::type> (
                    std::forward <Heavyweight> (heavyweight));
            return operator() (std::move (heavyweight_pointer), make_view);
        }

        /* Without MakeView. */

        template <class Heavyweight, class Enable
            = typename boost::enable_if <is_range <Heavyweight>>::type>
        view_of_shared <Heavyweight>
            operator() (std::shared_ptr <Heavyweight> heavyweight) const
        { return operator() (std::move (heavyweight), range::view); }

        template <class Heavyweight, class Enable
            = typename boost::enable_if <is_range <Heavyweight>>::type>
        view_of_shared <typename std::decay <Heavyweight>::type>
            operator() (Heavyweight && heavyweight) const
        {
            return operator() (
                std::make_shared <typename std::decay <Heavyweight>::type> (
                    std::forward <Heavyweight> (heavyweight)));
        }

    };

} // namespace callable

/**
\brief Return a view on a heavyweight range whose lifetime is tied to the view.

Normally, the onus is on the user to make sure that the container, say, that a
view is on, remains in scope while the view is being used.
However, sometimes this is impossible or undesirable.
For example, returning a range of which the type is an implementation detail is
fraught with difficulty.

The solution is to force the range to stay in memory as long as the view or any
copy or derived view does.
That is what this function does, by keeping the range in a std::shared_ptr.

The optional second argument is a function to convert the range into a view.
This is a function, not the view itself, because the range usually first needs
to be copied into the shared_ptr, before a view of the copy can be produced.

\param heavyweight
    The heavyweight range that the view will be on.
    If this is a std::shared_ptr, a copy of it will be kept.
    If this is a range, then a copy of it will be kept in a shared_ptr.
\param make_view (optional)
    Function that returns the right sort of view of the range.
    If this is not given, \ref view is used.
    Other simple or complex functors are possible.
    For example, use \ref reverse to produce a reversed view of the range.
*/
static auto constexpr view_shared = callable::view_shared();

} // namespace range

#endif // RANGE_VIEW_SHARED_HPP_INCLUDED
<commit_msg>Fix view_shared<commit_after>/*
Copyright 2015 Rogier van Dalen.

This file is part of Rogier van Dalen's Range library for C++.

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef RANGE_VIEW_SHARED_HPP_INCLUDED
#define RANGE_VIEW_SHARED_HPP_INCLUDED

#include <memory>
#include <type_traits>

#include "utility/returns.hpp"

#include "core.hpp"
#include "detail/underlying.hpp"

namespace range {

namespace operation { namespace view_shared_detail {

        struct make_view_of_shared;
        struct get_heavyweight_pointer;

}} // namespace operation::view_shared_detail

/**
Range that holds a std::shared_ptr, and also a view of the range.
All copies or derivatives of the range will hold a copy of the shared_ptr, and
the operations will effect only the view.
*/
template <class Heavyweight,
    class View = typename std::decay <typename std::result_of <
        callable::view (Heavyweight &)>::type>::type>
    struct view_of_shared
{
public:
    static_assert (std::is_same <Heavyweight, typename
        std::remove_reference <Heavyweight>::type>::value,
        "The heavyweight range should not be a reference type.");

    typedef Heavyweight heavyweight_type;
    typedef std::shared_ptr <Heavyweight> heavyweight_pointer;
    typedef View underlying_type;

private:
    heavyweight_pointer heavyweight_;
    underlying_type underlying_;

    friend class detail::callable::get_underlying;

public:
    view_of_shared (heavyweight_pointer heavyweight, View const & underlying)
    : heavyweight_ (std::move (heavyweight)), underlying_ (underlying) {}

    view_of_shared (heavyweight_pointer heavyweight, View && underlying)
    : heavyweight_ (std::move (heavyweight)),
        underlying_ (std::move (underlying)) {}

private:
    friend struct operation::view_shared_detail::make_view_of_shared;
    friend struct operation::view_shared_detail::get_heavyweight_pointer;

    heavyweight_pointer const & heavyweight() const { return heavyweight_; }
    heavyweight_pointer & heavyweight() { return heavyweight_; }

private:
    friend class operation::member_access;

    auto default_direction() const
    RETURNS (range::default_direction (underlying_));

    template <class Direction> typename
        result_of_or <range::callable::empty (
            Direction, underlying_type const &)
    >::type empty (Direction const & direction) const
    { return range::empty (direction, underlying_); }

    template <class Direction> typename
        result_of_or <range::callable::size (
            Direction, underlying_type const &)
    >::type size (Direction const & direction) const
    { return range::size (direction, underlying_); }

    template <class Direction> typename
        result_of_or <range::callable::chop_in_place (
            Direction, underlying_type &)
    >::type chop_in_place (Direction const & direction)
    { return range::chop_in_place (direction, underlying_); }
};

struct view_of_shared_tag;

template <class Heavyweight, class View>
    struct tag_of_qualified <view_of_shared <Heavyweight, View>>
{ typedef view_of_shared_tag type; };

namespace operation {

    namespace view_shared_detail {

        struct make_view_of_shared {
            template <class Heavyweight, class View>
                view_of_shared <Heavyweight, typename std::decay <View>::type>
                    operator() (std::shared_ptr <Heavyweight> heavyweight,
                        View && view) const
            {
                return view_of_shared <Heavyweight, View> (
                    std::move (heavyweight), std::forward <View> (view));
            }
        };

        struct get_heavyweight_pointer {
            template <class Range>
                typename Range::heavyweight_pointer && operator() (
                    Range && range) const
            { return std::move (range.heavyweight()); }

            template <class Range>
                typename Range::heavyweight_pointer const & operator() (
                    Range const & range) const
            { return range.heavyweight(); }
        };

    } // namespace view_shared_detail

    template <class Direction, class Range>
        struct first <view_of_shared_tag, Direction, Range, typename
            boost::enable_if <has <
                callable::first (Direction, typename underlying <Range>::type)
            >>::type>
    {
        auto operator() (Direction const & direction, Range && range) const
        RETURNS (range::first (direction, range::detail::get_underlying (
            std::forward <Range> (range))));
    };

    template <class Direction, class Increment, class Range>
        struct drop <view_of_shared_tag, Direction, Increment, Range, typename
            boost::enable_if <has <
                callable::drop (Direction, Increment,
                    typename underlying <Range>::type)
            >>::type>
    {
        auto operator() (Direction const & direction,
            Increment const & increment, Range && range) const
        RETURNS (view_shared_detail::make_view_of_shared() (
            view_shared_detail::get_heavyweight_pointer() (
                std::forward <Range> (range)),
            range::drop (direction, increment,
            range::detail::get_underlying (std::forward <Range> (range)))));
    };

    template <class Direction, class Range>
        struct chop <view_of_shared_tag, Direction, Range, typename
            boost::enable_if <has <
                callable::chop (Direction,
                    typename underlying <Range>::type)
            >>::type>
    {
        typedef typename result_of <callable::chop (Direction,
            typename underlying <Range>::type)>::type underlying_chopped_type;
        typedef typename underlying_chopped_type::first_type first_type;
        typedef typename underlying_chopped_type::rest_type
            underlying_rest_type;

        typedef typename std::decay <Range>::type::heavyweight_type
            heavyweight_type;

        typedef chopped <first_type,
                view_of_shared <heavyweight_type, underlying_rest_type>>
            result_type;

        result_type operator() (Direction const & direction, Range && range)
            const
        {
            auto underlying_chopped = range::chop (direction,
                range::detail::get_underlying (std::forward <Range> (range)));
            return result_type (underlying_chopped.move_first(),
                view_shared_detail::make_view_of_shared() (
                    view_shared_detail::get_heavyweight_pointer() (
                        std::forward <Range> (range)),
                    underlying_chopped.move_rest()));
        }
    };

} // namespace operation

namespace callable {

    struct view_shared {
    private:
        template <class MakeView, class Heavyweight, class Enable = void>
            struct make_view_if_range {};

        template <class MakeView, class Heavyweight>
            struct make_view_if_range <MakeView, Heavyweight, typename
                boost::enable_if <is_range <Heavyweight>>::type>
        : std::decay <typename std::result_of <MakeView (Heavyweight &)>::type>
        {};

    public:

        /* With MakeView. */

        template <class Heavyweight, class MakeView,
            class View = typename
                make_view_if_range <MakeView, Heavyweight>::type>
        view_of_shared <Heavyweight, View>
            operator() (std::shared_ptr <Heavyweight> heavyweight,
                MakeView const & make_view) const
        {
            Heavyweight & h = *heavyweight;
            return view_of_shared <Heavyweight, View> (
                std::move (heavyweight), make_view (h));
        }

        template <class Heavyweight, class MakeView,
            class View = typename
                make_view_if_range <MakeView, Heavyweight>::type>
        view_of_shared <typename std::decay <Heavyweight>::type, View>
            operator() (Heavyweight && heavyweight, MakeView const & make_view)
            const
        {
            auto heavyweight_pointer =
                std::make_shared <typename std::decay <Heavyweight>::type> (
                    std::forward <Heavyweight> (heavyweight));
            return operator() (std::move (heavyweight_pointer), make_view);
        }

        /* Without MakeView. */

        template <class Heavyweight, class Enable
            = typename boost::enable_if <is_range <Heavyweight>>::type>
        view_of_shared <Heavyweight>
            operator() (std::shared_ptr <Heavyweight> heavyweight) const
        { return operator() (std::move (heavyweight), range::view); }

        template <class Heavyweight, class Enable
            = typename boost::enable_if <is_range <Heavyweight>>::type>
        view_of_shared <typename std::decay <Heavyweight>::type>
            operator() (Heavyweight && heavyweight) const
        {
            return operator() (
                std::make_shared <typename std::decay <Heavyweight>::type> (
                    std::forward <Heavyweight> (heavyweight)));
        }

    };

} // namespace callable

/**
\brief Return a view on a heavyweight range whose lifetime is tied to the view.

Normally, the onus is on the user to make sure that the container, say, that a
view is on, remains in scope while the view is being used.
However, sometimes this is impossible or undesirable.
For example, returning a range of which the type is an implementation detail is
fraught with difficulty.

The solution is to force the range to stay in memory as long as the view or any
copy or derived view does.
That is what this function does, by keeping the range in a std::shared_ptr.

The optional second argument is a function to convert the range into a view.
This is a function, not the view itself, because the range usually first needs
to be copied into the shared_ptr, before a view of the copy can be produced.

\param heavyweight
    The heavyweight range that the view will be on.
    If this is a std::shared_ptr, a copy of it will be kept.
    If this is a range, then a copy of it will be kept in a shared_ptr.
\param make_view (optional)
    Function that returns the right sort of view of the range.
    If this is not given, \ref view is used.
    Other simple or complex functors are possible.
    For example, use \ref reverse to produce a reversed view of the range.
*/
static auto constexpr view_shared = callable::view_shared();

} // namespace range

#endif // RANGE_VIEW_SHARED_HPP_INCLUDED
<|endoftext|>