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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPointCloudScoringFilter.h"

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkKdTree.h>
#include <vtkPolyData.h>

mitk::PointCloudScoringFilter::PointCloudScoringFilter():
  m_NumberOfOutpPoints(0)
{
  m_OutpSurface = mitk::Surface::New();

  this->SetNthOutput(0, m_OutpSurface);
}

mitk::PointCloudScoringFilter::~PointCloudScoringFilter(){}

void mitk::PointCloudScoringFilter::GenerateData()
{
  if(SurfaceToSurfaceFilter::GetNumberOfInputs()!=2)
  {
    MITK_ERROR << "Not enough input arguments for PointCloudScoringFilter" << std::endl;
    return;
  }

  DataObjectPointerArray inputs = SurfaceToSurfaceFilter::GetInputs();
  mitk::Surface::Pointer edgeSurface = dynamic_cast<mitk::Surface*>(inputs.at(0).GetPointer());
  mitk::Surface::Pointer segmSurface = dynamic_cast<mitk::Surface*>(inputs.at(1).GetPointer());

  if(edgeSurface->IsEmpty() || segmSurface->IsEmpty())
  {
    if(edgeSurface->IsEmpty())
      MITK_ERROR << "Cannot convert EdgeSurface into Surfaces" << std::endl;
    if(segmSurface->IsEmpty())
      MITK_ERROR << "Cannot convert SegmSurface into Surfaces" << std::endl;
  }

  vtkSmartPointer<vtkPolyData> edgePolyData = edgeSurface->GetVtkPolyData();
  vtkSmartPointer<vtkPolyData> segmPolyData = segmSurface->GetVtkPolyData();

  // KdTree from here
  vtkSmartPointer<vtkPoints> kdPoints = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkKdTree> kdTree = vtkSmartPointer<vtkKdTree>::New();

  for(int i=0; i<edgePolyData->GetNumberOfPoints(); i++)
  {
    kdPoints->InsertNextPoint(edgePolyData->GetPoint(i));
  }

  kdTree->BuildLocatorFromPoints(kdPoints);
  // KdTree until here

  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  for(int i=0; i<segmPolyData->GetNumberOfPoints(); i++)
  {
    points->InsertNextPoint(segmPolyData->GetPoint(i));
  }

  std::vector< ScorePair > score;

  double dist_glob;
  double dist;

  for(int i=0; i<points->GetNumberOfPoints(); i++)
  {
    double point[3];
    points->GetPoint(i,point);
    kdTree->FindClosestPoint(point[0],point[1],point[2],dist);
    dist_glob+=dist;
    score.push_back(std::make_pair(i,dist));
  }

  double avg = dist_glob / points->GetNumberOfPoints();

  for(unsigned int i=0; i<score.size();++i)
  {
    if(score.at(i).second > avg)
    {
      m_FilteredScores.push_back(std::make_pair(score.at(i).first,score.at(i).second));
    }
  }

  m_NumberOfOutpPoints = m_FilteredScores.size();

  vtkSmartPointer<vtkPolyData> outpSurface = vtkSmartPointer<vtkPolyData>::New();
  vtkSmartPointer<vtkPoints> filteredPoints = vtkSmartPointer<vtkPoints>::New();

  for(unsigned int i=0; i<m_FilteredScores.size(); i++)
  {
    mitk::Point3D point;
    point = segmPolyData->GetPoint(m_FilteredScores.at(i).first);
    filteredPoints->InsertNextPoint(point[0],point[1],point[2]);
  }

  outpSurface->SetPoints(filteredPoints);
  m_OutpSurface->SetVtkPolyData(outpSurface);
}

void mitk::PointCloudScoringFilter::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}
<commit_msg>added lines between the points for correct visualization<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPointCloudScoringFilter.h"

#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkKdTree.h>
#include <vtkPolyData.h>
#include <vtkPolyLine.h>
#include <vtkCellArray.h>

mitk::PointCloudScoringFilter::PointCloudScoringFilter():
  m_NumberOfOutpPoints(0)
{
  m_OutpSurface = mitk::Surface::New();
//  this->SetNumberOfRequiredInputs(2);
//  this->SetNumberOfRequiredOutputs(1);

  this->SetNthOutput(0, m_OutpSurface);
}

mitk::PointCloudScoringFilter::~PointCloudScoringFilter(){}

void mitk::PointCloudScoringFilter::GenerateData()
{
  if(SurfaceToSurfaceFilter::GetNumberOfInputs()!=2)
  {
    MITK_ERROR << "Not enough input arguments for PointCloudScoringFilter" << std::endl;
    return;
  }

  DataObjectPointerArray inputs = SurfaceToSurfaceFilter::GetInputs();
  mitk::Surface::Pointer edgeSurface = dynamic_cast<mitk::Surface*>(inputs.at(0).GetPointer());
  mitk::Surface::Pointer segmSurface = dynamic_cast<mitk::Surface*>(inputs.at(1).GetPointer());

  if(edgeSurface->IsEmpty() || segmSurface->IsEmpty())
  {
    if(edgeSurface->IsEmpty())
      MITK_ERROR << "Cannot convert EdgeSurface into Surfaces" << std::endl;
    if(segmSurface->IsEmpty())
      MITK_ERROR << "Cannot convert SegmSurface into Surfaces" << std::endl;
  }

  vtkSmartPointer<vtkPolyData> edgePolyData = edgeSurface->GetVtkPolyData();
  vtkSmartPointer<vtkPolyData> segmPolyData = segmSurface->GetVtkPolyData();

  // KdTree from here
  vtkSmartPointer<vtkPoints> kdPoints = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkKdTree> kdTree = vtkSmartPointer<vtkKdTree>::New();

  for(int i=0; i<edgePolyData->GetNumberOfPoints(); i++)
  {
    kdPoints->InsertNextPoint(edgePolyData->GetPoint(i));
  }

  kdTree->BuildLocatorFromPoints(kdPoints);
  // KdTree until here

  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  for(int i=0; i<segmPolyData->GetNumberOfPoints(); i++)
  {
    points->InsertNextPoint(segmPolyData->GetPoint(i));
  }

  std::vector< ScorePair > score;

  double dist_glob;
  double dist;

  for(int i=0; i<points->GetNumberOfPoints(); i++)
  {
    double point[3];
    points->GetPoint(i,point);
    kdTree->FindClosestPoint(point[0],point[1],point[2],dist);
    dist_glob+=dist;
    score.push_back(std::make_pair(i,dist));
  }

  double avg = dist_glob / points->GetNumberOfPoints();

  for(unsigned int i=0; i<score.size();++i)
  {
    if(score.at(i).second > avg)
    {
      m_FilteredScores.push_back(std::make_pair(score.at(i).first,score.at(i).second));
    }
  }

  m_NumberOfOutpPoints = m_FilteredScores.size();

  vtkSmartPointer<vtkPolyData> outpSurface = vtkSmartPointer<vtkPolyData>::New();
  vtkSmartPointer<vtkPoints> filteredPoints = vtkSmartPointer<vtkPoints>::New();

  for(unsigned int i=0; i<m_FilteredScores.size(); i++)
  {
    mitk::Point3D point;
    point = segmPolyData->GetPoint(m_FilteredScores.at(i).first);
    filteredPoints->InsertNextPoint(point[0],point[1],point[2]);
  }

  unsigned int numPoints = filteredPoints->GetNumberOfPoints();

  vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();
  polyLine->GetPointIds()->SetNumberOfIds(numPoints);

  for(unsigned int i = 0; i < numPoints; i++)
  {
    polyLine->GetPointIds()->SetId(i,i);
  }

  vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
  cells->InsertNextCell(polyLine);

  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();

  polyData->SetPoints(filteredPoints);
  polyData->SetLines(cells);

  outpSurface->BuildCells();
  outpSurface->BuildLinks();
  m_OutpSurface->SetVtkPolyData(polyData);
}

void mitk::PointCloudScoringFilter::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* common headers */
#include "common.h"

#ifdef HAVE_SDL

/* interface headers */
#include "SDLJoystick.h"

/* implementation headers */
#include "ErrorHandler.h"
#include "bzfSDL.h"

SDLJoystick::SDLJoystick() : joystickID(NULL)
{
  if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
    std::vector<std::string> args;
    args.push_back(SDL_GetError());
    printError("Could not initialize SDL Joystick subsystem: %s.\n", &args);
  };
}

SDLJoystick::~SDLJoystick()
{
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}

void			SDLJoystick::initJoystick(const char* joystickName)
{
  if (!strcmp(joystickName, "off") || !strcmp(joystickName, "")) {
    if (joystickID != NULL) {
      SDL_JoystickClose(joystickID);
      joystickID = NULL;
    }
    return;
  }
  char num = joystickName[0];
  int  i   = (int)num - '0';
  if (!isdigit(num) || i >= SDL_NumJoysticks()) {
    printError("No supported SDL joysticks were found.");
    joystickID = NULL;
    return;
  }
  joystickID = SDL_JoystickOpen(i);
  if (joystickID == NULL)
    return;
  if (SDL_JoystickNumAxes(joystickID) < 2) {
    SDL_JoystickClose(joystickID);
    printError("Joystick has less then 2 axis:\n");
    joystickID = NULL;
    return;
  }
  joystickButtons = SDL_JoystickNumButtons(joystickID);
}

bool			SDLJoystick::joystick() const
{
  return joystickID != NULL;
}

void			SDLJoystick::getJoy(int& x, int& y) const
{
  x = y = 0;

  if (!joystickID)
    return;

  SDL_JoystickUpdate();
  x = SDL_JoystickGetAxis(joystickID, 0);
  y = SDL_JoystickGetAxis(joystickID, 1);

  x = x * 1000 / 32768;
  y = y * 1000 / 32768;

  // ballistic
  x = (x * abs(x)) / 1000;
  y = (y * abs(y)) / 1000;

}

unsigned long		SDLJoystick::getJoyButtons() const
{
  unsigned long buttons = 0;

  if (!joystickID)
    return 0;

  SDL_JoystickUpdate();
  for (int i = 0; i < joystickButtons; i++)
    buttons |= SDL_JoystickGetButton(joystickID, i) << i;

  return buttons;
}

void                    SDLJoystick::getJoyDevices(std::vector<std::string>
						 &list) const
{
  int numJoystick = SDL_NumJoysticks();
  int i;
  for (i = 0; i < numJoystick; i++) {
    char joystickName[256];
    sprintf(joystickName, "%d - %s", i, SDL_JoystickName(i));
    list.push_back(joystickName);
  }
}
#endif

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>deal with extraordinary values sanely (many joysticks or long names)<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* common headers */
#include "common.h"

#ifdef HAVE_SDL

/* interface headers */
#include "SDLJoystick.h"

/* implementation headers */
#include "ErrorHandler.h"
#include "bzfSDL.h"

SDLJoystick::SDLJoystick() : joystickID(NULL)
{
  if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
    std::vector<std::string> args;
    args.push_back(SDL_GetError());
    printError("Could not initialize SDL Joystick subsystem: %s.\n", &args);
  };
}

SDLJoystick::~SDLJoystick()
{
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}

