<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_unpacker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

class ExtensionUnpackerTest : public testing::Test {
public:
  ~ExtensionUnpackerTest() {
    LOG(WARNING) << "Deleting temp dir: "
                 << temp_dir_.path().LossyDisplayName();
    LOG(WARNING) << temp_dir_.Delete();
  }

  void SetupUnpacker(const std::string& crx_name) {
    FilePath original_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path));
    original_path = original_path.AppendASCII("extensions")
        .AppendASCII("unpacker")
        .AppendASCII(crx_name);
    ASSERT_TRUE(file_util::PathExists(original_path)) << original_path.value();

    // Try bots won't let us write into DIR_TEST_DATA, so we have to create
    // a temp folder to play in.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    FilePath crx_path = temp_dir_.path().AppendASCII(crx_name);
    ASSERT_TRUE(file_util::CopyFile(original_path, crx_path)) <<
        "Original path " << original_path.value() <<
        ", Crx path " << crx_path.value();

    unpacker_.reset(
        new ExtensionUnpacker(
            crx_path, Extension::INTERNAL, Extension::NO_FLAGS));
  }

 protected:
  ScopedTempDir temp_dir_;
  scoped_ptr<ExtensionUnpacker> unpacker_;
};

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_EmptyDefaultLocale EmptyDefaultLocale
#else
#define MAYBE_EmptyDefaultLocale EmptyDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_EmptyDefaultLocale) {
  SetupUnpacker("empty_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109385
#if defined(OS_WIN)
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#else
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_HasDefaultLocaleMissingLocalesFolder) {
  SetupUnpacker("has_default_missing_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesTreeMissing),
            unpacker_->error_message());
}

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_InvalidDefaultLocale InvalidDefaultLocale
#else
#define MAYBE_InvalidDefaultLocale InvalidDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_InvalidDefaultLocale) {
  SetupUnpacker("invalid_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Windows, see http://crbug.com/109738
#if defined(OS_WIN)
#define MAYBE_InvalidMessagesFile InvalidMessagesFile
#else
#define MAYBE_InvalidMessagesFile InvalidMessagesFile
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_InvalidMessagesFile) {
  SetupUnpacker("invalid_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16("*_locales?en_US?messages.json: Line: 2, column: 3,"
                " Dictionary keys must be quoted.")));
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingDefaultData MissingDefaultData
#else
#define MAYBE_MissingDefaultData MissingDefaultData
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingDefaultData) {
  SetupUnpacker("missing_default_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingDefaultLocaleHasLocalesFolder \
  MissingDefaultLocaleHasLocalesFolder
#else
#define MAYBE_MissingDefaultLocaleHasLocalesFolder \
  MissingDefaultLocaleHasLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingDefaultLocaleHasLocalesFolder) {
  SetupUnpacker("missing_default_has_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultLocaleSpecified),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingMessagesFile MissingMessagesFile
#else
#define MAYBE_MissingMessagesFile MissingMessagesFile
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingMessagesFile) {
  SetupUnpacker("missing_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16(errors::kLocalesMessagesFileMissing) +
    ASCIIToUTF16("*_locales?en_US?messages.json")));
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_NoLocaleData NoLocaleData
#else
#define MAYBE_NoLocaleData NoLocaleData
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_NoLocaleData) {
  SetupUnpacker("no_locale_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_GoodL10n GoodL10n
#else
#define MAYBE_GoodL10n GoodL10n
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_GoodL10n) {
  SetupUnpacker("good_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  ASSERT_EQ(2U, unpacker_->parsed_catalogs()->size());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_NoL10n NoL10n
#else
#define MAYBE_NoL10n NoL10n
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_NoL10n) {
  SetupUnpacker("no_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  EXPECT_EQ(0U, unpacker_->parsed_catalogs()->size());
}
<commit_msg>Disabling ExtensionUnpackerTest.EmptyDefaultLocale<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_unpacker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

class ExtensionUnpackerTest : public testing::Test {
public:
  ~ExtensionUnpackerTest() {
    LOG(WARNING) << "Deleting temp dir: "
                 << temp_dir_.path().LossyDisplayName();
    LOG(WARNING) << temp_dir_.Delete();
  }

  void SetupUnpacker(const std::string& crx_name) {
    FilePath original_path;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path));
    original_path = original_path.AppendASCII("extensions")
        .AppendASCII("unpacker")
        .AppendASCII(crx_name);
    ASSERT_TRUE(file_util::PathExists(original_path)) << original_path.value();

    // Try bots won't let us write into DIR_TEST_DATA, so we have to create
    // a temp folder to play in.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    FilePath crx_path = temp_dir_.path().AppendASCII(crx_name);
    ASSERT_TRUE(file_util::CopyFile(original_path, crx_path)) <<
        "Original path " << original_path.value() <<
        ", Crx path " << crx_path.value();

    unpacker_.reset(
        new ExtensionUnpacker(
            crx_path, Extension::INTERNAL, Extension::NO_FLAGS));
  }

 protected:
  ScopedTempDir temp_dir_;
  scoped_ptr<ExtensionUnpacker> unpacker_;
};

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_EmptyDefaultLocale DISABLED_EmptyDefaultLocale
#else
#define MAYBE_EmptyDefaultLocale EmptyDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_EmptyDefaultLocale) {
  SetupUnpacker("empty_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109385
#if defined(OS_WIN)
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#else
#define MAYBE_HasDefaultLocaleMissingLocalesFolder \
  HasDefaultLocaleMissingLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_HasDefaultLocaleMissingLocalesFolder) {
  SetupUnpacker("has_default_missing_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesTreeMissing),
            unpacker_->error_message());
}

// Crashes intermittently on Windows, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_InvalidDefaultLocale InvalidDefaultLocale
#else
#define MAYBE_InvalidDefaultLocale InvalidDefaultLocale
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_InvalidDefaultLocale) {
  SetupUnpacker("invalid_default_locale.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kInvalidDefaultLocale),
            unpacker_->error_message());
}

// Crashes intermittently on Windows, see http://crbug.com/109738
#if defined(OS_WIN)
#define MAYBE_InvalidMessagesFile InvalidMessagesFile
#else
#define MAYBE_InvalidMessagesFile InvalidMessagesFile
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_InvalidMessagesFile) {
  SetupUnpacker("invalid_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16("*_locales?en_US?messages.json: Line: 2, column: 3,"
                " Dictionary keys must be quoted.")));
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingDefaultData MissingDefaultData
#else
#define MAYBE_MissingDefaultData MissingDefaultData
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingDefaultData) {
  SetupUnpacker("missing_default_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingDefaultLocaleHasLocalesFolder \
  MissingDefaultLocaleHasLocalesFolder
#else
#define MAYBE_MissingDefaultLocaleHasLocalesFolder \
  MissingDefaultLocaleHasLocalesFolder
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingDefaultLocaleHasLocalesFolder) {
  SetupUnpacker("missing_default_has_locales.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultLocaleSpecified),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_MissingMessagesFile MissingMessagesFile
#else
#define MAYBE_MissingMessagesFile MissingMessagesFile
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_MissingMessagesFile) {
  SetupUnpacker("missing_messages_file.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_TRUE(MatchPattern(unpacker_->error_message(),
    ASCIIToUTF16(errors::kLocalesMessagesFileMissing) +
    ASCIIToUTF16("*_locales?en_US?messages.json")));
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_NoLocaleData NoLocaleData
#else
#define MAYBE_NoLocaleData NoLocaleData
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_NoLocaleData) {
  SetupUnpacker("no_locale_data.crx");
  EXPECT_FALSE(unpacker_->Run());
  EXPECT_EQ(ASCIIToUTF16(errors::kLocalesNoDefaultMessages),
            unpacker_->error_message());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_GoodL10n GoodL10n
#else
#define MAYBE_GoodL10n GoodL10n
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_GoodL10n) {
  SetupUnpacker("good_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  ASSERT_EQ(2U, unpacker_->parsed_catalogs()->size());
}

// Crashes intermittently on Vista, see http://crbug.com/109238
#if defined(OS_WIN)
#define MAYBE_NoL10n NoL10n
#else
#define MAYBE_NoL10n NoL10n
#endif
TEST_F(ExtensionUnpackerTest, MAYBE_NoL10n) {
  SetupUnpacker("no_l10n.crx");
  EXPECT_TRUE(unpacker_->Run());
  EXPECT_TRUE(unpacker_->error_message().empty());
  EXPECT_EQ(0U, unpacker_->parsed_catalogs()->size());
}
<|endoftext|>


<commit_before>//
//  FlashTests.cpp
//  Bedrock Tests
//
//  Created by Eric Yanush on 2015-12-26.
//  Copyright © 2015 EricYanush. All rights reserved.
//

#include "gtest/gtest.h"
#include "Flash.hpp"

class FlashTest : public ::testing::Test {

protected:

    virtual void SetUp() {
        flash = (Flash*) malloc(sizeof(Flash));
    }

    virtual void TearDown() {
        free(flash);
    }

    Flash* flash;
};

/** Ensure layout of Flash object adheres with Register Map
 * as defined in the STM32F3 Programming Manual
 */
TEST_F(FlashTest, TestFlashRegLayout) {
    ASSERT_EQ(0x00, offsetof(Flash, AC));
    ASSERT_EQ(0x04, offsetof(Flash, KEY));
    ASSERT_EQ(0x08, offsetof(Flash, OPTKEY));
    ASSERT_EQ(0x0C, offsetof(Flash, SR));
    ASSERT_EQ(0x10, offsetof(Flash, CR));
    ASSERT_EQ(0x14, offsetof(Flash, AR));
    ASSERT_EQ(0x18, offsetof(Flash, OB));
    ASSERT_EQ(0x1C, offsetof(Flash, WRP));
}

TEST_F(FlashTest, TestLatencySet) {
    flash->AC = 0;
    flash->setLatency(FlashWait::one);
    ASSERT_EQ(static_cast<uint32_t>(FlashWait::one), flash->AC);
}

TEST_F(FlashTest, TestPrefetchEnable) {
    flash->AC = 0;
    flash->enablePrefetch();
    ASSERT_EQ(1 << 4, flash->AC);
}

TEST_F(FlashTest, TestPrefetchDisable) {
    flash->AC = 0;
    flash->AC |= (1 << 4);
    flash->disablePrefetch();
    ASSERT_EQ(0, flash->AC);
}

<commit_msg>Refactor common code from FlashTests<commit_after>//
//  FlashTests.cpp
//  Bedrock Tests
//
//  Created by Eric Yanush on 2015-12-26.
//  Copyright © 2015 EricYanush. All rights reserved.
//

#include "gtest/gtest.h"
#include "Flash.hpp"

/**
 Note: upon initializtion of the test fixture, the flash member object is initialized
 to all zeros. The flashIsInInitState function checks to see if the flash member object
 is still all zeros.
 */
class FlashTest : public ::testing::Test {

protected:

    virtual void SetUp() {
    }

    virtual void TearDown() {
    }

    Flash flash{0};
    const Flash untouched{0};

    bool flashIsInInitState() {
        return (memcmp(&flash, &untouched, sizeof(Flash)) == 0);
    }
};

/** Ensure layout of Flash object adheres with Register Map
 * as defined in the STM32F3 Programming Manual
 */
TEST_F(FlashTest, TestFlashRegLayout) {
    ASSERT_EQ(0x00, offsetof(Flash, AC));
    ASSERT_EQ(0x04, offsetof(Flash, KEY));
    ASSERT_EQ(0x08, offsetof(Flash, OPTKEY));
    ASSERT_EQ(0x0C, offsetof(Flash, SR));
    ASSERT_EQ(0x10, offsetof(Flash, CR));
    ASSERT_EQ(0x14, offsetof(Flash, AR));
    ASSERT_EQ(0x18, offsetof(Flash, OB));
    ASSERT_EQ(0x1C, offsetof(Flash, WRP));
}

TEST_F(FlashTest, TestLatencySet) {
    flash.AC = 0;
    flash.setLatency(FlashWait::one);
    ASSERT_EQ(static_cast<uint32_t>(FlashWait::one), flash.AC);
}

TEST_F(FlashTest, TestPrefetchEnable) {
    flash.enablePrefetch();
    ASSERT_EQ(1 << 4, flash.AC);
    flash.AC &= ~(1 << 4);
    ASSERT_EQ(true, flashIsInInitState());
}

TEST_F(FlashTest, TestPrefetchDisable) {
    flash.AC |= (1 << 4); //Manually enable the prefetch
    flash.disablePrefetch();
    ASSERT_EQ(0, flash.AC);
    ASSERT_EQ(true, flashIsInInitState());
}

<|endoftext|>


<commit_before>#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/icp.h>
#include <pcl/registration/elch.h>

//#include <boost/graph/graphviz.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_traits.hpp>
using boost::graph_traits;

#include <boost/graph/adjacency_list.hpp>
using boost::edge_weight_t;

#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <fstream>
using std::ofstream;

#include <vector>
using std::vector;

#include <list>
using std::list;

#include <algorithm>
using std::swap;

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;
typedef std::pair<std::string, CloudPtr> CloudPair;
typedef std::vector<CloudPair> CloudVector;

typedef boost::adjacency_list<
  boost::listS, boost::vecS, boost::undirectedS,
  boost::no_property,
  boost::property< edge_weight_t, double > >
Graph;

void
elch (int start, int end, const CloudVector &clouds)
{
  CloudPtr tmp (new Cloud);
  pcl::registration::ELCH<pcl::PointXYZ> theclass;

  static Graph g;

  for (size_t i = num_vertices (g)+1; i < clouds.size (); i++)
    add_edge (i-1, i, g);

  //TODO use pose
  }
}

void
loopDetection (int end, const CloudVector &clouds, double dist)
{
  static double min_dist = -1;
  static int first, last;
  int state = 0;

  for (int i = end-1; i > 0; i--)
  {
    Eigen::Vector4f cstart, cend;
    //TODO use pose of scan
    pcl::compute3DCentroid (*(clouds[i].second), cstart);
    pcl::compute3DCentroid (*(clouds[end].second), cend);
    Eigen::Vector4f diff = cend - cstart;

    double norm = diff.norm ();

    //std::cout << "distance between " << i << " and " << end << " is " << norm << " state is " << state << std::endl;

    if (state == 0 && norm > dist)
    {
      state = 1;
      //std::cout << "state 1" << std::endl;
    }
    if (state > 0 && norm < dist)
    {
      state = 2;
      std::cout << "loop detected between scan " << i << " (" << clouds[i].first << ") and scan " << end << " (" << clouds[end].first << ")" << std::endl;
      if (min_dist < 0 || norm < min_dist)
      {
        min_dist = norm;
        first = i;
        last = end;
      }
    }
  }
  std::cout << "min_dist: " << min_dist << " state: " << state << " first: " << first << " end: " << end << std::endl;
  if (min_dist > 0 && (state < 2 || end == (int)clouds.size () - 1)) //TODO
  {
    min_dist = -1;
    std::cout << "calling elch with " << first << " and " << last << std::endl;
    elch (first, last, clouds);
    std::cout << "finished calling elch" << std::endl;
  }
}

int
main (int argc, char **argv)
{
  CloudVector clouds;
  for (int i = 1; i < argc; i++)
  {
    CloudPtr pc (new Cloud);
    pcl::io::loadPCDFile (argv[i], *pc);
    clouds.push_back (CloudPair (argv[i], pc));
    std::cout << "loading file: " << argv[i] << " size: " << pc->size () << std::endl;
  }

  for (size_t i = 0; i < clouds.size (); i++)
    loopDetection (i, clouds, 15.0);

  for (size_t i = 0; i < clouds.size (); i++)
  {
    std::string result_filename (clouds[i].first);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *(clouds[i].second));
    cout << "saving result to " << result_filename << endl;
  }

  return 0;
}
<commit_msg>Revert accidentally commit of elch.cpp.<commit_after>#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/icp.h>

