<commit_before>#include <vw/Plate/ToastDem.h>
#include <vw/Plate/PlateManager.h>
#include <vw/Plate/PlateFile.h>
#include <vw/Core.h>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <iostream>

using namespace std;
using namespace vw;
using namespace vw::platefile;

// There isn't much abstraction here. A Filter takes a platefile and writes a
// new platefile. This rules out lazy filters for the moment. The
// col/row/level/transaction_id is for the input value, the output can feel
// free to write things elsewhere.

// The function will be called for every input tile, including all transaction
// ids. The output function should feel no obligation to write a tile for every
// input.

template <typename ImplT>
struct FilterBase {
  inline ImplT& impl()             { return static_cast<ImplT&>(*this); }
  inline ImplT const& impl() const { return static_cast<ImplT const&>(*this); }

  inline void init(PlateFile& output, const PlateFile& input, int transaction_id) {
    return impl().init(output, input, transaction_id);
  }
  inline void fini(PlateFile& output, const PlateFile& input, int transaction_id) {
    return impl().fini(output, input, transaction_id);
  }

#   define lookup(name, type) type name(type data) const { return impl().name(data); }
    lookup(mode, string);
    lookup(tile_size, int);
    lookup(filetype, string);
    lookup(pixel_format, PixelFormatEnum);
    lookup(channel_type, ChannelTypeEnum);
#   undef lookup

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    impl()(output, input, col, row, level, transaction_id);
  }
};

struct Identity : public FilterBase<Identity> {
#   define lookup(name, type) type name(type data) const { return data; }
    lookup(mode, string);
    lookup(tile_size, int);
    lookup(filetype, string);
    lookup(pixel_format, PixelFormatEnum);
    lookup(channel_type, ChannelTypeEnum);
#   undef lookup

  inline void init(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) { output.write_request(); }
  inline void fini(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) { output.write_complete(); }

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    ImageView<PixelRGBA<double> > tile;
    TileHeader hdr = input.read(tile, col, row, level, transaction_id);
    output.write_update(tile, col, row, level, transaction_id);
  }
};

struct ToastDem : public FilterBase<ToastDem> {
  string mode(string) const { return "toast_dem"; }
  int tile_size(int)  const { return 32; }
  string filetype(string) const { return "toast_dem_v1"; }
  PixelFormatEnum pixel_format(PixelFormatEnum) const { return VW_PIXEL_SCALAR; }
  ChannelTypeEnum channel_type(ChannelTypeEnum) const { return VW_CHANNEL_UINT8; }

  inline void init(PlateFile& output, const PlateFile& input, int transaction_id) {
    output.write_request();

    // Write null tiles for the levels we don't have data for
    int level_difference = log(input.default_tile_size()/float(output.default_tile_size())) / log(2.) + 0.5;

    vw_out(InfoMessage, "plate.tools.plate2plate") << "Creating null tiles for a level difference of " << level_difference << std::endl;

    uint64 bytes;
    boost::shared_array<uint8> null_tile = toast_dem_null_tile(bytes);

    for (int level = 0; level < level_difference; ++level) {
      int region_size = 1 << level;
      for (int col = 0; col < region_size; ++col)
        for (int row = 0; row < region_size; ++row)
          output.write_update(null_tile, bytes, col, row, level, transaction_id);
    }
  }

  inline void fini(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) {
    output.write_complete();
  }

  struct DemWriter : public ToastDemWriter {
    PlateFile& platefile;
    DemWriter(PlateFile& output) : platefile(output) { }
    inline void operator()(const boost::shared_array<uint8> data, uint64 data_size, int32 dem_col, int32 dem_row, int32 dem_level, int32 transaction_id) const {
      platefile.write_update(data, data_size, dem_col, dem_row, dem_level, transaction_id);
    }
  };

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    DemWriter writer(output);
    make_toast_dem_tile(writer, input, col, row, level, transaction_id);
  }
};

struct Options {
  string input_name;
  string output_name;

  string mode;
  string description;
  int tile_size;
  string filetype;
  PixelFormatEnum pixel_format;
  ChannelTypeEnum channel_type;
  int bottom_level;

  string filter;

  Options() :
    tile_size(0), pixel_format(VW_PIXEL_UNKNOWN), channel_type(VW_CHANNEL_UNKNOWN) {}
};

VW_DEFINE_EXCEPTION(Usage, Exception);

void handle_arguments(int argc, char *argv[], Options& opt) {
  po::options_description options("Options");
  options.add_options()
    ("output-name,o",    po::value(&opt.output_name),  "Specify the URL of the input platefile.")
    ("input-name,i",     po::value(&opt.input_name),   "Specify the URL of the output platefile.")
    ("file-type",        po::value(&opt.filetype),     "Output file type")
    ("mode",             po::value(&opt.mode),         "Output mode [toast, kml]")
    ("tile-size",        po::value(&opt.tile_size),    "Output size, in pixels")
    ("filter",           po::value(&opt.filter),       "Filters to run")
    ("bottom-level",     po::value(&opt.bottom_level), "Bottom level to process")
    ("help,h",           "Display this help message.");

  po::variables_map vm;
  try {
    po::store( po::command_line_parser( argc, argv ).options(options).run(), vm );
    po::notify( vm );
  } catch (po::error &e) {
    vw_throw(Usage() << "Error parsing input:\n\t"
             << e.what() << "\n" << options );
  }

  if (opt.output_name.empty() || opt.input_name.empty() || opt.filter.empty())
    vw_throw(Usage() << options);
}

template <typename FilterT>
void run(Options& opt, FilterBase<FilterT>& filter) {
  PlateFile input(opt.input_name);

  // Use given option first, then use filter recommendation (it will probably
  // just recommend the value from the input platefile)

  if (opt.mode.empty())
    opt.mode = filter.mode(input.index_header().type());
  if (opt.tile_size == 0)
    opt.tile_size = filter.tile_size(input.default_tile_size());
  if (opt.filetype.empty())
    opt.filetype = filter.filetype(input.default_file_type());
  if (opt.pixel_format == VW_PIXEL_UNKNOWN)
    opt.pixel_format = filter.pixel_format(input.pixel_format());
  if (opt.channel_type == VW_CHANNEL_UNKNOWN)
    opt.channel_type = filter.channel_type(input.channel_type());

  PlateFile output(opt.output_name, opt.mode, opt.description, opt.tile_size, opt.filetype, opt.pixel_format, opt.channel_type);

  int transaction_id = output.transaction_request("plate2plate, reporting for duty", -1);

  filter.init(output, input, transaction_id);

  VW_ASSERT(input.num_levels() < 31, ArgumentErr() << "Can't handle plates deeper than 32 levels");

  int bottom_level = min(input.num_levels(), opt.bottom_level+1);

  for (int level = 0; level < bottom_level; ++level) {
    vw_out(InfoMessage) << "Processing level " << level << " of " << bottom_level-1 << std::endl;
    TerminalProgressCallback tpc("plate.plate2plate.progress", "");
    vw::Timer timer( "Processing time in seconds" );

    // The entire region contains 2^level tiles.
    int32 region_size = 1 << level;
    int subdivided_region_size = region_size / 32;
    if (subdivided_region_size < 1) subdivided_region_size = 1;

    double step = pow(subdivided_region_size/float(region_size),2.0);
    tpc.print_progress();

    BBox2i full_region(0,0,region_size,region_size);
    std::list<BBox2i> boxes1 = bbox_tiles(full_region,
                                          subdivided_region_size,
                                          subdivided_region_size);

    BOOST_FOREACH( const BBox2i& region1, boxes1 ) {
      std::list<TileHeader> tiles = input.search_by_region(level, region1, 0, std::numeric_limits<int>::max(), 1);
      BOOST_FOREACH( const TileHeader& tile, tiles ) {
        filter(output, input, tile.col(), tile.row(), tile.level(), transaction_id);
      }
      tpc.report_incremental_progress(step);
    }

    // for (int32 i = 0; i < region_size; ++i) {
    //   for (int32 j = 0; j < region_size; ++j) {
    //     std::list<TileHeader> tiles;
    //     try {
    //       tiles = input.search_by_location(i, j, level, 0, std::numeric_limits<int>::max());
    //     } catch (const TileNotFoundErr&) { continue; }

    //     BOOST_FOREACH(const TileHeader& tile, tiles)
    //       filter(output, input, tile.col(), tile.row(), tile.level(), transaction_id);
    //     tpc.report_incremental_progress(step);
    //   }
    // }
    tpc.report_finished();
    output.sync();
  }

  filter.fini(output, input, transaction_id);

  output.transaction_complete(transaction_id, true);
}

// Blah blah boilerplate
int main(int argc, char *argv[])
{
  Options opt;
  try {
    handle_arguments(argc, argv, opt);
    boost::to_lower(opt.filter);
    if (opt.filter == "identity") {
      Identity f;
      run(opt, f);
    } else if (opt.filter == "toast_dem") {
      ToastDem f;
      run(opt, f);
    }
  } catch (const Usage& e) {
    std::cout << e.what() << std::endl;
    return 1;
  } catch (const Exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }
  return 0;
}
<commit_msg>Pow call was ambiguous<commit_after>#include <vw/Plate/ToastDem.h>
#include <vw/Plate/PlateManager.h>
#include <vw/Plate/PlateFile.h>
#include <vw/Core.h>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <iostream>

using namespace std;
using namespace vw;
using namespace vw::platefile;

// There isn't much abstraction here. A Filter takes a platefile and writes a
// new platefile. This rules out lazy filters for the moment. The
// col/row/level/transaction_id is for the input value, the output can feel
// free to write things elsewhere.

