<commit_before>#include <chrono>
#include <cmath>
#include <iostream>
#include <vector>
#include <unordered_map>

struct Position {
  Position(std::size_t r, std::size_t c) : row(r), col(c) {}
  std::size_t row;
  std::size_t col;
};

using BoardCache = std::vector<std::vector<std::unordered_map<std::size_t, std::size_t>>>;

BoardCache new_board_cache(std::size_t board_size) {
  BoardCache b(board_size);
  for (std::size_t i = 0; i < board_size; ++i) {
    b[i] = std::vector<std::unordered_map<std::size_t, std::size_t>>(board_size);
  }
  return b;
}

std::size_t recursive_moves_helper(std::size_t n, std::size_t board_size, const Position& p, BoardCache& m) {
  if (n <= 0) return 0;
  auto& lookup = m[p.row][p.col];

  // Check cache
  if (lookup.find(n) != lookup.end()) return lookup[n];

  std::size_t up_left = 0;
  std::size_t up_right = 0;
  std::size_t down_left = 0;
  std::size_t down_right = 0;
  // Move left
  if (p.col>= 2) {
    // Move up
    if (p.row >= 1) {
      up_left = 1 + recursive_moves_helper(n-1, board_size, Position{p.row-1, p.col-2}, m);
    }
    // Move down
    if (p.row < board_size - 1) {
      down_left = 1 + recursive_moves_helper(n-1, board_size, Position{p.row+1, p.col-2}, m);
    }
  }

  // Move right
  if (p.col < board_size - 2) {
    // Move up
    if (p.row >= 1) {
      up_right = 1 + recursive_moves_helper(n-1, board_size, Position{p.row-1, p.col+2}, m);
    }
    // Move down
    if (p.row < board_size - 1) {
      down_right = 1 + recursive_moves_helper(n-1, board_size, Position{p.row+1, p.col+2}, m);
    }
  }

  auto total = up_left + up_right + down_left + down_right;
  lookup[n] = total;
  return total;
}

/**
 * Calculate the number of knights moves for a square board of size `board_size`
 * of length `n`, where a single, legal move of a knight has length 1.
 */
std::size_t knights_moves(std::size_t board_size, std::size_t n) {
  BoardCache b = new_board_cache(board_size);
  Position start_pos{0, 0};
  return recursive_moves_helper(n, board_size, start_pos, b);
}

int main() {
  auto start = std::chrono::steady_clock::now();
  std::cout << "Number of length 15 moves on a 10x10 board: " << knights_moves(15, 10);
  auto stop = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = stop - start;
  std::cout << " in " << elapsed.count() << "s\n";
  start = std::chrono::steady_clock::now();
  std::cout << "Number of length 15 moves on a 15x15 board: " << knights_moves(15, 15);
  stop = std::chrono::steady_clock::now();
  elapsed = stop - start;
  std::cout << " in " << elapsed.count() << "s\n";
  return 0;
}
<commit_msg>Adds additional search directions<commit_after>#include <chrono>
#include <cmath>
#include <iostream>
#include <vector>
#include <unordered_map>

struct Position {
  Position(std::size_t r, std::size_t c) : row(r), col(c) {}
  std::size_t row;
  std::size_t col;
};

using BoardCache = std::vector<std::vector<std::unordered_map<std::size_t, std::size_t>>>;

BoardCache new_board_cache(std::size_t board_size) {
  BoardCache b(board_size);
  for (std::size_t i = 0; i < board_size; ++i) {
    b[i] = std::vector<std::unordered_map<std::size_t, std::size_t>>(board_size);
  }
  return b;
}

std::size_t recursive_moves_helper(std::size_t n, std::size_t board_size, const Position& p, BoardCache& m) {
  if (n <= 0) return 0;
  auto& lookup = m[p.row][p.col];

  // Check cache
  if (lookup.find(n) != lookup.end()) return lookup[n];

  std::size_t up_left = 0;
  std::size_t up_right = 0;
  std::size_t down_left = 0;
  std::size_t down_right = 0;
  if (p.col>= 2) {
    // Move up left
    if (p.row >= 1) {
      up_left = 1 + recursive_moves_helper(n-1, board_size, Position{p.row-1, p.col-2}, m);
    }
    // Move down left
    if (p.row < board_size - 1) {
      down_left = 1 + recursive_moves_helper(n-1, board_size, Position{p.row+1, p.col-2}, m);
    }
  }

  if (p.col < board_size - 2) {
    // Move up right
    if (p.row >= 1) {
      up_right = 1 + recursive_moves_helper(n-1, board_size, Position{p.row-1, p.col+2}, m);
    }
    // Move down right
    if (p.row < board_size - 1) {
      down_right = 1 + recursive_moves_helper(n-1, board_size, Position{p.row+1, p.col+2}, m);
    }
  }

  if (p.row >= 2) {
    // Move up left
    if (p.col >= 1) {
      up_left += 1 + recursive_moves_helper(n-1, board_size, Position{p.row-2, p.col-1}, m);
    }
    // Move up right
    if (p.col < board_size - 1) {
      up_right += 1 + recursive_moves_helper(n-1, board_size, Position{p.row-2, p.col+1}, m);
    }
  }
  if (p.row < board_size - 2) {
    // Move down left
    if (p.col >= 1) {
      down_left += 1 + recursive_moves_helper(n-1, board_size, Position{p.row+2, p.col-1}, m);
    }
    // Move down right
    if (p.col < board_size - 1) {
      down_right += 1 + recursive_moves_helper(n-1, board_size, Position{p.row+2, p.col+1}, m);
    }
  }

  auto total = up_left + up_right + down_left + down_right;
  lookup[n] = total;
  return total;
}

/**
 * Calculate the number of knights moves for a square board of size `board_size`
 * of length `n`, where a single, legal move of a knight has length 1.
 */
std::size_t knights_moves(std::size_t board_size, std::size_t n) {
  BoardCache b = new_board_cache(board_size);
  Position start_pos{0, 0};
  return recursive_moves_helper(n, board_size, start_pos, b);
}

int main() {
  auto start = std::chrono::steady_clock::now();
  std::cout << "Number of length 10 moves on a 10x10 board: " << knights_moves(2, 10);
  auto stop = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = stop - start;
  std::cout << " in " << elapsed.count() << "s\n";
  start = std::chrono::steady_clock::now();
  std::cout << "Number of length 10 moves on a 15x15 board: " << knights_moves(15, 15);
  stop = std::chrono::steady_clock::now();
  elapsed = stop - start;
  std::cout << " in " << elapsed.count() << "s\n";
  return 0;
}
<|endoftext|>


<commit_before>#include "ExtendedInventoryScreen.h"

#include "InventoryTransitions.h"
#include "../../creative/CreativeTab.h"

#include "com/mojang/minecraftpe/client/MinecraftClient.h"
#include "com/mojang/minecraftpe/client/gui/NinePatchLayer.h"
#include "com/mojang/minecraftpe/client/gui/IntRectangle.h"
#include "com/mojang/minecraftpe/client/gui/ImageWithBackground.h"
#include "com/mojang/minecraftpe/client/gui/InventoryTab.h"
#include "com/mojang/minecraftpe/client/settings/Options.h"
#include "com/mojang/minecraftpe/client/renderer/Tessellator.h"
#include "com/mojang/minecraftpe/client/renderer/texture/TextureGroup.h"
#include "com/mojang/minecraftpe/client/renderer/entity/ItemRenderer.h"
#include "com/mojang/minecraftpe/client/renderer/ShaderColor.h"
#include "com/mojang/minecraftpe/world/item/ItemInstance.h"

ExtendedInventoryScreen::ExtendedInventoryScreen(MinecraftClient& client, std::vector<CreativeTab*> creativeTabs)
	: Screen(client)
{
	closeButton = NULL;
	backgroundLayer = NULL;
	leftButtonLayer = NULL;
	rightButtonLayer = NULL;
	ownedTabs = creativeTabs;
	testPane = NULL;
}

bool ExtendedInventoryScreen::renderGameBehind() const
{
	return mcClient->getOptions()->getFancyGraphics();
}

bool ExtendedInventoryScreen::closeOnPlayerHurt() const
{
	return true;
}

void ExtendedInventoryScreen::init()
{
	if(!closeButton)
	{
		InventoryTransitions::init(this);

		NinePatchFactory factory (mcClient->getTextures(), "gui/spritesheet.png");

		backgroundLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({34, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		leftButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({49, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		rightButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({65, 55, 14, 14}, 3, 3, 14.0F, 14.0F));

		closeButton = std::make_shared<ImageWithBackground>(2);
		closeButton->init(mcClient->getTextures(), 28, 28, {49, 43, 14, 14}, {49, 43, 14, 14}, 2, 2, "gui/spritesheet.png");
		closeButton->setImageDef({mcClient->getTextures()->getTexture("gui/spritesheet.png", TextureLocation::Default), 0, 1, 18.0F, 18.0F, {60, 0, 18, 18}, true}, true);

		for(int tab = 0; tab < ownedTabs.size(); tab++)
		{
			renderedTabs.emplace_back(createInventoryTab(tab + 3, ((tab < 4) ? false : true)));
		}

		selectedTabIndex = 0;

		buttonList.emplace_back(closeButton);
	}
}

void ExtendedInventoryScreen::render(int i1, int i2, float f1)
{
	if(renderGameBehind())
		renderBackground(1);
	else
		renderDirtBackground();

	renderToolBar(f1, 1.0F, false);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex)
		{
			renderedTabs[tab]->renderBg(mcClient, i1, i2);
			drawTabIcon(ownedTabs[tab], renderedTabs[tab], renderedTabs[tab]->pressed, false);
		}
	}

	backgroundLayer->draw(Tessellator::instance, backgroundLayer->xPosition, backgroundLayer->yPosition);

	renderedTabs[selectedTabIndex]->renderBg(mcClient, i1, i2);
	drawTabIcon(ownedTabs[selectedTabIndex], renderedTabs[selectedTabIndex], renderedTabs[selectedTabIndex]->pressed, true);

	InventoryTransitions::render(this, i1, i2, f1);

	Screen::render(i1, i2, f1);

	currentShaderColor.setColor(Color::WHITE);

	fill(backgroundLayer->xPosition + 5, backgroundLayer->yPosition + 4, width - 38, height - 27, {0.2F, 0.2F, 0.2F, 1.0F});

	testPane->render(i1, i2, f1, mcClient);

	renderOnSelectItemNameText(width, mcClient->getFont(), height - 41);
}

void ExtendedInventoryScreen::setupPositions()
{
	backgroundLayer->xPosition = 31;
	backgroundLayer->yPosition = 2;
	backgroundLayer->setSize((float)(width - 26 - 28) - 4.0F - 6.0F, (float)height - 25.0F);

	closeButton->xPosition = backgroundLayer->xPosition - 26;
	closeButton->yPosition = backgroundLayer->yPosition;

	closeButton->setSize(29, 28);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(!renderedTabs[tab]->isRight)
		{
			renderedTabs[tab]->xPosition = backgroundLayer->xPosition - 26;
			renderedTabs[tab]->yPosition = height - 25 - 29 - (tab * 31);
		}
		else
		{
			renderedTabs[tab]->xPosition = width - 6 - 29;
			renderedTabs[tab]->yPosition = height - 25 - 29 - ((tab - 4) * 31);
		}
		renderedTabs[tab]->width = 29;
		renderedTabs[tab]->height = 29;
	}

	testPane = std::shared_ptr<Touch::InventoryPane>(new Touch::InventoryPane(this, *mcClient, {backgroundLayer->xPosition + 7, backgroundLayer->yPosition + 8, 20, 20}, 1, 1.0F, 20, 0, 0, false, true, false));

	testPane->xPosition = backgroundLayer->xPosition + 7;
	testPane->yPosition = backgroundLayer->yPosition + 8;
	testPane->width = 60;
	testPane->height = 60;

	InventoryTransitions::setupPositions(this);
}