//#include <boost/graph/graphviz.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_traits.hpp>
using boost::graph_traits;

#include <boost/graph/adjacency_list.hpp>
using boost::edge_weight_t;

#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <fstream>
using std::ofstream;

#include <vector>
using std::vector;

#include <list>
using std::list;

#include <algorithm>
using std::swap;

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;
typedef std::pair<std::string, CloudPtr> CloudPair;
typedef std::vector<CloudPair> CloudVector;

typedef boost::adjacency_list<
  boost::listS, boost::vecS, boost::undirectedS,
  boost::no_property,
  boost::property< edge_weight_t, double > >
Graph;

/**
 * graph balancer algorithm computes the weights
 * @param g the graph
 * @param f index of the first node
 * @param l index of the last node
 * @param weights array for the weights
 */
void
loopOptimizerAlgorithm (Graph &g, int f, int l, double *weights)
{
  list<int> crossings, branches;
  crossings.push_back (f);
  crossings.push_back (l);
  weights[f] = 0;
  weights[l] = 1;

  int *p = new int[num_vertices (g)];
  int *p_min = new int[num_vertices (g)];
  double *d = new double[num_vertices (g)];
  double *d_min = new double[num_vertices (g)];
  double dist;
  bool do_swap = false;
  list<int>::iterator crossings_it, end_it, start_min, end_min;

  // process all junctions
  while (!crossings.empty ())
  {
    dist = -1;
    // find shortest crossing for all vertices on the loop
    for (crossings_it = crossings.begin (); crossings_it != crossings.end (); )
    {
      dijkstra_shortest_paths (g, *crossings_it, boost::predecessor_map (p).distance_map (d));
      end_it = crossings_it;
      end_it++;
      // find shortest crossing for one vertex
      for (; end_it != crossings.end (); end_it++)
      {
        if (*end_it != p[*end_it] && (dist < 0 || d[*end_it] < dist))
        {
          dist = d[*end_it];
          start_min = crossings_it;
          end_min = end_it;
          do_swap = true;
        }
      }
      if (do_swap)
      {
        swap (p, p_min);
        swap (d, d_min);
        do_swap = false;
      }
      // vertex starts a branch
      if (dist < 0)
      {
        branches.push_back (*crossings_it);
        crossings_it = crossings.erase (crossings_it);
      }
      else
        crossings_it++;
    }

    if (dist > -1)
    {
      remove_edge (*end_min, p_min[*end_min], g);
      for (int i = p_min[*end_min]; i != *start_min; i = p_min[i])
      {
        //even right with weights[*start_min] > weights[*end_min]! (math works)
        weights[i] = weights[*start_min] + (weights[*end_min] - weights[*start_min]) * d_min[i] / d_min[*end_min];
        remove_edge (i, p_min[i], g);
        if (degree (i, g) > 0)
        {
          crossings.push_back (i);
        }
      }

      if (degree (*start_min, g) == 0)
        crossings.erase (start_min);

      if (degree (*end_min, g) == 0)
        crossings.erase (end_min);
    }
  }

  delete[] p;
  delete[] p_min;
  delete[] d;
  delete[] d_min;

  graph_traits<Graph>::adjacency_iterator adjacent_it, adjacent_it_end;
  int s;

  // error propagation
  while (!branches.empty ())
  {
    s = branches.front ();
    branches.pop_front ();

    for (tie (adjacent_it, adjacent_it_end) = adjacent_vertices (s, g); adjacent_it != adjacent_it_end; ++adjacent_it)
    {
      weights[*adjacent_it] = weights[s];
      if (degree (*adjacent_it, g) > 1)
        branches.push_back (*adjacent_it);
    }
    clear_vertex (s, g);
  }
}