void			SDLJoystick::initJoystick(const char* joystickName)
{
  if (!strcmp(joystickName, "off") || !strcmp(joystickName, "")) {
    if (joystickID != NULL) {
      SDL_JoystickClose(joystickID);
      joystickID = NULL;
    }
    return;
  }
  char num = joystickName[0];
  int  i   = (int)num - '0';
  if (!isdigit(num) || i >= SDL_NumJoysticks()) {
    printError("No supported SDL joysticks were found.");
    joystickID = NULL;
    return;
  }
  joystickID = SDL_JoystickOpen(i);
  if (joystickID == NULL)
    return;
  if (SDL_JoystickNumAxes(joystickID) < 2) {
    SDL_JoystickClose(joystickID);
    printError("Joystick has less then 2 axis:\n");
    joystickID = NULL;
    return;
  }
  joystickButtons = SDL_JoystickNumButtons(joystickID);
}

bool			SDLJoystick::joystick() const
{
  return joystickID != NULL;
}

void			SDLJoystick::getJoy(int& x, int& y) const
{
  x = y = 0;

  if (!joystickID)
    return;

  SDL_JoystickUpdate();
  x = SDL_JoystickGetAxis(joystickID, 0);
  y = SDL_JoystickGetAxis(joystickID, 1);

  x = x * 1000 / 32768;
  y = y * 1000 / 32768;

  // ballistic
  x = (x * abs(x)) / 1000;
  y = (y * abs(y)) / 1000;

}

unsigned long		SDLJoystick::getJoyButtons() const
{
  unsigned long buttons = 0;

  if (!joystickID)
    return 0;

  SDL_JoystickUpdate();
  for (int i = 0; i < joystickButtons; i++)
    buttons |= SDL_JoystickGetButton(joystickID, i) << i;

  return buttons;
}

void                    SDLJoystick::getJoyDevices(std::vector<std::string>
						 &list) const
{
  int numJoystick = SDL_NumJoysticks();
  if (numJoystick > 9) //user would have to be insane to have this many anyway
    numJoystick = 9;
  int i;
  for (i = 0; i < numJoystick; i++) {
    char joystickName[50]; //only room for so much on the menu
    snprintf(joystickName, 50, "%d - %s", i, SDL_JoystickName(i));
    list.push_back(joystickName);
  }
}
#endif

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include "game.h"

#include "camera.h"
#include "util/gui/cutscene.h"
#include "world.h"

#include "util/bitmap.h"
#include "util/stretch-bitmap.h"
#include "util/debug.h"
#include "util/events.h"
#include "util/font.h"
#include "util/init.h"
#include "util/input/input-map.h"
#include "util/input/input-manager.h"
#include "util/input/input-source.h"
#include "util/file-system.h"
#include "util/load_exception.h"
#include "util/token.h"
#include "util/tokenreader.h"

#include <string>
#include <sstream>

using namespace std;
using namespace Platformer;

Game::Game(const std::string & filename){
    /* NOTE this is temporary to run tests on the engine
     * Eventually it will be replaced with a class that handles the entire game (worlds, etc...)
     */
    try {
	Global::debug(1,"platformer") << "Loading Platformer: " << filename << endl;
	TokenReader tr;

        Token * platformToken = tr.readTokenFromFile(filename);

	if ( *platformToken != "platformer" ){
	    throw LoadException(__FILE__, __LINE__, "Not a Platformer");
	}

	TokenView view = platformToken->view();
	while (view.hasMore()){
	    try{
		const Token * tok;
		view >> tok;
		if ( *tok == "world" ){
                    worlds.push_back(Util::ReferenceCount<Platformer::World>(new Platformer::World(tok)));
                } else if ( *tok == "cutscene" ){
                    std::string file;
                    tok->view() >> file;
                    //Util::ReferenceCount<Gui::CutScene> cutscene(new Gui::CutScene(tok));
                    Util::ReferenceCount<Gui::CutScene> cutscene(new Gui::CutScene(Filesystem::AbsolutePath(file)));
                    cutscenes[cutscene->getName()] = cutscene;
                } else {
		    Global::debug(3) << "Unhandled Platformer attribute: " << endl;
		    if (Global::getDebug() >= 3){
			tok->print(" ");
		    }
		}
	    } catch ( const TokenException & ex ) {
		throw LoadException(__FILE__, __LINE__, ex, "Platformer parse error");
	    } catch ( const LoadException & ex ) {
		// delete current;
		throw ex;
	    }
	}
    } catch (const TokenException & e){
        throw LoadException(__FILE__, __LINE__, e, "Error loading platformer file.");
    }

    // TODO remove test intro cutscene
    cutscenes["intro"]->setResolution(worlds[0]->getResolutionX(), worlds[0]->getResolutionY());
}

Game::~Game(){
}

void Game::run(){
    // NOTE Testing purposes only

    class Logic: public Util::Logic {
    public:
        Logic(InputMap<Keys> & input, std::vector < Util::ReferenceCount<Platformer::World> > & worlds):
        is_done(false),
        input(input),
        worlds(worlds){
        }

        bool is_done;
	InputMap<Keys> & input;
	std::vector < Util::ReferenceCount<Platformer::World> > & worlds;

	bool done(){
            return is_done;
        }

	void run(){
	    // FIXME figure out how many worlds... etc
            vector<InputMap<Keys>::InputEvent> out = InputManager::getEvents(input, InputSource());
	    for (vector<InputMap<Keys>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
            const InputMap<Keys>::InputEvent & event = *it;
            if (event.enabled){
                if (event.out == Esc){
                    is_done = true;
                }
                if (event.out == Up){
                    worlds[0]->moveCamera(0, 0,-5);
                }
                if (event.out == Down){
                    worlds[0]->moveCamera(0, 0,5);
                }
                if (event.out == Left){
                    worlds[0]->moveCamera(0, -5,0);
                }
                if (event.out == Right){
                    worlds[0]->moveCamera(0, 5,0);
                }
                if (event.out == K_1){
                    worlds[0]->moveCamera(1, -5,0);
                }
                if (event.out == K_2){
                    worlds[0]->moveCamera(1, 5,0);
                }
                if (event.out == K_3){
                    worlds[0]->moveCamera(1, 0, -5);
                }
                if (event.out == K_4){
                    worlds[0]->moveCamera(1, 0, 5);
                }
            }
        }

        worlds[0]->act();

        }

        double ticks(double system){
            return Global::ticksPerSecond(60) * system;
        }
    };

    class Draw: public Util::Draw {
    public:
        Draw(std::vector < Util::ReferenceCount<Platformer::World> > & worlds, const Logic & logic):
        worlds(worlds),
        logic(logic){
        }

        std::vector < Util::ReferenceCount<Platformer::World> > & worlds;
        const Logic & logic;

        void draw(const Graphics::Bitmap & buffer){
            // FIXME change this later as the actual resolution is in the world configuration
            Graphics::StretchedBitmap work(worlds[0]->getResolutionX(), worlds[0]->getResolutionY(), buffer);
            work.start();
            worlds[0]->draw(work);
            ostringstream info;
            info << "Camera Info - X: " << worlds[0]->getCamera(0)->getX() << " Y: " << worlds[0]->getCamera(0)->getY();
            Font::getDefaultFont().printf( 10, 10, Graphics::makeColor(255,255,255), work, info.str(), 0);
            info.str("");
            info << "Camera Info - X: " << worlds[0]->getCamera(1)->getX() << " Y: " << worlds[0]->getCamera(1)->getY();
            Font::getDefaultFont().printf( 10, 30, Graphics::makeColor(255,255,255), work, info.str(), 0);
            work.finish();
            buffer.BlitToScreen();
        }
    };

    // set input
    input.set(Keyboard::Key_ESC, 0, true, Esc);
    input.set(Keyboard::Key_UP, 0, true, Up);
    input.set(Keyboard::Key_DOWN, 0, true, Down);
    input.set(Keyboard::Key_LEFT, 0, true, Left);
    input.set(Keyboard::Key_RIGHT, 0, true, Right);
    input.set(Keyboard::Key_1, 0, true, K_1);
    input.set(Keyboard::Key_2, 0, true, K_2);
    input.set(Keyboard::Key_3, 0, true, K_3);
    input.set(Keyboard::Key_4, 0, true, K_4);

    // Graphics::Bitmap tmp(640, 480);

    cutscenes["intro"]->playAll();

    Logic logic(input, worlds);
    Draw draw(worlds, logic);

    Util::standardLoop(logic, draw);
}
<commit_msg>[platformer] Check if cutscene intro exists.<commit_after>#include "game.h"

#include "camera.h"
#include "util/gui/cutscene.h"
#include "world.h"

#include "util/bitmap.h"
#include "util/stretch-bitmap.h"
#include "util/debug.h"
#include "util/events.h"
#include "util/font.h"
#include "util/init.h"
#include "util/input/input-map.h"
#include "util/input/input-manager.h"
#include "util/input/input-source.h"
#include "util/file-system.h"
#include "util/load_exception.h"
#include "util/token.h"
#include "util/tokenreader.h"

#include <string>
#include <sstream>

using namespace std;
using namespace Platformer;

Game::Game(const std::string & filename){
    /* NOTE this is temporary to run tests on the engine
     * Eventually it will be replaced with a class that handles the entire game (worlds, etc...)
     */
    try {
	Global::debug(1,"platformer") << "Loading Platformer: " << filename << endl;
	TokenReader tr;

        Token * platformToken = tr.readTokenFromFile(filename);

	if ( *platformToken != "platformer" ){
	    throw LoadException(__FILE__, __LINE__, "Not a Platformer");
	}

	TokenView view = platformToken->view();
	while (view.hasMore()){
	    try{
		const Token * tok;
		view >> tok;
		if ( *tok == "world" ){
                    worlds.push_back(Util::ReferenceCount<Platformer::World>(new Platformer::World(tok)));
                } else if ( *tok == "cutscene" ){
                    std::string file;
                    tok->view() >> file;
                    //Util::ReferenceCount<Gui::CutScene> cutscene(new Gui::CutScene(tok));
                    Util::ReferenceCount<Gui::CutScene> cutscene(new Gui::CutScene(Filesystem::AbsolutePath(file)));
                    cutscenes[cutscene->getName()] = cutscene;
                } else {
		    Global::debug(3) << "Unhandled Platformer attribute: " << endl;
		    if (Global::getDebug() >= 3){
			tok->print(" ");
		    }
		}
	    } catch ( const TokenException & ex ) {
		throw LoadException(__FILE__, __LINE__, ex, "Platformer parse error");
	    } catch ( const LoadException & ex ) {
		// delete current;
		throw ex;
	    }
	}
    } catch (const TokenException & e){
        throw LoadException(__FILE__, __LINE__, e, "Error loading platformer file.");
    }

    // TODO remove test intro cutscene
    if (cutscenes["intro"] != NULL){
        cutscenes["intro"]->setResolution(worlds[0]->getResolutionX(), worlds[0]->getResolutionY());
    }
}

Game::~Game(){
}