void ExtendedInventoryScreen::_buttonClicked(Button& button)
{
	InventoryTransitions::_buttonClicked(this, button);

	if(button.id == closeButton->id)
		InventoryTransitions::pushPreviousScreen(this);
}

void ExtendedInventoryScreen::_pointerReleased(int x, int y)
{
	Screen::_pointerReleased(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex && renderedTabs[tab]->isInside(x, y) && renderedTabs[tab]->pressed)
			selectedTabIndex = tab;

		renderedTabs[tab]->pressed = false;
	}
}

void ExtendedInventoryScreen::_pointerPressed(int x, int y)
{
	Screen::_pointerPressed(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(renderedTabs[tab]->isInside(x, y))
		{
			renderedTabs[tab]->pressed = true;
			return;
		}
	}
}

void ExtendedInventoryScreen::handleBackEvent(bool b1)
{
	if(!b1)
		InventoryTransitions::pushPreviousScreen(this);
}

bool ExtendedInventoryScreen::isModal() const
{
	return true;
}

void ExtendedInventoryScreen::tick()
{

}

std::string ExtendedInventoryScreen::getScreenName()
{
	return "extended_creative_screen";
}

std::shared_ptr<InventoryTab> ExtendedInventoryScreen::createInventoryTab(int id, bool isRight)
{
	NinePatchLayer* buttonLayer = isRight ? rightButtonLayer.get() : leftButtonLayer.get();
	std::shared_ptr<InventoryTab> button = std::make_shared<InventoryTab>(id, "", buttonLayer, isRight);
	button->setOverrideScreenRendering(true);
	return button;
}

void ExtendedInventoryScreen::drawTabIcon(CreativeTab* ownedTab, std::shared_ptr<InventoryTab> imageButton, bool isPressed, bool isSelected)
{
	ItemRenderer::getInstance()->renderGuiItemNew(ownedTab->getTabIcon(), 0, ((float)imageButton->xPosition + (float)((imageButton->width / 2) - 8) + (isPressed ? 1.0F : 0.7F)), ((float)imageButton->yPosition + (float)((imageButton->height / 2) - 8)), 1.0F, (isSelected ? 1.0F : 0.7F), (((float)imageButton->width) - (isPressed ? 2.0F : 0.0F)) * 0.04F, false);
}

bool ExtendedInventoryScreen::addItem(Touch::InventoryPane& pane, int slot)
{
	return true;
}

bool ExtendedInventoryScreen::isAllowed(int slot)
{
	return true;
}

std::vector<const ItemInstance*> ExtendedInventoryScreen::getItems(const Touch::InventoryPane& pane)
{
	std::vector<const ItemInstance*> itemVector;
	return itemVector;
}<commit_msg>It NOW WORKS!<commit_after>#include "ExtendedInventoryScreen.h"

#include "InventoryTransitions.h"
#include "../../creative/CreativeTab.h"

#include "com/mojang/minecraftpe/client/MinecraftClient.h"
#include "com/mojang/minecraftpe/client/gui/NinePatchLayer.h"
#include "com/mojang/minecraftpe/client/gui/IntRectangle.h"
#include "com/mojang/minecraftpe/client/gui/ImageWithBackground.h"
#include "com/mojang/minecraftpe/client/gui/InventoryTab.h"
#include "com/mojang/minecraftpe/client/settings/Options.h"
#include "com/mojang/minecraftpe/client/renderer/Tessellator.h"
#include "com/mojang/minecraftpe/client/renderer/texture/TextureGroup.h"
#include "com/mojang/minecraftpe/client/renderer/entity/ItemRenderer.h"
#include "com/mojang/minecraftpe/client/renderer/ShaderColor.h"
#include "com/mojang/minecraftpe/world/item/ItemInstance.h"

ExtendedInventoryScreen::ExtendedInventoryScreen(MinecraftClient& client, std::vector<CreativeTab*> creativeTabs)
	: Screen(client)
{
	closeButton = NULL;
	backgroundLayer = NULL;
	leftButtonLayer = NULL;
	rightButtonLayer = NULL;
	ownedTabs = creativeTabs;
	testPane = NULL;
}

bool ExtendedInventoryScreen::renderGameBehind() const
{
	return mcClient->getOptions()->getFancyGraphics();
}

bool ExtendedInventoryScreen::closeOnPlayerHurt() const
{
	return true;
}

void ExtendedInventoryScreen::init()
{
	if(!closeButton)
	{
		InventoryTransitions::init(this);

		NinePatchFactory factory (mcClient->getTextures(), "gui/spritesheet.png");

		backgroundLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({34, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		leftButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({49, 43, 14, 14}, 3, 3, 14.0F, 14.0F));
		rightButtonLayer = std::shared_ptr<NinePatchLayer>(factory.createSymmetrical({65, 55, 14, 14}, 3, 3, 14.0F, 14.0F));

		closeButton = std::make_shared<ImageWithBackground>(2);
		closeButton->init(mcClient->getTextures(), 28, 28, {49, 43, 14, 14}, {49, 43, 14, 14}, 2, 2, "gui/spritesheet.png");
		closeButton->setImageDef({mcClient->getTextures()->getTexture("gui/spritesheet.png", TextureLocation::Default), 0, 1, 18.0F, 18.0F, {60, 0, 18, 18}, true}, true);

		for(int tab = 0; tab < ownedTabs.size(); tab++)
		{
			renderedTabs.emplace_back(createInventoryTab(tab + 3, ((tab < 4) ? false : true)));
		}

		selectedTabIndex = 0;

		buttonList.emplace_back(closeButton);
	}
}

void ExtendedInventoryScreen::render(int i1, int i2, float f1)
{
	if(renderGameBehind())
		renderBackground(1);
	else
		renderDirtBackground();

	renderToolBar(f1, 1.0F, false);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex)
		{
			renderedTabs[tab]->renderBg(mcClient, i1, i2);
			drawTabIcon(ownedTabs[tab], renderedTabs[tab], renderedTabs[tab]->pressed, false);
		}
	}

	backgroundLayer->draw(Tessellator::instance, backgroundLayer->xPosition, backgroundLayer->yPosition);

	renderedTabs[selectedTabIndex]->renderBg(mcClient, i1, i2);
	drawTabIcon(ownedTabs[selectedTabIndex], renderedTabs[selectedTabIndex], renderedTabs[selectedTabIndex]->pressed, true);

	InventoryTransitions::render(this, i1, i2, f1);

	Screen::render(i1, i2, f1);

	currentShaderColor.setColor(Color::WHITE);

	fill(backgroundLayer->xPosition + 5, backgroundLayer->yPosition + 4, width - 38, height - 27, {0.2F, 0.2F, 0.2F, 1.0F});

	testPane->render(i1, i2, f1, mcClient);

	renderOnSelectItemNameText(width, mcClient->getFont(), height - 41);
}

void ExtendedInventoryScreen::setupPositions()
{
	backgroundLayer->xPosition = 31;
	backgroundLayer->yPosition = 2;
	backgroundLayer->setSize((float)(width - 26 - 28) - 4.0F - 6.0F, (float)height - 25.0F);

	closeButton->xPosition = backgroundLayer->xPosition - 26;
	closeButton->yPosition = backgroundLayer->yPosition;

	closeButton->setSize(29, 28);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(!renderedTabs[tab]->isRight)
		{
			renderedTabs[tab]->xPosition = backgroundLayer->xPosition - 26;
			renderedTabs[tab]->yPosition = height - 25 - 29 - (tab * 31);
		}
		else
		{
			renderedTabs[tab]->xPosition = width - 6 - 29;
			renderedTabs[tab]->yPosition = height - 25 - 29 - ((tab - 4) * 31);
		}
		renderedTabs[tab]->width = 29;
		renderedTabs[tab]->height = 29;
	}

	testPane = std::shared_ptr<Touch::InventoryPane>(new Touch::InventoryPane(this, *mcClient, {backgroundLayer->xPosition + 11, backgroundLayer->yPosition + 8, 120, 120}, 1, 1.0F, 5, 26, 1, false, true, false));

	testPane->xPosition = backgroundLayer->xPosition + 11;
	testPane->yPosition = backgroundLayer->yPosition + 8;
	testPane->width = 120;
	testPane->height = 120;

	InventoryTransitions::setupPositions(this);
}

void ExtendedInventoryScreen::_buttonClicked(Button& button)
{
	InventoryTransitions::_buttonClicked(this, button);

	if(button.id == closeButton->id)
		InventoryTransitions::pushPreviousScreen(this);
}

void ExtendedInventoryScreen::_pointerReleased(int x, int y)
{
	Screen::_pointerReleased(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(tab != selectedTabIndex && renderedTabs[tab]->isInside(x, y) && renderedTabs[tab]->pressed)
			selectedTabIndex = tab;

		renderedTabs[tab]->pressed = false;
	}
}

void ExtendedInventoryScreen::_pointerPressed(int x, int y)
{
	Screen::_pointerPressed(x, y);

	for(int tab = 0; tab < renderedTabs.size(); tab++)
	{
		if(renderedTabs[tab]->isInside(x, y))
		{
			renderedTabs[tab]->pressed = true;
			return;
		}
	}
}