void
elch (int start, int end, const CloudVector &clouds)
{
  CloudPtr tmp (new Cloud);

  Eigen::Vector4f cstart;
  pcl::compute3DCentroid (*(clouds[start].second), cstart);
  Eigen::Vector3f cs2 (cstart[0], cstart[1], cstart[2]);

  Eigen::Vector4f cend2;
  pcl::compute3DCentroid (*(clouds[end].second), cend2);
  Eigen::Vector3f ce2 (cend2[0], cend2[1], cend2[2]);
  ce2 = cs2 - ce2;
  pcl::transformPointCloud (*(clouds[end].second), *tmp, ce2, Eigen::Quaternionf::Identity ());

  pcl::IterativeClosestPoint<PointType, PointType> icp;

  icp.setMaximumIterations (50);
  icp.setMaxCorrespondenceDistance (1.5);
  icp.setRANSACOutlierRejectionThreshold (1.5);
  //icp.setRANSACOutlierRejectionThreshold (DBL_MAX);

  icp.setInputTarget (clouds[start].second);

  icp.setInputCloud (tmp);

  icp.align (*tmp);

  Eigen::Matrix3f m (icp.getFinalTransformation ().block (0, 0, 3, 3));
  Eigen::Quaternionf q (m);
  Eigen::Vector4f ta (icp.getFinalTransformation ().col (3));
  Eigen::Vector3f t (ta[0], ta[1], ta[2]);
  //TODO hack
  t += ce2;

  std::cout << icp.getFinalTransformation () << std::endl;

  static Graph g;

  for (size_t i = num_vertices (g)+1; i < clouds.size (); i++)
    add_edge (i-1, i, g);

  Graph grb[4];

  graph_traits<Graph>::edge_iterator edge_it, edge_it_end;
  for (tie (edge_it, edge_it_end) = edges (g); edge_it != edge_it_end; edge_it++)
  {
    for (int j = 0; j < 4; j++)
      add_edge (source (*edge_it, g), target (*edge_it, g), 1, grb[j]);  //TODO add variance
  }

  double *weights[4];
  for (int i = 0; i < 4; i++)
  {
    weights[i] = new double[clouds.size ()];
    loopOptimizerAlgorithm (grb[i], start, end, weights[i]);
  }

  //TODO use pose
  Eigen::Vector4f cend;
  pcl::compute3DCentroid (*(clouds[end].second), cend);
  Eigen::Translation3f tend (cend[0], cend[1], cend[2]);
  Eigen::Affine3f aend (tend);
  Eigen::Affine3f aendI = aend.inverse ();

  for (size_t i = 0; i < clouds.size (); i++)
  {
    CloudPtr tmp (new Cloud);

    Eigen::Vector3f t2;
    t2[0] = t[0] * weights[0][i];
    t2[1] = t[1] * weights[1][i];
    t2[2] = t[2] * weights[2][i];

    Eigen::Quaternionf q2;
    q2 = Eigen::Quaternionf::Identity ().slerp (weights[3][i], q);

    //TODO use rotation from branch start
    Eigen::Translation3f t3 (t2);
    Eigen::Affine3f a (t3 * q2);
    a = aend * a * aendI;

    //std::cout << "transform cloud " << i << " to:" << std::endl << a.matrix () << std::endl;
    pcl::transformPointCloud (*(clouds[i].second), *(clouds[i].second), a);
  }
}

void
loopDetection (int end, const CloudVector &clouds, double dist)
{
  static double min_dist = -1;
  static int first, last;
  int state = 0;

  for (int i = end-1; i > 0; i--)
  {
    Eigen::Vector4f cstart, cend;
    //TODO use pose of scan
    pcl::compute3DCentroid (*(clouds[i].second), cstart);
    pcl::compute3DCentroid (*(clouds[end].second), cend);
    Eigen::Vector4f diff = cend - cstart;

    double norm = diff.norm ();

    //std::cout << "distance between " << i << " and " << end << " is " << norm << " state is " << state << std::endl;

    if (state == 0 && norm > dist)
    {
      state = 1;
      //std::cout << "state 1" << std::endl;
    }
    if (state > 0 && norm < dist)
    {
      state = 2;
      std::cout << "loop detected between scan " << i << " (" << clouds[i].first << ") and scan " << end << " (" << clouds[end].first << ")" << std::endl;
      if (min_dist < 0 || norm < min_dist)
      {
        min_dist = norm;
        first = i;
        last = end;
      }
    }
  }
  std::cout << "min_dist: " << min_dist << " state: " << state << " first: " << first << " end: " << end << std::endl;
  if (min_dist > 0 && (state < 2 || end == (int)clouds.size () - 1)) //TODO
  {
    min_dist = -1;
    std::cout << "calling elch with " << first << " and " << last << std::endl;
    elch (first, last, clouds);
    std::cout << "finished calling elch" << std::endl;
  }
}

int
main (int argc, char **argv)
{
  CloudVector clouds;
  for (int i = 1; i < argc; i++)
  {
    CloudPtr pc (new Cloud);
    pcl::io::loadPCDFile (argv[i], *pc);
    clouds.push_back (CloudPair (argv[i], pc));
    std::cout << "loading file: " << argv[i] << " size: " << pc->size () << std::endl;
  }

  for (size_t i = 0; i < clouds.size (); i++)
    loopDetection (i, clouds, 15.0);

  for (size_t i = 0; i < clouds.size (); i++)
  {
    std::string result_filename (clouds[i].first);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *(clouds[i].second));
    cout << "saving result to " << result_filename << endl;
  }

  return 0;
}
<|endoftext|>


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

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#include <iostream>
#include <string>

// Pubic nomlib interface headers
#include <nomlib/math.hpp>
#include <nomlib/system.hpp>
#include <nomlib/graphics.hpp>
// #include <nomlib/gui.hpp>

/// File path name of the resources directory; this must be a relative file path.
const std::string APP_RESOURCES_DIR = "Resources";

/// \brief  Relative file path name of our resource example
const nom::Path p;
const std::string RESOURCE_ICON = APP_RESOURCES_DIR + p.native() + "icon.png";

/// \brief Relative filename path to saved screen shot example
///
/// Default path should resolve to the same directory as the app example
/// executable
const std::string OUTPUT_SCREENSHOT_FILENAME = "screenshot.png";

/// \brief Name of our application.
const std::string APP_NAME = "Examples Template App";

/// \brief Width, in pixels, of our effective rendering surface.
const nom::int32 WINDOW_WIDTH = 768;

/// \brief Height, in pixels, of our effective rendering surface.
const nom::int32 WINDOW_HEIGHT = 448;

/// \brief Maximum number of active windows we will attempt to spawn in this
/// example.
const nom::int32 MAXIMUM_WINDOWS = 2;

const nom::int32 USER_EVENT_DEBUG = 0;

/// \brief Usage example
/// \remarks For unit testing: ensure that library is compiled with
/// the appropriate defines enabled within EventHandler.hpp.
class App: public nom::SDLApp
{
  public:
    App( nom::int32 argc, char* argv[] )
    {
      NOM_LOG_TRACE( NOM );

      // Fatal error; if we are not able to complete this step, it means that
      // we probably cannot rely on our resource paths!
      if( nom::init( argc, argv ) == false )
      {
        nom::DialogMessageBox( APP_NAME, "ERROR: Could not initialize nomlib." );
        exit( NOM_EXIT_FAILURE );
      }

      atexit( nom::quit );
    } // end App

    ~App( void )
    {
      NOM_LOG_TRACE( NOM );
    } // end ~App

    bool on_init( void )
    {
      nom::uint32 window_flags = SDL_WINDOW_RESIZABLE;

      for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
      {
        if ( this->window[idx].create( APP_NAME, ( WINDOW_WIDTH / 2 ), WINDOW_HEIGHT, window_flags ) == false )
        {
          return false;
        }

        this->window[idx].set_position( 0 + ( WINDOW_WIDTH / 2 ) * idx, ( WINDOW_HEIGHT / 2 ) );

        if( this->window[idx].set_window_icon( RESOURCE_ICON ) == false )
        {
          nom::DialogMessageBox( APP_NAME, "ERROR: Could not load window icon: " + RESOURCE_ICON );
          return false;
        }

        this->window_size[idx] = this->window[idx].size();

        // Scale window contents up by the new width & height
        // this->window[idx].set_logical_size( this->window_size[idx].x, this->window_size[idx].y );
      }

      // Start out execution with both windows minimized.
      nom::EventDispatcher dispatcher;
      nom::EventCallback delegate1( [&] { this->minimize(0); } );
      nom::EventCallback delegate2( [&] { this->minimize(1); } );

      dispatcher.dispatch( nom::UserEvent( USER_EVENT_DEBUG, nullptr, NOM_SCAST( nom::EventCallback*, &delegate1 ), 0 ) );
      dispatcher.dispatch( nom::UserEvent( USER_EVENT_DEBUG, nullptr, NOM_SCAST( nom::EventCallback*, &delegate2 ), 0 ) );

      // C++ style syntax for adding an input map:
      this->add_input_mapping ( "minimize_window_0",
                                nom::Action (
                                              SDL_MOUSEBUTTONDOWN, SDL_BUTTON_LEFT, nom::EventCallback( [&] { this->minimize(0); } )
                                            )
                              );

      nom::EventCallback restore_callback( [&] { this->restore(0); } );

      // C style syntax for adding an input map:
      nom::Action restore_window_0;
      restore_window_0.type = SDL_MOUSEBUTTONDOWN;
      restore_window_0.event = SDL_BUTTON_RIGHT;
      restore_window_0.callback = restore_callback;
      this->add_input_mapping( "restore_window_0", restore_window_0 );

      return true;
    } // end on_init

    void minimize( int idx )
    {
      this->window[idx].minimize_window();
    }

    void restore( int idx )
    {
      this->window[idx].restore_window();
    }