// The function will be called for every input tile, including all transaction
// ids. The output function should feel no obligation to write a tile for every
// input.

template <typename ImplT>
struct FilterBase {
  inline ImplT& impl()             { return static_cast<ImplT&>(*this); }
  inline ImplT const& impl() const { return static_cast<ImplT const&>(*this); }

  inline void init(PlateFile& output, const PlateFile& input, int transaction_id) {
    return impl().init(output, input, transaction_id);
  }
  inline void fini(PlateFile& output, const PlateFile& input, int transaction_id) {
    return impl().fini(output, input, transaction_id);
  }

#   define lookup(name, type) type name(type data) const { return impl().name(data); }
    lookup(mode, string);
    lookup(tile_size, int);
    lookup(filetype, string);
    lookup(pixel_format, PixelFormatEnum);
    lookup(channel_type, ChannelTypeEnum);
#   undef lookup

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    impl()(output, input, col, row, level, transaction_id);
  }
};

struct Identity : public FilterBase<Identity> {
#   define lookup(name, type) type name(type data) const { return data; }
    lookup(mode, string);
    lookup(tile_size, int);
    lookup(filetype, string);
    lookup(pixel_format, PixelFormatEnum);
    lookup(channel_type, ChannelTypeEnum);
#   undef lookup

  inline void init(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) { output.write_request(); }
  inline void fini(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) { output.write_complete(); }

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    ImageView<PixelRGBA<double> > tile;
    TileHeader hdr = input.read(tile, col, row, level, transaction_id);
    output.write_update(tile, col, row, level, transaction_id);
  }
};

struct ToastDem : public FilterBase<ToastDem> {
  string mode(string) const { return "toast_dem"; }
  int tile_size(int)  const { return 32; }
  string filetype(string) const { return "toast_dem_v1"; }
  PixelFormatEnum pixel_format(PixelFormatEnum) const { return VW_PIXEL_SCALAR; }
  ChannelTypeEnum channel_type(ChannelTypeEnum) const { return VW_CHANNEL_UINT8; }

  inline void init(PlateFile& output, const PlateFile& input, int transaction_id) {
    output.write_request();

    // Write null tiles for the levels we don't have data for
    int level_difference = log(input.default_tile_size()/float(output.default_tile_size())) / log(2.) + 0.5;

    vw_out(InfoMessage, "plate.tools.plate2plate") << "Creating null tiles for a level difference of " << level_difference << std::endl;

    uint64 bytes;
    boost::shared_array<uint8> null_tile = toast_dem_null_tile(bytes);

    for (int level = 0; level < level_difference; ++level) {
      int region_size = 1 << level;
      for (int col = 0; col < region_size; ++col)
        for (int row = 0; row < region_size; ++row)
          output.write_update(null_tile, bytes, col, row, level, transaction_id);
    }
  }

  inline void fini(PlateFile& output, const PlateFile& /*input*/, int /*transaction_id*/) {
    output.write_complete();
  }

  struct DemWriter : public ToastDemWriter {
    PlateFile& platefile;
    DemWriter(PlateFile& output) : platefile(output) { }
    inline void operator()(const boost::shared_array<uint8> data, uint64 data_size, int32 dem_col, int32 dem_row, int32 dem_level, int32 transaction_id) const {
      platefile.write_update(data, data_size, dem_col, dem_row, dem_level, transaction_id);
    }
  };

  inline void operator()( PlateFile& output, const PlateFile& input, int32 col, int32 row, int32 level, int32 transaction_id) {
    DemWriter writer(output);
    make_toast_dem_tile(writer, input, col, row, level, transaction_id);
  }
};

struct Options {
  string input_name;
  string output_name;

  string mode;
  string description;
  int tile_size;
  string filetype;
  PixelFormatEnum pixel_format;
  ChannelTypeEnum channel_type;
  int bottom_level;

  string filter;

  Options() :
    tile_size(0), pixel_format(VW_PIXEL_UNKNOWN), channel_type(VW_CHANNEL_UNKNOWN) {}
};

VW_DEFINE_EXCEPTION(Usage, Exception);

void handle_arguments(int argc, char *argv[], Options& opt) {
  po::options_description options("Options");
  options.add_options()
    ("output-name,o",    po::value(&opt.output_name),  "Specify the URL of the input platefile.")
    ("input-name,i",     po::value(&opt.input_name),   "Specify the URL of the output platefile.")
    ("file-type",        po::value(&opt.filetype),     "Output file type")
    ("mode",             po::value(&opt.mode),         "Output mode [toast, kml]")
    ("tile-size",        po::value(&opt.tile_size),    "Output size, in pixels")
    ("filter",           po::value(&opt.filter),       "Filters to run")
    ("bottom-level",     po::value(&opt.bottom_level), "Bottom level to process")
    ("help,h",           "Display this help message.");

  po::variables_map vm;
  try {
    po::store( po::command_line_parser( argc, argv ).options(options).run(), vm );
    po::notify( vm );
  } catch (po::error &e) {
    vw_throw(Usage() << "Error parsing input:\n\t"
             << e.what() << "\n" << options );
  }

  if (opt.output_name.empty() || opt.input_name.empty() || opt.filter.empty())
    vw_throw(Usage() << options);
}

template <typename FilterT>
void run(Options& opt, FilterBase<FilterT>& filter) {
  PlateFile input(opt.input_name);

  // Use given option first, then use filter recommendation (it will probably
  // just recommend the value from the input platefile)

  if (opt.mode.empty())
    opt.mode = filter.mode(input.index_header().type());
  if (opt.tile_size == 0)
    opt.tile_size = filter.tile_size(input.default_tile_size());
  if (opt.filetype.empty())
    opt.filetype = filter.filetype(input.default_file_type());
  if (opt.pixel_format == VW_PIXEL_UNKNOWN)
    opt.pixel_format = filter.pixel_format(input.pixel_format());
  if (opt.channel_type == VW_CHANNEL_UNKNOWN)
    opt.channel_type = filter.channel_type(input.channel_type());

  PlateFile output(opt.output_name, opt.mode, opt.description, opt.tile_size, opt.filetype, opt.pixel_format, opt.channel_type);

  int transaction_id = output.transaction_request("plate2plate, reporting for duty", -1);

  filter.init(output, input, transaction_id);

  VW_ASSERT(input.num_levels() < 31, ArgumentErr() << "Can't handle plates deeper than 32 levels");

  int bottom_level = min(input.num_levels(), opt.bottom_level+1);

  for (int level = 0; level < bottom_level; ++level) {
    vw_out(InfoMessage) << "Processing level " << level << " of " << bottom_level-1 << std::endl;
    TerminalProgressCallback tpc("plate.plate2plate.progress", "");
    vw::Timer timer( "Processing time in seconds" );

    // The entire region contains 2^level tiles.
    int32 region_size = 1 << level;
    int subdivided_region_size = region_size / 32;
    if (subdivided_region_size < 1) subdivided_region_size = 1;

    double step = pow(subdivided_region_size/double(region_size),2.0);
    tpc.print_progress();

    BBox2i full_region(0,0,region_size,region_size);
    std::list<BBox2i> boxes1 = bbox_tiles(full_region,
                                          subdivided_region_size,
                                          subdivided_region_size);

    BOOST_FOREACH( const BBox2i& region1, boxes1 ) {
      std::list<TileHeader> tiles = input.search_by_region(level, region1, 0, std::numeric_limits<int>::max(), 1);
      BOOST_FOREACH( const TileHeader& tile, tiles ) {
        filter(output, input, tile.col(), tile.row(), tile.level(), transaction_id);
      }
      tpc.report_incremental_progress(step);
    }

    // for (int32 i = 0; i < region_size; ++i) {
    //   for (int32 j = 0; j < region_size; ++j) {
    //     std::list<TileHeader> tiles;
    //     try {
    //       tiles = input.search_by_location(i, j, level, 0, std::numeric_limits<int>::max());
    //     } catch (const TileNotFoundErr&) { continue; }

    //     BOOST_FOREACH(const TileHeader& tile, tiles)
    //       filter(output, input, tile.col(), tile.row(), tile.level(), transaction_id);
    //     tpc.report_incremental_progress(step);
    //   }
    // }
    tpc.report_finished();
    output.sync();
  }

  filter.fini(output, input, transaction_id);

  output.transaction_complete(transaction_id, true);
}

// Blah blah boilerplate
int main(int argc, char *argv[])
{
  Options opt;
  try {
    handle_arguments(argc, argv, opt);
    boost::to_lower(opt.filter);
    if (opt.filter == "identity") {
      Identity f;
      run(opt, f);
    } else if (opt.filter == "toast_dem") {
      ToastDem f;
      run(opt, f);
    }
  } catch (const Usage& e) {
    std::cout << e.what() << std::endl;
    return 1;
  } catch (const Exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }
  return 0;
}
<|endoftext|>