void ExtendedInventoryScreen::handleBackEvent(bool b1)
{
	if(!b1)
		InventoryTransitions::pushPreviousScreen(this);
}

bool ExtendedInventoryScreen::isModal() const
{
	return true;
}

void ExtendedInventoryScreen::tick()
{

}

std::string ExtendedInventoryScreen::getScreenName()
{
	return "extended_creative_screen";
}

std::shared_ptr<InventoryTab> ExtendedInventoryScreen::createInventoryTab(int id, bool isRight)
{
	NinePatchLayer* buttonLayer = isRight ? rightButtonLayer.get() : leftButtonLayer.get();
	std::shared_ptr<InventoryTab> button = std::make_shared<InventoryTab>(id, "", buttonLayer, isRight);
	button->setOverrideScreenRendering(true);
	return button;
}

void ExtendedInventoryScreen::drawTabIcon(CreativeTab* ownedTab, std::shared_ptr<InventoryTab> imageButton, bool isPressed, bool isSelected)
{
	ItemRenderer::getInstance()->renderGuiItemNew(ownedTab->getTabIcon(), 0, ((float)imageButton->xPosition + (float)((imageButton->width / 2) - 8) + (isPressed ? 1.0F : 0.7F)), ((float)imageButton->yPosition + (float)((imageButton->height / 2) - 8)), 1.0F, (isSelected ? 1.0F : 0.7F), (((float)imageButton->width) - (isPressed ? 2.0F : 0.0F)) * 0.04F, false);
}

bool ExtendedInventoryScreen::addItem(Touch::InventoryPane& pane, int slot)
{
	return true;
}

bool ExtendedInventoryScreen::isAllowed(int slot)
{
	return true;
}

std::vector<const ItemInstance*> ExtendedInventoryScreen::getItems(const Touch::InventoryPane& pane)
{
	std::vector<const ItemInstance*> itemVector = {new ItemInstance(4, 1, 0), new ItemInstance(98, 1, 0), new ItemInstance(98, 1, 1)};
	return itemVector;
}<|endoftext|>


<commit_before>/*
 * SessionPanmirrorZotero.cpp
 *
 * Copyright (C) 2009-20 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionPanmirrorZotero.hpp"

#include <shared_core/Error.hpp>
#include <shared_core/json/Json.hpp>

#include <core/Exec.hpp>

#include <core/system/Process.hpp>

#include <session/prefs/UserPrefs.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/SessionAsyncDownloadFile.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace panmirror {
namespace zotero {

namespace {

const char * const kZoteroApiHost = "https://api.zotero.org";

std::string zoteroApiKey()
{
   return prefs::userPrefs().zoteroApiKey();
}

typedef boost::function<void(const Error&,int,json::Value)> ZoteroJsonResponseHandler;

void zoteroJsonRequest(const std::string& resource,
                       http::Fields queryParams,
                       bool authenticated,
                       const ZoteroJsonResponseHandler& handler)
{
   // authorize using header or url param as required
   http::Fields headers;
   if (authenticated)
   {
      if (module_context::hasMinimumRVersion("3.6"))
      {
         boost::format fmt("Bearer %s");
         headers.push_back(std::make_pair("Authorization", "Bearer " + zoteroApiKey()));
      }
      else
      {
         queryParams.push_back(std::make_pair("key", zoteroApiKey()));
      }
   }

   // build query string
   std::string queryString;
   core::http::util::buildQueryString(queryParams, &queryString);
   if (queryString.length() > 0)
      queryString = "?" + queryString;

   // build the url and make the request
   boost::format fmt("%s/%s%s");
   const std::string url = boost::str(fmt % kZoteroApiHost % resource % queryString);
   asyncDownloadFile(url, headers, [handler](const core::system::ProcessResult& result) {
      if (result.exitStatus == EXIT_SUCCESS)
      {
         json::Value resultJson;
         Error error = resultJson.parse(result.stdOut);
         if (error)
            handler(error, 500, json::Value());
         else
            handler(Success(), 200, resultJson);
      }
      else
      {
         Error error = systemError(boost::system::errc::state_not_recoverable, result.stdErr, ERROR_LOCATION);
         handler(error, 500, json::Value());
      }
   });
}

void zoteroJsonRequest(const std::string& resource,
                      http::Fields queryParams,
                      const ZoteroJsonResponseHandler& handler)
{
   zoteroJsonRequest(resource, queryParams, true, handler);
}

void zoteroKeyInfo(const ZoteroJsonResponseHandler& handler)
{
   boost::format fmt("keys/%s");
   zoteroJsonRequest(boost::str(fmt % zoteroApiKey()),
                     http::Fields(),
                     false,
                     handler);
}

void zoteroCollections(int userID, const ZoteroJsonResponseHandler& handler)
{
   http::Fields params;
   params.push_back(std::make_pair("format", "json"));

   boost::format fmt("users/%d/collections");
   zoteroJsonRequest(boost::str(fmt % userID),
                     params,
                     handler);
}

void onDeferredInit(bool)
{
   zoteroKeyInfo([](const Error& error,int status,json::Value jsonValue) {

      if (error)
      {
         LOG_ERROR(error);
         return;
      }

      int userID;
      json::Object jsonResult = jsonValue.getObject();
      Error jsonError = core::json::readObject(jsonResult, "userID", userID);
      if (jsonError)
      {
         LOG_ERROR(jsonError);
         return;
      }

      zoteroCollections(userID, [](const Error& error,int status,json::Value jsonValue) {
         if (error)
         {
            LOG_ERROR(error);
            return;
         }

          jsonValue.writeFormatted(std::cerr);

      });

   });

}

} // end anonymous namespace

Error initialize()
{
   module_context::events().onDeferredInit.connect(onDeferredInit);

   ExecBlock initBlock;
   initBlock.addFunctions()

   ;
   return initBlock.execute();
}

} // end namespace zotero
} // end namespace panmirror
} // end namespace modules
} // end namespace session
} // end namespace rstudio
<commit_msg>Add Zotero End Points and Schema<commit_after>/*
 * SessionPanmirrorZotero.cpp
 *
 * Copyright (C) 2009-20 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionPanmirrorZotero.hpp"

#include <shared_core/Error.hpp>
#include <shared_core/json/Json.hpp>

#include <core/Exec.hpp>

#include <core/system/Process.hpp>

#include <session/prefs/UserPrefs.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/SessionAsyncDownloadFile.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace panmirror {
namespace zotero {

namespace {

const char * const kZoteroApiHost = "https://api.zotero.org";

const char * const kKeySchema = R"(
{
  "$id": "http://rstudio.org/schemas/zotero-key.json",
  "$schema": "http://json-schema.org/schema#",
  "title": "Zotero Key Metadata Schema",
  "type": "object",
  "properties": {
    "key": {
      "type": "string"
    },
    "userID": {
      "type": "number"
    },
    "username": {
      "type": "string"
    },
    "access": {
      "type": "object",
      "properties": {
        "user": {
          "type": "object",
          "properties": {
            "library": {
              "type": "boolean"
            },
            "files": {
              "type": "boolean"
            }
          }
        },
        "groups": {
          "type": "object",
          "properties": {
            "all": {
              "type": "object",
              "properties": {
                "library": {
                  "type": "boolean"
                },
                "write": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      }
    }
  }
})";

const char * const kCollectionSchema = R"(
{
  "$id": "http://rstudio.org/schemas/zotero-collections.json",
  "$schema": "http://json-schema.org/schema#",
  "title": "Zotero Collections Metadata Schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties" : {
      	"key" : {
          	"type": "string"
        },
        "version": {
          	"type": "number"
        },
        "library": {
          "type": "object",
          "properties": {
            	"type": {
                  	"type": "string"
                },
                "id": {
                  "type": "number"
                },
                "name": {
                  "type": "string"
                }
          }
        },
        "data": {
          "type": "object",
          "properties": {
            "key" : {
              "type": "string"
            },
            "version": {
              "type": "number"
            },
            "name": {
              "type": "string"
            }
          }
        }
    }
  }
})";

const char * const kItemSchema = R"(
{
  "$id": "http://rstudio.org/schemas/zotero-collections.json",
  "$schema": "http://json-schema.org/schema#",
  "title": "Zotero Collections Metadata Schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties" : {
      	"key" : {
          	"type": "string"
        },
        "version": {
          	"type": "number"
        },
        "library": {
          "type": "object",
          "properties": {
            	"type": {
                  	"type": "string"
                },
                "id": {
                  "type": "number"
                },
                "name": {
                  "type": "string"
                }
          }
        },
        "data": {
          "type": "object",
          "properties": {
            "key" : {
              "type": "string"
            },
            "version": {
              "type": "number"
            },
            "itemType": {
              "type": "string"
            }
          }
        }
    }
  }
})";

std::string zoteroApiKey()
{
   return prefs::userPrefs().zoteroApiKey();
}

typedef boost::function<void(const Error&,int,json::Value)> ZoteroJsonResponseHandler;

void zoteroJsonRequest(const std::string& resource,
                       http::Fields queryParams,
                       bool authenticated,
                       const std::string& schema,
                       const ZoteroJsonResponseHandler& handler)
{
   // authorize using header or url param as required
   http::Fields headers;
   if (authenticated)
   {
      if (module_context::hasMinimumRVersion("3.6"))
      {
         boost::format fmt("Bearer %s");
         headers.push_back(std::make_pair("Authorization", "Bearer " + zoteroApiKey()));
      }
      else
      {
         queryParams.push_back(std::make_pair("key", zoteroApiKey()));
      }
   }

   // build query string
   std::string queryString;
   core::http::util::buildQueryString(queryParams, &queryString);
   if (queryString.length() > 0)
      queryString = "?" + queryString;

   // build the url and make the request
   boost::format fmt("%s/%s%s");
   const std::string url = boost::str(fmt % kZoteroApiHost % resource % queryString);
   asyncDownloadFile(url, headers, [handler, schema](const core::system::ProcessResult& result) {
      if (result.exitStatus == EXIT_SUCCESS)
      {
         json::Value resultJson;
         Error error;
         if (schema.length() > 0)
         {
            error = resultJson.parseAndValidate(result.stdOut, schema);
         } else {
            error = resultJson.parse(result.stdOut);
         }

         if (error)
         {
            handler(error, 500, json::Value());
         }
         else
         {
            handler(Success(), 200, resultJson);
         }
      }
      else
      {
         Error error = systemError(boost::system::errc::state_not_recoverable, result.stdErr, ERROR_LOCATION);
         handler(error, 500, json::Value());
      }
   });
}

void zoteroJsonRequest(const std::string& resource,
                      http::Fields queryParams,
                      const ZoteroJsonResponseHandler& handler)
{
   zoteroJsonRequest(resource, queryParams, true, "", handler);
}

void zoteroKeyInfo(const ZoteroJsonResponseHandler& handler)
{
   boost::format fmt("keys/%s");
   zoteroJsonRequest(boost::str(fmt % zoteroApiKey()),
                     http::Fields(),
                     false,
                     kKeySchema,
                     handler);
}

void zoteroCollections(int userID, const ZoteroJsonResponseHandler& handler)
{
   http::Fields params;
   params.push_back(std::make_pair("format", "json"));

   boost::format fmt("users/%d/collections");
   zoteroJsonRequest(boost::str(fmt % userID),
                     params,
                     true,
                     kCollectionSchema,
                     handler);
}

void zoteroItemRequest(const std::string& path, const ZoteroJsonResponseHandler& handler) {

   http::Fields params;
   params.push_back(std::make_pair("format", "json"));
   params.push_back(std::make_pair("itemType", "-attachment"));

   zoteroJsonRequest(path,
                     params,
                     true,
                     kItemSchema,
                     handler);
}

void zoteroItemsForCollection(int userID, const std::string& collectionID, const ZoteroJsonResponseHandler& handler)
{
   boost::format fmt("users/%d/collections/%s/items");
   zoteroItemRequest(boost::str(fmt % userID % collectionID),
                     handler);
}

void zoteroDeletedData(int userID, int since, const ZoteroJsonResponseHandler& handler)
{
   http::Fields params;
   params.push_back(std::make_pair("since", std::to_string(since)));

   boost::format fmt("users/%d/deleted");
   zoteroJsonRequest(boost::str(fmt % userID),
                     params,
                     true,
                     "", // TODO: deleted schema
                     handler);
}

void onDeferredInit(bool)
{
   zoteroKeyInfo([](const Error& error,int status,json::Value jsonValue) {

      if (error)
      {
         LOG_ERROR(error);
         return;
      }

      int userID;
      json::Object jsonResult = jsonValue.getObject();
      Error jsonError = core::json::readObject(jsonResult, "userID", userID);
      if (jsonError)
      {
         LOG_ERROR(jsonError);
         return;
      }

      zoteroItemsForCollection(userID, "HFB52FJF", [](const Error& error,int status,json::Value jsonValue) {
          if (error)
          {
             LOG_ERROR(error);
             return;
          }
          jsonValue.writeFormatted(std::cerr);
        });

/*     zoteroItems(userID, [](const Error& error,int status,json::Value jsonValue) {
       if (error)
       {
          LOG_ERROR(error);
          return;
       }

       jsonValue.writeFormatted(std::cerr);
     });

      zoteroCollections(userID, [](const Error& error,int status,json::Value jsonValue) {
         if (error)
         {
            LOG_ERROR(error);
            return;
         }
         jsonValue.writeFormatted(std::cerr);

      });

         */

   });
}

} // end anonymous namespace