    nom::sint Run( void )
    {
      for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
      {
        this->update[idx].start();
        this->fps[idx].start();
      }

      // 1. Events
      // 2. Logic
      // 3. Render

      while( this->running() == true )
      {
        while( this->poll_event( &this->event ) )
        {
          this->on_event( &this->event );
        }

        for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
        {
          this->window[idx].update();
          this->fps[idx].update();

          // Refresh the frames per second at 1 second intervals
          if ( this->update[idx].ticks() > 1000 )
          {
            if ( this->show_fps() == true )
            {
              this->window[idx].set_window_title( APP_NAME + " - " + this->fps[idx].asString() + ' ' + "fps" );
            }
            else
            {
              this->window[idx].set_window_title( APP_NAME + " [" + std::to_string(this->window[idx].window_id()) + "]" + " - " + "Display" + ' ' + std::to_string ( this->window[idx].window_display_id() ) );
            }

            this->update[idx].restart();
          } // end refresh cycle
        } // end for MAXIMUM_WINDOWS update loop

        for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
        {
          this->window[idx].fill( nom::Color4i::SkyBlue );
        }
      } // end while SDLApp::running() is true

      return NOM_EXIT_SUCCESS;
    } // end Run()

  private:
    /// \brief Event handler for key down actions
    ///
    /// \remarks Implements nom::Input::on_key_down
/*
    void on_key_down( const nom::Event& ev )
    {
      switch( ev.key.sym )
      {
        default: break;

        // Use inherited SDLApp::on_app_quit method -- you may also provide your
        // own event handler for this.
        case SDLK_ESCAPE:
        case SDLK_q: this->on_app_quit( ev ); break;

        case SDLK_BACKSLASH:
        {
          if ( this->toggle_fps() )
          {
            // Stub for doing something cool here
          }
          else
          {
            // Stub for doing something cool here
          }
          break;
        }

        case SDLK_F1:
        {
          if( this->window[ev.key.window_id - 1].window_id() == ev.key.window_id )
          {
            if( this->window[ev.key.window_id - 1].save_screenshot( OUTPUT_SCREENSHOT_FILENAME ) == false )
            {
              nom::DialogMessageBox( APP_NAME, "ERROR: Could not save screen-shot");
              break;
            } // end save_screenshot err check
          } // end window_id check
          break;
        }

        // Toggle full-screen
        case SDLK_f:
        {
          if ( this->window[ev.key.window_id - 1].window_id() == ev.key.window_id )
          {
            this->window[ev.key.window_id - 1].toggle_fullscreen();
          } // end window_id match
          break;
        } // end SDLK_f
      } // end switch key
    } // end on_key_down
*/
    /// \remarks Implements nom::EventHandler::on_user_event
    void on_user_event( const nom::UserEvent& ev )
    {
      // A call is made here to the virtual method being re-implemented here in
      // order to catch debugging output with debug builds compiled in; see
      // EventHandler.hpp.
      // Input::on_user_event( ev );

      if( ev.code == USER_EVENT_DEBUG )
      {
        nom::EventCallback* delegate = ev.get_callback();

        if( delegate != nullptr )
        {
          delegate->execute();
        }
      }
    }

  private:
    /// \brief Window handles
    ///
    /// \TODO Use std::vector?
    nom::RenderWindow window[MAXIMUM_WINDOWS];

    nom::Point2i window_size[MAXIMUM_WINDOWS];

    /// \brief Interval at which we refresh the frames per second counter
    nom::Timer update[MAXIMUM_WINDOWS];

    /// \brief Timer for tracking frames per second
    nom::FPS fps[MAXIMUM_WINDOWS];
}; // end class App

nom::sint main( nom::int32 argc, char* argv[] )
{
  App app ( argc, argv );

  if ( app.on_init() == false )
  {
    nom::DialogMessageBox( APP_NAME, "ERROR: Could not initialize application." );
    return NOM_EXIT_FAILURE;
  }

  return app.Run();

  // ...Goodbye cruel world!
}
<commit_msg>examples/events: Remove on_key_down method<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

******************************************************************************/
#include <iostream>
#include <string>

// Pubic nomlib interface headers
#include <nomlib/math.hpp>
#include <nomlib/system.hpp>
#include <nomlib/graphics.hpp>
// #include <nomlib/gui.hpp>

/// File path name of the resources directory; this must be a relative file path.
const std::string APP_RESOURCES_DIR = "Resources";

/// \brief  Relative file path name of our resource example
const nom::Path p;
const std::string RESOURCE_ICON = APP_RESOURCES_DIR + p.native() + "icon.png";

/// \brief Relative filename path to saved screen shot example
///
/// Default path should resolve to the same directory as the app example
/// executable
const std::string OUTPUT_SCREENSHOT_FILENAME = "screenshot.png";

/// \brief Name of our application.
const std::string APP_NAME = "Examples Template App";

/// \brief Width, in pixels, of our effective rendering surface.
const nom::int32 WINDOW_WIDTH = 768;

/// \brief Height, in pixels, of our effective rendering surface.
const nom::int32 WINDOW_HEIGHT = 448;

/// \brief Maximum number of active windows we will attempt to spawn in this
/// example.
const nom::int32 MAXIMUM_WINDOWS = 2;

const nom::int32 USER_EVENT_DEBUG = 0;

/// \brief Usage example
/// \remarks For unit testing: ensure that library is compiled with
/// the appropriate defines enabled within EventHandler.hpp.
class App: public nom::SDLApp
{
  public:
    App( nom::int32 argc, char* argv[] )
    {
      NOM_LOG_TRACE( NOM );

      // Fatal error; if we are not able to complete this step, it means that
      // we probably cannot rely on our resource paths!
      if( nom::init( argc, argv ) == false )
      {
        nom::DialogMessageBox( APP_NAME, "ERROR: Could not initialize nomlib." );
        exit( NOM_EXIT_FAILURE );
      }

      atexit( nom::quit );
    } // end App

    ~App( void )
    {
      NOM_LOG_TRACE( NOM );
    } // end ~App

    bool on_init( void )
    {
      nom::uint32 window_flags = SDL_WINDOW_RESIZABLE;

      for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
      {
        if ( this->window[idx].create( APP_NAME, ( WINDOW_WIDTH / 2 ), WINDOW_HEIGHT, window_flags ) == false )
        {
          return false;
        }

        this->window[idx].set_position( 0 + ( WINDOW_WIDTH / 2 ) * idx, ( WINDOW_HEIGHT / 2 ) );

        if( this->window[idx].set_window_icon( RESOURCE_ICON ) == false )
        {
          nom::DialogMessageBox( APP_NAME, "ERROR: Could not load window icon: " + RESOURCE_ICON );
          return false;
        }

        this->window_size[idx] = this->window[idx].size();

        // Scale window contents up by the new width & height
        // this->window[idx].set_logical_size( this->window_size[idx].x, this->window_size[idx].y );
      }

      // Start out execution with both windows minimized.
      nom::EventDispatcher dispatcher;
      nom::EventCallback delegate1( [&] { this->minimize(0); } );
      nom::EventCallback delegate2( [&] { this->minimize(1); } );

      dispatcher.dispatch( nom::UserEvent( USER_EVENT_DEBUG, nullptr, NOM_SCAST( nom::EventCallback*, &delegate1 ), 0 ) );
      dispatcher.dispatch( nom::UserEvent( USER_EVENT_DEBUG, nullptr, NOM_SCAST( nom::EventCallback*, &delegate2 ), 0 ) );

      // C++ style syntax for adding an input map:
      this->add_input_mapping ( "minimize_window_0",
                                nom::Action (
                                              SDL_MOUSEBUTTONDOWN, SDL_BUTTON_LEFT, nom::EventCallback( [&] { this->minimize(0); } )
                                            )
                              );

      nom::EventCallback restore_callback( [&] { this->restore(0); } );

      // C style syntax for adding an input map:
      nom::Action restore_window_0;
      restore_window_0.type = SDL_MOUSEBUTTONDOWN;
      restore_window_0.event = SDL_BUTTON_RIGHT;
      restore_window_0.callback = restore_callback;
      this->add_input_mapping( "restore_window_0", restore_window_0 );

      return true;
    } // end on_init

    void minimize( int idx )
    {
      this->window[idx].minimize_window();
    }

    void restore( int idx )
    {
      this->window[idx].restore_window();
    }

    nom::sint Run( void )
    {
      for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
      {
        this->update[idx].start();
        this->fps[idx].start();
      }

      // 1. Events
      // 2. Logic
      // 3. Render

      while( this->running() == true )
      {
        while( this->poll_event( &this->event ) )
        {
          this->on_event( &this->event );
        }

        for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
        {
          this->window[idx].update();
          this->fps[idx].update();

          // Refresh the frames per second at 1 second intervals
          if ( this->update[idx].ticks() > 1000 )
          {
            if ( this->show_fps() == true )
            {
              this->window[idx].set_window_title( APP_NAME + " - " + this->fps[idx].asString() + ' ' + "fps" );
            }
            else
            {
              this->window[idx].set_window_title( APP_NAME + " [" + std::to_string(this->window[idx].window_id()) + "]" + " - " + "Display" + ' ' + std::to_string ( this->window[idx].window_display_id() ) );
            }

            this->update[idx].restart();
          } // end refresh cycle
        } // end for MAXIMUM_WINDOWS update loop

        for( auto idx = 0; idx < MAXIMUM_WINDOWS; ++idx )
        {
          this->window[idx].fill( nom::Color4i::SkyBlue );
        }
      } // end while SDLApp::running() is true

      return NOM_EXIT_SUCCESS;
    } // end Run()