<commit_before>#include "UniformCompliance.inl"
#include <sofa/defaulttype/VecTypes.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{
namespace component
{
namespace forcefield
{

using namespace sofa::defaulttype;

// Register in the Factory
int UniformComplianceClass = core::RegisterObject("Uniform compliance")
#ifndef SOFA_FLOAT
        .add< UniformCompliance< Vec1dTypes > >(true)
        .add< UniformCompliance< Vec3dTypes > >()
        .add< UniformCompliance< Vec6dTypes > >()
#endif
#ifndef SOFA_DOUBLE
        .add< UniformCompliance< Vec1fTypes > >()
        .add< UniformCompliance< Vec3fTypes > >()
        .add< UniformCompliance< Vec6fTypes > >()
#endif
        ;

SOFA_DECL_CLASS(UniformCompliance)

#ifndef SOFA_FLOAT
template class SOFA_Compliant_API UniformCompliance<Vec1dTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec3dTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec6dTypes>;
#endif
#ifndef SOFA_DOUBLE
template class SOFA_Compliant_API UniformCompliance<Vec1fTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec3fTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec6fTypes>;
#endif

}
}
}
<commit_msg>Compliant: compiling UniformCompliance for Vec2<commit_after>#include "UniformCompliance.inl"
#include <sofa/defaulttype/VecTypes.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{
namespace component
{
namespace forcefield
{

using namespace sofa::defaulttype;

// Register in the Factory
int UniformComplianceClass = core::RegisterObject("Uniform compliance")
#ifndef SOFA_FLOAT
        .add< UniformCompliance< Vec1dTypes > >(true)
        .add< UniformCompliance< Vec2dTypes > >()
        .add< UniformCompliance< Vec3dTypes > >()
        .add< UniformCompliance< Vec6dTypes > >()
#endif
#ifndef SOFA_DOUBLE
        .add< UniformCompliance< Vec1fTypes > >()
        .add< UniformCompliance< Vec2fTypes > >()
        .add< UniformCompliance< Vec3fTypes > >()
        .add< UniformCompliance< Vec6fTypes > >()
#endif
        ;

SOFA_DECL_CLASS(UniformCompliance)

#ifndef SOFA_FLOAT
template class SOFA_Compliant_API UniformCompliance<Vec1dTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec2dTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec3dTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec6dTypes>;
#endif
#ifndef SOFA_DOUBLE
template class SOFA_Compliant_API UniformCompliance<Vec1fTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec2fTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec3fTypes>;
template class SOFA_Compliant_API UniformCompliance<Vec6fTypes>;
#endif

}
}
}
<|endoftext|>


<commit_before>/*
 * fiberrenderer.cpp
 *
 * Created on: 28.12.2012
 * @author Ralph Schurade
 */
#include "fiberrenderer.h"
#include "fiberrendererthread.h"

#include "glfunctions.h"

#include "../../data/enums.h"
#include "../../data/models.h"
#include "../../data/datasets/fiberselector.h"

#include "../../data/properties/propertygroup.h"

#include <QtOpenGL/QGLShaderProgram>
#include <QDebug>

FiberRenderer::FiberRenderer( FiberSelector* selector, QVector< QVector< float > >* data, QVector< QVector< float > >* extraData, int numPoints )  :
    ObjectRenderer(),
    m_selector( selector ),
    vbo( 0 ),
    dataVbo( 0 ),
    m_data( data ),
    m_extraData( extraData ),
    m_numLines( data->size() ),
    m_numPoints( numPoints ),
    m_isInitialized( false )
{
    m_colorField.resize( m_numLines );
}

FiberRenderer::~FiberRenderer()
{
    glDeleteBuffers( 1, &vbo );
    glDeleteBuffers( 1, &dataVbo );
    glDeleteBuffers( 1, &indexVbo );
}

void FiberRenderer::init()
{
    glGenBuffers( 1, &vbo );
    glGenBuffers( 1, &dataVbo );
    glGenBuffers( 1, &indexVbo );
}

void FiberRenderer::draw( QMatrix4x4 p_matrix, QMatrix4x4 mv_matrix, int width, int height, int renderMode, PropertyGroup* props )
{
    float alpha = props->get( Fn::Property::D_ALPHA ).toFloat();
    if ( renderMode == 0 ) // picking
    {
        return;
    }
    else if ( renderMode == 1 ) // we are drawing opaque objects
    {
        if ( alpha < 1.0 )
        {
            // obviously not opaque
            return;
        }
    }
    else // we are drawing tranparent objects
    {
        if ( !(alpha < 1.0 ) )
        {
            // not transparent
            return;
        }
    }

    QGLShaderProgram* program = GLFunctions::getShader( "fiber" );
    program->bind();

    GLFunctions::setupTextures();
    GLFunctions::setTextureUniforms( GLFunctions::getShader( "fiber" ), "maingl" );

    // Set modelview-projection matrix
    program->setUniformValue( "mvp_matrix", p_matrix * mv_matrix );
    program->setUniformValue( "mv_matrixInvert", mv_matrix.inverted() );

    initGeometry();

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    setShaderVars( props );

    glBindBuffer( GL_ARRAY_BUFFER, dataVbo );
    int extraLocation = program->attributeLocation( "a_extra" );
    program->enableAttributeArray( extraLocation );
    glVertexAttribPointer( extraLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 );

    glBindBuffer( GL_ARRAY_BUFFER, indexVbo );
    int indexLocation = program->attributeLocation( "a_indexes" );
    program->enableAttributeArray( indexLocation );
    glVertexAttribPointer( indexLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 );

    program->setUniformValue( "u_alpha", alpha );
    program->setUniformValue( "u_renderMode", renderMode );
    program->setUniformValue( "u_canvasSize", width, height );
    program->setUniformValue( "D0", 9 );
    program->setUniformValue( "D1", 10 );
    program->setUniformValue( "D2", 11 );
    program->setUniformValue( "P0", 12 );
    program->setUniformValue( "C5", 13 );
    program->setUniformValue( "u_fibGrowth", props->get( Fn::Property::D_FIBER_GROW_LENGTH).toFloat() );

    program->setUniformValue( "u_lighting", props->get( Fn::Property::D_LIGHT_SWITCH ).toBool() );
    program->setUniformValue( "u_lightAmbient", props->get( Fn::Property::D_LIGHT_AMBIENT ).toFloat() );
    program->setUniformValue( "u_lightDiffuse", props->get( Fn::Property::D_LIGHT_DIFFUSE ).toFloat() );
    program->setUniformValue( "u_materialAmbient", props->get( Fn::Property::D_MATERIAL_AMBIENT ).toFloat() );
    program->setUniformValue( "u_materialDiffuse", props->get( Fn::Property::D_MATERIAL_DIFFUSE ).toFloat() );
    program->setUniformValue( "u_materialSpecular", props->get( Fn::Property::D_MATERIAL_SPECULAR ).toFloat() );
    program->setUniformValue( "u_materialShininess", props->get( Fn::Property::D_MATERIAL_SHININESS ).toFloat() );

    glLineWidth( props->get( Fn::Property::D_FIBER_THICKNESS ).toFloat() );

    QVector<bool>*selected = m_selector->getSelection();

    for ( int i = 0; i < m_data->size(); ++i )
    {
        if ( selected->at( i ) )
        {
            program->setUniformValue( "u_color", m_colorField[i].redF(),
                                                   m_colorField[i].greenF(),
                                                   m_colorField[i].blueF(), 1.0 );
            program->setUniformValue( "u_globalColor", m_globalColors[i].x(),
                                                         m_globalColors[i].y(),
                                                         m_globalColors[i].z(), 1.0 );
            glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] );
        }
    }

    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

void FiberRenderer::setupTextures()
{
}

void FiberRenderer::setShaderVars( PropertyGroup* props )
{
    QGLShaderProgram* program = GLFunctions::getShader( "fiber" );

    program->bind();

    intptr_t offset = 0;
    // Tell OpenGL programmable pipeline how to locate vertex position data
    int numFloats = 6;

    int vertexLocation = program->attributeLocation( "a_position" );
    program->enableAttributeArray( vertexLocation );
    glVertexAttribPointer( vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float) * numFloats, (const void *) offset );
    offset += sizeof(float) * 3;

    int normalLocation = program->attributeLocation( "a_normal" );
    program->enableAttributeArray( normalLocation );
    glVertexAttribPointer( normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float) * numFloats, (const void *) offset );
    offset += sizeof(float) * 3;

    program->setUniformValue( "u_colorMode", props->get( Fn::Property::D_COLORMODE ).toInt() );
    program->setUniformValue( "u_colormap", props->get( Fn::Property::D_COLORMAP ).toInt() );
    program->setUniformValue( "u_color", 1.0, 0.0, 0.0, 1.0 );
    program->setUniformValue( "u_selectedMin", props->get( Fn::Property::D_SELECTED_MIN ).toFloat() );
    program->setUniformValue( "u_selectedMax", props->get( Fn::Property::D_SELECTED_MAX ).toFloat() );
    program->setUniformValue( "u_lowerThreshold", props->get( Fn::Property::D_LOWER_THRESHOLD ).toFloat() );
    program->setUniformValue( "u_upperThreshold", props->get( Fn::Property::D_UPPER_THRESHOLD ).toFloat() );
    program->setUniformValue( "u_dx", props->get( Fn::Property::D_DX ).toFloat() );
    program->setUniformValue( "u_dy", props->get( Fn::Property::D_DY ).toFloat() );
    program->setUniformValue( "u_dz", props->get( Fn::Property::D_DZ ).toFloat() );
    program->setUniformValue( "u_x", props->get( Fn::Property::D_NX ).toFloat() / 10.f );
    program->setUniformValue( "u_y", props->get( Fn::Property::D_NY ).toFloat() / 10.f );
    program->setUniformValue( "u_z", props->get( Fn::Property::D_NZ ).toFloat() / 10.f );
}