Error initialize()
{
   module_context::events().onDeferredInit.connect(onDeferredInit);

   ExecBlock initBlock;
   initBlock.addFunctions()

   ;
   return initBlock.execute();
}

} // end namespace zotero
} // end namespace panmirror
} // end namespace modules
} // end namespace session
} // end namespace rstudio
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P10_INFRASTRUCT_HELP_H_
#define _P10_INFRASTRUCT_HELP_H_

#ifdef WIN32
    #include "win32_stdint.h"
#else
    #include <stdint.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

//
// Various image/ring buffer sizes. Must be used by all users (VBU, FSP, HB, HBI, Cronus)
//
const uint32_t  MAX_SBE_SEEPROM_SIZE    = 4 * 64 * 1024; // Max SBE Seeprom size
const uint32_t  MAX_SEEPROM_IMAGE_SIZE  = 4 * ((64 * 1024) / 9 * 8) -
        256; // Max Seeprom image size, excl ECC bits (4 banks).
const uint32_t  MAX_RT_IMAGE_SIZE       = 1024 * 1024;   // Max Runtime size.

// The below buffer sizes are governed by the longest p10 engd ring, n1_fure, which is
// some 1,775,113 bits long.  And we need to hold both data *and* care parts in the buffer.
// So... 1,775,113 x 2 / 8 = 443,778 + size to grow
const uint32_t  MAX_RING_BUF_SIZE       = 450000;        // Max ring buffer size (agreed w/HB).
const uint32_t  MAX_RING_BUF_SIZE_TOOL  = 450000;        // Max ring buf size for tools.

const uint32_t  MAX_DYN_RING_SECTION_SIZE = 1024 * 1024; // Max dynamic ring section size.
const uint32_t  MAX_OVERRIDES_SIZE      = 2 * 1024;      // Max overrides ring section size.
const uint32_t  MAX_HBBL_SIZE           = 20 * 1024;     // Max hbbl bin section size.

const uint32_t  MAX_NOOF_DD_LEVELS_IN_IMAGE = 20;

#if defined(__FAPI)
    #include <fapi2.H>
    #define MY_INF(_fmt_, _args_...) FAPI_INF(_fmt_, ##_args_)
    #define MY_ERR(_fmt_, _args_...) FAPI_ERR(_fmt_, ##_args_)
    #define MY_DBG(_fmt_, _args_...) FAPI_DBG(_fmt_, ##_args_)
#else
    #ifdef WIN32
        #define MY_INF(...) { printf(__VA_ARGS__); }
        #define MY_ERR(...) { printf(__VA_ARGS__); }
        #define MY_DBG(...) { printf(__VA_ARGS__); }
    #else
        #define MY_INF(_fmt_, _args_...) printf(_fmt_, ##_args_)
        #define MY_ERR(_fmt_, _args_...) printf(_fmt_, ##_args_)
        #define MY_DBG(_fmt_, _args_...) printf(_fmt_, ##_args_)
    #endif
#endif

// N-byte align an address, offset or size (aos)
inline uint64_t myByteAlign( const uint8_t nBytes, const uint64_t aos)
{
    return ((aos + nBytes - 1) / nBytes) * nBytes;
}

#endif //_P10_INFRASTRUCT_HELP_H_
<commit_msg>infra: Increase the maximum ring buffer size<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2020                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P10_INFRASTRUCT_HELP_H_
#define _P10_INFRASTRUCT_HELP_H_

#ifdef WIN32
    #include "win32_stdint.h"
#else
    #include <stdint.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

//
// Various image/ring buffer sizes. Must be used by all users (VBU, FSP, HB, HBI, Cronus)
//
const uint32_t  MAX_SBE_SEEPROM_SIZE    = 4 * 64 * 1024; // Max SBE Seeprom size
const uint32_t  MAX_SEEPROM_IMAGE_SIZE  = 4 * ((64 * 1024) / 9 * 8) -
        256; // Max Seeprom image size, excl ECC bits (4 banks).
const uint32_t  MAX_RT_IMAGE_SIZE       = 1024 * 1024;   // Max Runtime size.

// The below buffer sizes are governed by the longest p10 engd ring, n1_fure, which is
// some 1,775,113 bits long.  And we need to hold both data *and* care parts in the buffer.
// So... 1,775,113 x 2 / 8 = 443,778 + size to grow
const uint32_t  MAX_RING_BUF_SIZE       = 650000;        // Max ring buffer size (agreed w/HB).
const uint32_t  MAX_RING_BUF_SIZE_TOOL  = 450000;        // Max ring buf size for tools.

const uint32_t  MAX_DYN_RING_SECTION_SIZE = 1024 * 1024; // Max dynamic ring section size.
const uint32_t  MAX_OVERRIDES_SIZE      = 2 * 1024;      // Max overrides ring section size.
const uint32_t  MAX_HBBL_SIZE           = 20 * 1024;     // Max hbbl bin section size.

const uint32_t  MAX_NOOF_DD_LEVELS_IN_IMAGE = 20;

#if defined(__FAPI)
    #include <fapi2.H>
    #define MY_INF(_fmt_, _args_...) FAPI_INF(_fmt_, ##_args_)
    #define MY_ERR(_fmt_, _args_...) FAPI_ERR(_fmt_, ##_args_)
    #define MY_DBG(_fmt_, _args_...) FAPI_DBG(_fmt_, ##_args_)
#else
    #ifdef WIN32
        #define MY_INF(...) { printf(__VA_ARGS__); }
        #define MY_ERR(...) { printf(__VA_ARGS__); }
        #define MY_DBG(...) { printf(__VA_ARGS__); }
    #else
        #define MY_INF(_fmt_, _args_...) printf(_fmt_, ##_args_)
        #define MY_ERR(_fmt_, _args_...) printf(_fmt_, ##_args_)
        #define MY_DBG(_fmt_, _args_...) printf(_fmt_, ##_args_)
    #endif
#endif

// N-byte align an address, offset or size (aos)
inline uint64_t myByteAlign( const uint8_t nBytes, const uint64_t aos)
{
    return ((aos + nBytes - 1) / nBytes) * nBytes;
}

#endif //_P10_INFRASTRUCT_HELP_H_
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012      Shou Ya <shouyatf@gmail.com>
// Copyright 2012      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "KmlPhotoOverlayWriter.h"

#include "GeoDataPhotoOverlay.h"
#include "GeoDataTypes.h"
#include "GeoWriter.h"
#include "KmlElementDictionary.h"