  private:
    /// \brief Event handler for user-defined events.
    ///
    /// \remarks Implements nom::EventHandler::on_user_event
    void on_user_event( const nom::UserEvent& ev )
    {
      // A call is made here to the virtual method being re-implemented here in
      // order to catch debugging output with debug builds compiled in; see
      // EventHandler.hpp.
      // Input::on_user_event( ev );

      if( ev.code == USER_EVENT_DEBUG )
      {
        nom::EventCallback* delegate = ev.get_callback();

        if( delegate != nullptr )
        {
          delegate->execute();
        }
      }
    }

  private:
    /// \brief Window handles
    ///
    /// \TODO Use std::vector?
    nom::RenderWindow window[MAXIMUM_WINDOWS];

    nom::Point2i window_size[MAXIMUM_WINDOWS];

    /// \brief Interval at which we refresh the frames per second counter
    nom::Timer update[MAXIMUM_WINDOWS];

    /// \brief Timer for tracking frames per second
    nom::FPS fps[MAXIMUM_WINDOWS];
}; // end class App

nom::sint main( nom::int32 argc, char* argv[] )
{
  App app ( argc, argv );

  if ( app.on_init() == false )
  {
    nom::DialogMessageBox( APP_NAME, "ERROR: Could not initialize application." );
    return NOM_EXIT_FAILURE;
  }

  return app.Run();

  // ...Goodbye cruel world!
}
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "DebugResidualAux.h"
#include "NonlinearSystem.h"

template<>
InputParameters validParams<DebugResidualAux>()
{
  InputParameters params = validParams<AuxKernel>();
  params.addRequiredParam<std::string>("debug_variable", "The variable that is being debugged.");

  return params;
}

DebugResidualAux::DebugResidualAux(const std::string & name, InputParameters parameters) :
    AuxKernel(name, parameters),
    _debug_var(_nl_sys.getVariable(_tid, parameters.get<std::string>("debug_variable"))),
    _residual_copy(_nl_sys.residualGhosted())
{
  mooseAssert(_nodal == true, "Cannot use DebugResidualAux on elemental variables");
}

DebugResidualAux::~DebugResidualAux()
{
}

Real
DebugResidualAux::computeValue()
{
  unsigned int dof = _current_node->dof_number(_nl_sys.number(), _debug_var.index(), 0);
  return _residual_copy(dof);
}
<commit_msg>DebugResidualAux now uses NonlinearVariable for 'debug_variable' (closes-#2037)<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "DebugResidualAux.h"
#include "NonlinearSystem.h"

template<>
InputParameters validParams<DebugResidualAux>()
{
  InputParameters params = validParams<AuxKernel>();
  params.addRequiredParam<NonlinearVariableName>("debug_variable", "The variable that is being debugged.");
  return params;
}

DebugResidualAux::DebugResidualAux(const std::string & name, InputParameters parameters) :
    AuxKernel(name, parameters),
    _debug_var(_nl_sys.getVariable(_tid, getParam<std::string>("debug_variable"))),
    _residual_copy(_nl_sys.residualGhosted())
{
  mooseAssert(_nodal == true, "Cannot use DebugResidualAux on elemental variables");
}

DebugResidualAux::~DebugResidualAux()
{
}

Real
DebugResidualAux::computeValue()
{
  unsigned int dof = _current_node->dof_number(_nl_sys.number(), _debug_var.index(), 0);
  return _residual_copy(dof);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
** This file is part of the Ovi services plugin for the Maps and
** Navigation API.  The use of these services, whether by use of the
** plugin or by other means, is governed by the terms and conditions
** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in
** this package, located in the directory containing the Ovi services
** plugin source code.
**
****************************************************************************/

#include "qgeomappingmanagerengine_nokia.h"
#include "qgeomapreply_nokia.h"
#include "qgeotiledmapdata_nokia.h"

#include <qgeotiledmaprequest.h>

#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QNetworkProxy>
#include <QSize>
#include <QDir>
#include <QDateTime>

#include <QDebug>

#define LARGE_TILE_DIMENSION 256

// TODO: Tweak the max size or create something better
#if defined(Q_OS_SYMBIAN)
#define DISK_CACHE_MAX_SIZE 10*1024*1024  //10MB
#else
#define DISK_CACHE_MAX_SIZE 50*1024*1024  //50MB
#endif

#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
#undef DISK_CACHE_ENABLED
#else
#define DISK_CACHE_ENABLED 1
#endif

QGeoMappingManagerEngineNokia::QGeoMappingManagerEngineNokia(const QMap<QString, QVariant> &parameters, QGeoServiceProvider::Error *error, QString *errorString)
        : QGeoTiledMappingManagerEngine(parameters),
        m_cache(0),
        m_host("maptile.maps.svc.ovi.com"),
        m_token(QGeoServiceProviderFactoryNokia::defaultToken),
        m_referer(QGeoServiceProviderFactoryNokia::defaultReferer)
{
    Q_UNUSED(error)
    Q_UNUSED(errorString)

    setTileSize(QSize(256, 256));
    setMinimumZoomLevel(0.0);
    setMaximumZoomLevel(18.0);

    QList<QGraphicsGeoMap::MapType> types;
    types << QGraphicsGeoMap::StreetMap;
    types << QGraphicsGeoMap::SatelliteMapDay;
    types << QGraphicsGeoMap::TerrainMap;
    setSupportedMapTypes(types);

    QList<QGraphicsGeoMap::ConnectivityMode> modes;
    modes << QGraphicsGeoMap::OnlineMode;
    setSupportedConnectivityModes(modes);

    m_networkManager = new QNetworkAccessManager(this);

    if (parameters.contains("mapping.proxy")) {
        QString proxy = parameters.value("mapping.proxy").toString();
        if (!proxy.isEmpty())
            m_networkManager->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxy, 8080));
    }

    if (parameters.contains("mapping.host")) {
        QString host = parameters.value("mapping.host").toString();
        if (!host.isEmpty())
            m_host = host;
    }

    if (parameters.contains("mapping.referer")) {
        m_referer = parameters.value("mapping.referer").toString();
    }

    if (parameters.contains("mapping.token")) {
        m_token = parameters.value("mapping.token").toString();
    }
    else if (parameters.contains("token")) {
        m_token = parameters.value("token").toString();
    }

#ifdef DISK_CACHE_ENABLED
    m_cache = new QNetworkDiskCache(this);

    QDir dir = QDir::temp();
    dir.mkdir("maptiles");
    dir.cd("maptiles");

    m_cache->setCacheDirectory(dir.path());

    if (parameters.contains("mapping.cache.directory")) {
        QString cacheDir = parameters.value("mapping.cache.directory").toString();
        if (!cacheDir.isEmpty())
            m_cache->setCacheDirectory(cacheDir);
    }

    if (parameters.contains("mapping.cache.size")) {
        bool ok = false;
        qint64 cacheSize = parameters.value("mapping.cache.size").toString().toLongLong(&ok);
        if (ok)
            m_cache->setMaximumCacheSize(cacheSize);
    }

    if (m_cache->maximumCacheSize() > DISK_CACHE_MAX_SIZE)
        m_cache->setMaximumCacheSize(DISK_CACHE_MAX_SIZE);

    m_networkManager->setCache(m_cache);
#endif
}

QGeoMappingManagerEngineNokia::~QGeoMappingManagerEngineNokia() {}

QGeoMapData* QGeoMappingManagerEngineNokia::createMapData()
{
    QGeoMapData *data = new QGeoTiledMapDataNokia(this);
    if (!data)
        return 0;

    data->setConnectivityMode(QGraphicsGeoMap::OnlineMode);
    return data;
}

QGeoTiledMapReply* QGeoMappingManagerEngineNokia::getTileImage(const QGeoTiledMapRequest &request)
{
    // TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode
    QString rawRequest = getRequestString(request);

    QNetworkRequest netRequest((QUrl(rawRequest))); // The extra pair of parens disambiguates this from a function declaration
    netRequest.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);

#ifdef DISK_CACHE_ENABLED
    netRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
    m_cache->metaData(netRequest.url()).setLastModified(QDateTime::currentDateTime());
#endif

    QNetworkReply* netReply = m_networkManager->get(netRequest);

    QGeoTiledMapReply* mapReply = new QGeoMapReplyNokia(netReply, request);

    // TODO goes badly on linux
    //qDebug() << "request: " << QString::number(reinterpret_cast<int>(mapReply), 16) << " " << request.row() << "," << request.column();
    // this one might work better. It follows defined behaviour, unlike reinterpret_cast
    //qDebug("request: %p %i,%i @ %i", mapReply, request.row(), request.column(), request.zoomLevel());
    return mapReply;
}

QString QGeoMappingManagerEngineNokia::getRequestString(const QGeoTiledMapRequest &request) const
{
    const int maxDomains = 11; // TODO: hmmm....
    const char subdomain = 'a' + (request.row() + request.column()) % maxDomains; // a...k
    static const QString http("http://");
    static const QString path("/maptiler/maptile/newest/");
    static const QChar dot('.');
    static const QChar slash('/');

    QString requestString = http;
    requestString += subdomain;
    requestString += dot;
    requestString += m_host;
    requestString += path;
    requestString += mapTypeToStr(request.mapType());
    requestString += slash;
    requestString += QString::number(request.zoomLevel());
    requestString += slash;
    requestString += QString::number(request.column());
    requestString += slash;
    requestString += QString::number(request.row());
    requestString += slash;
    requestString += sizeToStr(tileSize());
//#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    static const QString slashpng("/png8");
//#else
//    static const QString slashpng("/png");
//#endif
    requestString += slashpng;

    if (!m_token.isEmpty()) {
        requestString += "?token=";
        requestString += m_token;

        if (!m_referer.isEmpty()) {
            requestString += "&referer=";
            requestString += m_referer;
        }
    } else if (!m_referer.isEmpty()) {
        requestString += "?referer=";
        requestString += m_referer;
    }

    return requestString;
}