void Game::run(){
    // NOTE Testing purposes only

    class Logic: public Util::Logic {
    public:
        Logic(InputMap<Keys> & input, std::vector < Util::ReferenceCount<Platformer::World> > & worlds):
        is_done(false),
        input(input),
        worlds(worlds){
        }

        bool is_done;
	InputMap<Keys> & input;
	std::vector < Util::ReferenceCount<Platformer::World> > & worlds;

	bool done(){
            return is_done;
        }

	void run(){
	    // FIXME figure out how many worlds... etc
            vector<InputMap<Keys>::InputEvent> out = InputManager::getEvents(input, InputSource());
	    for (vector<InputMap<Keys>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
            const InputMap<Keys>::InputEvent & event = *it;
            if (event.enabled){
                if (event.out == Esc){
                    is_done = true;
                }
                if (event.out == Up){
                    worlds[0]->moveCamera(0, 0,-5);
                }
                if (event.out == Down){
                    worlds[0]->moveCamera(0, 0,5);
                }
                if (event.out == Left){
                    worlds[0]->moveCamera(0, -5,0);
                }
                if (event.out == Right){
                    worlds[0]->moveCamera(0, 5,0);
                }
                if (event.out == K_1){
                    worlds[0]->moveCamera(1, -5,0);
                }
                if (event.out == K_2){
                    worlds[0]->moveCamera(1, 5,0);
                }
                if (event.out == K_3){
                    worlds[0]->moveCamera(1, 0, -5);
                }
                if (event.out == K_4){
                    worlds[0]->moveCamera(1, 0, 5);
                }
            }
        }

        worlds[0]->act();

        }

        double ticks(double system){
            return Global::ticksPerSecond(60) * system;
        }
    };

    class Draw: public Util::Draw {
    public:
        Draw(std::vector < Util::ReferenceCount<Platformer::World> > & worlds, const Logic & logic):
        worlds(worlds),
        logic(logic){
        }

        std::vector < Util::ReferenceCount<Platformer::World> > & worlds;
        const Logic & logic;

        void draw(const Graphics::Bitmap & buffer){
            // FIXME change this later as the actual resolution is in the world configuration
            Graphics::StretchedBitmap work(worlds[0]->getResolutionX(), worlds[0]->getResolutionY(), buffer);
            work.start();
            worlds[0]->draw(work);
            ostringstream info;
            info << "Camera Info - X: " << worlds[0]->getCamera(0)->getX() << " Y: " << worlds[0]->getCamera(0)->getY();
            Font::getDefaultFont().printf( 10, 10, Graphics::makeColor(255,255,255), work, info.str(), 0);
            info.str("");
            info << "Camera Info - X: " << worlds[0]->getCamera(1)->getX() << " Y: " << worlds[0]->getCamera(1)->getY();
            Font::getDefaultFont().printf( 10, 30, Graphics::makeColor(255,255,255), work, info.str(), 0);
            work.finish();
            buffer.BlitToScreen();
        }
    };

    // set input
    input.set(Keyboard::Key_ESC, 0, true, Esc);
    input.set(Keyboard::Key_UP, 0, true, Up);
    input.set(Keyboard::Key_DOWN, 0, true, Down);
    input.set(Keyboard::Key_LEFT, 0, true, Left);
    input.set(Keyboard::Key_RIGHT, 0, true, Right);
    input.set(Keyboard::Key_1, 0, true, K_1);
    input.set(Keyboard::Key_2, 0, true, K_2);
    input.set(Keyboard::Key_3, 0, true, K_3);
    input.set(Keyboard::Key_4, 0, true, K_4);

    // Graphics::Bitmap tmp(640, 480);

    if (cutscenes["intro"] != NULL){
        cutscenes["intro"]->playAll();
    }

    Logic logic(input, worlds);
    Draw draw(worlds, logic);

    Util::standardLoop(logic, draw);
}
<|endoftext|>


<commit_before>#include "../stdafx.h"

#include "SLCImageProcess.h"

#include <vector>

namespace slcimage
{
	//====================================================================================================================
	//--------------------------------------------------------------------------------------------------------------------
	void DuplicateImage(const ATL::CImage& srcImage, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull());
		if (srcImage == dstImage)		return;
		if (!dstImage.IsNull())         dstImage.Destroy();

		int srcBitsCount = srcImage.GetBPP();
		if (srcBitsCount == 32)	dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), srcBitsCount, CImage::createAlphaChannel);
		else                    dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), srcBitsCount, 0);

		if (srcImage.IsIndexed())	{
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0)	{
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}
		}

		srcImage.BitBlt(dstImage.GetDC(), 0, 0, SRCCOPY);
		dstImage.ReleaseDC(); // Remember to dstImage.ReleaseDC() after dstImage.GetDC()
	};// End of DuplicateImage(const CImage& srcImage, CImage& destImage)

	//========================================================================================================================
	//========================================================================================================================
	//------------------------------------------------------------------------------------------------------------------------
	void StretchImageByWidth(const ATL::CImage& srcImage, int widthInPixel, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && widthInPixel > 0);

		int srcBitsCount = srcImage.GetBPP();
		double imageAspectRatio = static_cast<double>( srcImage.GetHeight() ) / srcImage.GetWidth() ;

		// Get valid dstImageWidth and dstImageHeight
		int dstImageWidth = widthInPixel;
		double tmpDstImageHeight = imageAspectRatio * dstImageWidth;
		int dstImageHeight = tmpDstImageHeight > 1.0 ? static_cast<int>(tmpDstImageHeight) : 1;

		if (!dstImage.IsNull()) dstImage.Destroy();
		if (srcBitsCount == 32)	dstImage.Create(dstImageWidth, dstImageHeight, srcBitsCount, CImage::createAlphaChannel);
		else                    dstImage.Create(dstImageWidth, dstImageHeight, srcBitsCount, 0);

		// For 8bit CImage, we need to copy the ColorTable after image creation
		if (srcImage.IsIndexed()) {
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0) {
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}
		}

		HDC dstHDC = dstImage.GetDC();
		SetStretchBltMode(dstHDC, COLORONCOLOR);
		srcImage.StretchBlt(dstHDC, 0, 0, dstImageWidth, dstImageHeight, SRCCOPY);
		dstImage.ReleaseDC(); // Remember to dstImage.ReleaseDC() after dstImage.GetDC()

		//========== Below is for DownSample Algorithms Testing ===============================================
		//----------     include #include <wincodec.h> before using IWICBitmapScaler   ------------------------

		//IWICImagingFactory *imagingFactory;
		//CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&imagingFactory));
		//IWICBitmap* srcIWICBitmap;
		//imagingFactory->CreateBitmapFromHBITMAP(srcImage, 0, WICBitmapUseAlpha, &srcIWICBitmap);
		//IWICBitmapScaler* bitmapScaler;
		//imagingFactory->CreateBitmapScaler(&bitmapScaler);
		//bitmapScaler->Initialize(srcIWICBitmap, dstImageWidth, dstImageHeight, WICBitmapInterpolationModeCubic);

		//WICRect rect = { 0, 0, dstImageWidth, 1 };
		//int stride = std::abs(dstImage.GetPitch());
		//BYTE* bufferEntry = static_cast<BYTE*>(dstImage.GetBits());

		//for (int i = 0; i < dstImageHeight; ++i)
		//{
		//	bitmapScaler->CopyPixels(&rect, stride, stride, bufferEntry);
		//	bufferEntry -= stride;
		//	rect.Y += 1;
		//}

		//bitmapScaler->Release();
		//imagingFactory->Release();

	}// End of GetSmallerImageByWidth(const ATL::CImage& srcImage, int widthInPixel, ATL::CImage& dstImage)

	//====================================================================================================================
	//--------------------------------------------------------------------------------------------------------------------
	/// Converting 1Bit/4Bit image to 8Bit/24Bit, help low bit image loading for LibreImage
	void Convert8BitBelowToAbove(const ATL::CImage& srcImage, int dstBitPerPixel, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && srcImage.GetBPP() <= 8 && srcImage.GetBPP() < dstBitPerPixel);
		assert(dstBitPerPixel == 1 || dstBitPerPixel == 4 || dstBitPerPixel == 8 // GrayScaled
			|| dstBitPerPixel == 24 || dstBitPerPixel == 32);                    // Colored

		if (!dstImage.IsNull())     dstImage.Destroy();
		dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), dstBitPerPixel, 0);

		// For 8bit CImage, we need to copy the ColorTable after image creation
		if (dstImage.IsIndexed()) {
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0) {
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}
		}

		srcImage.BitBlt(dstImage.GetDC(), 0, 0, SRCCOPY);
		dstImage.ReleaseDC(); // Remember to dstImage.ReleaseDC() after dstImage.GetDC()
	}

	void Convert8bitTo32Bit(const ATL::CImage& srcImage, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && srcImage.GetBPP() == 8);

		if (!dstImage.IsNull())     dstImage.Destroy();
		dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), 32, CImage::createAlphaChannel);

		// CImage::BitBlt won't work with alpha channel, we have to set pixel one by one
		for (int row = 0; row < dstImage.GetHeight(); row++)
		{
			for (int col = 0; col < dstImage.GetWidth(); col++)
			{
				BYTE* pixelEntry = static_cast<BYTE*>(dstImage.GetPixelAddress(col, row));
				const BYTE intensity = static_cast<const BYTE*>(srcImage.GetPixelAddress(col, row))[0];
				pixelEntry[0] = intensity;
				pixelEntry[1] = intensity;
				pixelEntry[2] = intensity;
				pixelEntry[3] = 0xFF;
			}
		}
	}

} // End of namespace slcimage
<commit_msg>Fix use CImage srcImage.StretchBlt HALFTONE for 8bit image<commit_after>#include "../stdafx.h"
#include "SLCImageProcess.h"

#include <vector>
#include <wincodec.h> // for COM: IWICImagingFactory / IWICBitmapScaler
#include <VersionHelpers.h>

namespace slcimage
{
	//====================================================================================================================
	//--------------------------------------------------------------------------------------------------------------------
	void DuplicateImage(const ATL::CImage& srcImage, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull());
		if (srcImage == dstImage)		return;
		if (!dstImage.IsNull())         dstImage.Destroy();