namespace Marble
{

static GeoTagWriterRegistrar s_writerLookAt(
    GeoTagWriter::QualifiedName( GeoDataTypes::GeoDataPhotoOverlayType,
				 kml::kmlTag_nameSpace22 ),
    new KmlPhotoOverlayWriter );

KmlPhotoOverlayWriter::KmlPhotoOverlayWriter() : KmlOverlayTagWriter( kml::kmlTag_PhotoOverlay )
{
    // nothing to do
}

bool KmlPhotoOverlayWriter::writeMid( const GeoNode *node, GeoWriter &writer ) const
{
    KmlOverlayTagWriter::writeMid( node, writer );

    const GeoDataPhotoOverlay *photo_overlay =
        static_cast<const GeoDataPhotoOverlay*>( node );

    // rotation
    QString rot_value = QString::number( photo_overlay->rotation(), 'f', 3 );
    writer.writeOptionalElement( kml::kmlTag_rotation, rot_value, "0.000" );

    // ViewVolume
    writer.writeStartElement( kml::kmlTag_ViewVolume );
    writer.writeOptionalElement<qreal>( kml::kmlTag_near, photo_overlay->viewVolume().near(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_leftFov, photo_overlay->viewVolume().leftFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_rightFov, photo_overlay->viewVolume().rightFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_bottomFov, photo_overlay->viewVolume().bottomFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_topFov, photo_overlay->viewVolume().topFov(), 0 );
    writer.writeEndElement();

    // ImagePyramid
    writer.writeStartElement( kml::kmlTag_ImagePyramid );
    writer.writeOptionalElement<int>( kml::kmlTag_tileSize, photo_overlay->imagePyramid().tileSize(), 256);
    writer.writeOptionalElement<int>( kml::kmlTag_maxWidth, photo_overlay->imagePyramid().maxWidth() );
    writer.writeOptionalElement<int>( kml::kmlTag_maxHeight, photo_overlay->imagePyramid().maxHeight() );

    writer.writeStartElement( kml::kmlTag_gridOrigin);
    switch ( photo_overlay->imagePyramid().gridOrigin() )
    {
    case GeoDataImagePyramid::LowerLeft:
        writer.writeCharacters( "lowerLeft" );
        break;
    case GeoDataImagePyramid::UpperLeft:
        writer.writeCharacters( "upperLeft" );
        break;
    }
    writer.writeEndElement();
    writer.writeEndElement();

    // Point
    writeElement(&photo_overlay->point(), writer);

    // shape
    switch ( photo_overlay->shape() )
    {
    case GeoDataPhotoOverlay::Rectangle:
        break;
    case GeoDataPhotoOverlay::Cylinder:
        writer.writeStartElement( kml::kmlTag_shape );
        writer.writeCharacters( "cylinder" );
        writer.writeEndElement();
        break;
    case GeoDataPhotoOverlay::Sphere:
        writer.writeStartElement( kml::kmlTag_shape );
        writer.writeCharacters( "sphere" );
        writer.writeEndElement();
        break;
    }

    return true;
}

}
<commit_msg>Simplify, code style<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012      Shou Ya <shouyatf@gmail.com>
// Copyright 2012      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "KmlPhotoOverlayWriter.h"

#include "GeoDataPhotoOverlay.h"
#include "GeoDataTypes.h"
#include "GeoWriter.h"
#include "KmlElementDictionary.h"

namespace Marble
{

static GeoTagWriterRegistrar s_writerLookAt(
    GeoTagWriter::QualifiedName( GeoDataTypes::GeoDataPhotoOverlayType,
				 kml::kmlTag_nameSpace22 ),
    new KmlPhotoOverlayWriter );

KmlPhotoOverlayWriter::KmlPhotoOverlayWriter() : KmlOverlayTagWriter( kml::kmlTag_PhotoOverlay )
{
    // nothing to do
}

bool KmlPhotoOverlayWriter::writeMid( const GeoNode *node, GeoWriter &writer ) const
{
    KmlOverlayTagWriter::writeMid( node, writer );

    const GeoDataPhotoOverlay *photo_overlay =
        static_cast<const GeoDataPhotoOverlay*>( node );

    // rotation
    QString const rotation = QString::number( photo_overlay->rotation(), 'f', 3 );
    writer.writeOptionalElement( kml::kmlTag_rotation, rotation, "0.000" );

    // ViewVolume
    writer.writeStartElement( kml::kmlTag_ViewVolume );
    writer.writeOptionalElement<qreal>( kml::kmlTag_near, photo_overlay->viewVolume().near(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_leftFov, photo_overlay->viewVolume().leftFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_rightFov, photo_overlay->viewVolume().rightFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_bottomFov, photo_overlay->viewVolume().bottomFov(), 0 );
    writer.writeOptionalElement<qreal>( kml::kmlTag_topFov, photo_overlay->viewVolume().topFov(), 0 );
    writer.writeEndElement();

    // ImagePyramid
    writer.writeStartElement( kml::kmlTag_ImagePyramid );
    writer.writeOptionalElement<int>( kml::kmlTag_tileSize, photo_overlay->imagePyramid().tileSize(), 256 );
    writer.writeOptionalElement<int>( kml::kmlTag_maxWidth, photo_overlay->imagePyramid().maxWidth() );
    writer.writeOptionalElement<int>( kml::kmlTag_maxHeight, photo_overlay->imagePyramid().maxHeight() );

    switch ( photo_overlay->imagePyramid().gridOrigin() )
    {
    case GeoDataImagePyramid::LowerLeft:
        writer.writeElement( kml::kmlTag_gridOrigin, "lowerLeft" );
        break;
    case GeoDataImagePyramid::UpperLeft:
        writer.writeElement( kml::kmlTag_gridOrigin, "upperLeft" );
        break;
    }
    writer.writeEndElement();

    // Point
    writeElement( &photo_overlay->point(), writer );

    // shape
    switch ( photo_overlay->shape() )
    {
    case GeoDataPhotoOverlay::Rectangle:
        break;
    case GeoDataPhotoOverlay::Cylinder:
        writer.writeElement( kml::kmlTag_shape, "cylinder" );
        break;
    case GeoDataPhotoOverlay::Sphere:
        writer.writeElement( kml::kmlTag_shape, "sphere" );
        break;
    }

    return true;
}

}
<|endoftext|>


<commit_before>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// (c) COPYRIGHT URI/MIT 1995-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
//      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>

// These functions are utility functions used by the various DAP parsers (the
// DAS, DDS and constraint expression parsers).
// jhrg 9/7/95

#include "config.h"

static char rcsid[] not_used =
    { "$Id$"
    };

#include <cerrno>
#include <cassert>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>

//  We wrap VC++ 6.x strtod() to account for a short comming
//  in that function in regards to "NaN".
#ifdef WIN32
#include <limits>
double w32strtod(const char *, char **);
#endif

#include "debug.h"
#include "parser.h"             // defines constants such as ID_MAX
#include "dods-limits.h"
#include "util.h"               // Jose Garcia: for append_long_to_string.

using std::cerr;
using std::endl;

#ifdef WIN32
//  VC++ 6.x strtod() doesn't recognize "NaN".  Account for it
//  by wrapping it around a check for the Nan string.  Use of
//  the product is obsolete as of 1/2007, but it is unknown if
//  the issue is still there in later releases of that product.
//  ROM - 01/2007
double w32strtod(const char *val, char **ptr)
{
    //  Convert the two char arrays to compare to strings.
    string *sval = new string(val);
    string *snan = new string("NaN");

    //  If val doesn't contain "NaN|Nan|nan|etc", use strtod as
    //  provided.
    if (stricmp(sval->c_str(), snan->c_str()) != 0)
        return (strtod(val, ptr));

    //  But if it does, return the bit pattern for Nan and point
    //  the parsing ptr arg at the trailing '\0'.
    *ptr = (char *) val + strlen(val);
    return (std::numeric_limits < double >::quiet_NaN());
}
#endif

namespace libdap {

// Deprecated, but still used by the HDF4 EOS server code.
void
parse_error(parser_arg * arg, const char *msg, const int line_num,
            const char *context)
{
    // Jose Garcia
    // This assert(s) is (are) only for developing purposes
    // For production servers remove it by compiling with NDEBUG
    assert(arg);
    assert(msg);

    arg->set_status(FALSE);

    string oss = "";

    if (line_num != 0) {
        oss += "Error parsing the text on line ";
        append_long_to_string(line_num, 10, oss);
    }
    else {
        oss += "Parse error.";
    }

    if (context)
        oss += (string) " at or near: " + context + (string) "\n" + msg
               + (string) "\n";
    else
        oss += (string) "\n" + msg + (string) "\n";

    arg->set_error(new Error(unknown_error, oss));
}

void
parse_error(const char *msg, const int line_num, const char *context)
{
    // Jose Garcia
    // This assert(s) is (are) only for developing purposes
    // For production servers remove it by compiling with NDEBUG
    assert(msg);

    string oss = "";

    if (line_num != 0) {
        oss += "Error parsing the text on line ";
        append_long_to_string(line_num, 10, oss);
    }
    else {
        oss += "Parse error.";
    }

    if (context)
        oss += (string) " at or near: " + context + (string) "\n" + msg
               + (string) "\n";
    else
        oss += (string) "\n" + msg + (string) "\n";

    throw Error(oss);
}

// context comes from the parser and will always be a char * unless the
// parsers change dramatically.
void
parse_error(const string & msg, const int line_num, const char *context)
{
    parse_error(msg.c_str(), line_num, context);
}

void save_str(char *dst, const char *src, const int line_num)
{
    if (strlen(src) >= ID_MAX)
        parse_error(string("The word `") + string(src)
                    + string("' is too long (it should be no longer than ")
                    + long_to_string(ID_MAX) + string(")."), line_num);

    strncpy(dst, src, ID_MAX);
    dst[ID_MAX - 1] = '\0';     /* in case ... */
}

void save_str(string & dst, const char *src, const int)
{
    dst = src;
}

bool is_keyword(string id, const string & keyword)
{
    downcase(id);
    id = prune_spaces(id);
    DBG(cerr << "is_keyword: " << keyword << " = " << id << endl);
    return id == keyword;
}

int check_byte(const char *val)
{
    char *ptr;
    long v = strtol(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "v: " << v << endl);

    // We're very liberal here with values. Anything that can fit into 8 bits
    // is allowed through. Clients will have to deal with the fact that the
    // ASCII representation for the value might need to be tweaked. This is
    // especially the case for Java clients where Byte datatypes are
    // signed. 3/20/2000 jhrg
    if ((v < 0 && v < DODS_SCHAR_MIN)
        || v > 0 && static_cast < unsigned long >(v) > DODS_UCHAR_MAX)
        return FALSE;

    return TRUE;
}

// This version of check_int will pass base 8, 10 and 16 numbers when they
// use the ANSI standard for string representation of those number bases.

int check_int16(const char *val)
{
    char *ptr;
    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }
    // Don't use the constant from limits.h, use the ones in dods-limits.h
    if (v > DODS_SHRT_MAX || v < DODS_SHRT_MIN) {
        return FALSE;
    }