void FiberRenderer::initGeometry()
{
    if ( m_isInitialized )
    {
        return;
    }
    qDebug() << "create fiber vbo's...";

    std::vector<float>verts;

    try
    {
        verts.reserve( m_numPoints * 6 );
        m_globalColors.reserve( m_numLines * 3 );
    }
    catch ( std::bad_alloc& )
    {
        qDebug() << "***error*** failed to allocate enough memory for vbo";
        exit ( 0 );
    }

    for ( int i = 0; i < m_data->size(); ++i )
    {
        QVector<float> fib = m_data->at(i);

        if ( fib.size() < 6 )
        {
            printf( "fib with size < 2 detected" );
            continue;
        }

        int numFloats = fib.size();
        QVector3D lineStart( fib[0], fib[1], fib[2] );
        QVector3D lineEnd( fib[numFloats-3], fib[numFloats-2], fib[numFloats-1] );

        QVector3D gc( fabs( lineStart.x() - lineEnd.x() ), fabs( lineStart.y() - lineEnd.y() ), fabs( lineStart.z() - lineEnd.z() ) );
        gc.normalize();
        m_globalColors.push_back( gc );

        // push back the first vertex, done seperately because of nomal calculation
        verts.push_back( fib[0] );
        verts.push_back( fib[1] );
        verts.push_back( fib[2] );

        QVector3D localColor( fabs( fib[0] - fib[3] ), fabs( fib[1] - fib[4] ), fabs( fib[2] - fib[5] ) );
        localColor.normalize();

        verts.push_back( localColor.x() );
        verts.push_back( localColor.y() );
        verts.push_back( localColor.z() );

        for ( int k = 1; k < fib.size() / 3 - 1; ++k )
        {
            verts.push_back( fib[k*3] );
            verts.push_back( fib[k*3+1] );
            verts.push_back( fib[k*3+2] );

            QVector3D localColor( fabs( fib[k*3-3] - fib[k*3+3] ), fabs( fib[k*3-2] - fib[k*3+4] ), fabs( fib[k*3-1] - fib[k*3+5] ) );
            localColor.normalize();

            verts.push_back( localColor.x() );
            verts.push_back( localColor.y() );
            verts.push_back( localColor.z() );

        }

        // push back the last vertex, done seperately because of nomal calculation
        verts.push_back( fib[numFloats-3] );
        verts.push_back( fib[numFloats-2] );
        verts.push_back( fib[numFloats-1] );

        QVector3D localColor2( fabs( fib[numFloats-6] - fib[numFloats-3] ), fabs( fib[numFloats-5] - fib[numFloats-2] ), fabs( fib[numFloats-4] - fib[numFloats-1] ) );
        localColor.normalize();

        verts.push_back( localColor2.x() );
        verts.push_back( localColor2.y() );
        verts.push_back( localColor2.z() );
    }

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof(GLfloat), verts.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    verts.clear();
    //verts.squeeze();

    m_pointsPerLine.resize( m_data->size() );
    m_startIndexes.resize( m_data->size() );

    int currentStart = 0;
    for ( int i = 0; i < m_data->size(); ++i )
    {
        m_pointsPerLine[i] = m_data->at( i ).size() / 3;
        m_startIndexes[i] = currentStart;
        currentStart += m_pointsPerLine[i];
    }

    updateExtraData( m_extraData );

    qDebug() << "create fiber vbo's done";

    m_numPoints = verts.size() / 6;

    m_isInitialized = true;
}

void FiberRenderer::colorChanged( QVariant color )
{
    QVector<bool>*selected = m_selector->getSelection();
    for ( int i = 0; i < m_numLines; ++i )
    {
        if ( selected->at( i ) )
        {
            m_colorField.replace( i, color.value<QColor>() );
        }
    }
}

void FiberRenderer::updateExtraData( QVector< QVector< float > >* extraData )
{
    m_extraData = extraData;
    QVector<float>data;
    QVector<float>indexes;
    for ( int i = 0; i < extraData->size(); ++i )
    {
        QVector<float>fib = extraData->at(i);
        for ( int k = 0; k < fib.size(); ++k )
        {
            data.push_back( fib[k] );
            indexes.push_back( k );
        }
    }

    glDeleteBuffers( 1, &dataVbo );
    glGenBuffers( 1, &dataVbo );

    glDeleteBuffers( 1, &indexVbo );
    glGenBuffers( 1, &indexVbo );

    glBindBuffer( GL_ARRAY_BUFFER, dataVbo );
    glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );

    glBindBuffer( GL_ARRAY_BUFFER, indexVbo );
    glBufferData( GL_ARRAY_BUFFER, indexes.size() * sizeof(GLfloat), indexes.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );

}
<commit_msg>added include for mac compile<commit_after>/*
 * fiberrenderer.cpp
 *
 * Created on: 28.12.2012
 * @author Ralph Schurade
 */
#include "fiberrenderer.h"
#include "fiberrendererthread.h"

#include "glfunctions.h"

#include "../../data/enums.h"
#include "../../data/models.h"
#include "../../data/datasets/fiberselector.h"

#include "../../data/properties/propertygroup.h"

#include <QtOpenGL/QGLShaderProgram>
#include <QDebug>

#include "math.h"

FiberRenderer::FiberRenderer( FiberSelector* selector, QVector< QVector< float > >* data, QVector< QVector< float > >* extraData, int numPoints )  :
    ObjectRenderer(),
    m_selector( selector ),
    vbo( 0 ),
    dataVbo( 0 ),
    m_data( data ),
    m_extraData( extraData ),
    m_numLines( data->size() ),
    m_numPoints( numPoints ),
    m_isInitialized( false )
{
    m_colorField.resize( m_numLines );
}

FiberRenderer::~FiberRenderer()
{
    glDeleteBuffers( 1, &vbo );
    glDeleteBuffers( 1, &dataVbo );
    glDeleteBuffers( 1, &indexVbo );
}

void FiberRenderer::init()
{
    glGenBuffers( 1, &vbo );
    glGenBuffers( 1, &dataVbo );
    glGenBuffers( 1, &indexVbo );
}

void FiberRenderer::draw( QMatrix4x4 p_matrix, QMatrix4x4 mv_matrix, int width, int height, int renderMode, PropertyGroup* props )
{
    float alpha = props->get( Fn::Property::D_ALPHA ).toFloat();
    if ( renderMode == 0 ) // picking
    {
        return;
    }
    else if ( renderMode == 1 ) // we are drawing opaque objects
    {
        if ( alpha < 1.0 )
        {
            // obviously not opaque
            return;
        }
    }
    else // we are drawing tranparent objects
    {
        if ( !(alpha < 1.0 ) )
        {
            // not transparent
            return;
        }
    }

    QGLShaderProgram* program = GLFunctions::getShader( "fiber" );
    program->bind();

    GLFunctions::setupTextures();
    GLFunctions::setTextureUniforms( GLFunctions::getShader( "fiber" ), "maingl" );

    // Set modelview-projection matrix
    program->setUniformValue( "mvp_matrix", p_matrix * mv_matrix );
    program->setUniformValue( "mv_matrixInvert", mv_matrix.inverted() );

    initGeometry();

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    setShaderVars( props );

    glBindBuffer( GL_ARRAY_BUFFER, dataVbo );
    int extraLocation = program->attributeLocation( "a_extra" );
    program->enableAttributeArray( extraLocation );
    glVertexAttribPointer( extraLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 );

    glBindBuffer( GL_ARRAY_BUFFER, indexVbo );
    int indexLocation = program->attributeLocation( "a_indexes" );
    program->enableAttributeArray( indexLocation );
    glVertexAttribPointer( indexLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 );

    program->setUniformValue( "u_alpha", alpha );
    program->setUniformValue( "u_renderMode", renderMode );
    program->setUniformValue( "u_canvasSize", width, height );
    program->setUniformValue( "D0", 9 );
    program->setUniformValue( "D1", 10 );
    program->setUniformValue( "D2", 11 );
    program->setUniformValue( "P0", 12 );
    program->setUniformValue( "C5", 13 );
    program->setUniformValue( "u_fibGrowth", props->get( Fn::Property::D_FIBER_GROW_LENGTH).toFloat() );

    program->setUniformValue( "u_lighting", props->get( Fn::Property::D_LIGHT_SWITCH ).toBool() );
    program->setUniformValue( "u_lightAmbient", props->get( Fn::Property::D_LIGHT_AMBIENT ).toFloat() );
    program->setUniformValue( "u_lightDiffuse", props->get( Fn::Property::D_LIGHT_DIFFUSE ).toFloat() );
    program->setUniformValue( "u_materialAmbient", props->get( Fn::Property::D_MATERIAL_AMBIENT ).toFloat() );
    program->setUniformValue( "u_materialDiffuse", props->get( Fn::Property::D_MATERIAL_DIFFUSE ).toFloat() );
    program->setUniformValue( "u_materialSpecular", props->get( Fn::Property::D_MATERIAL_SPECULAR ).toFloat() );
    program->setUniformValue( "u_materialShininess", props->get( Fn::Property::D_MATERIAL_SHININESS ).toFloat() );

    glLineWidth( props->get( Fn::Property::D_FIBER_THICKNESS ).toFloat() );

    QVector<bool>*selected = m_selector->getSelection();

    for ( int i = 0; i < m_data->size(); ++i )
    {
        if ( selected->at( i ) )
        {
            program->setUniformValue( "u_color", m_colorField[i].redF(),
                                                   m_colorField[i].greenF(),
                                                   m_colorField[i].blueF(), 1.0 );
            program->setUniformValue( "u_globalColor", m_globalColors[i].x(),
                                                         m_globalColors[i].y(),
                                                         m_globalColors[i].z(), 1.0 );
            glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] );
        }
    }

    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

void FiberRenderer::setupTextures()
{
}