		int srcBitsCount = srcImage.GetBPP();
		if (srcBitsCount == 32)	dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), srcBitsCount, CImage::createAlphaChannel);
		else                    dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), srcBitsCount, 0);

		if (srcImage.IsIndexed())	{
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0)	{
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}
		}

		srcImage.BitBlt(dstImage.GetDC(), 0, 0, SRCCOPY);
		dstImage.ReleaseDC(); // Remember to dstImage.ReleaseDC() after dstImage.GetDC()
	};// End of DuplicateImage(const CImage& srcImage, CImage& destImage)

	//========================================================================================================================
	//========================================================================================================================
	//------------------------------------------------------------------------------------------------------------------------
	void StretchImageByWidth(const ATL::CImage& srcImage, int widthInPixel, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && widthInPixel > 0);

		int srcBitsCount = srcImage.GetBPP();
		double imageAspectRatio = static_cast<double>( srcImage.GetHeight() ) / srcImage.GetWidth() ;

		// Get valid dstImageWidth and dstImageHeight
		int dstImageWidth = widthInPixel;
		double tmpDstImageHeight = imageAspectRatio * dstImageWidth;
		int dstImageHeight = tmpDstImageHeight > 1.0 ? static_cast<int>(tmpDstImageHeight) : 1;

		if (!dstImage.IsNull()) dstImage.Destroy();
		if (srcBitsCount == 32)	dstImage.Create(dstImageWidth, dstImageHeight, srcBitsCount, CImage::createAlphaChannel);
		else                    dstImage.Create(dstImageWidth, dstImageHeight, srcBitsCount, 0);

		// For 8bit CImage, we need to copy the ColorTable after image creation
		// IWICBitmapScaler::CopyPixels will always fail on 8bit image and BPP smaller than 8, can only use StretchBlt
		if (srcImage.IsIndexed()) {
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0) {
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}

			HDC dstHDC = dstImage.GetDC();
			SetBrushOrgEx(dstHDC, 0, 0, nullptr);
			SetStretchBltMode(dstHDC, HALFTONE);
			srcImage.StretchBlt(dstHDC, 0, 0, dstImageWidth, dstImageHeight, SRCCOPY);
			dstImage.ReleaseDC();
		}
		else
		{
			// Down-Sampling using Bicubic algorithm
			IWICImagingFactory *imagingFactory;
			HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
			assert(hr == S_OK);
			hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&imagingFactory));
			assert(hr == S_OK);
			if (hr != S_OK)  return;

			IWICBitmap* srcIWICBitmap;
			hr = imagingFactory->CreateBitmapFromHBITMAP(srcImage, 0, WICBitmapUseAlpha, &srcIWICBitmap);
			IWICBitmapScaler* bitmapScaler;
			hr = imagingFactory->CreateBitmapScaler(&bitmapScaler);
			if (IsWindows10OrGreater())
				hr = bitmapScaler->Initialize(srcIWICBitmap, dstImageWidth, dstImageHeight, WICBitmapInterpolationModeHighQualityCubic);
			else
				hr = bitmapScaler->Initialize(srcIWICBitmap, dstImageWidth, dstImageHeight, WICBitmapInterpolationModeCubic);

			WICRect rect = { 0, 0, dstImageWidth, 1 };
			int stride = std::abs(dstImage.GetPitch());
			BYTE* bufferEntry = static_cast<BYTE*>(dstImage.GetBits());

			for (int i = 0; i < dstImageHeight; ++i) {
				hr = bitmapScaler->CopyPixels(&rect, stride, stride, bufferEntry);
				bufferEntry -= stride;
				rect.Y += 1;
			}

			bitmapScaler->Release();
			imagingFactory->Release();

			CoUninitialize();
		}
	}// End of GetSmallerImageByWidth(const ATL::CImage& srcImage, int widthInPixel, ATL::CImage& dstImage)

	//====================================================================================================================
	//--------------------------------------------------------------------------------------------------------------------
	/// Converting 1Bit/4Bit image to 8Bit/24Bit, help low bit image loading for LibreImage
	void Convert8BitBelowToAbove(const ATL::CImage& srcImage, int dstBitPerPixel, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && srcImage.GetBPP() <= 8 && srcImage.GetBPP() < dstBitPerPixel);
		assert(dstBitPerPixel == 1 || dstBitPerPixel == 4 || dstBitPerPixel == 8 // GrayScaled
			|| dstBitPerPixel == 24 || dstBitPerPixel == 32);                    // Colored

		if (!dstImage.IsNull())     dstImage.Destroy();
		dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), dstBitPerPixel, 0);

		// For 8bit CImage, we need to copy the ColorTable after image creation
		if (dstImage.IsIndexed()) {
			// 8-bit: 0x100000000 = 256, in the same way, 4-bit: 0x10000 = 16, 2-bit: 0x100 = 4, 1-bit: 0x10 = 2
			int nColors = srcImage.GetMaxColorTableEntries();
			if (nColors > 0) {
				std::vector<RGBQUAD> rgbColors(nColors);
				srcImage.GetColorTable(0, nColors, rgbColors.data());
				dstImage.SetColorTable(0, nColors, rgbColors.data());
			}
		}

		srcImage.BitBlt(dstImage.GetDC(), 0, 0, SRCCOPY);
		dstImage.ReleaseDC(); // Remember to dstImage.ReleaseDC() after dstImage.GetDC()
	}

	void Convert8bitTo32Bit(const ATL::CImage& srcImage, ATL::CImage& dstImage)
	{
		assert(!srcImage.IsNull() && srcImage != dstImage && srcImage.GetBPP() == 8);

		if (!dstImage.IsNull())     dstImage.Destroy();
		dstImage.Create(srcImage.GetWidth(), srcImage.GetHeight(), 32, CImage::createAlphaChannel);

		// CImage::BitBlt won't work with alpha channel, we have to set pixel one by one
		for (int row = 0; row < dstImage.GetHeight(); row++)
		{
			for (int col = 0; col < dstImage.GetWidth(); col++)
			{
				BYTE* pixelEntry = static_cast<BYTE*>(dstImage.GetPixelAddress(col, row));
				const BYTE intensity = static_cast<const BYTE*>(srcImage.GetPixelAddress(col, row))[0];
				pixelEntry[0] = intensity;
				pixelEntry[1] = intensity;
				pixelEntry[2] = intensity;
				pixelEntry[3] = 0xFF;
			}
		}
	}

} // End of namespace slcimage
<|endoftext|>


<commit_before><commit_msg>ServiceWorker: Add null check in ServiceWorkerContextWrapper::DeleteAndStartOver<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
namespace RenderPass
{
namespace
{
Resources::ImageRef _shadowBufferImageRef;
_INTR_ARRAY(Resources::FramebufferRef) _framebufferRefs;
Resources::RenderPassRef _renderPassRef;

// <-

_INTR_INLINE void
calculateFrustumForSplit(uint32_t p_SplitIdx,
                         Core::Resources::FrustumRef p_FrustumRef,
                         Components::CameraRef p_CameraRef)
{
  _INTR_PROFILE_CPU("Render Pass", "Calc. Shadow Map Matrices");

  // Make this configurable
  const bool lastSplit = p_SplitIdx == _INTR_PSSM_SPLIT_COUNT - 1u;
  const float maxShadowDistance = 3000.0f;
  const float splitDistance = 5.0f;

  // TODO: Replace this with an actual scene AABB
  Math::AABB worldBounds = {glm::vec3(-5000.0f, -5000.0f, -5000.0f),
                            glm::vec3(5000.0f, 5000.0f, 5000.0f)};

  const glm::vec3 worldBoundsHalfExtent = Math::calcAABBHalfExtent(worldBounds);
  const float worldBoundsHalfExtentLength = glm::length(worldBoundsHalfExtent);
  const glm::vec3 worldBoundsCenter = Math::calcAABBCenter(worldBounds);

  const glm::vec3 eye =
      worldBoundsHalfExtentLength *
      (Core::Resources::PostEffectManager::_descMainLightOrientation(
           Core::Resources::PostEffectManager::_blendTargetRef) *
       glm::vec3(0.0f, 0.0f, 1.0f));
  const glm::vec3 center = glm::vec3(0.0f, 0.0f, 0.0f);

  glm::mat4& shadowViewMatrix =
      Core::Resources::FrustumManager::_descViewMatrix(p_FrustumRef);
  shadowViewMatrix = glm::lookAt(eye, center, glm::vec3(0.0f, 1.0f, 0.0f));

  const float nearPlane =
      glm::max(glm::pow(splitDistance * p_SplitIdx, 2.0f), 0.1f);
  const float farPlane = !lastSplit
                             ? glm::pow(splitDistance * (p_SplitIdx + 1u), 2.0f)
                             : maxShadowDistance;

  const glm::mat4 inverseProj =
      glm::inverse(Components::CameraManager::computeCustomProjMatrix(
          p_CameraRef, nearPlane, farPlane));

  Math::FrustumCorners viewSpaceCorners;
  Math::extractFrustumsCorners(inverseProj, viewSpaceCorners);

  glm::vec3 fpMin = glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX);
  glm::vec3 fpMax = glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX);

  for (uint32_t cornerIdx = 0; cornerIdx < 8u; ++cornerIdx)
  {
    const glm::vec3& fp = viewSpaceCorners.c[cornerIdx];

    fpMin = Math::calcVecMin(fpMin, fp);
    fpMax = Math::calcVecMax(fpMax, fp);
  }

  const glm::vec3 boundingSphereCenter = (fpMin + fpMax) * 0.5f;
  const glm::mat4 viewToShadowView =
      shadowViewMatrix *
      Components::CameraManager::_inverseViewMatrix(p_CameraRef);
  const glm::vec3 boundingSphereCenterShadowSpace =
      glm::vec3(viewToShadowView * glm::vec4(boundingSphereCenter, 1.0f));
  const float boundingSphereRadius = glm::length(fpMax - fpMin) * 0.5f;

  fpMin = boundingSphereCenterShadowSpace - boundingSphereRadius;
  fpMax = boundingSphereCenterShadowSpace + boundingSphereRadius;

  // Snap to texel increments
  {
    const glm::vec2 worldUnitsPerTexel =
        glm::vec2(fpMax - fpMin) / glm::vec2(Shadow::_shadowMapSize);

    fpMin.x /= worldUnitsPerTexel.x;
    fpMin.y /= worldUnitsPerTexel.y;
    fpMin.x = floor(fpMin.x);
    fpMin.y = floor(fpMin.y);
    fpMin.x *= worldUnitsPerTexel.x;
    fpMin.y *= worldUnitsPerTexel.y;

    fpMax.x /= worldUnitsPerTexel.x;
    fpMax.y /= worldUnitsPerTexel.y;
    fpMax.x = floor(fpMax.x);
    fpMax.y = floor(fpMax.y);
    fpMax.x *= worldUnitsPerTexel.x;
    fpMax.y *= worldUnitsPerTexel.y;
  }

  const float orthoLeft = fpMin.x;
  const float orthoRight = fpMax.x;
  const float orthoBottom = fpMax.y;
  const float orthoTop = fpMin.y;
  float orthoNear = FLT_MAX;
  float orthoFar = -FLT_MAX;

  // Calc. near/fear
  {
    glm::vec3 aabbCorners[8];
    Math::calcAABBCorners(worldBounds, aabbCorners);

    for (uint32_t i = 0u; i < 8; ++i)
    {
      aabbCorners[i] =
          glm::vec3(shadowViewMatrix * glm::vec4(aabbCorners[i], 1.0));

      orthoNear = glm::min(orthoNear, -aabbCorners[i].z);
      orthoFar = glm::max(orthoFar, -aabbCorners[i].z);
    }
  }

  Core::Resources::FrustumManager::_descProjectionType(p_FrustumRef) =
      Core::Resources::ProjectionType::kOrthographic;
  Core::Resources::FrustumManager::_descNearFarPlaneDistances(p_FrustumRef) =
      glm::vec2(orthoNear, orthoFar);
  Core::Resources::FrustumManager::_descProjectionMatrix(p_FrustumRef) =
      glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, orthoNear,
                 orthoFar);
}
}

// <-

// Static members
glm::uvec2 Shadow::_shadowMapSize = glm::uvec2(1024u, 1024u);

// <-