    return TRUE;
}

int check_uint16(const char *val)
{
    char *ptr;
    unsigned long v = strtol(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    if (v > DODS_USHRT_MAX) {
        return FALSE;
    }

    return TRUE;
}

int check_int32(const char *val)
{
    char *ptr;
    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
        return FALSE;
    }

    return TRUE;
}

int check_uint32(const char *val)
{
    char *ptr;
    unsigned long v = strtol(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    return TRUE;
}

// Check first for system errors (like numbers so small they convert
// (erroneously) to zero. Then make sure that the value is within
// limits.

int check_float32(const char *val)
{
    char *ptr;
    errno = 0;                  // Clear previous value. Fix for the 64bit
    // IRIX from Rob Morris. 5/21/2001 jhrg

#ifdef WIN32
    double v = w32strtod(val, &ptr);
#else
    double v = strtod(val, &ptr);
#endif

    DBG(cerr << "v: " << v << ", ptr: " << ptr
        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
        || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
    double abs_val = fabs(v);
    if (abs_val > DODS_FLT_MAX
        || (abs_val != 0.0 && abs_val < DODS_FLT_MIN))
        return FALSE;

    return TRUE;
}

int check_float64(const char *val)
{
    DBG(cerr << "val: " << val << endl);
    char *ptr;
    errno = 0;                  // Clear previous value. 5/21/2001 jhrg

#ifdef WIN32
    double v = w32strtod(val, &ptr);
#else
    double v = strtod(val, &ptr);
#endif

    DBG(cerr << "v: " << v << ", ptr: " << ptr
        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);

    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
        || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
    double abs_val = fabs(v);
    if (abs_val > DODS_DBL_MAX
        || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
        return FALSE;

    return TRUE;
}

/*
  Maybe someday we will really check the Urls to see if they are valid...
*/

int check_url(const char *)
{
    return TRUE;
}

} // namespace libdap
<commit_msg>Fixed several issues with the DAP type checking routines (which I re-used in NcML handler) failing to reject out of range Int32 and accepting a negative number as valid UInt32.<commit_after>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// (c) COPYRIGHT URI/MIT 1995-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
//      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>

// These functions are utility functions used by the various DAP parsers (the
// DAS, DDS and constraint expression parsers).
// jhrg 9/7/95

#include "config.h"

static char rcsid[] not_used =
    { "$Id$"
    };

#include <cerrno>
#include <cassert>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>

//  We wrap VC++ 6.x strtod() to account for a short comming
//  in that function in regards to "NaN".
#ifdef WIN32
#include <limits>
double w32strtod(const char *, char **);
#endif

#include "debug.h"
#include "parser.h"             // defines constants such as ID_MAX
#include "dods-limits.h"
#include "util.h"               // Jose Garcia: for append_long_to_string.

using std::cerr;
using std::endl;

#ifdef WIN32
//  VC++ 6.x strtod() doesn't recognize "NaN".  Account for it
//  by wrapping it around a check for the Nan string.  Use of
//  the product is obsolete as of 1/2007, but it is unknown if
//  the issue is still there in later releases of that product.
//  ROM - 01/2007
double w32strtod(const char *val, char **ptr)
{
    //  Convert the two char arrays to compare to strings.
    string *sval = new string(val);
    string *snan = new string("NaN");

    //  If val doesn't contain "NaN|Nan|nan|etc", use strtod as
    //  provided.
    if (stricmp(sval->c_str(), snan->c_str()) != 0)
        return (strtod(val, ptr));

    //  But if it does, return the bit pattern for Nan and point
    //  the parsing ptr arg at the trailing '\0'.
    *ptr = (char *) val + strlen(val);
    return (std::numeric_limits < double >::quiet_NaN());
}
#endif

namespace libdap {

// Deprecated, but still used by the HDF4 EOS server code.
void
parse_error(parser_arg * arg, const char *msg, const int line_num,
            const char *context)
{
    // Jose Garcia
    // This assert(s) is (are) only for developing purposes
    // For production servers remove it by compiling with NDEBUG
    assert(arg);
    assert(msg);

    arg->set_status(FALSE);

    string oss = "";

    if (line_num != 0) {
        oss += "Error parsing the text on line ";
        append_long_to_string(line_num, 10, oss);
    }
    else {
        oss += "Parse error.";
    }

    if (context)
        oss += (string) " at or near: " + context + (string) "\n" + msg
               + (string) "\n";
    else
        oss += (string) "\n" + msg + (string) "\n";

    arg->set_error(new Error(unknown_error, oss));
}

void
parse_error(const char *msg, const int line_num, const char *context)
{
    // Jose Garcia
    // This assert(s) is (are) only for developing purposes
    // For production servers remove it by compiling with NDEBUG
    assert(msg);

    string oss = "";

    if (line_num != 0) {
        oss += "Error parsing the text on line ";
        append_long_to_string(line_num, 10, oss);
    }
    else {
        oss += "Parse error.";
    }

    if (context)
        oss += (string) " at or near: " + context + (string) "\n" + msg
               + (string) "\n";
    else
        oss += (string) "\n" + msg + (string) "\n";

    throw Error(oss);
}

// context comes from the parser and will always be a char * unless the
// parsers change dramatically.
void
parse_error(const string & msg, const int line_num, const char *context)
{
    parse_error(msg.c_str(), line_num, context);
}

void save_str(char *dst, const char *src, const int line_num)
{
    if (strlen(src) >= ID_MAX)
        parse_error(string("The word `") + string(src)
                    + string("' is too long (it should be no longer than ")
                    + long_to_string(ID_MAX) + string(")."), line_num);

    strncpy(dst, src, ID_MAX);
    dst[ID_MAX - 1] = '\0';     /* in case ... */
}

void save_str(string & dst, const char *src, const int)
{
    dst = src;
}

bool is_keyword(string id, const string & keyword)
{
    downcase(id);
    id = prune_spaces(id);
    DBG(cerr << "is_keyword: " << keyword << " = " << id << endl);
    return id == keyword;
}

int check_byte(const char *val)
{
    char *ptr;
    long v = strtol(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "v: " << v << endl);

    // We're very liberal here with values. Anything that can fit into 8 bits
    // is allowed through. Clients will have to deal with the fact that the
    // ASCII representation for the value might need to be tweaked. This is
    // especially the case for Java clients where Byte datatypes are
    // signed. 3/20/2000 jhrg
    if ((v < 0 && v < DODS_SCHAR_MIN)
        || v > 0 && static_cast < unsigned long >(v) > DODS_UCHAR_MAX)
        return FALSE;

    return TRUE;
}

// This version of check_int will pass base 8, 10 and 16 numbers when they
// use the ANSI standard for string representation of those number bases.

int check_int16(const char *val)
{
    char *ptr;
    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }
    // Don't use the constant from limits.h, use the ones in dods-limits.h
    if (v > DODS_SHRT_MAX || v < DODS_SHRT_MIN) {
        return FALSE;
    }

    return TRUE;
}

int check_uint16(const char *val)
{
    char *ptr;
    unsigned long v = strtol(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    if (v > DODS_USHRT_MAX) {
        return FALSE;
    }

    return TRUE;
}

int check_int32(const char *val)
{
    char *ptr;
    errno = 0;
    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    // We need to check errno since strtol return clamps on overflow so the check
    // against the DODS values below will always pass, even for out of bounds
    // values in the string.  mjohnson 7/20/09
    if (errno == ERANGE) {
        return FALSE;
    }

    if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
        return FALSE;
    }

    return TRUE;
}

int check_uint32(const char *val)
{
  // Eat whitespace and check for an initial '-' sign...
  // strtoul allows an initial minus. mjohnson
    const char* c = val;
    while (c && isspace(*c)) {
         c++;
    }
    if (c && (*c == '-')) {
         return FALSE;
    }

    char *ptr;
    errno = 0;
    unsigned long v = strtoul(val, &ptr, 0);

    if ((v == 0 && val == ptr) || *ptr != '\0') {
        return FALSE;
    }

    // check overflow first, or the below check is invalid due to
    // clamping to the maximum value by strtoul
    // maybe consider using long long for these checks? mjohnson
    if (errno == ERANGE) {
      return FALSE;
    }

    if (v > DODS_UINT_MAX) {
      return FALSE;
    }

    return TRUE;
}

// Check first for system errors (like numbers so small they convert
// (erroneously) to zero. Then make sure that the value is within
// limits.

int check_float32(const char *val)
{
    char *ptr;
    errno = 0;                  // Clear previous value. Fix for the 64bit
    // IRIX from Rob Morris. 5/21/2001 jhrg

#ifdef WIN32
    double v = w32strtod(val, &ptr);
#else
    double v = strtod(val, &ptr);
#endif

    DBG(cerr << "v: " << v << ", ptr: " << ptr
        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
        || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
    double abs_val = fabs(v);
    if (abs_val > DODS_FLT_MAX
        || (abs_val != 0.0 && abs_val < DODS_FLT_MIN))
        return FALSE;

    return TRUE;
}

int check_float64(const char *val)
{
    DBG(cerr << "val: " << val << endl);
    char *ptr;
    errno = 0;                  // Clear previous value. 5/21/2001 jhrg

#ifdef WIN32
    double v = w32strtod(val, &ptr);
#else
    double v = strtod(val, &ptr);
#endif

    DBG(cerr << "v: " << v << ", ptr: " << ptr
        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);

    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
        || *ptr != '\0') {
        return FALSE;
    }

    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
    double abs_val = fabs(v);
    if (abs_val > DODS_DBL_MAX
        || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
        return FALSE;

    return TRUE;
}

/*
  Maybe someday we will really check the Urls to see if they are valid...
*/

int check_url(const char *)
{
    return TRUE;
}

} // namespace libdap
<|endoftext|>


<commit_before><commit_msg>Fixed bug with 2D model disconnected state after switching from real model<commit_after><|endoftext|>


<commit_before>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//-----------------
// Test summary:
//-----------------
// - Create features points and matching from the synthetic dataset
// - Init a SfM_Data scene View and Intrinsic from a synthetic dataset
// - Perform Sequential SfM on the data
// - Assert that:
//   - mean residual error is below the gaussian noise added to observation
//   - the desired number of tracks are found,
//   - the desired number of poses are found.
//-----------------

#include "openMVG/sfm/pipelines/pipelines_test.hpp"
#include "openMVG/sfm/sfm.hpp"
using namespace openMVG;
using namespace openMVG::cameras;
using namespace openMVG::geometry;
using namespace openMVG::sfm;

#include "testing/testing.h"

#include <cmath>
#include <cstdio>
#include <iostream>

// Test a scene where all the camera intrinsics are known
TEST(SEQUENTIAL_SFM, Known_Intrinsics) {

  const int nviews = 6;
  const int npoints = 32;
  const nViewDatasetConfigurator config;
  const NViewDataSet d = NRealisticCamerasRing(nviews, npoints, config);

  // Translate the input dataset to a SfM_Data scene
  const SfM_Data sfm_data = getInputScene(d, config, PINHOLE_CAMERA);

  // Remove poses and structure
  SfM_Data sfm_data_2 = sfm_data;
  sfm_data_2.poses.clear();
  sfm_data_2.structure.clear();

  SequentialSfMReconstructionEngine sfmEngine(
    sfm_data_2,
    "./",
    stlplus::create_filespec("./", "Reconstruction_Report.html"));

  // Configure the features_provider & the matches_provider from the synthetic dataset
  std::shared_ptr<Features_Provider> feats_provider =
    std::make_shared<Synthetic_Features_Provider>();
  // Add a tiny noise in 2D observations to make data more realistic
  std::normal_distribution<double> distribution(0.0,0.5);
  dynamic_cast<Synthetic_Features_Provider*>(feats_provider.get())->load(d,distribution);

  std::shared_ptr<Matches_Provider> matches_provider =
    std::make_shared<Synthetic_Matches_Provider>();
  dynamic_cast<Synthetic_Matches_Provider*>(matches_provider.get())->load(d);

  // Configure data provider (Features and Matches)
  sfmEngine.SetFeaturesProvider(feats_provider.get());
  sfmEngine.SetMatchesProvider(matches_provider.get());

  // Set an initial pair
  sfmEngine.setInitialPair(Pair(0,1));

  // Configure reconstruction parameters (intrinsic parameters are held constant)
  sfmEngine.Set_Intrinsics_Refinement_Type(cameras::Intrinsic_Parameter_Type::NONE);

  EXPECT_TRUE (sfmEngine.Process());

  const double dResidual = RMSE(sfmEngine.Get_SfM_Data());
  std::cout << "RMSE residual: " << dResidual << std::endl;
  EXPECT_TRUE( dResidual < 0.5);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints);
  EXPECT_TRUE( IsTracksOneCC(sfmEngine.Get_SfM_Data()));
}

// Test a scene where only the two first camera have known intrinsics
TEST(SEQUENTIAL_SFM, Partially_Known_Intrinsics) {

  const int nviews = 6;
  const int npoints = 32;
  const nViewDatasetConfigurator config;
  const NViewDataSet d = NRealisticCamerasRing(nviews, npoints, config);

  // Translate the input dataset to a SfM_Data scene
  const SfM_Data sfm_data = getInputScene(d, config, PINHOLE_CAMERA);

  // Remove poses and structure
  SfM_Data sfm_data_2 = sfm_data;
  sfm_data_2.poses.clear();
  sfm_data_2.structure.clear();
  // Only the first two views will have valid intrinsics
  // Remaining one will have undefined intrinsics
  for (Views::iterator iterV = sfm_data_2.views.begin();
    iterV != sfm_data_2.views.end(); ++iterV)
  {
    if (std::distance(sfm_data_2.views.begin(),iterV) >1)
    {
      iterV->second.get()->id_intrinsic = UndefinedIndexT;
    }
  }

  SequentialSfMReconstructionEngine sfmEngine(
    sfm_data_2,
    "./",
    stlplus::create_filespec("./", "Reconstruction_Report.html"));

  // Configure the features_provider & the matches_provider from the synthetic dataset
  std::shared_ptr<Features_Provider> feats_provider =
    std::make_shared<Synthetic_Features_Provider>();
  // Add a tiny noise in 2D observations to make data more realistic
  std::normal_distribution<double> distribution(0.0,0.5);
  dynamic_cast<Synthetic_Features_Provider*>(feats_provider.get())->load(d,distribution);

  std::shared_ptr<Matches_Provider> matches_provider =
    std::make_shared<Synthetic_Matches_Provider>();
  dynamic_cast<Synthetic_Matches_Provider*>(matches_provider.get())->load(d);

  // Configure data provider (Features and Matches)
  sfmEngine.SetFeaturesProvider(feats_provider.get());
  sfmEngine.SetMatchesProvider(matches_provider.get());

  // Set an initial pair
  sfmEngine.setInitialPair(Pair(0,1));

  // Configure reconstruction parameters (intrinsic parameters are held constant)
  sfmEngine.Set_Intrinsics_Refinement_Type(cameras::Intrinsic_Parameter_Type::NONE);

  EXPECT_TRUE (sfmEngine.Process());

  const double dResidual = RMSE(sfmEngine.Get_SfM_Data());
  std::cout << "RMSE residual: " << dResidual << std::endl;
  EXPECT_TRUE( dResidual < 0.5);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints);
  EXPECT_TRUE( IsTracksOneCC(sfmEngine.Get_SfM_Data()));
}

/* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
/* ************************************************************************* */
<commit_msg>sequential_sfm does not longer force the pair 0,1 to be used. Automatic pair choice is so now tested.<commit_after>
// Copyright (c) 2015 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//-----------------
// Test summary:
//-----------------
// - Create features points and matching from the synthetic dataset
// - Init a SfM_Data scene View and Intrinsic from a synthetic dataset
// - Perform Sequential SfM on the data
// - Assert that:
//   - mean residual error is below the gaussian noise added to observation
//   - the desired number of tracks are found,
//   - the desired number of poses are found.
//-----------------

#include "openMVG/sfm/pipelines/pipelines_test.hpp"
#include "openMVG/sfm/sfm.hpp"
using namespace openMVG;
using namespace openMVG::cameras;
using namespace openMVG::geometry;
using namespace openMVG::sfm;

#include "testing/testing.h"

#include <cmath>
#include <cstdio>
#include <iostream>

// Test a scene where all the camera intrinsics are known
TEST(SEQUENTIAL_SFM, Known_Intrinsics) {

  const int nviews = 6;
  const int npoints = 32;
  const nViewDatasetConfigurator config;
  const NViewDataSet d = NRealisticCamerasRing(nviews, npoints, config);

  // Translate the input dataset to a SfM_Data scene
  const SfM_Data sfm_data = getInputScene(d, config, PINHOLE_CAMERA);

  // Remove poses and structure
  SfM_Data sfm_data_2 = sfm_data;
  sfm_data_2.poses.clear();
  sfm_data_2.structure.clear();

  SequentialSfMReconstructionEngine sfmEngine(
    sfm_data_2,
    "./",
    stlplus::create_filespec("./", "Reconstruction_Report.html"));

  // Configure the features_provider & the matches_provider from the synthetic dataset
  std::shared_ptr<Features_Provider> feats_provider =
    std::make_shared<Synthetic_Features_Provider>();
  // Add a tiny noise in 2D observations to make data more realistic
  std::normal_distribution<double> distribution(0.0,0.5);
  dynamic_cast<Synthetic_Features_Provider*>(feats_provider.get())->load(d,distribution);

  std::shared_ptr<Matches_Provider> matches_provider =
    std::make_shared<Synthetic_Matches_Provider>();
  dynamic_cast<Synthetic_Matches_Provider*>(matches_provider.get())->load(d);

  // Configure data provider (Features and Matches)
  sfmEngine.SetFeaturesProvider(feats_provider.get());
  sfmEngine.SetMatchesProvider(matches_provider.get());

  // Configure reconstruction parameters (intrinsic parameters are held constant)
  sfmEngine.Set_Intrinsics_Refinement_Type(cameras::Intrinsic_Parameter_Type::NONE);

  EXPECT_TRUE (sfmEngine.Process());

  const double dResidual = RMSE(sfmEngine.Get_SfM_Data());
  std::cout << "RMSE residual: " << dResidual << std::endl;
  EXPECT_TRUE( dResidual < 0.5);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints);
  EXPECT_TRUE( IsTracksOneCC(sfmEngine.Get_SfM_Data()));
}

// Test a scene where only the two first camera have known intrinsics
TEST(SEQUENTIAL_SFM, Partially_Known_Intrinsics) {

  const int nviews = 6;
  const int npoints = 32;
  const nViewDatasetConfigurator config;
  const NViewDataSet d = NRealisticCamerasRing(nviews, npoints, config);

  // Translate the input dataset to a SfM_Data scene
  const SfM_Data sfm_data = getInputScene(d, config, PINHOLE_CAMERA);

  // Remove poses and structure
  SfM_Data sfm_data_2 = sfm_data;
  sfm_data_2.poses.clear();
  sfm_data_2.structure.clear();
  // Only the first two views will have valid intrinsics
  // Remaining one will have undefined intrinsics
  for (Views::iterator iterV = sfm_data_2.views.begin();
    iterV != sfm_data_2.views.end(); ++iterV)
  {
    if (std::distance(sfm_data_2.views.begin(),iterV) >1)
    {
      iterV->second.get()->id_intrinsic = UndefinedIndexT;
    }
  }

  SequentialSfMReconstructionEngine sfmEngine(
    sfm_data_2,
    "./",
    stlplus::create_filespec("./", "Reconstruction_Report.html"));

  // Configure the features_provider & the matches_provider from the synthetic dataset
  std::shared_ptr<Features_Provider> feats_provider =
    std::make_shared<Synthetic_Features_Provider>();
  // Add a tiny noise in 2D observations to make data more realistic
  std::normal_distribution<double> distribution(0.0,0.5);
  dynamic_cast<Synthetic_Features_Provider*>(feats_provider.get())->load(d,distribution);

  std::shared_ptr<Matches_Provider> matches_provider =
    std::make_shared<Synthetic_Matches_Provider>();
  dynamic_cast<Synthetic_Matches_Provider*>(matches_provider.get())->load(d);

  // Configure data provider (Features and Matches)
  sfmEngine.SetFeaturesProvider(feats_provider.get());
  sfmEngine.SetMatchesProvider(matches_provider.get());

  // Configure reconstruction parameters (intrinsic parameters are held constant)
  sfmEngine.Set_Intrinsics_Refinement_Type(cameras::Intrinsic_Parameter_Type::NONE);

  EXPECT_TRUE (sfmEngine.Process());

  const double dResidual = RMSE(sfmEngine.Get_SfM_Data());
  std::cout << "RMSE residual: " << dResidual << std::endl;
  EXPECT_TRUE( dResidual < 0.5);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews);
  EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints);
  EXPECT_TRUE( IsTracksOneCC(sfmEngine.Get_SfM_Data()));
}

/* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
/* ************************************************************************* */
<|endoftext|>


<commit_before>#define DEBUG_TYPE "enerc"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

#include <sstream>
#include <set>
#include <cstdio>

#define ECQ_PRECISE 0
#define ECQ_APPROX 1

#define FUNC_TRACE "enerc_trace"

// I'm not sure why, but I can't seem to enable debug output in the usual way
// (with command line flags). Here's a hack.
#undef DEBUG
#define DEBUG(s) s

using namespace llvm;

namespace {
  cl::opt<bool> optInstrument ("accept-inst",
      cl::desc("ACCEPT: enable profiling instrumentation"));

  // Look at the qualifier metadata on the instruction and determine whether it
  // has approximate semantics.
  bool isApprox(Instruction *instr) {
    MDNode *md = instr->getMetadata("quals");
    if (!md)
      return false;

    Value *val = md->getOperand(0);
    ConstantInt *ci = cast<ConstantInt>(val);
    if (ci) {
      APInt intval = ci->getValue();
      return intval == ECQ_APPROX;
    } else {
      llvm::errs() << "INVALID METADATA";
      return false;
    }
  }

  // Is it legal to elide this instruction?
  bool elidable_helper(Instruction *instr,
                       std::set<Instruction*> &seen) {
    // Check for cycles.
    if (seen.count(instr)) {
      llvm::errs() << "CYCLE DETECTED\n";
      return false;
    }
    seen.insert(instr);

    if (isApprox(instr)) {
      return true;
    } else if (isa<StoreInst>(instr) ||
               isa<ReturnInst>(instr) ||
               isa<BranchInst>(instr)) {
      // Precise stores, returns, branches: never elidable.
      return false;
    } else {
      // Recursive case: all consumers are elidable.
      for (Value::use_iterator ui = instr->use_begin();
            ui != instr->use_end(); ++ui) {
        Instruction *user = dyn_cast<Instruction>(*ui);
        if (user && !elidable_helper(user, seen)) {
          return false;
        }
      }
      return true; // No non-elidable consumers.
    }
  }
  // Start with an empty "seen" (cycle-detection) set.
  bool elidable(Instruction *instr) {
    std::set<Instruction*> seen;
    return elidable_helper(instr, seen);
  }