void FiberRenderer::setShaderVars( PropertyGroup* props )
{
    QGLShaderProgram* program = GLFunctions::getShader( "fiber" );

    program->bind();

    intptr_t offset = 0;
    // Tell OpenGL programmable pipeline how to locate vertex position data
    int numFloats = 6;

    int vertexLocation = program->attributeLocation( "a_position" );
    program->enableAttributeArray( vertexLocation );
    glVertexAttribPointer( vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float) * numFloats, (const void *) offset );
    offset += sizeof(float) * 3;

    int normalLocation = program->attributeLocation( "a_normal" );
    program->enableAttributeArray( normalLocation );
    glVertexAttribPointer( normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float) * numFloats, (const void *) offset );
    offset += sizeof(float) * 3;

    program->setUniformValue( "u_colorMode", props->get( Fn::Property::D_COLORMODE ).toInt() );
    program->setUniformValue( "u_colormap", props->get( Fn::Property::D_COLORMAP ).toInt() );
    program->setUniformValue( "u_color", 1.0, 0.0, 0.0, 1.0 );
    program->setUniformValue( "u_selectedMin", props->get( Fn::Property::D_SELECTED_MIN ).toFloat() );
    program->setUniformValue( "u_selectedMax", props->get( Fn::Property::D_SELECTED_MAX ).toFloat() );
    program->setUniformValue( "u_lowerThreshold", props->get( Fn::Property::D_LOWER_THRESHOLD ).toFloat() );
    program->setUniformValue( "u_upperThreshold", props->get( Fn::Property::D_UPPER_THRESHOLD ).toFloat() );
    program->setUniformValue( "u_dx", props->get( Fn::Property::D_DX ).toFloat() );
    program->setUniformValue( "u_dy", props->get( Fn::Property::D_DY ).toFloat() );
    program->setUniformValue( "u_dz", props->get( Fn::Property::D_DZ ).toFloat() );
    program->setUniformValue( "u_x", props->get( Fn::Property::D_NX ).toFloat() / 10.f );
    program->setUniformValue( "u_y", props->get( Fn::Property::D_NY ).toFloat() / 10.f );
    program->setUniformValue( "u_z", props->get( Fn::Property::D_NZ ).toFloat() / 10.f );
}

void FiberRenderer::initGeometry()
{
    if ( m_isInitialized )
    {
        return;
    }
    qDebug() << "create fiber vbo's...";

    std::vector<float>verts;

    try
    {
        verts.reserve( m_numPoints * 6 );
        m_globalColors.reserve( m_numLines * 3 );
    }
    catch ( std::bad_alloc& )
    {
        qDebug() << "***error*** failed to allocate enough memory for vbo";
        exit ( 0 );
    }

    for ( int i = 0; i < m_data->size(); ++i )
    {
        QVector<float> fib = m_data->at(i);

        if ( fib.size() < 6 )
        {
            printf( "fib with size < 2 detected" );
            continue;
        }

        int numFloats = fib.size();
        QVector3D lineStart( fib[0], fib[1], fib[2] );
        QVector3D lineEnd( fib[numFloats-3], fib[numFloats-2], fib[numFloats-1] );

        QVector3D gc( fabs( lineStart.x() - lineEnd.x() ), fabs( lineStart.y() - lineEnd.y() ), fabs( lineStart.z() - lineEnd.z() ) );
        gc.normalize();
        m_globalColors.push_back( gc );

        // push back the first vertex, done seperately because of nomal calculation
        verts.push_back( fib[0] );
        verts.push_back( fib[1] );
        verts.push_back( fib[2] );

        QVector3D localColor( fabs( fib[0] - fib[3] ), fabs( fib[1] - fib[4] ), fabs( fib[2] - fib[5] ) );
        localColor.normalize();

        verts.push_back( localColor.x() );
        verts.push_back( localColor.y() );
        verts.push_back( localColor.z() );

        for ( int k = 1; k < fib.size() / 3 - 1; ++k )
        {
            verts.push_back( fib[k*3] );
            verts.push_back( fib[k*3+1] );
            verts.push_back( fib[k*3+2] );

            QVector3D localColor( fabs( fib[k*3-3] - fib[k*3+3] ), fabs( fib[k*3-2] - fib[k*3+4] ), fabs( fib[k*3-1] - fib[k*3+5] ) );
            localColor.normalize();

            verts.push_back( localColor.x() );
            verts.push_back( localColor.y() );
            verts.push_back( localColor.z() );

        }

        // push back the last vertex, done seperately because of nomal calculation
        verts.push_back( fib[numFloats-3] );
        verts.push_back( fib[numFloats-2] );
        verts.push_back( fib[numFloats-1] );

        QVector3D localColor2( fabs( fib[numFloats-6] - fib[numFloats-3] ), fabs( fib[numFloats-5] - fib[numFloats-2] ), fabs( fib[numFloats-4] - fib[numFloats-1] ) );
        localColor.normalize();

        verts.push_back( localColor2.x() );
        verts.push_back( localColor2.y() );
        verts.push_back( localColor2.z() );
    }

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof(GLfloat), verts.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    verts.clear();
    //verts.squeeze();

    m_pointsPerLine.resize( m_data->size() );
    m_startIndexes.resize( m_data->size() );

    int currentStart = 0;
    for ( int i = 0; i < m_data->size(); ++i )
    {
        m_pointsPerLine[i] = m_data->at( i ).size() / 3;
        m_startIndexes[i] = currentStart;
        currentStart += m_pointsPerLine[i];
    }

    updateExtraData( m_extraData );

    qDebug() << "create fiber vbo's done";

    m_numPoints = verts.size() / 6;

    m_isInitialized = true;
}

void FiberRenderer::colorChanged( QVariant color )
{
    QVector<bool>*selected = m_selector->getSelection();
    for ( int i = 0; i < m_numLines; ++i )
    {
        if ( selected->at( i ) )
        {
            m_colorField.replace( i, color.value<QColor>() );
        }
    }
}

void FiberRenderer::updateExtraData( QVector< QVector< float > >* extraData )
{
    m_extraData = extraData;
    QVector<float>data;
    QVector<float>indexes;
    for ( int i = 0; i < extraData->size(); ++i )
    {
        QVector<float>fib = extraData->at(i);
        for ( int k = 0; k < fib.size(); ++k )
        {
            data.push_back( fib[k] );
            indexes.push_back( k );
        }
    }

    glDeleteBuffers( 1, &dataVbo );
    glGenBuffers( 1, &dataVbo );

    glDeleteBuffers( 1, &indexVbo );
    glGenBuffers( 1, &indexVbo );

    glBindBuffer( GL_ARRAY_BUFFER, dataVbo );
    glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );

    glBindBuffer( GL_ARRAY_BUFFER, indexVbo );
    glBufferData( GL_ARRAY_BUFFER, indexes.size() * sizeof(GLfloat), indexes.data(), GL_STATIC_DRAW );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );

}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-5-25 21:27:40
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int Q;
char c;
ll a, b;
ll A = 0;
ll B = 0;
ll cnt_l = 0;
ll cnt_r = 0;
ll lower = -1000000000000LL;
priority_queue<ll> L;
priority_queue<ll, vector<ll>, greater<ll>> R;

void merge()
{
  ll x = L.top();
  ll y = R.top();
  if (a <= x)
  {
    L.push(a);
  }
  else if (a >= y)
  {
    R.push(a);
  }
  else
  {
    L.push(a);
  }
  while (L.size() > R.size())
  {
    ll t = L.top();
    L.pop();
    R.push(t);
  }
  while (L.size() < R.size())
  {
    ll t = R.top();
    R.pop();
    L.push(t);
  }
  B += b;
  if (a < 0)
  {
    cnt_l++;
    A += abs(a);
  }
  else
  {
    cnt_r++;
    A += abs(a);
  }
}

void flush()
{
  ll val = L.top();
  ll ans = A + B;
  ll dist = abs(val);
  ll c = (abs(cnt_l - cnt_r) + 1) / 2;
  ans -= dist * c;
  cout << val << " " << ans << endl;
}

int main()
{
  cin >> Q;
  L.push(-1000000000000LL);
  R.push(1000000000000LL);
  for (auto i = 0; i < Q; i++)
  {
    cin >> c;
    if (c == '1')
    {
      cin >> a >> b;
      merge();
    }
    else
    {
      flush();
    }
  }
}<commit_msg>submit F.cpp to 'F - Absolute Minima' (abc127) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1

/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-5-25 21:27:40
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int Q;
char c;
ll a, b;
ll A = 0;
ll B = 0;
ll cnt_l = 0;
ll cnt_r = 0;
ll lower = -1000000000000LL;
priority_queue<ll> L;
priority_queue<ll, vector<ll>, greater<ll>> R;

void merge()
{
  ll x = L.top();
  ll y = R.top();
  if (a <= x)
  {
    L.push(a);
  }
  else if (a >= y)
  {
    R.push(a);
  }
  else
  {
    L.push(a);
  }
  while (L.size() > R.size())
  {
    ll t = L.top();
    L.pop();
    R.push(t);
  }
  while (L.size() < R.size())
  {
    ll t = R.top();
    R.pop();
    L.push(t);
  }
  B += b;
  if (a < 0)
  {
    cnt_l++;
    A += abs(a);
  }
  else
  {
    cnt_r++;
    A += abs(a);
  }
}

void flush()
{
  ll val = L.top();
  ll ans = A + B;
  ll dist = abs(val);
  ll c = abs(cnt_l - cnt_r);
  ans -= dist * c;
  cout << val << " " << ans << endl;
}

int main()
{
  cin >> Q;
  L.push(-1000000000000LL);
  R.push(1000000000000LL);
  for (auto i = 0; i < Q; i++)
  {
    cin >> c;
    if (c == '1')
    {
      cin >> a >> b;
      merge();
    }
    else
    {
      flush();
    }
  }
}<|endoftext|>


<commit_before>#include <convert.hpp>
#include <errors.hpp>
#include <debug.hpp>

#include <ingridientWindow.hpp>
#include "ui_ingridientWindow.h"