void Shadow::init()
{
  using namespace Resources;

  RenderPassRefArray renderPassesToCreate;
  ImageRefArray imagesToCreate;

  // Render passes
  {
    _renderPassRef = RenderPassManager::createRenderPass(_N(Shadow));
    RenderPassManager::resetToDefault(_renderPassRef);

    AttachmentDescription shadowBufferAttachment = {
        (uint8_t)RenderSystem::_depthStencilFormatToUse,
        AttachmentFlags::kClearOnLoad | AttachmentFlags::kClearStencilOnLoad};
    RenderPassManager::_descAttachments(_renderPassRef)
        .push_back(shadowBufferAttachment);
  }
  renderPassesToCreate.push_back(_renderPassRef);

  RenderPassManager::createResources(renderPassesToCreate);

  glm::uvec3 dim = glm::uvec3(_shadowMapSize, 1u);

  // Create images
  _shadowBufferImageRef = ImageManager::createImage(_N(ShadowBuffer));
  {
    ImageManager::resetToDefault(_shadowBufferImageRef);
    ImageManager::addResourceFlags(
        _shadowBufferImageRef,
        Dod::Resources::ResourceFlags::kResourceVolatile);

    ImageManager::_descDimensions(_shadowBufferImageRef) = dim;
    ImageManager::_descImageFormat(_shadowBufferImageRef) =
        RenderSystem::_depthStencilFormatToUse;
    ImageManager::_descImageType(_shadowBufferImageRef) = ImageType::kTexture;
    ImageManager::_descArrayLayerCount(_shadowBufferImageRef) =
        _INTR_MAX_SHADOW_MAP_COUNT;
  }
  imagesToCreate.push_back(_shadowBufferImageRef);

  // Create framebuffers
  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < _INTR_MAX_SHADOW_MAP_COUNT;
       ++shadowMapIdx)
  {
    FramebufferRef frameBufferRef =
        FramebufferManager::createFramebuffer(_N(RenderPassShadow));
    {
      FramebufferManager::resetToDefault(frameBufferRef);
      FramebufferManager::addResourceFlags(
          frameBufferRef, Dod::Resources::ResourceFlags::kResourceVolatile);

      FramebufferManager::_descAttachedImages(frameBufferRef)
          .push_back(AttachmentInfo(_shadowBufferImageRef, shadowMapIdx));
      FramebufferManager::_descDimensions(frameBufferRef) = glm::uvec2(dim);
      FramebufferManager::_descRenderPass(frameBufferRef) = _renderPassRef;
    }
    _framebufferRefs.push_back(frameBufferRef);
  }

  ImageManager::createResources(imagesToCreate);
  FramebufferManager::createResources(_framebufferRefs);
}

// <-

void Shadow::onReinitRendering() {}

// <-

void Shadow::destroy() {}

// <-

void Shadow::prepareFrustums(Components::CameraRef p_CameraRef,
                             _INTR_ARRAY(Core::Resources::FrustumRef) &
                                 p_ShadowFrustums)
{
  _INTR_PROFILE_CPU("Render Pass", "Prepare Shadow Frustums");

  for (uint32_t i = 0u; i < p_ShadowFrustums.size(); ++i)
  {
    Core::Resources::FrustumManager::destroyFrustum(p_ShadowFrustums[i]);
  }
  p_ShadowFrustums.clear();

  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < _INTR_PSSM_SPLIT_COUNT;
       ++shadowMapIdx)
  {
    Core::Resources::FrustumRef frustumRef =
        Core::Resources::FrustumManager::createFrustum(_N(ShadowFrustum));

    calculateFrustumForSplit(shadowMapIdx, frustumRef, p_CameraRef);

    p_ShadowFrustums.push_back(frustumRef);
  }
}

// <-

void Shadow::render(float p_DeltaT, Components::CameraRef p_CameraRef)
{
  using namespace Resources;

  _INTR_PROFILE_CPU("Render Pass", "Render Shadows");
  _INTR_PROFILE_GPU("Render Shadows");

  _INTR_PROFILE_COUNTER_SET("Dispatched Draw Calls (Shadows)",
                            DrawCallDispatcher::_dispatchedDrawCallCount);

  const _INTR_ARRAY(Core::Resources::FrustumRef)& shadowFrustums =
      RenderProcess::Default::_shadowFrustums[p_CameraRef];
  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < shadowFrustums.size();
       ++shadowMapIdx)
  {
    _INTR_PROFILE_CPU("Render Pass", "Render Shadow Map");
    _INTR_PROFILE_GPU("Render Shadow Map");

    Core::Resources::FrustumRef frustumRef = shadowFrustums[shadowMapIdx];

    ImageManager::insertImageMemoryBarrierSubResource(
        _shadowBufferImageRef, VK_IMAGE_LAYOUT_UNDEFINED,
        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0u, shadowMapIdx);

    const uint32_t frustumIdx = shadowMapIdx + 1u;

    static DrawCallRefArray visibleDrawCalls;
    visibleDrawCalls.clear();

    RenderProcess::Default::getVisibleDrawCalls(
        p_CameraRef, frustumIdx, MaterialManager::getMaterialPassId(_N(Shadow)))
        .copy(visibleDrawCalls);
    RenderProcess::Default::getVisibleDrawCalls(
        p_CameraRef, frustumIdx,
        MaterialManager::getMaterialPassId(_N(ShadowFoliage)))
        .copy(visibleDrawCalls);

    DrawCallManager::sortDrawCallsFrontToBack(visibleDrawCalls);

    // Update per mesh uniform data
    {
      Components::MeshManager::updatePerInstanceData(p_CameraRef, frustumIdx);
      Core::Components::MeshManager::updateUniformData(visibleDrawCalls);
    }

    VkClearValue clearValues[1] = {};
    {
      clearValues[0].depthStencil.depth = 1.0f;
      clearValues[0].depthStencil.stencil = 0u;
    }

    RenderSystem::beginRenderPass(
        _renderPassRef, _framebufferRefs[shadowMapIdx],
        VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, 1u, clearValues);
    {
      DrawCallDispatcher::queueDrawCalls(visibleDrawCalls, _renderPassRef,
                                         _framebufferRefs[shadowMapIdx]);
      _INTR_PROFILE_COUNTER_ADD("Dispatched Draw Calls (Shadows)",
                                DrawCallDispatcher::_dispatchedDrawCallCount);
    }
    RenderSystem::endRenderPass(_renderPassRef);

    ImageManager::insertImageMemoryBarrierSubResource(
        _shadowBufferImageRef, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0u, shadowMapIdx);
  }
}
}
}
}
}
<commit_msg>Use 1.5k shadow maps by default<commit_after>// Copyright 2016 Benjamin Glatzel
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Precompiled header file
#include "stdafx_vulkan.h"
#include "stdafx.h"

namespace Intrinsic
{
namespace Renderer
{
namespace Vulkan
{
namespace RenderPass
{
namespace
{
Resources::ImageRef _shadowBufferImageRef;
_INTR_ARRAY(Resources::FramebufferRef) _framebufferRefs;
Resources::RenderPassRef _renderPassRef;

// <-

_INTR_INLINE void
calculateFrustumForSplit(uint32_t p_SplitIdx,
                         Core::Resources::FrustumRef p_FrustumRef,
                         Components::CameraRef p_CameraRef)
{
  _INTR_PROFILE_CPU("Render Pass", "Calc. Shadow Map Matrices");

  // Make this configurable
  const bool lastSplit = p_SplitIdx == _INTR_PSSM_SPLIT_COUNT - 1u;
  const float maxShadowDistance = 3000.0f;
  const float splitDistance = 5.0f;

  // TODO: Replace this with an actual scene AABB
  Math::AABB worldBounds = {glm::vec3(-5000.0f, -5000.0f, -5000.0f),
                            glm::vec3(5000.0f, 5000.0f, 5000.0f)};

  const glm::vec3 worldBoundsHalfExtent = Math::calcAABBHalfExtent(worldBounds);
  const float worldBoundsHalfExtentLength = glm::length(worldBoundsHalfExtent);
  const glm::vec3 worldBoundsCenter = Math::calcAABBCenter(worldBounds);

  const glm::vec3 eye =
      worldBoundsHalfExtentLength *
      (Core::Resources::PostEffectManager::_descMainLightOrientation(
           Core::Resources::PostEffectManager::_blendTargetRef) *
       glm::vec3(0.0f, 0.0f, 1.0f));
  const glm::vec3 center = glm::vec3(0.0f, 0.0f, 0.0f);

  glm::mat4& shadowViewMatrix =
      Core::Resources::FrustumManager::_descViewMatrix(p_FrustumRef);
  shadowViewMatrix = glm::lookAt(eye, center, glm::vec3(0.0f, 1.0f, 0.0f));

  const float nearPlane =
      glm::max(glm::pow(splitDistance * p_SplitIdx, 2.0f), 0.1f);
  const float farPlane = !lastSplit
                             ? glm::pow(splitDistance * (p_SplitIdx + 1u), 2.0f)
                             : maxShadowDistance;

  const glm::mat4 inverseProj =
      glm::inverse(Components::CameraManager::computeCustomProjMatrix(
          p_CameraRef, nearPlane, farPlane));

  Math::FrustumCorners viewSpaceCorners;
  Math::extractFrustumsCorners(inverseProj, viewSpaceCorners);

  glm::vec3 fpMin = glm::vec3(FLT_MAX, FLT_MAX, FLT_MAX);
  glm::vec3 fpMax = glm::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX);

  for (uint32_t cornerIdx = 0; cornerIdx < 8u; ++cornerIdx)
  {
    const glm::vec3& fp = viewSpaceCorners.c[cornerIdx];

    fpMin = Math::calcVecMin(fpMin, fp);
    fpMax = Math::calcVecMax(fpMax, fp);
  }

  const glm::vec3 boundingSphereCenter = (fpMin + fpMax) * 0.5f;
  const glm::mat4 viewToShadowView =
      shadowViewMatrix *
      Components::CameraManager::_inverseViewMatrix(p_CameraRef);
  const glm::vec3 boundingSphereCenterShadowSpace =
      glm::vec3(viewToShadowView * glm::vec4(boundingSphereCenter, 1.0f));
  const float boundingSphereRadius = glm::length(fpMax - fpMin) * 0.5f;

  fpMin = boundingSphereCenterShadowSpace - boundingSphereRadius;
  fpMax = boundingSphereCenterShadowSpace + boundingSphereRadius;

  // Snap to texel increments
  {
    const glm::vec2 worldUnitsPerTexel =
        glm::vec2(fpMax - fpMin) / glm::vec2(Shadow::_shadowMapSize);

    fpMin.x /= worldUnitsPerTexel.x;
    fpMin.y /= worldUnitsPerTexel.y;
    fpMin.x = floor(fpMin.x);
    fpMin.y = floor(fpMin.y);
    fpMin.x *= worldUnitsPerTexel.x;
    fpMin.y *= worldUnitsPerTexel.y;

    fpMax.x /= worldUnitsPerTexel.x;
    fpMax.y /= worldUnitsPerTexel.y;
    fpMax.x = floor(fpMax.x);
    fpMax.y = floor(fpMax.y);
    fpMax.x *= worldUnitsPerTexel.x;
    fpMax.y *= worldUnitsPerTexel.y;
  }

  const float orthoLeft = fpMin.x;
  const float orthoRight = fpMax.x;
  const float orthoBottom = fpMax.y;
  const float orthoTop = fpMin.y;
  float orthoNear = FLT_MAX;
  float orthoFar = -FLT_MAX;