  struct EnerC : public FunctionPass {
      static char ID;
      EnerC() : FunctionPass(ID) {
        gApproxInsts = 0;
        gElidableInsts = 0;
        gTotalInsts = 0;
      }

      Constant *blockCountFunction;
      unsigned long gApproxInsts;
      unsigned long gElidableInsts;
      unsigned long gTotalInsts;

      virtual bool runOnFunction(Function &F) {
        for (Function::iterator bbi = F.begin(); bbi != F.end(); ++bbi) {
          unsigned int approxInsts = 0;
          unsigned int elidableInsts = 0;
          unsigned int totalInsts = 0;

          for (BasicBlock::iterator ii = bbi->begin(); ii != bbi->end();
                ++ii) {
            if ((Instruction*)ii == bbi->getTerminator()) {
              // Terminator instruction is not checked.
              continue;
            }

            // Record information about this instruction.
            bool iApprox = isApprox(ii);
            bool iElidable = elidable(ii);
            ++gTotalInsts;
            ++totalInsts;
            if (iApprox) {
              ++gApproxInsts;
              ++approxInsts;
            }
            if (iElidable) {
              ++gElidableInsts;
              ++elidableInsts;
            }
          }

          // Call the runtime profiling library for this block.
          if (optInstrument)
            insertTraceCall(F, bbi, approxInsts, elidableInsts, totalInsts);
        }

        return false;
      }

      virtual bool doInitialization(Module &M) {
        errs() << "initializing\n";

        // Add instrumentation function.
        if (optInstrument)
          blockCountFunction = M.getOrInsertFunction(
            FUNC_TRACE,
            Type::getVoidTy(M.getContext()), // return type
            Type::getInt32Ty(M.getContext()), // approx
            Type::getInt32Ty(M.getContext()), // elidable
            Type::getInt32Ty(M.getContext()), // total
            NULL
          );

        return false;
      }

      virtual bool doFinalization(Module &M) {
        FILE *results_file = fopen("enerc_static.txt", "w+");
        fprintf(results_file,
                "%lu %lu %lu\n", gApproxInsts, gElidableInsts, gTotalInsts);
        fclose(results_file);
        return false;
      }

    protected:
      void insertTraceCall(Function &F, BasicBlock* bb,
                           unsigned int approx,
                           unsigned int elidable,
                           unsigned int total) {
        std::vector<Value *> args;
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), approx)
        );
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), elidable)
        );
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), total)
        );

        // For now, we're inserting calls at the end of basic blocks.
        CallInst::Create(
          blockCountFunction,
          args,
          "",
          bb->getTerminator()
        );
      }
  };
  char EnerC::ID = 0;

  // Register EnerC as a "standard pass". This allows the pass to run without
  // running opt explicitly (e.g., as part of running `clang`).
  static void registerACCEPTPass(const PassManagerBuilder &,
                                 PassManagerBase &PM) {
    PM.add(new EnerC());
  }
  static RegisterStandardPasses
      RegisterACCEPT(PassManagerBuilder::EP_EarlyAsPossible,
                     registerACCEPTPass);
}
<commit_msg>change pass name<commit_after>#define DEBUG_TYPE "enerc"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Analysis/LoopPass.h"

#include <sstream>
#include <set>
#include <cstdio>

#define ECQ_PRECISE 0
#define ECQ_APPROX 1

#define FUNC_TRACE "enerc_trace"

// I'm not sure why, but I can't seem to enable debug output in the usual way
// (with command line flags). Here's a hack.
#undef DEBUG
#define DEBUG(s) s

using namespace llvm;

namespace {
  cl::opt<bool> optInstrument ("accept-inst",
      cl::desc("ACCEPT: enable profiling instrumentation"));

  // Look at the qualifier metadata on the instruction and determine whether it
  // has approximate semantics.
  bool isApprox(Instruction *instr) {
    MDNode *md = instr->getMetadata("quals");
    if (!md)
      return false;

    Value *val = md->getOperand(0);
    ConstantInt *ci = cast<ConstantInt>(val);
    if (ci) {
      APInt intval = ci->getValue();
      return intval == ECQ_APPROX;
    } else {
      llvm::errs() << "INVALID METADATA";
      return false;
    }
  }

  // Is it legal to elide this instruction?
  bool elidable_helper(Instruction *instr,
                       std::set<Instruction*> &seen) {
    // Check for cycles.
    if (seen.count(instr)) {
      llvm::errs() << "CYCLE DETECTED\n";
      return false;
    }
    seen.insert(instr);

    if (isApprox(instr)) {
      return true;
    } else if (isa<StoreInst>(instr) ||
               isa<ReturnInst>(instr) ||
               isa<BranchInst>(instr)) {
      // Precise stores, returns, branches: never elidable.
      return false;
    } else {
      // Recursive case: all consumers are elidable.
      for (Value::use_iterator ui = instr->use_begin();
            ui != instr->use_end(); ++ui) {
        Instruction *user = dyn_cast<Instruction>(*ui);
        if (user && !elidable_helper(user, seen)) {
          return false;
        }
      }
      return true; // No non-elidable consumers.
    }
  }
  // Start with an empty "seen" (cycle-detection) set.
  bool elidable(Instruction *instr) {
    std::set<Instruction*> seen;
    return elidable_helper(instr, seen);
  }

  struct ACCEPTPass : public FunctionPass {
      static char ID;
      ACCEPTPass() : FunctionPass(ID) {
        gApproxInsts = 0;
        gElidableInsts = 0;
        gTotalInsts = 0;
      }

      Constant *blockCountFunction;
      unsigned long gApproxInsts;
      unsigned long gElidableInsts;
      unsigned long gTotalInsts;

      virtual bool runOnFunction(Function &F) {
        for (Function::iterator bbi = F.begin(); bbi != F.end(); ++bbi) {
          unsigned int approxInsts = 0;
          unsigned int elidableInsts = 0;
          unsigned int totalInsts = 0;

          for (BasicBlock::iterator ii = bbi->begin(); ii != bbi->end();
                ++ii) {
            if ((Instruction*)ii == bbi->getTerminator()) {
              // Terminator instruction is not checked.
              continue;
            }

            // Record information about this instruction.
            bool iApprox = isApprox(ii);
            bool iElidable = elidable(ii);
            ++gTotalInsts;
            ++totalInsts;
            if (iApprox) {
              ++gApproxInsts;
              ++approxInsts;
            }
            if (iElidable) {
              ++gElidableInsts;
              ++elidableInsts;
            }
          }

          // Call the runtime profiling library for this block.
          if (optInstrument)
            insertTraceCall(F, bbi, approxInsts, elidableInsts, totalInsts);
        }

        return false;
      }

      virtual bool doInitialization(Module &M) {
        errs() << "initializing\n";

        // Add instrumentation function.
        if (optInstrument)
          blockCountFunction = M.getOrInsertFunction(
            FUNC_TRACE,
            Type::getVoidTy(M.getContext()), // return type
            Type::getInt32Ty(M.getContext()), // approx
            Type::getInt32Ty(M.getContext()), // elidable
            Type::getInt32Ty(M.getContext()), // total
            NULL
          );

        return false;
      }

      virtual bool doFinalization(Module &M) {
        FILE *results_file = fopen("enerc_static.txt", "w+");
        fprintf(results_file,
                "%lu %lu %lu\n", gApproxInsts, gElidableInsts, gTotalInsts);
        fclose(results_file);
        return false;
      }

    protected:
      void insertTraceCall(Function &F, BasicBlock* bb,
                           unsigned int approx,
                           unsigned int elidable,
                           unsigned int total) {
        std::vector<Value *> args;
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), approx)
        );
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), elidable)
        );
        args.push_back(
            ConstantInt::get(Type::getInt32Ty(F.getContext()), total)
        );

        // For now, we're inserting calls at the end of basic blocks.
        CallInst::Create(
          blockCountFunction,
          args,
          "",
          bb->getTerminator()
        );
      }
  };
  char ACCEPTPass::ID = 0;

  // Register ACCEPT as a "standard pass". This allows the pass to run without
  // running opt explicitly (e.g., as part of running `clang`).
  static void registerACCEPTPass(const PassManagerBuilder &,
                                 PassManagerBase &PM) {
    PM.add(new ACCEPTPass());
  }
  static RegisterStandardPasses
      RegisterACCEPT(PassManagerBuilder::EP_EarlyAsPossible,
                     registerACCEPTPass);
}
<|endoftext|>