QString QGeoMappingManagerEngineNokia::sizeToStr(const QSize &size)
{
    static const QString s256("256");
    static const QString s128("128");
    if (size.height() >= LARGE_TILE_DIMENSION ||
            size.width() >= LARGE_TILE_DIMENSION)
        return s256;
    else
        return s128;
}

QString QGeoMappingManagerEngineNokia::mapTypeToStr(QGraphicsGeoMap::MapType type)
{
    if (type == QGraphicsGeoMap::StreetMap)
        return "normal.day";
    else if (type == QGraphicsGeoMap::SatelliteMapDay ||
             type == QGraphicsGeoMap::SatelliteMapNight) {
        return "satellite.day";
    } else if (type == QGraphicsGeoMap::TerrainMap)
        return "terrain.day";
    else
        return "normal.day";
}

<commit_msg>Adds the ability to specify a proxy port in the Nokia maps plugin.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
** This file is part of the Ovi services plugin for the Maps and
** Navigation API.  The use of these services, whether by use of the
** plugin or by other means, is governed by the terms and conditions
** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in
** this package, located in the directory containing the Ovi services
** plugin source code.
**
****************************************************************************/

#include "qgeomappingmanagerengine_nokia.h"
#include "qgeomapreply_nokia.h"
#include "qgeotiledmapdata_nokia.h"

#include <qgeotiledmaprequest.h>

#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QNetworkProxy>
#include <QSize>
#include <QDir>
#include <QUrl>
#include <QDateTime>

#include <QDebug>

#define LARGE_TILE_DIMENSION 256

// TODO: Tweak the max size or create something better
#if defined(Q_OS_SYMBIAN)
#define DISK_CACHE_MAX_SIZE 10*1024*1024  //10MB
#else
#define DISK_CACHE_MAX_SIZE 50*1024*1024  //50MB
#endif

#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
#undef DISK_CACHE_ENABLED
#else
#define DISK_CACHE_ENABLED 1
#endif

QGeoMappingManagerEngineNokia::QGeoMappingManagerEngineNokia(const QMap<QString, QVariant> &parameters, QGeoServiceProvider::Error *error, QString *errorString)
        : QGeoTiledMappingManagerEngine(parameters),
        m_cache(0),
        m_host("maptile.maps.svc.ovi.com"),
        m_token(QGeoServiceProviderFactoryNokia::defaultToken),
        m_referer(QGeoServiceProviderFactoryNokia::defaultReferer)
{
    Q_UNUSED(error)
    Q_UNUSED(errorString)

    setTileSize(QSize(256, 256));
    setMinimumZoomLevel(0.0);
    setMaximumZoomLevel(18.0);

    QList<QGraphicsGeoMap::MapType> types;
    types << QGraphicsGeoMap::StreetMap;
    types << QGraphicsGeoMap::SatelliteMapDay;
    types << QGraphicsGeoMap::TerrainMap;
    setSupportedMapTypes(types);

    QList<QGraphicsGeoMap::ConnectivityMode> modes;
    modes << QGraphicsGeoMap::OnlineMode;
    setSupportedConnectivityModes(modes);

    m_networkManager = new QNetworkAccessManager(this);

    if (parameters.contains("mapping.proxy")) {
        QString proxy = parameters.value("mapping.proxy").toString();
        if (!proxy.isEmpty()) {
            QUrl proxyUrl(proxy);
            if (proxyUrl.isValid()) {
                m_networkManager->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy,
                    proxyUrl.host(),
                    proxyUrl.port(8080),
                    proxyUrl.userName(),
                    proxyUrl.password()));
            }
        }
    }

    if (parameters.contains("mapping.host")) {
        QString host = parameters.value("mapping.host").toString();
        if (!host.isEmpty())
            m_host = host;
    }

    if (parameters.contains("mapping.referer")) {
        m_referer = parameters.value("mapping.referer").toString();
    }

    if (parameters.contains("mapping.token")) {
        m_token = parameters.value("mapping.token").toString();
    }
    else if (parameters.contains("token")) {
        m_token = parameters.value("token").toString();
    }

#ifdef DISK_CACHE_ENABLED
    m_cache = new QNetworkDiskCache(this);

    QDir dir = QDir::temp();
    dir.mkdir("maptiles");
    dir.cd("maptiles");

    m_cache->setCacheDirectory(dir.path());

    if (parameters.contains("mapping.cache.directory")) {
        QString cacheDir = parameters.value("mapping.cache.directory").toString();
        if (!cacheDir.isEmpty())
            m_cache->setCacheDirectory(cacheDir);
    }

    if (parameters.contains("mapping.cache.size")) {
        bool ok = false;
        qint64 cacheSize = parameters.value("mapping.cache.size").toString().toLongLong(&ok);
        if (ok)
            m_cache->setMaximumCacheSize(cacheSize);
    }

    if (m_cache->maximumCacheSize() > DISK_CACHE_MAX_SIZE)
        m_cache->setMaximumCacheSize(DISK_CACHE_MAX_SIZE);

    m_networkManager->setCache(m_cache);
#endif
}

QGeoMappingManagerEngineNokia::~QGeoMappingManagerEngineNokia() {}

QGeoMapData* QGeoMappingManagerEngineNokia::createMapData()
{
    QGeoMapData *data = new QGeoTiledMapDataNokia(this);
    if (!data)
        return 0;

    data->setConnectivityMode(QGraphicsGeoMap::OnlineMode);
    return data;
}

QGeoTiledMapReply* QGeoMappingManagerEngineNokia::getTileImage(const QGeoTiledMapRequest &request)
{
    // TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode
    QString rawRequest = getRequestString(request);

    QNetworkRequest netRequest((QUrl(rawRequest))); // The extra pair of parens disambiguates this from a function declaration
    netRequest.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);

#ifdef DISK_CACHE_ENABLED
    netRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
    m_cache->metaData(netRequest.url()).setLastModified(QDateTime::currentDateTime());
#endif

    QNetworkReply* netReply = m_networkManager->get(netRequest);

    QGeoTiledMapReply* mapReply = new QGeoMapReplyNokia(netReply, request);

    // TODO goes badly on linux
    //qDebug() << "request: " << QString::number(reinterpret_cast<int>(mapReply), 16) << " " << request.row() << "," << request.column();
    // this one might work better. It follows defined behaviour, unlike reinterpret_cast
    //qDebug("request: %p %i,%i @ %i", mapReply, request.row(), request.column(), request.zoomLevel());
    return mapReply;
}

QString QGeoMappingManagerEngineNokia::getRequestString(const QGeoTiledMapRequest &request) const
{
    const int maxDomains = 11; // TODO: hmmm....
    const char subdomain = 'a' + (request.row() + request.column()) % maxDomains; // a...k
    static const QString http("http://");
    static const QString path("/maptiler/maptile/newest/");
    static const QChar dot('.');
    static const QChar slash('/');

    QString requestString = http;
    requestString += subdomain;
    requestString += dot;
    requestString += m_host;
    requestString += path;
    requestString += mapTypeToStr(request.mapType());
    requestString += slash;
    requestString += QString::number(request.zoomLevel());
    requestString += slash;
    requestString += QString::number(request.column());
    requestString += slash;
    requestString += QString::number(request.row());
    requestString += slash;
    requestString += sizeToStr(tileSize());
//#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    static const QString slashpng("/png8");
//#else
//    static const QString slashpng("/png");
//#endif
    requestString += slashpng;

    if (!m_token.isEmpty()) {
        requestString += "?token=";
        requestString += m_token;

        if (!m_referer.isEmpty()) {
            requestString += "&referer=";
            requestString += m_referer;
        }
    } else if (!m_referer.isEmpty()) {
        requestString += "?referer=";
        requestString += m_referer;
    }

    return requestString;
}

QString QGeoMappingManagerEngineNokia::sizeToStr(const QSize &size)
{
    static const QString s256("256");
    static const QString s128("128");
    if (size.height() >= LARGE_TILE_DIMENSION ||
            size.width() >= LARGE_TILE_DIMENSION)
        return s256;
    else
        return s128;
}

QString QGeoMappingManagerEngineNokia::mapTypeToStr(QGraphicsGeoMap::MapType type)
{
    if (type == QGraphicsGeoMap::StreetMap)
        return "normal.day";
    else if (type == QGraphicsGeoMap::SatelliteMapDay ||
             type == QGraphicsGeoMap::SatelliteMapNight) {
        return "satellite.day";
    } else if (type == QGraphicsGeoMap::TerrainMap)
        return "terrain.day";
    else
        return "normal.day";
}

<|endoftext|>


<commit_before>/**
 * MegaMol
 * Copyright (c) 2021, MegaMol Dev Team
 * All rights reserved.
 */

#include "ResolutionScalingRenderer2D.h"

#include <vector>

#include "mmcore/param/BoolParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/utility/log/Log.h"

using namespace megamol::infovis_gl;
using megamol::core::utility::log::Log;

ResolutionScalingRenderer2D::ResolutionScalingRenderer2D()
        : BaseAmortizedRenderer2D()
        , amortLevelParam("AmortLevel", "Level of Amortization")
        , skipInterpolationParam("SkipInterpolation", "Do not interpolate missing pixels.") {

    amortLevelParam << new core::param::IntParam(1, 1);
    MakeSlotAvailable(&amortLevelParam);

    skipInterpolationParam << new core::param::BoolParam(false);
    MakeSlotAvailable(&skipInterpolationParam);
}

ResolutionScalingRenderer2D::~ResolutionScalingRenderer2D() {
    Release();
}