  // Calc. near/fear
  {
    glm::vec3 aabbCorners[8];
    Math::calcAABBCorners(worldBounds, aabbCorners);

    for (uint32_t i = 0u; i < 8; ++i)
    {
      aabbCorners[i] =
          glm::vec3(shadowViewMatrix * glm::vec4(aabbCorners[i], 1.0));

      orthoNear = glm::min(orthoNear, -aabbCorners[i].z);
      orthoFar = glm::max(orthoFar, -aabbCorners[i].z);
    }
  }

  Core::Resources::FrustumManager::_descProjectionType(p_FrustumRef) =
      Core::Resources::ProjectionType::kOrthographic;
  Core::Resources::FrustumManager::_descNearFarPlaneDistances(p_FrustumRef) =
      glm::vec2(orthoNear, orthoFar);
  Core::Resources::FrustumManager::_descProjectionMatrix(p_FrustumRef) =
      glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, orthoNear,
                 orthoFar);
}
}

// <-

// Static members
glm::uvec2 Shadow::_shadowMapSize = glm::uvec2(1536u, 1536u);

// <-

void Shadow::init()
{
  using namespace Resources;

  RenderPassRefArray renderPassesToCreate;
  ImageRefArray imagesToCreate;

  // Render passes
  {
    _renderPassRef = RenderPassManager::createRenderPass(_N(Shadow));
    RenderPassManager::resetToDefault(_renderPassRef);

    AttachmentDescription shadowBufferAttachment = {
        (uint8_t)RenderSystem::_depthStencilFormatToUse,
        AttachmentFlags::kClearOnLoad | AttachmentFlags::kClearStencilOnLoad};
    RenderPassManager::_descAttachments(_renderPassRef)
        .push_back(shadowBufferAttachment);
  }
  renderPassesToCreate.push_back(_renderPassRef);

  RenderPassManager::createResources(renderPassesToCreate);

  glm::uvec3 dim = glm::uvec3(_shadowMapSize, 1u);

  // Create images
  _shadowBufferImageRef = ImageManager::createImage(_N(ShadowBuffer));
  {
    ImageManager::resetToDefault(_shadowBufferImageRef);
    ImageManager::addResourceFlags(
        _shadowBufferImageRef,
        Dod::Resources::ResourceFlags::kResourceVolatile);

    ImageManager::_descDimensions(_shadowBufferImageRef) = dim;
    ImageManager::_descImageFormat(_shadowBufferImageRef) =
        RenderSystem::_depthStencilFormatToUse;
    ImageManager::_descImageType(_shadowBufferImageRef) = ImageType::kTexture;
    ImageManager::_descArrayLayerCount(_shadowBufferImageRef) =
        _INTR_MAX_SHADOW_MAP_COUNT;
  }
  imagesToCreate.push_back(_shadowBufferImageRef);

  // Create framebuffers
  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < _INTR_MAX_SHADOW_MAP_COUNT;
       ++shadowMapIdx)
  {
    FramebufferRef frameBufferRef =
        FramebufferManager::createFramebuffer(_N(RenderPassShadow));
    {
      FramebufferManager::resetToDefault(frameBufferRef);
      FramebufferManager::addResourceFlags(
          frameBufferRef, Dod::Resources::ResourceFlags::kResourceVolatile);

      FramebufferManager::_descAttachedImages(frameBufferRef)
          .push_back(AttachmentInfo(_shadowBufferImageRef, shadowMapIdx));
      FramebufferManager::_descDimensions(frameBufferRef) = glm::uvec2(dim);
      FramebufferManager::_descRenderPass(frameBufferRef) = _renderPassRef;
    }
    _framebufferRefs.push_back(frameBufferRef);
  }

  ImageManager::createResources(imagesToCreate);
  FramebufferManager::createResources(_framebufferRefs);
}

// <-

void Shadow::onReinitRendering() {}

// <-

void Shadow::destroy() {}

// <-

void Shadow::prepareFrustums(Components::CameraRef p_CameraRef,
                             _INTR_ARRAY(Core::Resources::FrustumRef) &
                                 p_ShadowFrustums)
{
  _INTR_PROFILE_CPU("Render Pass", "Prepare Shadow Frustums");

  for (uint32_t i = 0u; i < p_ShadowFrustums.size(); ++i)
  {
    Core::Resources::FrustumManager::destroyFrustum(p_ShadowFrustums[i]);
  }
  p_ShadowFrustums.clear();

  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < _INTR_PSSM_SPLIT_COUNT;
       ++shadowMapIdx)
  {
    Core::Resources::FrustumRef frustumRef =
        Core::Resources::FrustumManager::createFrustum(_N(ShadowFrustum));

    calculateFrustumForSplit(shadowMapIdx, frustumRef, p_CameraRef);

    p_ShadowFrustums.push_back(frustumRef);
  }
}

// <-

void Shadow::render(float p_DeltaT, Components::CameraRef p_CameraRef)
{
  using namespace Resources;

  _INTR_PROFILE_CPU("Render Pass", "Render Shadows");
  _INTR_PROFILE_GPU("Render Shadows");

  _INTR_PROFILE_COUNTER_SET("Dispatched Draw Calls (Shadows)",
                            DrawCallDispatcher::_dispatchedDrawCallCount);

  const _INTR_ARRAY(Core::Resources::FrustumRef)& shadowFrustums =
      RenderProcess::Default::_shadowFrustums[p_CameraRef];
  for (uint32_t shadowMapIdx = 0u; shadowMapIdx < shadowFrustums.size();
       ++shadowMapIdx)
  {
    _INTR_PROFILE_CPU("Render Pass", "Render Shadow Map");
    _INTR_PROFILE_GPU("Render Shadow Map");

    Core::Resources::FrustumRef frustumRef = shadowFrustums[shadowMapIdx];

    ImageManager::insertImageMemoryBarrierSubResource(
        _shadowBufferImageRef, VK_IMAGE_LAYOUT_UNDEFINED,
        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0u, shadowMapIdx);

    const uint32_t frustumIdx = shadowMapIdx + 1u;

    static DrawCallRefArray visibleDrawCalls;
    visibleDrawCalls.clear();

    RenderProcess::Default::getVisibleDrawCalls(
        p_CameraRef, frustumIdx, MaterialManager::getMaterialPassId(_N(Shadow)))
        .copy(visibleDrawCalls);
    RenderProcess::Default::getVisibleDrawCalls(
        p_CameraRef, frustumIdx,
        MaterialManager::getMaterialPassId(_N(ShadowFoliage)))
        .copy(visibleDrawCalls);

    DrawCallManager::sortDrawCallsFrontToBack(visibleDrawCalls);

    // Update per mesh uniform data
    {
      Components::MeshManager::updatePerInstanceData(p_CameraRef, frustumIdx);
      Core::Components::MeshManager::updateUniformData(visibleDrawCalls);
    }

    VkClearValue clearValues[1] = {};
    {
      clearValues[0].depthStencil.depth = 1.0f;
      clearValues[0].depthStencil.stencil = 0u;
    }

    RenderSystem::beginRenderPass(
        _renderPassRef, _framebufferRefs[shadowMapIdx],
        VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, 1u, clearValues);
    {
      DrawCallDispatcher::queueDrawCalls(visibleDrawCalls, _renderPassRef,
                                         _framebufferRefs[shadowMapIdx]);
      _INTR_PROFILE_COUNTER_ADD("Dispatched Draw Calls (Shadows)",
                                DrawCallDispatcher::_dispatchedDrawCallCount);
    }
    RenderSystem::endRenderPass(_renderPassRef);

    ImageManager::insertImageMemoryBarrierSubResource(
        _shadowBufferImageRef, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0u, shadowMapIdx);
  }
}
}
}
}
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE path_element_tests

// boost.test
#include <boost/test/included/unit_test.hpp>

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

// mapnik
#include <mapnik/map.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/svg/output/svg_renderer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/color_factory.hpp>

// stl
#include <fstream>
#include <iterator>

namespace fs = boost::filesystem;
using namespace mapnik;

void prepare_map(Map& m)
{
    const std::string mapnik_dir("/usr/local/lib/mapnik/");
    std::cout << " looking for 'shape.input' plugin in... " << mapnik_dir << "input/" << "\n";
    datasource_cache::instance().register_datasources(mapnik_dir + "input/");

    // create styles

    // Provinces (polygon)
    feature_type_style provpoly_style;

    rule provpoly_rule_on;
    provpoly_rule_on.set_filter(parse_expression("[NAME_EN] = 'Ontario'"));
    provpoly_rule_on.append(polygon_symbolizer(color(250, 190, 183)));
    provpoly_style.add_rule(provpoly_rule_on);

    rule provpoly_rule_qc;
    provpoly_rule_qc.set_filter(parse_expression("[NOM_FR] = 'Québec'"));
    provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203)));
    provpoly_style.add_rule(provpoly_rule_qc);

    m.insert_style("provinces",provpoly_style);

    // Provinces (polyline)
    feature_type_style provlines_style;

    stroke provlines_stk (color(0,0,0),1.0);
    provlines_stk.add_dash(8, 4);
    provlines_stk.add_dash(2, 2);
    provlines_stk.add_dash(2, 2);

    rule provlines_rule;
    provlines_rule.append(line_symbolizer(provlines_stk));
    provlines_style.add_rule(provlines_rule);

    m.insert_style("provlines",provlines_style);

    // Drainage
    feature_type_style qcdrain_style;

    rule qcdrain_rule;
    qcdrain_rule.set_filter(parse_expression("[HYC] = 8"));
    qcdrain_rule.append(polygon_symbolizer(color(153, 204, 255)));
    qcdrain_style.add_rule(qcdrain_rule);

    m.insert_style("drainage",qcdrain_style);

    // Roads 3 and 4 (The "grey" roads)
    feature_type_style roads34_style;
    rule roads34_rule;
    roads34_rule.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4"));
    stroke roads34_rule_stk(color(171,158,137),2.0);
    roads34_rule_stk.set_line_cap(ROUND_CAP);
    roads34_rule_stk.set_line_join(ROUND_JOIN);
    roads34_rule.append(line_symbolizer(roads34_rule_stk));
    roads34_style.add_rule(roads34_rule);

    m.insert_style("smallroads",roads34_style);

    // Roads 2 (The thin yellow ones)
    feature_type_style roads2_style_1;
    rule roads2_rule_1;
    roads2_rule_1.set_filter(parse_expression("[CLASS] = 2"));
    stroke roads2_rule_stk_1(color(171,158,137),4.0);
    roads2_rule_stk_1.set_line_cap(ROUND_CAP);
    roads2_rule_stk_1.set_line_join(ROUND_JOIN);
    roads2_rule_1.append(line_symbolizer(roads2_rule_stk_1));
    roads2_style_1.add_rule(roads2_rule_1);

    m.insert_style("road-border", roads2_style_1);

    feature_type_style roads2_style_2;
    rule roads2_rule_2;
    roads2_rule_2.set_filter(parse_expression("[CLASS] = 2"));
    stroke roads2_rule_stk_2(color(255,250,115),2.0);
    roads2_rule_stk_2.set_line_cap(ROUND_CAP);
    roads2_rule_stk_2.set_line_join(ROUND_JOIN);
    roads2_rule_2.append(line_symbolizer(roads2_rule_stk_2));
    roads2_style_2.add_rule(roads2_rule_2);

    m.insert_style("road-fill", roads2_style_2);

    // Roads 1 (The big orange ones, the highways)
    feature_type_style roads1_style_1;
    rule roads1_rule_1;
    roads1_rule_1.set_filter(parse_expression("[CLASS] = 1"));
    stroke roads1_rule_stk_1(color(188,149,28),7.0);
    roads1_rule_stk_1.set_line_cap(ROUND_CAP);
    roads1_rule_stk_1.set_line_join(ROUND_JOIN);
    roads1_rule_1.append(line_symbolizer(roads1_rule_stk_1));
    roads1_style_1.add_rule(roads1_rule_1);
    m.insert_style("highway-border", roads1_style_1);

    feature_type_style roads1_style_2;
    rule roads1_rule_2;
    roads1_rule_2.set_filter(parse_expression("[CLASS] = 1"));
    stroke roads1_rule_stk_2(color(242,191,36),5.0);
    roads1_rule_stk_2.set_line_cap(ROUND_CAP);
    roads1_rule_stk_2.set_line_join(ROUND_JOIN);
    roads1_rule_2.append(line_symbolizer(roads1_rule_stk_2));
    roads1_style_2.add_rule(roads1_rule_2);
    m.insert_style("highway-fill", roads1_style_2);

    // layers
    // Provincial  polygons
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/boundaries";

        layer lyr("Provinces");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("provinces");
        m.addLayer(lyr);
    }

    // Drainage
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/qcdrainage";
        layer lyr("Quebec Hydrography");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("drainage");
        m.addLayer(lyr);
    }

    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/ontdrainage";

        layer lyr("Ontario Hydrography");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("drainage");
        m.addLayer(lyr);
    }

    // Provincial boundaries
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/boundaries_l";
        layer lyr("Provincial borders");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("provlines");
        m.addLayer(lyr);
    }

    // Roads
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/roads";
        layer lyr("Roads");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("smallroads");
        lyr.add_style("road-border");
        lyr.add_style("road-fill");
        lyr.add_style("highway-border");
        lyr.add_style("highway-fill");

        m.addLayer(lyr);
    }
}