IngridientWindow::IngridientWindow(QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()} {

    setupMeasureList();
    ui->lineEdit_2->setDisabled(true);

    PRINT_OBJ("IngridientWindow created");
}

IngridientWindow::IngridientWindow(Item* item, QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()},
    editMode {true},
    editedItem {item} {

    setupMeasureList();
    applyItemStats(item);
    this->setWindowTitle("Edit item");

    PRINT_OBJ("Existed item edit window created");
}

IngridientWindow::IngridientWindow(Food* food, QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()},
    editMode {true},
    editedItem {food} {

    setupMeasureList();
    applyFoodStats(food);
    this->setWindowTitle("Edit food");

    PRINT_OBJ("Existed food edit window created");
}

IngridientWindow::~IngridientWindow() {
    delete ui;

    PRINT_OBJ("IngridientWindow destroyed");
}

void IngridientWindow::on_buttonBox_1_accepted() {
    if ( editMode ) {
        if ( ui->radioButton_1->isChecked() ) {
            editFood(dynamic_cast<Food*>(editedItem));
        } else if ( ui->radioButton_2->isChecked() ) {
            editItem(editedItem);
        }
    } else {
        if ( ui->radioButton_1->isChecked() ) {
            emit foodObjectReady(createNewFood());
        } else if ( ui->radioButton_2->isChecked() ) {
            emit itemObjectReady(createNewItem());
        }
    }

    this->hide();

    PRINT_DEBUG("New item/food accepted");
}

void IngridientWindow::on_buttonBox_1_rejected() {
    this->hide();

    PRINT_DEBUG("New item/food rejected");
}

void IngridientWindow::setupMeasureList(void) {
    const std::string* names = Item::getItemMeasureTypeNamesList();

    ui->setupUi(this);

    for ( int i = 0; !names[i].empty(); i++ ) {
        measureList.append(QString::fromStdString(names[i]));
    }

    ui->comboBox_1->addItems(measureList);
}

void IngridientWindow::applyItemStats(Item* item) {
    ui->lineEdit_1->setText(QString::fromStdString(item->getName()));
    ui->lineEdit_1->setDisabled(true);
    ui->comboBox_1->setCurrentIndex(static_cast<int>(item->getUnitType()));
    if ( item->getUnitType() != Item::KGRAM ) {
        ui->lineEdit_2->setText(massToQString(item->getMass()));
    } else {
        ui->lineEdit_2->setDisabled(true);
    }
    ui->lineEdit_4->setText(priceToQString(item->getPrice()));

    on_radioButton_2_clicked();
    ui->radioButton_2->setChecked(true);
    ui->radioButton_1->setDisabled(true);

    PRINT_DEBUG("All items stats are applied");
}

void IngridientWindow::applyFoodStats(Food* food) {
    ui->lineEdit_1->setText(QString::fromStdString(food->getName()));
    ui->lineEdit_1->setDisabled(true);
    ui->comboBox_1->setCurrentIndex(static_cast<int>(food->getUnitType()));
    if ( food->getUnitType() != Item::KGRAM ) {
        ui->lineEdit_2->setText(massToQString(food->getMass()));
    } else {
        ui->lineEdit_2->setDisabled(true);
    }
    ui->lineEdit_4->setText(priceToQString(food->getPrice()));
    ui->lineEdit_3->setText(fatsToQString(food->getFats()));
    ui->lineEdit_5->setText(proteinsToQString(food->getProteins()));
    ui->lineEdit_6->setText(carbohydratesToQString(food->getCarbohydrates()));
    ui->lineEdit_7->setText(caloriesToQString(food->getCalories()));

    ui->radioButton_1->setChecked(true);
    ui->radioButton_2->setDisabled(true);

    PRINT_DEBUG("All food stats are applied");
}

Item* IngridientWindow::createNewItem(void) {
    PRINT_DEBUG("Creating new item");

    QString name = ui->lineEdit_1->text();
    QString mass = ui->lineEdit_2->text();
    QString price = ui->lineEdit_4->text();

    if ( name.isEmpty() ) {
        PRINT_ERR("Ingridient name could not be empty");

        throw EmptyIngridientNameException();
    }

    if ( mass.isEmpty() ) {
        PRINT_ERR("Ingridient mass could not be empty");

        throw EmptyIngridientMassException();
    }

    if ( price.isEmpty() ) {
        PRINT_ERR("Ingridient price could not be empty");

        throw EmptyIngridientPriceException();
    }

    return new Item(name.toStdString(), (!ui->comboBox_1->currentText().toStdString().compare("kg") ? 1 : QStringToMass(mass)),
                    QStringToPrice(price), static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()));
}

Food* IngridientWindow::createNewFood(void) {
    bool isKg = !ui->comboBox_1->currentText().toStdString().compare("kg");

    PRINT_DEBUG("Creating new food");

    QString name = ui->lineEdit_1->text();
    QString mass = ui->lineEdit_2->text();
    QString price = ui->lineEdit_4->text();
    QString fats = ui->lineEdit_3->text();
    QString proteins = ui->lineEdit_5->text();
    QString carbohydrates = ui->lineEdit_6->text();
    QString calories = ui->lineEdit_7->text();

    if ( name.isEmpty() ) {
        PRINT_ERR("Food name could not be empty");

        throw EmptyIngridientNameException();
    }

    if ( mass.isEmpty() && !isKg ) {
        PRINT_ERR("Food mass could not be empty");

        throw EmptyIngridientMassException();
    }

    if ( price.isEmpty() ) {
        PRINT_ERR("Food price could not be empty");

        throw EmptyIngridientPriceException();
    }

    if ( fats.isEmpty() ) {
        PRINT_ERR("Food fats could not be empty");

        throw EmptyIngridientFatsException();
    }

    if ( proteins.isEmpty() ) {
        PRINT_ERR("Food proteins could not be empty");

        throw EmptyIngridientProteinsException();
    }

    if ( carbohydrates.isEmpty() ) {
        PRINT_ERR("Food carbohydrates could not be empty");

        throw EmptyIngridientCarbohydratesException();
    }

    if ( calories.isEmpty() ) {
        PRINT_ERR("Food calories could not be empty");

        throw EmptyIngridientCaloriesException();
    }

    return new Food(name.toStdString(), isKg ? 1 : QStringToMass(mass),
                    QStringToPrice(price), static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()),
                    QStringToFats(fats),
                    QStringToProteins(proteins),
                    QStringToCarbohydrates(carbohydrates),
                    QStringToCalories(calories));
}

void IngridientWindow::editItem(Item* item) {
    PRINT_DEBUG("Editing item");

    if ( !ui->comboBox_1->currentText().toStdString().compare("kg") ) {
        item->setItemMass(1);
    } else {
        item->setItemMass(ui->lineEdit_2->text().toLong());
    }
    item->setItemPrice(ui->lineEdit_4->text().toLong());
    item->setItemUnitType(static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()));
}

void IngridientWindow::editFood(Food* food) {
    PRINT_DEBUG("Editing food");

    editItem(food);
    food->setItemFats(ui->lineEdit_3->text().toLong());
    food->setItemProteins(ui->lineEdit_5->text().toLong());
    food->setItemCarbohydrates(ui->lineEdit_6->text().toLong());
    food->setItemCalories(ui->lineEdit_7->text().toLong());
}

void IngridientWindow::on_radioButton_1_clicked() {
    ui->lineEdit_3->setDisabled(false);
    ui->lineEdit_5->setDisabled(false);
    ui->lineEdit_6->setDisabled(false);
    ui->lineEdit_7->setDisabled(false);
}

void IngridientWindow::on_radioButton_2_clicked() {
    ui->lineEdit_3->setDisabled(true);
    ui->lineEdit_5->setDisabled(true);
    ui->lineEdit_6->setDisabled(true);
    ui->lineEdit_7->setDisabled(true);
}

void IngridientWindow::on_comboBox_1_currentIndexChanged(const QString& arg1) {
    if ( !arg1.toStdString().compare("kg") ) {
        ui->lineEdit_2->setDisabled(true);
    } else {
        ui->lineEdit_2->setDisabled(false);
    }

    PRINT_DEBUG(arg1.toStdString() << " selected");
}
<commit_msg>ingridientWindow: Use convert functions for values<commit_after>#include <convert.hpp>
#include <errors.hpp>
#include <debug.hpp>

#include <ingridientWindow.hpp>
#include "ui_ingridientWindow.h"

IngridientWindow::IngridientWindow(QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()} {

    setupMeasureList();
    ui->lineEdit_2->setDisabled(true);

    PRINT_OBJ("IngridientWindow created");
}

IngridientWindow::IngridientWindow(Item* item, QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()},
    editMode {true},
    editedItem {item} {

    setupMeasureList();
    applyItemStats(item);
    this->setWindowTitle("Edit item");

    PRINT_OBJ("Existed item edit window created");
}

IngridientWindow::IngridientWindow(Food* food, QWidget* parent) :
    QDialog {parent},
    ui {new Ui::IngridientWindow},
    measureList {QStringList()},
    editMode {true},
    editedItem {food} {

    setupMeasureList();
    applyFoodStats(food);
    this->setWindowTitle("Edit food");

    PRINT_OBJ("Existed food edit window created");
}

IngridientWindow::~IngridientWindow() {
    delete ui;

    PRINT_OBJ("IngridientWindow destroyed");
}