bool ResolutionScalingRenderer2D::createImpl(const msf::ShaderFactoryOptionsOpenGL& shaderOptions) {
    try {
        shader_ = core::utility::make_glowl_shader("amort_resolutionscaling", shaderOptions,
            "infovis_gl/amort/amort_quad.vert.glsl", "infovis_gl/amort/amort_resolutionscaling.frag.glsl");
    } catch (std::exception& e) {
        Log::DefaultLog.WriteMsg(Log::LEVEL_ERROR, ("ResolutionScalingRenderer2D: " + std::string(e.what())).c_str());
        return false;
    }

    lowResFBO_ = std::make_shared<glowl::FramebufferObject>(1, 1);
    lowResFBO_->createColorAttachment(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);

    // Store texture layout for later resize
    texLayout_ = glowl::TextureLayout(GL_RGBA8, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1,
        {
            {GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_MIN_FILTER, GL_NEAREST},
            {GL_TEXTURE_MAG_FILTER, GL_NEAREST},
        },
        {});
    distTexLayout_ = glowl::TextureLayout(GL_RG32F, 1, 1, 1, GL_RG, GL_FLOAT, 1,
        {
            {GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_MIN_FILTER, GL_NEAREST},
            {GL_TEXTURE_MAG_FILTER, GL_NEAREST},
        },
        {});

    texRead_ = std::make_unique<glowl::Texture2D>("texStoreA", texLayout_, nullptr);
    texWrite_ = std::make_unique<glowl::Texture2D>("texStoreB", texLayout_, nullptr);
    distTexRead_ = std::make_unique<glowl::Texture2D>("distTexR", distTexLayout_, nullptr);
    distTexWrite_ = std::make_unique<glowl::Texture2D>("distTexW", distTexLayout_, nullptr);

    auto err = glGetError();
    if (err != GL_NO_ERROR) {
        Log::DefaultLog.WriteError("GL_ERROR in ResolutionScalingRenderer2D: %i", err);
    }

    return true;
}

void ResolutionScalingRenderer2D::releaseImpl() {
    // nothing to do
}