void render_to_file(Map const& m, const std::string output_filename)
{
    std::ofstream output_stream(output_filename.c_str());

    if(output_stream)
    {
        typedef svg_renderer<std::ostream_iterator<char> > svg_ren;

        std::ostream_iterator<char> output_stream_iterator(output_stream);

        svg_ren renderer(m, output_stream_iterator);
        renderer.apply();

        output_stream.close();

        fs::path output_filename_path =
            fs::system_complete(fs::path(".")) / fs::path(output_filename);

        BOOST_CHECK_MESSAGE(fs::exists(output_filename_path),
                            "File '"+output_filename_path.string()+"' was created.");
    }
    else
    {
        BOOST_FAIL("Could not create create/open file '"+output_filename+"'.");
    }
}

BOOST_AUTO_TEST_CASE(path_element_test_case_1)
{
    Map m(800,600);
    m.set_background(parse_color("steelblue"));

    prepare_map(m);

    //m.zoom_to_box(box2d<double>(1405120.04127408, -247003.813399447,
    //1706357.31328276, -25098.593149577));
    m.zoom_all();
    render_to_file(m, "path_element_test_case_1.svg");
}
<commit_msg>catch another addLayer -> add_layer case<commit_after>#define BOOST_TEST_MODULE path_element_tests

// boost.test
#include <boost/test/included/unit_test.hpp>

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

// mapnik
#include <mapnik/map.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/svg/output/svg_renderer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/color_factory.hpp>

// stl
#include <fstream>
#include <iterator>

namespace fs = boost::filesystem;
using namespace mapnik;

void prepare_map(Map& m)
{
    const std::string mapnik_dir("/usr/local/lib/mapnik/");
    std::cout << " looking for 'shape.input' plugin in... " << mapnik_dir << "input/" << "\n";
    datasource_cache::instance().register_datasources(mapnik_dir + "input/");

    // create styles

    // Provinces (polygon)
    feature_type_style provpoly_style;

    rule provpoly_rule_on;
    provpoly_rule_on.set_filter(parse_expression("[NAME_EN] = 'Ontario'"));
    provpoly_rule_on.append(polygon_symbolizer(color(250, 190, 183)));
    provpoly_style.add_rule(provpoly_rule_on);

    rule provpoly_rule_qc;
    provpoly_rule_qc.set_filter(parse_expression("[NOM_FR] = 'Québec'"));
    provpoly_rule_qc.append(polygon_symbolizer(color(217, 235, 203)));
    provpoly_style.add_rule(provpoly_rule_qc);

    m.insert_style("provinces",provpoly_style);

    // Provinces (polyline)
    feature_type_style provlines_style;

    stroke provlines_stk (color(0,0,0),1.0);
    provlines_stk.add_dash(8, 4);
    provlines_stk.add_dash(2, 2);
    provlines_stk.add_dash(2, 2);

    rule provlines_rule;
    provlines_rule.append(line_symbolizer(provlines_stk));
    provlines_style.add_rule(provlines_rule);

    m.insert_style("provlines",provlines_style);

    // Drainage
    feature_type_style qcdrain_style;

    rule qcdrain_rule;
    qcdrain_rule.set_filter(parse_expression("[HYC] = 8"));
    qcdrain_rule.append(polygon_symbolizer(color(153, 204, 255)));
    qcdrain_style.add_rule(qcdrain_rule);

    m.insert_style("drainage",qcdrain_style);

    // Roads 3 and 4 (The "grey" roads)
    feature_type_style roads34_style;
    rule roads34_rule;
    roads34_rule.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4"));
    stroke roads34_rule_stk(color(171,158,137),2.0);
    roads34_rule_stk.set_line_cap(ROUND_CAP);
    roads34_rule_stk.set_line_join(ROUND_JOIN);
    roads34_rule.append(line_symbolizer(roads34_rule_stk));
    roads34_style.add_rule(roads34_rule);

    m.insert_style("smallroads",roads34_style);

    // Roads 2 (The thin yellow ones)
    feature_type_style roads2_style_1;
    rule roads2_rule_1;
    roads2_rule_1.set_filter(parse_expression("[CLASS] = 2"));
    stroke roads2_rule_stk_1(color(171,158,137),4.0);
    roads2_rule_stk_1.set_line_cap(ROUND_CAP);
    roads2_rule_stk_1.set_line_join(ROUND_JOIN);
    roads2_rule_1.append(line_symbolizer(roads2_rule_stk_1));
    roads2_style_1.add_rule(roads2_rule_1);

    m.insert_style("road-border", roads2_style_1);

    feature_type_style roads2_style_2;
    rule roads2_rule_2;
    roads2_rule_2.set_filter(parse_expression("[CLASS] = 2"));
    stroke roads2_rule_stk_2(color(255,250,115),2.0);
    roads2_rule_stk_2.set_line_cap(ROUND_CAP);
    roads2_rule_stk_2.set_line_join(ROUND_JOIN);
    roads2_rule_2.append(line_symbolizer(roads2_rule_stk_2));
    roads2_style_2.add_rule(roads2_rule_2);

    m.insert_style("road-fill", roads2_style_2);

    // Roads 1 (The big orange ones, the highways)
    feature_type_style roads1_style_1;
    rule roads1_rule_1;
    roads1_rule_1.set_filter(parse_expression("[CLASS] = 1"));
    stroke roads1_rule_stk_1(color(188,149,28),7.0);
    roads1_rule_stk_1.set_line_cap(ROUND_CAP);
    roads1_rule_stk_1.set_line_join(ROUND_JOIN);
    roads1_rule_1.append(line_symbolizer(roads1_rule_stk_1));
    roads1_style_1.add_rule(roads1_rule_1);
    m.insert_style("highway-border", roads1_style_1);

    feature_type_style roads1_style_2;
    rule roads1_rule_2;
    roads1_rule_2.set_filter(parse_expression("[CLASS] = 1"));
    stroke roads1_rule_stk_2(color(242,191,36),5.0);
    roads1_rule_stk_2.set_line_cap(ROUND_CAP);
    roads1_rule_stk_2.set_line_join(ROUND_JOIN);
    roads1_rule_2.append(line_symbolizer(roads1_rule_stk_2));
    roads1_style_2.add_rule(roads1_rule_2);
    m.insert_style("highway-fill", roads1_style_2);

    // layers
    // Provincial  polygons
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/boundaries";

        layer lyr("Provinces");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("provinces");
        m.add_layer(lyr);
    }

    // Drainage
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/qcdrainage";
        layer lyr("Quebec Hydrography");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("drainage");
        m.add_layer(lyr);
    }

    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/ontdrainage";

        layer lyr("Ontario Hydrography");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("drainage");
        m.add_layer(lyr);
    }

    // Provincial boundaries
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/boundaries_l";
        layer lyr("Provincial borders");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("provlines");
        m.add_layer(lyr);
    }

    // Roads
    {
        parameters p;
        p["type"]="shape";
        p["file"]="../../../demo/data/roads";
        layer lyr("Roads");
        lyr.set_datasource(datasource_cache::instance().create(p));
        lyr.add_style("smallroads");
        lyr.add_style("road-border");
        lyr.add_style("road-fill");
        lyr.add_style("highway-border");
        lyr.add_style("highway-fill");

        m.add_layer(lyr);
    }
}

void render_to_file(Map const& m, const std::string output_filename)
{
    std::ofstream output_stream(output_filename.c_str());

    if(output_stream)
    {
        typedef svg_renderer<std::ostream_iterator<char> > svg_ren;

        std::ostream_iterator<char> output_stream_iterator(output_stream);

        svg_ren renderer(m, output_stream_iterator);
        renderer.apply();

        output_stream.close();

        fs::path output_filename_path =
            fs::system_complete(fs::path(".")) / fs::path(output_filename);

        BOOST_CHECK_MESSAGE(fs::exists(output_filename_path),
                            "File '"+output_filename_path.string()+"' was created.");
    }
    else
    {
        BOOST_FAIL("Could not create create/open file '"+output_filename+"'.");
    }
}