void IngridientWindow::on_buttonBox_1_accepted() {
    if ( editMode ) {
        if ( ui->radioButton_1->isChecked() ) {
            editFood(dynamic_cast<Food*>(editedItem));
        } else if ( ui->radioButton_2->isChecked() ) {
            editItem(editedItem);
        }
    } else {
        if ( ui->radioButton_1->isChecked() ) {
            emit foodObjectReady(createNewFood());
        } else if ( ui->radioButton_2->isChecked() ) {
            emit itemObjectReady(createNewItem());
        }
    }

    this->hide();

    PRINT_DEBUG("New item/food accepted");
}

void IngridientWindow::on_buttonBox_1_rejected() {
    this->hide();

    PRINT_DEBUG("New item/food rejected");
}

void IngridientWindow::setupMeasureList(void) {
    const std::string* names = Item::getItemMeasureTypeNamesList();

    ui->setupUi(this);

    for ( int i = 0; !names[i].empty(); i++ ) {
        measureList.append(QString::fromStdString(names[i]));
    }

    ui->comboBox_1->addItems(measureList);
}

void IngridientWindow::applyItemStats(Item* item) {
    ui->lineEdit_1->setText(QString::fromStdString(item->getName()));
    ui->lineEdit_1->setDisabled(true);
    ui->comboBox_1->setCurrentIndex(static_cast<int>(item->getUnitType()));
    if ( item->getUnitType() != Item::KGRAM ) {
        ui->lineEdit_2->setText(massToQString(item->getMass()));
    } else {
        ui->lineEdit_2->setDisabled(true);
    }
    ui->lineEdit_4->setText(priceToQString(item->getPrice()));

    on_radioButton_2_clicked();
    ui->radioButton_2->setChecked(true);
    ui->radioButton_1->setDisabled(true);

    PRINT_DEBUG("All items stats are applied");
}

void IngridientWindow::applyFoodStats(Food* food) {
    ui->lineEdit_1->setText(QString::fromStdString(food->getName()));
    ui->lineEdit_1->setDisabled(true);
    ui->comboBox_1->setCurrentIndex(static_cast<int>(food->getUnitType()));
    if ( food->getUnitType() != Item::KGRAM ) {
        ui->lineEdit_2->setText(massToQString(food->getMass()));
    } else {
        ui->lineEdit_2->setDisabled(true);
    }
    ui->lineEdit_4->setText(priceToQString(food->getPrice()));
    ui->lineEdit_3->setText(fatsToQString(food->getFats()));
    ui->lineEdit_5->setText(proteinsToQString(food->getProteins()));
    ui->lineEdit_6->setText(carbohydratesToQString(food->getCarbohydrates()));
    ui->lineEdit_7->setText(caloriesToQString(food->getCalories()));

    ui->radioButton_1->setChecked(true);
    ui->radioButton_2->setDisabled(true);

    PRINT_DEBUG("All food stats are applied");
}

Item* IngridientWindow::createNewItem(void) {
    PRINT_DEBUG("Creating new item");

    QString name = ui->lineEdit_1->text();
    QString mass = ui->lineEdit_2->text();
    QString price = ui->lineEdit_4->text();

    if ( name.isEmpty() ) {
        PRINT_ERR("Ingridient name could not be empty");

        throw EmptyIngridientNameException();
    }

    if ( mass.isEmpty() ) {
        PRINT_ERR("Ingridient mass could not be empty");

        throw EmptyIngridientMassException();
    }

    if ( price.isEmpty() ) {
        PRINT_ERR("Ingridient price could not be empty");

        throw EmptyIngridientPriceException();
    }

    return new Item(name.toStdString(), (!ui->comboBox_1->currentText().toStdString().compare("kg") ? 1 : QStringToMass(mass)),
                    QStringToPrice(price), static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()));
}

Food* IngridientWindow::createNewFood(void) {
    bool isKg = !ui->comboBox_1->currentText().toStdString().compare("kg");

    PRINT_DEBUG("Creating new food");

    QString name = ui->lineEdit_1->text();
    QString mass = ui->lineEdit_2->text();
    QString price = ui->lineEdit_4->text();
    QString fats = ui->lineEdit_3->text();
    QString proteins = ui->lineEdit_5->text();
    QString carbohydrates = ui->lineEdit_6->text();
    QString calories = ui->lineEdit_7->text();

    if ( name.isEmpty() ) {
        PRINT_ERR("Food name could not be empty");

        throw EmptyIngridientNameException();
    }

    if ( mass.isEmpty() && !isKg ) {
        PRINT_ERR("Food mass could not be empty");

        throw EmptyIngridientMassException();
    }

    if ( price.isEmpty() ) {
        PRINT_ERR("Food price could not be empty");

        throw EmptyIngridientPriceException();
    }

    if ( fats.isEmpty() ) {
        PRINT_ERR("Food fats could not be empty");

        throw EmptyIngridientFatsException();
    }

    if ( proteins.isEmpty() ) {
        PRINT_ERR("Food proteins could not be empty");

        throw EmptyIngridientProteinsException();
    }

    if ( carbohydrates.isEmpty() ) {
        PRINT_ERR("Food carbohydrates could not be empty");

        throw EmptyIngridientCarbohydratesException();
    }

    if ( calories.isEmpty() ) {
        PRINT_ERR("Food calories could not be empty");

        throw EmptyIngridientCaloriesException();
    }

    return new Food(name.toStdString(), isKg ? 1 : QStringToMass(mass),
                    QStringToPrice(price), static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()),
                    QStringToFats(fats),
                    QStringToProteins(proteins),
                    QStringToCarbohydrates(carbohydrates),
                    QStringToCalories(calories));
}

void IngridientWindow::editItem(Item* item) {
    PRINT_DEBUG("Editing item");

    if ( !ui->comboBox_1->currentText().toStdString().compare("kg") ) {
        item->setItemMass(1);
    } else {
        item->setItemMass(QStringToMass(ui->lineEdit_2->text()));
    }
    item->setItemPrice(QStringToPrice(ui->lineEdit_4->text()));
    item->setItemUnitType(static_cast<Item::MeasureType>(ui->comboBox_1->currentIndex()));
}

void IngridientWindow::editFood(Food* food) {
    PRINT_DEBUG("Editing food");

    editItem(food);
    food->setItemFats(QStringToFats(ui->lineEdit_3->text()));
    food->setItemProteins(QStringToProteins(ui->lineEdit_5->text()));
    food->setItemCarbohydrates(QStringToCarbohydrates(ui->lineEdit_6->text()));
    food->setItemCalories(QStringToCalories(ui->lineEdit_7->text()));
}

void IngridientWindow::on_radioButton_1_clicked() {
    ui->lineEdit_3->setDisabled(false);
    ui->lineEdit_5->setDisabled(false);
    ui->lineEdit_6->setDisabled(false);
    ui->lineEdit_7->setDisabled(false);
}

void IngridientWindow::on_radioButton_2_clicked() {
    ui->lineEdit_3->setDisabled(true);
    ui->lineEdit_5->setDisabled(true);
    ui->lineEdit_6->setDisabled(true);
    ui->lineEdit_7->setDisabled(true);
}

void IngridientWindow::on_comboBox_1_currentIndexChanged(const QString& arg1) {
    if ( !arg1.toStdString().compare("kg") ) {
        ui->lineEdit_2->setDisabled(true);
    } else {
        ui->lineEdit_2->setDisabled(false);
    }

    PRINT_DEBUG(arg1.toStdString() << " selected");
}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-5-26 21:31:42
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, Q;
ll S[200010], T[200010], X[200010];
ll D[200010];
int ans[200010];
typedef tuple<ll, ll, ll, int> K;
vector<K> KK;
typedef tuple<ll, int, int> info;
priority_queue<info, vector<info>, greater<info>> P;

int main()
{
  cin >> N >> Q;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i] >> T[i] >> X[i];
    KK.push_back(K(X[i], S[i], T[i], i));
  }
  sort(KK.begin(), KK.end());
  for (auto i = 0; i < Q; i++)
  {
    cin >> D[i];
  }
  for (auto i = 0; i < N; i++)
  {
    ll x = get<0>(KK[i]);
    ll s = get<1>(KK[i]);
    ll t = get<2>(KK[i]);
    int ind = get<3>(KK[i]);
    P.push(info(s - x, ind, 0));
    P.push(info(t - x, ind, 1));
  }
  int ind = 0;
  set<int> S;
  fill(ans, ans + Q, -1);
  while (!P.empty())
  {
    info x = P.top();
    P.pop();
    ll next_t = get<0>(x);
    int point = get<1>(x);
    bool start = (get<2>(x) == 0);
    if (next_t <= D[ind])
    {
      if (start)
      {
        S.insert(point);
      }
      else
      {
        S.erase(S.find(point));
      }
      continue;
    }
    else
    {
      while (next_t > D[ind])
      {
        int a = -1;
        if (S.empty())
        {
          a = -1;
        }
        else
        {
          a = *S.begin();
        }
        ans[ind] = a;
        ind++;
        if (ind == Q)
        {
          goto EXIT;
        }
      }
      if (start)
      {
        S.insert(point);
      }
      else
      {
        S.erase(S.find(point));
      }
    }
  }
EXIT:
  for (auto i = 0; i < Q; i++)
  {
    if (ans[i] == -1)
    {
      cout << -1 << endl;
    }
    else
    {
      cout << X[ans[i]] << endl;
    }
  }
}<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-5-26 21:31:42
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, Q;
ll S[200010], T[200010], X[200010];
ll D[200010];
int ans[200010];
typedef tuple<ll, ll, ll, int> K;
vector<K> KK;
typedef tuple<ll, int, int> info;
priority_queue<info, vector<info>, greater<info>> P;