bool ResolutionScalingRenderer2D::renderImpl(
    core_gl::view::CallRender2DGL& call, core_gl::view::CallRender2DGL& nextRendererCall) {

    auto const& fbo = call.GetFramebuffer();
    auto const& cam = call.GetCamera();
    auto const& bg = call.BackgroundColor();

    const int a = amortLevelParam.Param<core::param::IntParam>()->Value();
    const int w = fbo->getWidth();
    const int h = fbo->getHeight();

    if (a != oldAmortLevel_ || w != oldWidth_ || h != oldHeight_) {
        updateSize(a, w, h);
        oldAmortLevel_ = a;
        oldWidth_ = w;
        oldHeight_ = h;
    }

    lowResFBO_->bind();
    glClearColor(bg.r, bg.g, bg.b, bg.a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    lastViewProjMx_ = viewProjMx_;
    viewProjMx_ = cam.getProjectionMatrix() * cam.getViewMatrix();

    auto lowResCam = cam;
    setupCamera(lowResCam, w, h, a);

    nextRendererCall.SetFramebuffer(lowResFBO_);
    nextRendererCall.SetCamera(lowResCam);
    (nextRendererCall)(core::view::AbstractCallRender::FnRender);

    reconstruct(fbo, cam, a);

    return true;
}

void ResolutionScalingRenderer2D::updateSize(int a, int w, int h) {
    viewProjMx_ = glm::mat4(1.0f);
    lastViewProjMx_ = glm::mat4(1.0f);
    camOffsets_.resize(a * a);
    for (int j = 0; j < a; j++) {
        for (int i = 0; i < a; i++) {
            const float x = static_cast<float>(2 * i - a + 1) / static_cast<float>(w);
            const float y = static_cast<float>(2 * j - a + 1) / static_cast<float>(h);
            camOffsets_[j * a + i] = glm::vec3(x, y, 0.0f);
        }
    }

    lowResFBO_->resize((w + a - 1) / a, (h + a - 1) / a); // Integer division with round up.

    texLayout_.width = w;
    texLayout_.height = h;
    const std::vector<uint32_t> zeroData(w * h, 0); // uin32_t <=> RGBA8.
    texRead_ = std::make_unique<glowl::Texture2D>("texRead", texLayout_, zeroData.data());
    texWrite_ = std::make_unique<glowl::Texture2D>("texWrite", texLayout_, zeroData.data());

    distTexLayout_.width = w;
    distTexLayout_.height = h;
    const std::vector<float> posInit(2 * w * h, std::numeric_limits<float>::lowest()); // RG32F
    distTexRead_ = std::make_unique<glowl::Texture2D>("distTexRead", distTexLayout_, posInit.data());
    distTexWrite_ = std::make_unique<glowl::Texture2D>("distTexWrite", distTexLayout_, posInit.data());

    samplingSequence_.clear();

    const int nextPowerOfTwoExp = static_cast<int>(std::ceil(std::log2(a)));
    const int nextPowerOfTwoVal = static_cast<int>(std::pow(2, nextPowerOfTwoExp));

    std::array<std::array<int, 2>, 4> offsetPattern{{{0, 0}, {1, 1}, {0, 1}, {1, 0}}};
    std::vector<int> offsetLength(nextPowerOfTwoExp, 0);
    for (int i = 0; i < nextPowerOfTwoExp; i++) {
        offsetLength[i] = static_cast<int>(std::pow(2, nextPowerOfTwoExp - i - 1));
    }

    for (int i = 0; i < nextPowerOfTwoVal * nextPowerOfTwoVal; i++) {
        int x = 0;
        int y = 0;
        for (int j = 0; j < nextPowerOfTwoExp; j++) {
            const int levelIndex = (i / static_cast<int>(std::pow(4, j))) % 4;
            x += offsetPattern[levelIndex][0] * offsetLength[j];
            y += offsetPattern[levelIndex][1] * offsetLength[j];
        }
        if (x < a && y < a) {
            samplingSequence_.push_back(x + y * a);
        }
    }

    samplingSequencePosition_ = 0;
    frameIdx_ = samplingSequence_[samplingSequencePosition_];
}

void ResolutionScalingRenderer2D::setupCamera(core::view::Camera& cam, int width, int height, int a) {
    auto intrinsics = cam.get<core::view::Camera::OrthographicParameters>();
    auto pose = cam.get<core::view::Camera::Pose>();

    const float aspect = intrinsics.aspect.value();
    const float frustumHeight = intrinsics.frustrum_height.value();
    const float frustumWidth = aspect * frustumHeight;

    float wOffs = 0.5f * frustumWidth * camOffsets_[frameIdx_].x;
    float hOffs = 0.5f * frustumHeight * camOffsets_[frameIdx_].y;

    const int lowResWidth = (width + a - 1) / a;
    const int lowResHeight = (height + a - 1) / a;

    const float wAdj = static_cast<float>(lowResWidth * a) / static_cast<float>(width);
    const float hAdj = static_cast<float>(lowResHeight * a) / static_cast<float>(height);

    wOffs += 0.5f * (wAdj - 1.0f) * frustumWidth;
    hOffs += 0.5f * (hAdj - 1.0f) * frustumHeight;

    pose.position += glm::vec3(wOffs, hOffs, 0.0f);
    intrinsics.frustrum_height = hAdj * frustumHeight;
    intrinsics.aspect = wAdj / hAdj * aspect;

    cam.setOrthographicProjection(intrinsics);
    cam.setPose(pose);
}

void ResolutionScalingRenderer2D::reconstruct(
    std::shared_ptr<glowl::FramebufferObject> const& fbo, core::view::Camera const& cam, int a) {
    int w = fbo->getWidth();
    int h = fbo->getHeight();

    glViewport(0, 0, w, h);
    fbo->bind();

    // Calculate inverse and shift matrix in double precision
    const glm::dmat4 shiftMx = glm::dmat4(lastViewProjMx_) * glm::inverse(glm::dmat4(viewProjMx_));

    const auto intrinsics = cam.get<core::view::Camera::OrthographicParameters>();

    shader_->use();
    shader_->setUniform("amortLevel", a);
    shader_->setUniform("resolution", w, h);
    shader_->setUniform("lowResResolution", lowResFBO_->getWidth(), lowResFBO_->getHeight());
    shader_->setUniform("frameIdx", frameIdx_);
    shader_->setUniform("shiftMx", glm::mat4(shiftMx));
    shader_->setUniform("camCenter", cam.getPose().position);
    shader_->setUniform("camAspect", intrinsics.aspect.value());
    shader_->setUniform("frustumHeight", intrinsics.frustrum_height.value());
    shader_->setUniform(
        "skipInterpolation", static_cast<int>(skipInterpolationParam.Param<core::param::BoolParam>()->Value()));

    glActiveTexture(GL_TEXTURE0);
    lowResFBO_->bindColorbuffer(0);
    shader_->setUniform("texLowResFBO", 0);

    texRead_->bindImage(0, GL_READ_ONLY);
    texWrite_->bindImage(1, GL_WRITE_ONLY);
    distTexRead_->bindImage(2, GL_READ_ONLY);
    distTexWrite_->bindImage(3, GL_WRITE_ONLY);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glUseProgram(0);

    samplingSequencePosition_ = (samplingSequencePosition_ + 1) % (a * a);
    frameIdx_ = samplingSequence_[samplingSequencePosition_];
    texRead_.swap(texWrite_);
    distTexRead_.swap(distTexWrite_);
}
<commit_msg>premultiply fbo alpha<commit_after>/**
 * MegaMol
 * Copyright (c) 2021, MegaMol Dev Team
 * All rights reserved.
 */

#include "ResolutionScalingRenderer2D.h"

#include <vector>

#include "mmcore/param/BoolParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/utility/log/Log.h"

using namespace megamol::infovis_gl;
using megamol::core::utility::log::Log;

ResolutionScalingRenderer2D::ResolutionScalingRenderer2D()
        : BaseAmortizedRenderer2D()
        , amortLevelParam("AmortLevel", "Level of Amortization")
        , skipInterpolationParam("SkipInterpolation", "Do not interpolate missing pixels.") {

    amortLevelParam << new core::param::IntParam(1, 1);
    MakeSlotAvailable(&amortLevelParam);

    skipInterpolationParam << new core::param::BoolParam(false);
    MakeSlotAvailable(&skipInterpolationParam);
}

ResolutionScalingRenderer2D::~ResolutionScalingRenderer2D() {
    Release();
}

bool ResolutionScalingRenderer2D::createImpl(const msf::ShaderFactoryOptionsOpenGL& shaderOptions) {
    try {
        shader_ = core::utility::make_glowl_shader("amort_resolutionscaling", shaderOptions,
            "infovis_gl/amort/amort_quad.vert.glsl", "infovis_gl/amort/amort_resolutionscaling.frag.glsl");
    } catch (std::exception& e) {
        Log::DefaultLog.WriteMsg(Log::LEVEL_ERROR, ("ResolutionScalingRenderer2D: " + std::string(e.what())).c_str());
        return false;
    }

    lowResFBO_ = std::make_shared<glowl::FramebufferObject>(1, 1);
    lowResFBO_->createColorAttachment(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);

    // Store texture layout for later resize
    texLayout_ = glowl::TextureLayout(GL_RGBA8, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1,
        {
            {GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_MIN_FILTER, GL_NEAREST},
            {GL_TEXTURE_MAG_FILTER, GL_NEAREST},
        },
        {});
    distTexLayout_ = glowl::TextureLayout(GL_RG32F, 1, 1, 1, GL_RG, GL_FLOAT, 1,
        {
            {GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER},
            {GL_TEXTURE_MIN_FILTER, GL_NEAREST},
            {GL_TEXTURE_MAG_FILTER, GL_NEAREST},
        },
        {});

    texRead_ = std::make_unique<glowl::Texture2D>("texStoreA", texLayout_, nullptr);
    texWrite_ = std::make_unique<glowl::Texture2D>("texStoreB", texLayout_, nullptr);
    distTexRead_ = std::make_unique<glowl::Texture2D>("distTexR", distTexLayout_, nullptr);
    distTexWrite_ = std::make_unique<glowl::Texture2D>("distTexW", distTexLayout_, nullptr);

    auto err = glGetError();
    if (err != GL_NO_ERROR) {
        Log::DefaultLog.WriteError("GL_ERROR in ResolutionScalingRenderer2D: %i", err);
    }

    return true;
}

void ResolutionScalingRenderer2D::releaseImpl() {
    // nothing to do
}

bool ResolutionScalingRenderer2D::renderImpl(
    core_gl::view::CallRender2DGL& call, core_gl::view::CallRender2DGL& nextRendererCall) {

    auto const& fbo = call.GetFramebuffer();
    auto const& cam = call.GetCamera();
    auto const& bg = call.BackgroundColor();

    const int a = amortLevelParam.Param<core::param::IntParam>()->Value();
    const int w = fbo->getWidth();
    const int h = fbo->getHeight();

    if (a != oldAmortLevel_ || w != oldWidth_ || h != oldHeight_) {
        updateSize(a, w, h);
        oldAmortLevel_ = a;
        oldWidth_ = w;
        oldHeight_ = h;
    }

    lowResFBO_->bind();
    glClearColor(bg.r * bg.a, bg.g * bg.a, bg.b * bg.a, bg.a);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    lastViewProjMx_ = viewProjMx_;
    viewProjMx_ = cam.getProjectionMatrix() * cam.getViewMatrix();

    auto lowResCam = cam;
    setupCamera(lowResCam, w, h, a);

    nextRendererCall.SetFramebuffer(lowResFBO_);
    nextRendererCall.SetCamera(lowResCam);
    (nextRendererCall)(core::view::AbstractCallRender::FnRender);

    reconstruct(fbo, cam, a);

    return true;
}

void ResolutionScalingRenderer2D::updateSize(int a, int w, int h) {
    viewProjMx_ = glm::mat4(1.0f);
    lastViewProjMx_ = glm::mat4(1.0f);
    camOffsets_.resize(a * a);
    for (int j = 0; j < a; j++) {
        for (int i = 0; i < a; i++) {
            const float x = static_cast<float>(2 * i - a + 1) / static_cast<float>(w);
            const float y = static_cast<float>(2 * j - a + 1) / static_cast<float>(h);
            camOffsets_[j * a + i] = glm::vec3(x, y, 0.0f);
        }
    }

    lowResFBO_->resize((w + a - 1) / a, (h + a - 1) / a); // Integer division with round up.

    texLayout_.width = w;
    texLayout_.height = h;
    const std::vector<uint32_t> zeroData(w * h, 0); // uin32_t <=> RGBA8.
    texRead_ = std::make_unique<glowl::Texture2D>("texRead", texLayout_, zeroData.data());
    texWrite_ = std::make_unique<glowl::Texture2D>("texWrite", texLayout_, zeroData.data());

    distTexLayout_.width = w;
    distTexLayout_.height = h;
    const std::vector<float> posInit(2 * w * h, std::numeric_limits<float>::lowest()); // RG32F
    distTexRead_ = std::make_unique<glowl::Texture2D>("distTexRead", distTexLayout_, posInit.data());
    distTexWrite_ = std::make_unique<glowl::Texture2D>("distTexWrite", distTexLayout_, posInit.data());

    samplingSequence_.clear();

    const int nextPowerOfTwoExp = static_cast<int>(std::ceil(std::log2(a)));
    const int nextPowerOfTwoVal = static_cast<int>(std::pow(2, nextPowerOfTwoExp));

    std::array<std::array<int, 2>, 4> offsetPattern{{{0, 0}, {1, 1}, {0, 1}, {1, 0}}};
    std::vector<int> offsetLength(nextPowerOfTwoExp, 0);
    for (int i = 0; i < nextPowerOfTwoExp; i++) {
        offsetLength[i] = static_cast<int>(std::pow(2, nextPowerOfTwoExp - i - 1));
    }

    for (int i = 0; i < nextPowerOfTwoVal * nextPowerOfTwoVal; i++) {
        int x = 0;
        int y = 0;
        for (int j = 0; j < nextPowerOfTwoExp; j++) {
            const int levelIndex = (i / static_cast<int>(std::pow(4, j))) % 4;
            x += offsetPattern[levelIndex][0] * offsetLength[j];
            y += offsetPattern[levelIndex][1] * offsetLength[j];
        }
        if (x < a && y < a) {
            samplingSequence_.push_back(x + y * a);
        }
    }

    samplingSequencePosition_ = 0;
    frameIdx_ = samplingSequence_[samplingSequencePosition_];
}

void ResolutionScalingRenderer2D::setupCamera(core::view::Camera& cam, int width, int height, int a) {
    auto intrinsics = cam.get<core::view::Camera::OrthographicParameters>();
    auto pose = cam.get<core::view::Camera::Pose>();

    const float aspect = intrinsics.aspect.value();
    const float frustumHeight = intrinsics.frustrum_height.value();
    const float frustumWidth = aspect * frustumHeight;

    float wOffs = 0.5f * frustumWidth * camOffsets_[frameIdx_].x;
    float hOffs = 0.5f * frustumHeight * camOffsets_[frameIdx_].y;

    const int lowResWidth = (width + a - 1) / a;
    const int lowResHeight = (height + a - 1) / a;

    const float wAdj = static_cast<float>(lowResWidth * a) / static_cast<float>(width);
    const float hAdj = static_cast<float>(lowResHeight * a) / static_cast<float>(height);

    wOffs += 0.5f * (wAdj - 1.0f) * frustumWidth;
    hOffs += 0.5f * (hAdj - 1.0f) * frustumHeight;

    pose.position += glm::vec3(wOffs, hOffs, 0.0f);
    intrinsics.frustrum_height = hAdj * frustumHeight;
    intrinsics.aspect = wAdj / hAdj * aspect;

    cam.setOrthographicProjection(intrinsics);
    cam.setPose(pose);
}

void ResolutionScalingRenderer2D::reconstruct(
    std::shared_ptr<glowl::FramebufferObject> const& fbo, core::view::Camera const& cam, int a) {
    int w = fbo->getWidth();
    int h = fbo->getHeight();

    glViewport(0, 0, w, h);
    fbo->bind();

    // Calculate inverse and shift matrix in double precision
    const glm::dmat4 shiftMx = glm::dmat4(lastViewProjMx_) * glm::inverse(glm::dmat4(viewProjMx_));

    const auto intrinsics = cam.get<core::view::Camera::OrthographicParameters>();

    shader_->use();
    shader_->setUniform("amortLevel", a);
    shader_->setUniform("resolution", w, h);
    shader_->setUniform("lowResResolution", lowResFBO_->getWidth(), lowResFBO_->getHeight());
    shader_->setUniform("frameIdx", frameIdx_);
    shader_->setUniform("shiftMx", glm::mat4(shiftMx));
    shader_->setUniform("camCenter", cam.getPose().position);
    shader_->setUniform("camAspect", intrinsics.aspect.value());
    shader_->setUniform("frustumHeight", intrinsics.frustrum_height.value());
    shader_->setUniform(
        "skipInterpolation", static_cast<int>(skipInterpolationParam.Param<core::param::BoolParam>()->Value()));

    glActiveTexture(GL_TEXTURE0);
    lowResFBO_->bindColorbuffer(0);
    shader_->setUniform("texLowResFBO", 0);

    texRead_->bindImage(0, GL_READ_ONLY);
    texWrite_->bindImage(1, GL_WRITE_ONLY);
    distTexRead_->bindImage(2, GL_READ_ONLY);
    distTexWrite_->bindImage(3, GL_WRITE_ONLY);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glUseProgram(0);

    samplingSequencePosition_ = (samplingSequencePosition_ + 1) % (a * a);
    frameIdx_ = samplingSequence_[samplingSequencePosition_];
    texRead_.swap(texWrite_);
    distTexRead_.swap(distTexWrite_);
}
<|endoftext|>