BOOST_AUTO_TEST_CASE(path_element_test_case_1)
{
    Map m(800,600);
    m.set_background(parse_color("steelblue"));

    prepare_map(m);

    //m.zoom_to_box(box2d<double>(1405120.04127408, -247003.813399447,
    //1706357.31328276, -25098.593149577));
    m.zoom_all();
    render_to_file(m, "path_element_test_case_1.svg");
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkAutoSelectingDICOMReaderService.h"

#include <mitkDICOMFileReaderSelector.h>

namespace mitk {

AutoSelectingDICOMReaderService::AutoSelectingDICOMReaderService()
  : BaseDICOMReaderService("MITK DICOM Reader v2 (autoselect)")
{
  this->RegisterService();
}

DICOMFileReader::Pointer AutoSelectingDICOMReaderService::GetReader(const mitk::StringList& relevantFiles) const
{
  mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New();

  selector->LoadBuiltIn3DConfigs();
  selector->LoadBuiltIn3DnTConfigs();
  selector->SetInputFiles(relevantFiles);

  mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages();
  if(reader.IsNotNull())
  {
      //reset tag cache to ensure that additional tags of interest
      //will be regarded by the reader if set later on.
      reader->SetTagCache(nullptr);
  }

  return reader;
};

AutoSelectingDICOMReaderService* AutoSelectingDICOMReaderService::Clone() const
{
  return new AutoSelectingDICOMReaderService(*this);
}

}
<commit_msg>Increase autoselect dicom reader ranking to make it default<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkAutoSelectingDICOMReaderService.h"

#include <mitkDICOMFileReaderSelector.h>

namespace mitk {

AutoSelectingDICOMReaderService::AutoSelectingDICOMReaderService()
  : BaseDICOMReaderService("MITK DICOM Reader v2 (autoselect)")
{
  this->SetRanking(5);
  this->RegisterService();
}

DICOMFileReader::Pointer AutoSelectingDICOMReaderService::GetReader(const mitk::StringList& relevantFiles) const
{
  mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New();

  selector->LoadBuiltIn3DConfigs();
  selector->LoadBuiltIn3DnTConfigs();
  selector->SetInputFiles(relevantFiles);

  mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages();
  if(reader.IsNotNull())
  {
      //reset tag cache to ensure that additional tags of interest
      //will be regarded by the reader if set later on.
      reader->SetTagCache(nullptr);
  }

  return reader;
};

AutoSelectingDICOMReaderService* AutoSelectingDICOMReaderService::Clone() const
{
  return new AutoSelectingDICOMReaderService(*this);
}

}
<|endoftext|>


<commit_before><commit_msg>fix typo<commit_after><|endoftext|>


<commit_before>#include "addressbookdialog.h"
#include "ui_addressbookdialog.h"

#include "addresstablemodel.h"
#include "editaddressdialog.h"

#include <QSortFilterProxyModel>
#include <QClipboard>
#include <QDebug>

AddressBookDialog::AddressBookDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AddressBookDialog),
    model(0)
{
    ui->setupUi(this);

    switch(mode)
    {
    case ForSending:
        connect(ui->receiveTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_buttonBox_accepted()));
        connect(ui->sendTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_buttonBox_accepted()));
        break;
    case ForEditing:
        connect(ui->receiveTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_editButton_clicked()));
        connect(ui->sendTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_editButton_clicked()));
        break;
    }
}

AddressBookDialog::~AddressBookDialog()
{
    delete ui;
}

void AddressBookDialog::setModel(AddressTableModel *model)
{
    this->model = model;
    // Refresh list from core
    model->updateList();

    // Receive filter
    QSortFilterProxyModel *receive_model = new QSortFilterProxyModel(this);
    receive_model->setSourceModel(model);
    receive_model->setDynamicSortFilter(true);
    receive_model->setFilterRole(AddressTableModel::TypeRole);
    receive_model->setFilterFixedString(AddressTableModel::Receive);
    ui->receiveTableView->setModel(receive_model);

    // Send filter
    QSortFilterProxyModel *send_model = new QSortFilterProxyModel(this);
    send_model->setSourceModel(model);
    send_model->setDynamicSortFilter(true);
    send_model->setFilterRole(AddressTableModel::TypeRole);
    send_model->setFilterFixedString(AddressTableModel::Send);
    ui->sendTableView->setModel(send_model);

    // Set column widths
    ui->receiveTableView->horizontalHeader()->resizeSection(
            AddressTableModel::Address, 320);
    ui->receiveTableView->horizontalHeader()->setResizeMode(
            AddressTableModel::Label, QHeaderView::Stretch);
    ui->sendTableView->horizontalHeader()->resizeSection(
            AddressTableModel::Address, 320);
    ui->sendTableView->horizontalHeader()->setResizeMode(
            AddressTableModel::Label, QHeaderView::Stretch);
}

void AddressBookDialog::setTab(int tab)
{
    ui->tabWidget->setCurrentIndex(tab);
    on_tabWidget_currentChanged(tab);
}

QTableView *AddressBookDialog::getCurrentTable()
{
    switch(ui->tabWidget->currentIndex())
    {
    case SendingTab:
        return ui->sendTableView;
    case ReceivingTab:
        return ui->receiveTableView;
    default:
        return 0;
    }
}

void AddressBookDialog::on_copyToClipboard_clicked()
{
    // Copy currently selected address to clipboard
    //   (or nothing, if nothing selected)
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);

    foreach (QModelIndex index, indexes)
    {
        QVariant address = index.data();
        QApplication::clipboard()->setText(address.toString());
    }
}

void AddressBookDialog::on_editButton_clicked()
{
    QModelIndexList indexes = getCurrentTable()->selectionModel()->selectedRows();
    if(indexes.isEmpty())
    {
        return;
    }
    // Map selected index to source address book model
    QAbstractProxyModel *proxy_model = static_cast<QAbstractProxyModel*>(getCurrentTable()->model());
    QModelIndex selected = proxy_model->mapToSource(indexes.at(0));

    // Double click also triggers edit button
    EditAddressDialog dlg(
            ui->tabWidget->currentIndex() == SendingTab ?
            EditAddressDialog::EditSendingAddress :
            EditAddressDialog::EditReceivingAddress);
    dlg.setModel(model);
    dlg.loadRow(selected.row());
    if(dlg.exec())
    {
        dlg.saveCurrentRow();
    }
}

void AddressBookDialog::on_newAddressButton_clicked()
{
    EditAddressDialog dlg(
            ui->tabWidget->currentIndex() == SendingTab ?
            EditAddressDialog::NewSendingAddress :
            EditAddressDialog::NewReceivingAddress);
    dlg.setModel(model);
    if(dlg.exec())
    {
        dlg.saveCurrentRow();
    }
}

void AddressBookDialog::on_tabWidget_currentChanged(int index)
{
    // Enable/disable buttons based on selected tab
    switch(index)
    {
    case SendingTab:
        ui->deleteButton->setEnabled(true);
        break;
    case ReceivingTab:
        ui->deleteButton->setEnabled(false);
        break;
    }
}

void AddressBookDialog::on_deleteButton_clicked()
{
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows();
    if(!indexes.isEmpty())
    {
        table->model()->removeRow(indexes.at(0).row());
    }
}

void AddressBookDialog::on_buttonBox_accepted()
{
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);

    foreach (QModelIndex index, indexes)
    {
        QVariant address = table->model()->data(index);
        returnValue = address.toString();
    }
    if(!returnValue.isEmpty())
    {
        accept();
    }
    else
    {
        reject();
    }
}

<commit_msg>fix sorting in address table dialog<commit_after>#include "addressbookdialog.h"
#include "ui_addressbookdialog.h"

#include "addresstablemodel.h"
#include "editaddressdialog.h"

#include <QSortFilterProxyModel>
#include <QClipboard>
#include <QDebug>

AddressBookDialog::AddressBookDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AddressBookDialog),
    model(0)
{
    ui->setupUi(this);

    switch(mode)
    {
    case ForSending:
        connect(ui->receiveTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_buttonBox_accepted()));
        connect(ui->sendTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_buttonBox_accepted()));
        break;
    case ForEditing:
        connect(ui->receiveTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_editButton_clicked()));
        connect(ui->sendTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_editButton_clicked()));
        break;
    }
}

AddressBookDialog::~AddressBookDialog()
{
    delete ui;
}

void AddressBookDialog::setModel(AddressTableModel *model)
{
    this->model = model;
    // Refresh list from core
    model->updateList();

    // Receive filter
    QSortFilterProxyModel *receive_model = new QSortFilterProxyModel(this);
    receive_model->setSourceModel(model);
    receive_model->setDynamicSortFilter(true);
    receive_model->setFilterRole(AddressTableModel::TypeRole);
    receive_model->setFilterFixedString(AddressTableModel::Receive);
    ui->receiveTableView->setModel(receive_model);
    ui->receiveTableView->sortByColumn(0, Qt::AscendingOrder);

    // Send filter
    QSortFilterProxyModel *send_model = new QSortFilterProxyModel(this);
    send_model->setSourceModel(model);
    send_model->setDynamicSortFilter(true);
    send_model->setFilterRole(AddressTableModel::TypeRole);
    send_model->setFilterFixedString(AddressTableModel::Send);
    ui->sendTableView->setModel(send_model);
    ui->sendTableView->sortByColumn(0, Qt::AscendingOrder);

    // Set column widths
    ui->receiveTableView->horizontalHeader()->resizeSection(
            AddressTableModel::Address, 320);
    ui->receiveTableView->horizontalHeader()->setResizeMode(
            AddressTableModel::Label, QHeaderView::Stretch);
    ui->sendTableView->horizontalHeader()->resizeSection(
            AddressTableModel::Address, 320);
    ui->sendTableView->horizontalHeader()->setResizeMode(
            AddressTableModel::Label, QHeaderView::Stretch);
}

void AddressBookDialog::setTab(int tab)
{
    ui->tabWidget->setCurrentIndex(tab);
    on_tabWidget_currentChanged(tab);
}

QTableView *AddressBookDialog::getCurrentTable()
{
    switch(ui->tabWidget->currentIndex())
    {
    case SendingTab:
        return ui->sendTableView;
    case ReceivingTab:
        return ui->receiveTableView;
    default:
        return 0;
    }
}

void AddressBookDialog::on_copyToClipboard_clicked()
{
    // Copy currently selected address to clipboard
    //   (or nothing, if nothing selected)
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);

    foreach (QModelIndex index, indexes)
    {
        QVariant address = index.data();
        QApplication::clipboard()->setText(address.toString());
    }
}

void AddressBookDialog::on_editButton_clicked()
{
    QModelIndexList indexes = getCurrentTable()->selectionModel()->selectedRows();
    if(indexes.isEmpty())
    {
        return;
    }
    // Map selected index to source address book model
    QAbstractProxyModel *proxy_model = static_cast<QAbstractProxyModel*>(getCurrentTable()->model());
    QModelIndex selected = proxy_model->mapToSource(indexes.at(0));

    // Double click also triggers edit button
    EditAddressDialog dlg(
            ui->tabWidget->currentIndex() == SendingTab ?
            EditAddressDialog::EditSendingAddress :
            EditAddressDialog::EditReceivingAddress);
    dlg.setModel(model);
    dlg.loadRow(selected.row());
    if(dlg.exec())
    {
        dlg.saveCurrentRow();
    }
}

void AddressBookDialog::on_newAddressButton_clicked()
{
    EditAddressDialog dlg(
            ui->tabWidget->currentIndex() == SendingTab ?
            EditAddressDialog::NewSendingAddress :
            EditAddressDialog::NewReceivingAddress);
    dlg.setModel(model);
    if(dlg.exec())
    {
        dlg.saveCurrentRow();
    }
}

void AddressBookDialog::on_tabWidget_currentChanged(int index)
{
    // Enable/disable buttons based on selected tab
    switch(index)
    {
    case SendingTab:
        ui->deleteButton->setEnabled(true);
        break;
    case ReceivingTab:
        ui->deleteButton->setEnabled(false);
        break;
    }
}

void AddressBookDialog::on_deleteButton_clicked()
{
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows();
    if(!indexes.isEmpty())
    {
        table->model()->removeRow(indexes.at(0).row());
    }
}

void AddressBookDialog::on_buttonBox_accepted()
{
    QTableView *table = getCurrentTable();
    QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);

    foreach (QModelIndex index, indexes)
    {
        QVariant address = table->model()->data(index);
        returnValue = address.toString();
    }
    if(!returnValue.isEmpty())
    {
        accept();
    }
    else
    {
        reject();
    }
}

<|endoftext|>