int main()
{
  cin >> N >> Q;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i] >> T[i] >> X[i];
    KK.push_back(K(X[i], S[i], T[i], i));
  }
  sort(KK.begin(), KK.end());
  for (auto i = 0; i < Q; i++)
  {
    cin >> D[i];
  }
  for (auto i = 0; i < N; i++)
  {
    ll x = get<0>(KK[i]);
    ll s = get<1>(KK[i]);
    ll t = get<2>(KK[i]);
    int ind = get<3>(KK[i]);
    P.push(info(s - x, ind, 0));
    P.push(info(t - x, ind, 1));
  }
  int ind = 0;
  set<int> S;
  fill(ans, ans + Q, -1);
  while (!P.empty())
  {
    info x = P.top();
    P.pop();
    ll next_t = get<0>(x);
    int point = get<1>(x);
    bool start = (get<2>(x) == 0);
    while (next_t > D[ind])
    {
      int a = -1;
      if (S.empty())
      {
        a = -1;
      }
      else
      {
        a = *S.begin();
      }
      ans[ind] = a;
      ind++;
      if (ind == Q)
      {
        goto EXIT;
      }
    }
    if (start)
    {
      S.insert(point);
    }
    else
    {
      S.erase(S.find(point));
    }
  }
EXIT:
  for (auto i = 0; i < Q; i++)
  {
    if (ans[i] == -1)
    {
      cout << -1 << endl;
    }
    else
    {
      cout << X[ans[i]] << endl;
    }
  }
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 7/5/2020, 5:33:34 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

using Event = tuple<ll, int, int>;

int main()
{
  int n, q;
  cin >> n >> q;
  vector<ll> s(n), t(n), x(n), d(q);
  for (auto i{0}; i < n; ++i)
  {
    cin >> s[i] >> t[i] >> x[i];
  }
  for (auto i{0}; i < q; ++i)
  {
    cin >> d[i];
  }
  vector<Event> v;
  for (auto i{0}; i < n; ++i)
  {
    v.emplace_back(s[i] - x[i], 0, i);
    v.emplace_back(t[i] - x[i], 2, i);
  }
  for (auto i{0}; i < q; ++i)
  {
    v.emplace_back(-d[i], 1, i);
  }
  sort(v.begin(), v.end());
  multiset<ll> st;
  vector<ll> ans(q, -1);
  for (auto [l, t, id] : v)
  {
    if (t == 0)
    {
      st.insert(x[id]);
    }
    else if (t == 2)
    {
      st.erase(st.find(x[id]));
    }
    else
    {
      if (!st.empty())
      {
        ans[id] = *st.begin() - d[id];
      }
    }
  }
  for (auto e : ans)
  {
    cout << e << endl;
  }
}
<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 7/5/2020, 5:33:34 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

using Event = tuple<ll, int, int>;

int main()
{
  int n, q;
  cin >> n >> q;
  vector<ll> s(n), t(n), x(n), d(q);
  for (auto i{0}; i < n; ++i)
  {
    cin >> s[i] >> t[i] >> x[i];
  }
  for (auto i{0}; i < q; ++i)
  {
    cin >> d[i];
  }
  vector<Event> v;
  for (auto i{0}; i < n; ++i)
  {
    v.emplace_back(s[i] - x[i], 0, i);
    v.emplace_back(t[i] - x[i], 1, i);
  }
  for (auto i{0}; i < q; ++i)
  {
    v.emplace_back(d[i], 2, i);
  }
  sort(v.begin(), v.end());
  multiset<ll> st;
  vector<ll> ans(q, -1);
  for (auto [l, t, id] : v)
  {
    if (t == 0)
    {
      st.insert(x[id]);
    }
    else if (t == 1)
    {
      st.erase(st.find(x[id]));
    }
    else
    {
      if (!st.empty())
      {
        ans[id] = *st.begin() - d[id];
      }
    }
  }
  for (auto e : ans)
  {
    cout << e << endl;
  }
}
<|endoftext|>


<commit_before>

template<class INFERENCE>
class VisitorInterface{

	void begin(){

	}

	bool visit(){

	}

	void end(){

	}

	void logg

};<commit_msg>implemented new visitors<commit_after>#include <iostream>

template<class INFERENCE>
class EmptyVisitor{
public:
	EmptyVisitor(){
	}
	void begin(INFERENCE & inf){
	}
	bool operator()(INFERENCE & inf){
		return true;
	}
	void end(INFERENCE & inf){
	}
};

template<class INFERENCE>
class VerboseVisitor{
public:
	VerboseVisitor(){
	}
	void begin(INFERENCE & inf){
		std::cout<<"value "<<inf.value()<<" bound "<<inf.bound()<<"\n";
	}
	bool operator()(INFERENCE & inf){
		std::cout<<"value "<<inf.value()<<" bound "<<inf.bound()<<"\n";
		return true;
	}
	void end(INFERENCE & inf){
		std::cout<<"value "<<inf.value()<<" bound "<<inf.bound()<<"\n";
	}
};

template<class INFERENCE>
class TimingVisitor{
public:
	typedef typename  INFERENCE::ValueType ValueType;

	TimingVisitor()
	:
		iteration_(0)
		times_(),
		values_(),
		bounds_(),
		iterations_(),
		timer_()
	{
		timer_.tic();
	}

	void begin(INFERENCE & inf){
		// stop timer
		timer_.toc();
		// store values
		const ValueType val=inf.value();
		const ValueType bound=inf.bound();
        times_.push_back(timer_.elapsedTime());
        values_.push_back(values_);
        bounds_.push_back(bounds_);

        std::cout<<"value "<<val<<" bound "<<bound<<"\n";

        ++iteration_;
		// restart timer
		timer_.tic():
	}

	bool operator()(INFERENCE & inf){
		// stop timer
		timer_.toc();
		// store values
		const ValueType val=inf.value();
		const ValueType bound=inf.bound();
        times_.push_back(timer_.elapsedTime());
        values_.push_back(values_);
        bounds_.push_back(bounds_);

        std::cout<<"value "<<val<<" bound "<<bound<<"\n";

        ++iteration_;
		// restart timer
		timer_.tic():
		return true;
	}

	void end(INFERENCE & inf){
		// stop timer
		timer_.toc();
		// store values
		const ValueType val=inf.value();
		const ValueType bound=inf.bound();
        times_.push_back(timer_.elapsedTime());
        values_.push_back(values_);
        bounds_.push_back(bounds_);

        std::cout<<"value "<<val<<" bound "<<bound<<"\n";

	}
private:
	iteration_;
	std::vector<float  > times_;
	std::vector<float  > values_;
	std::vector<float  > bounds_;
	std::vector<size_t > iterations_;
	opengm::Timer timer_;
};
<|endoftext|>


<commit_before><commit_msg>1. enable verticle mode for Japanese punctuation; 2. also can copy access plugin dylib for debug(libaccessplugin_debug.dylib)<commit_after><|endoftext|>


<commit_before><commit_msg>initializeControlModel needs parent to be set<commit_after><|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface to create an OpenGL
// graphics window, and OSG for rendering.

#include <Producer/RenderSurface>
#include <osg/Timer>
#include <osgUtil/SceneView>
#include <osgDB/ReadFile>

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // create the window to draw to.
    osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
    renderSurface->setWindowName("osgsimple");
    renderSurface->setWindowRectangle(100,100,800,600);
    renderSurface->useBorder(true);
    renderSurface->realize();

    // create the view of the scene.
    osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
    sceneView->setDefaults();
    sceneView->setSceneData(loadedModel.get());

    // initialize the view to look at the center of the scene graph
    const osg::BoundingSphere& bs = loadedModel->getBound();
    osg::Matrix viewMatrix;
    viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    unsigned int frameNum = 0;

    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
    while( renderSurface->isRealized() )
    {
        // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
        osg::FrameStamp* frameStamp = new osg::FrameStamp;
        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
        frameStamp->setFrameNumber(frameNum++);

        // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp
        sceneView->setFrameStamp(frameStamp);

        // update the viewport dimensions, incase the window has been resized.
        sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight());

        // set the view
        sceneView->setViewMatrix(viewMatrix);

        // do the update traversal the scene graph - such as updating animations
        sceneView->update();

        // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins
        sceneView->cull();

        // draw the rendering bins.
        sceneView->draw();

    	// Swap Buffers
    	renderSurface->swapBuffers();
    }

    return 0;
}

<commit_msg>Oops.  Fixed glaring memory leak in main loop of osgsimple<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface to create an OpenGL
// graphics window, and OSG for rendering.

#include <Producer/RenderSurface>
#include <osg/Timer>
#include <osgUtil/SceneView>
#include <osgDB/ReadFile>

int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // create the window to draw to.
    osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
    renderSurface->setWindowName("osgsimple");
    renderSurface->setWindowRectangle(100,100,800,600);
    renderSurface->useBorder(true);
    renderSurface->realize();

    // create the view of the scene.
    osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
    sceneView->setDefaults();
    sceneView->setSceneData(loadedModel.get());

    // initialize the view to look at the center of the scene graph
    const osg::BoundingSphere& bs = loadedModel->getBound();
    osg::Matrix viewMatrix;
    viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    unsigned int frameNum = 0;

    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
    while( renderSurface->isRealized() )
    {
        // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
        osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp;
        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
        frameStamp->setFrameNumber(frameNum++);

        // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp
        sceneView->setFrameStamp(frameStamp.get());

        // update the viewport dimensions, incase the window has been resized.
        sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight());

        // set the view
        sceneView->setViewMatrix(viewMatrix);

        // do the update traversal the scene graph - such as updating animations
        sceneView->update();

        // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins
        sceneView->cull();

        // draw the rendering bins.
        sceneView->draw();

    	// Swap Buffers
    	renderSurface->swapBuffers();
    }

    return 0;
}

<|endoftext|>