<commit_before>#include <errno.h>

#include <iostream>
#include <string>

using namespace std;

#include "config.h"

#include <cryptopp/osrng.h>
#include "common/common_init.h"

#include "common/armor.h"
#include "rgw_user.h"
#include "rgw_access.h"
#include "rgw_acl.h"

#define SECRET_KEY_LEN 40
#define PUBLIC_ID_LEN 20

void usage()
{
  cerr << "usage: radosgw_admin <--user-gen | --user-modify | --read-policy | --list-buckets > [options...]" << std::endl;
  cerr << "options:" << std::endl;
  cerr << "   --uid=<id> (S3 uid)" << std::endl;
  cerr << "   --auth_uid=<auid> (librados uid)" << std::endl;
  cerr << "   --secret=<key>" << std::endl;
  cerr << "   --email=<email>" << std::endl;
  cerr << "   --display-name=<name>" << std::endl;
  cerr << "   --bucket=<bucket>" << std::endl;
  cerr << "   --object=<object>" << std::endl;
  generic_client_usage();
  exit(1);
}

int gen_rand_base64(char *dest, int size) /* size should be the required string size + 1 */
{
  unsigned char buf[size];
  char tmp_dest[size + 4]; /* so that there's space for the extra '=' characters, and some */

  CryptoPP::AutoSeededRandomPool rng;
  rng.GenerateBlock(buf, sizeof(buf));

  int ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)],
		   (const char *)buf, ((const char *)buf) + ((size - 1) * 3 + 4 - 1) / 4);
  if (ret < 0) {
    cerr << "ceph_armor failed" << std::endl;
    return -1;
  }
  tmp_dest[ret] = '\0';
  memcpy(dest, tmp_dest, size);
  dest[size] = '\0';

  return 0;
}

static const char alphanum_table[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int gen_rand_alphanumeric(char *dest, int size) /* size should be the required string size + 1 */
{
  CryptoPP::AutoSeededRandomPool rng;
  rng.GenerateBlock((unsigned char *)dest, size);

  int i;
  for (i=0; i<size - 1; i++) {
    int pos = (unsigned)dest[i];
    dest[i] = alphanum_table[pos % (sizeof(alphanum_table) - 1)];
  }
  dest[i] = '\0';

  return 0;
}

int main(int argc, char **argv)
{
  DEFINE_CONF_VARS(usage);
  vector<const char*> args;
  argv_to_vec(argc, (const char **)argv, args);
  env_to_vec(args);

  common_set_defaults(true);
  common_init(args, "rgw", true);

  const char *user_id = 0;
  const char *secret_key = 0;
  const char *user_email = 0;
  const char *display_name = 0;
  const char *bucket = 0;
  const char *object = 0;
  bool gen_user = false;
  bool mod_user = false;
  bool read_policy = false;
  bool list_buckets = false;
  bool delete_user = false;
  int actions = 0 ;
  uint64_t auid = 0;
  RGWUserInfo info;
  RGWAccess *store;

  if (g_conf.clock_tare) g_clock.tare();

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("user-gen", 'g')) {
      gen_user = true;
    } else if (CONF_ARG_EQ("user-modify", 'm')) {
      mod_user = true;
    } else if (CONF_ARG_EQ("read-policy", 'p')) {
      read_policy = true;
    } else if (CONF_ARG_EQ("list-buckets", 'l')) {
      list_buckets = true;
    } else if (CONF_ARG_EQ("uid", 'i')) {
      CONF_SAFE_SET_ARG_VAL(&user_id, OPT_STR);
    } else if (CONF_ARG_EQ("secret", 's')) {
      CONF_SAFE_SET_ARG_VAL(&secret_key, OPT_STR);
    } else if (CONF_ARG_EQ("email", 'e')) {
      CONF_SAFE_SET_ARG_VAL(&user_email, OPT_STR);
    } else if (CONF_ARG_EQ("display-name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&display_name, OPT_STR);
    } else if (CONF_ARG_EQ("bucket", 'b')) {
      CONF_SAFE_SET_ARG_VAL(&bucket, OPT_STR);
    } else if (CONF_ARG_EQ("object", 'o')) {
      CONF_SAFE_SET_ARG_VAL(&object, OPT_STR);
    } else if (CONF_ARG_EQ("auth_uid", 'a')) {
      CONF_SAFE_SET_ARG_VAL(&auid, OPT_LONGLONG);
    } else if (CONF_ARG_EQ("delete_user", 'd')) {
      delete_user = true;
    } else {
      cerr << "unrecognized arg " << args[i] << std::endl;
      ARGS_USAGE();
    }
  }

  store = RGWAccess::init_storage_provider("rados", argc, argv);
  if (!store) {
    cerr << "couldn't init storage provider" << std::endl;
    return 5; //EIO
  }

  if (mod_user) {
    actions++;

    if (!user_id) {
      cerr << "user_id was not specified, aborting" << std::endl;
      return 0;
    }

    string user_id_str = user_id;

    if (rgw_get_user_info(user_id_str, info) < 0) {
      cerr << "error reading user info, aborting" << std::endl;
      exit(1);
    }
  }

  if (gen_user) {
    actions++;
    char secret_key_buf[SECRET_KEY_LEN + 1];
    char public_id_buf[PUBLIC_ID_LEN + 1];
    int ret;

    if (!display_name) {
      cerr << "display name was not specified, aborting" << std::endl;
      return 0;
    }

    if (!secret_key) {
      ret = gen_rand_base64(secret_key_buf, sizeof(secret_key_buf));
      if (ret < 0) {
        cerr << "aborting" << std::endl;
        exit(1);
      }
      secret_key = secret_key_buf;
    }
    if (!user_id) {
      RGWUserInfo duplicate_check;
      string duplicate_check_id;
      do {
	ret = gen_rand_alphanumeric(public_id_buf, sizeof(public_id_buf));
	if (ret < 0) {
	  cerr << "aborting" << std::endl;
	  exit(1);
	}
	user_id = public_id_buf;
	duplicate_check_id = user_id;
      } while (!rgw_get_user_info(duplicate_check_id, duplicate_check));
    }
  }

  if (gen_user || mod_user) {
    if (user_id)
      info.user_id = user_id;
    if (secret_key)
      info.secret_key = secret_key;
    if (display_name)
      info.display_name = display_name;
    if (user_email)
      info.user_email = user_email;
    if (auid)
      info.auid = auid;

    int err;
    if ((err = rgw_store_user_info(info)) < 0) {
      cerr << "error storing user info" << strerror(-err) << std::endl;
    } else {
      cout << "User ID: " << info.user_id << std::endl;
      cout << "Secret Key: " << info.secret_key << std::endl;
      cout << "Display Name: " << info.display_name << std::endl;
    }
  }

  if (read_policy) {
    actions++;
    bufferlist bl;
    if (!bucket)
      bucket = "";
    if (!object)
      object = "";
    string bucket_str(bucket);
    string object_str(object);
    int ret = store->get_attr(bucket_str, object_str,
                       RGW_ATTR_ACL, bl);

    RGWAccessControlPolicy policy;
    if (ret >= 0) {
      bufferlist::iterator iter = bl.begin();
      policy.decode(iter);
      policy.to_xml(cout);
      cout << std::endl;
    }
  }

  if (list_buckets) {
    actions++;
    string id;
    RGWAccessHandle handle;

    if (user_id) {
      RGWUserBuckets buckets;
      if (rgw_get_user_buckets(user_id, buckets) < 0) {
        cout << "could not get buckets for uid " << user_id << std::endl;
      } else {
        cout << "listing buckets for uid " << user_id << std::endl;
        map<string, RGWObjEnt>& m = buckets.get_buckets();
        map<string, RGWObjEnt>::iterator iter;

        for (iter = m.begin(); iter != m.end(); ++iter) {
          RGWObjEnt obj = iter->second;
          cout << obj.name << std::endl;
        }
      }
    } else {
      if (store->list_buckets_init(id, &handle) < 0) {
        cout << "list-buckets: no entries found" << std::endl;
      } else {
        RGWObjEnt obj;
        cout << "listing all buckets" << std::endl;
        while (store->list_buckets_next(id, obj, &handle) >= 0) {
          cout << obj.name << std::endl;
        }
      }
    }
  }

  if (delete_user) {
    ++actions;
    rgw_delete_user(info);
  }

  if (!actions)
    ARGS_USAGE();

  return 0;
}
<commit_msg>rgw_admin: call common_set_defaults as non-daemon<commit_after>#include <errno.h>

#include <iostream>
#include <string>

using namespace std;

#include "config.h"

#include <cryptopp/osrng.h>
#include "common/common_init.h"

#include "common/armor.h"
#include "rgw_user.h"
#include "rgw_access.h"
#include "rgw_acl.h"

#define SECRET_KEY_LEN 40
#define PUBLIC_ID_LEN 20

void usage()
{
  cerr << "usage: radosgw_admin <--user-gen | --user-modify | --read-policy | --list-buckets > [options...]" << std::endl;
  cerr << "options:" << std::endl;
  cerr << "   --uid=<id> (S3 uid)" << std::endl;
  cerr << "   --auth_uid=<auid> (librados uid)" << std::endl;
  cerr << "   --secret=<key>" << std::endl;
  cerr << "   --email=<email>" << std::endl;
  cerr << "   --display-name=<name>" << std::endl;
  cerr << "   --bucket=<bucket>" << std::endl;
  cerr << "   --object=<object>" << std::endl;
  generic_client_usage();
  exit(1);
}

int gen_rand_base64(char *dest, int size) /* size should be the required string size + 1 */
{
  unsigned char buf[size];
  char tmp_dest[size + 4]; /* so that there's space for the extra '=' characters, and some */

  CryptoPP::AutoSeededRandomPool rng;
  rng.GenerateBlock(buf, sizeof(buf));

  int ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)],
		   (const char *)buf, ((const char *)buf) + ((size - 1) * 3 + 4 - 1) / 4);
  if (ret < 0) {
    cerr << "ceph_armor failed" << std::endl;
    return -1;
  }
  tmp_dest[ret] = '\0';
  memcpy(dest, tmp_dest, size);
  dest[size] = '\0';

  return 0;
}

static const char alphanum_table[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int gen_rand_alphanumeric(char *dest, int size) /* size should be the required string size + 1 */
{
  CryptoPP::AutoSeededRandomPool rng;
  rng.GenerateBlock((unsigned char *)dest, size);

  int i;
  for (i=0; i<size - 1; i++) {
    int pos = (unsigned)dest[i];
    dest[i] = alphanum_table[pos % (sizeof(alphanum_table) - 1)];
  }
  dest[i] = '\0';

  return 0;
}

int main(int argc, char **argv)
{
  DEFINE_CONF_VARS(usage);
  vector<const char*> args;
  argv_to_vec(argc, (const char **)argv, args);
  env_to_vec(args);

  common_set_defaults(false);
  common_init(args, "rgw", true);

  const char *user_id = 0;
  const char *secret_key = 0;
  const char *user_email = 0;
  const char *display_name = 0;
  const char *bucket = 0;
  const char *object = 0;
  bool gen_user = false;
  bool mod_user = false;
  bool read_policy = false;
  bool list_buckets = false;
  bool delete_user = false;
  int actions = 0 ;
  uint64_t auid = 0;
  RGWUserInfo info;
  RGWAccess *store;

  if (g_conf.clock_tare) g_clock.tare();

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("user-gen", 'g')) {
      gen_user = true;
    } else if (CONF_ARG_EQ("user-modify", 'm')) {
      mod_user = true;
    } else if (CONF_ARG_EQ("read-policy", 'p')) {
      read_policy = true;
    } else if (CONF_ARG_EQ("list-buckets", 'l')) {
      list_buckets = true;
    } else if (CONF_ARG_EQ("uid", 'i')) {
      CONF_SAFE_SET_ARG_VAL(&user_id, OPT_STR);
    } else if (CONF_ARG_EQ("secret", 's')) {
      CONF_SAFE_SET_ARG_VAL(&secret_key, OPT_STR);
    } else if (CONF_ARG_EQ("email", 'e')) {
      CONF_SAFE_SET_ARG_VAL(&user_email, OPT_STR);
    } else if (CONF_ARG_EQ("display-name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&display_name, OPT_STR);
    } else if (CONF_ARG_EQ("bucket", 'b')) {
      CONF_SAFE_SET_ARG_VAL(&bucket, OPT_STR);
    } else if (CONF_ARG_EQ("object", 'o')) {
      CONF_SAFE_SET_ARG_VAL(&object, OPT_STR);
    } else if (CONF_ARG_EQ("auth_uid", 'a')) {
      CONF_SAFE_SET_ARG_VAL(&auid, OPT_LONGLONG);
    } else if (CONF_ARG_EQ("delete_user", 'd')) {
      delete_user = true;
    } else {
      cerr << "unrecognized arg " << args[i] << std::endl;
      ARGS_USAGE();
    }
  }

  store = RGWAccess::init_storage_provider("rados", argc, argv);
  if (!store) {
    cerr << "couldn't init storage provider" << std::endl;
    return 5; //EIO
  }

  if (mod_user) {
    actions++;

    if (!user_id) {
      cerr << "user_id was not specified, aborting" << std::endl;
      return 0;
    }

    string user_id_str = user_id;

    if (rgw_get_user_info(user_id_str, info) < 0) {
      cerr << "error reading user info, aborting" << std::endl;
      exit(1);
    }
  }

  if (gen_user) {
    actions++;
    char secret_key_buf[SECRET_KEY_LEN + 1];
    char public_id_buf[PUBLIC_ID_LEN + 1];
    int ret;

    if (!display_name) {
      cerr << "display name was not specified, aborting" << std::endl;
      return 0;
    }

    if (!secret_key) {
      ret = gen_rand_base64(secret_key_buf, sizeof(secret_key_buf));
      if (ret < 0) {
        cerr << "aborting" << std::endl;
        exit(1);
      }
      secret_key = secret_key_buf;
    }
    if (!user_id) {
      RGWUserInfo duplicate_check;
      string duplicate_check_id;
      do {
	ret = gen_rand_alphanumeric(public_id_buf, sizeof(public_id_buf));
	if (ret < 0) {
	  cerr << "aborting" << std::endl;
	  exit(1);
	}
	user_id = public_id_buf;
	duplicate_check_id = user_id;
      } while (!rgw_get_user_info(duplicate_check_id, duplicate_check));
    }
  }

  if (gen_user || mod_user) {
    if (user_id)
      info.user_id = user_id;
    if (secret_key)
      info.secret_key = secret_key;
    if (display_name)
      info.display_name = display_name;
    if (user_email)
      info.user_email = user_email;
    if (auid)
      info.auid = auid;

    int err;
    if ((err = rgw_store_user_info(info)) < 0) {
      cerr << "error storing user info" << strerror(-err) << std::endl;
    } else {
      cout << "User ID: " << info.user_id << std::endl;
      cout << "Secret Key: " << info.secret_key << std::endl;
      cout << "Display Name: " << info.display_name << std::endl;
    }
  }

  if (read_policy) {
    actions++;
    bufferlist bl;
    if (!bucket)
      bucket = "";
    if (!object)
      object = "";
    string bucket_str(bucket);
    string object_str(object);
    int ret = store->get_attr(bucket_str, object_str,
                       RGW_ATTR_ACL, bl);

    RGWAccessControlPolicy policy;
    if (ret >= 0) {
      bufferlist::iterator iter = bl.begin();
      policy.decode(iter);
      policy.to_xml(cout);
      cout << std::endl;
    }
  }

  if (list_buckets) {
    actions++;
    string id;
    RGWAccessHandle handle;

    if (user_id) {
      RGWUserBuckets buckets;
      if (rgw_get_user_buckets(user_id, buckets) < 0) {
        cout << "could not get buckets for uid " << user_id << std::endl;
      } else {
        cout << "listing buckets for uid " << user_id << std::endl;
        map<string, RGWObjEnt>& m = buckets.get_buckets();
        map<string, RGWObjEnt>::iterator iter;

        for (iter = m.begin(); iter != m.end(); ++iter) {
          RGWObjEnt obj = iter->second;
          cout << obj.name << std::endl;
        }
      }
    } else {
      if (store->list_buckets_init(id, &handle) < 0) {
        cout << "list-buckets: no entries found" << std::endl;
      } else {
        RGWObjEnt obj;
        cout << "listing all buckets" << std::endl;
        while (store->list_buckets_next(id, obj, &handle) >= 0) {
          cout << obj.name << std::endl;
        }
      }
    }
  }

  if (delete_user) {
    ++actions;
    rgw_delete_user(info);
  }

  if (!actions)
    ARGS_USAGE();

  return 0;
}
<|endoftext|>


<commit_before>//#define _GRIBCXX_DEBUG
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// 基本テンプレート
#pragma region MACRO
#define P(x) cout << (x) << endl
#define p(x) cout << (x)
#define PED cout << "\n"
#define rep(i,n) for(int i=0; i<(int)n; ++i)
#define REP(i,x,n) for(int i=x; i<(int)n; ++i)
#define repi(i,n) for(int i=0; i<=(int)n; ++i)
#define REPI(i,x,n) for(int i=x; i<=(int)n; ++i)
#define ILP while(true)
#define FOR(i,c) for(__typeof((c).begin())!=(c).begin(); i!=(c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define mp make_pair
#pragma endregion

#pragma region TYPE_DEF
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<int, string> pis;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<long> vl;
typedef vector<long long> vll;
typedef vector<string> vs;
#pragma endregion

// Effective std
#pragma region ESTD
template<typename C, typename T>
constexpr int count(C& c, T t) { return count(ALL(c), t); }
template<typename C, typename F>
constexpr int count_if(C& c, F f) { return count_if(ALL(c), f); }
template<typename C, typename T, typename U>
constexpr void replace(C& c, T t, U u) { replace(ALL(c), t, u); }
template<typename C, typename F, typename U>
constexpr void replace_if(C& c, F f, U u) { (ALL(c), f, u); }
template<typename C>
constexpr void sort(C& c) { sort(ALL(c)); }
template<typename C, typename Pred>
constexpr void sort(C& c, Pred p) { sort(ALL(c), p); }
template<typename C>
constexpr void reverse(C& c) { reverse(ALL(c)); }
#pragma endregion

// 素数
#pragma region PRIME
bool is_prime(unsigned n) {
  switch(n) {
    case 0:
    case 1: return false;
    case 2: return true;
  }
  if (n%2==0) return false;
  for (unsigned i=3; i*i<=n; i+=2)
    if (n%i==0) return false;
  return true;
}
#pragma endregion

// 大文字/小文字変換
#pragma region TRANSFORM
void mutal_tr(string &s) {
  for(int i=s.size(); i--;) {
    if(islower(s[i])) s[i] = toupper(s[i]);
    else if (isupper(s[i])) s[i] = tolower(s[i]);
  }
}
void to_upper(string &s) { for(int i=s.size(); i--;) s[i] = toupper(s[i]); }
void to_lower(string &s) { for(int i=s.size(); i--;) s[i] = tolower(s[i]); }
#pragma endregion

// 集合
#pragma region SET
template<class T>
set<T> intersection(const set<T>& sa, const set<T>& sb) {
  set<T> ret;
  for(T a : sa) if(sb.find(a) != sb.end()) ret.insert(a);
  return ret;
}
#pragma endregion

// Union Find
#pragma region UF
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool union_set(int x, int y) {
    x = root(x); y = root(y);
    if(x!=y) {
      if(data[y] < data[x]) swap(x, y);
      data[x] += data[y]; data[y] = x;
    }
    return x != y;
  }
  bool find_set(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
#pragma endregion

// 定数
#pragma region CONST_VAL
#define PI (2*acos(0.0))
#define EPS (1e-9)
#define MOD (int)(1e9+7)
#pragma endregion

int main() {
  return 0;
}
<commit_msg>template.cpp<commit_after>//#define _GRIBCXX_DEBUG
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// 基本テンプレート
#pragma region MACRO
#define P(x) cout << (x) << endl
#define p(x) cout << (x)
#define PED cout << "\n"
#define rep(i,n) for(int i=0; i<(int)n; ++i)
#define REP(i,x,n) for(int i=x; i<(int)n; ++i)
#define repi(i,n) for(int i=0; i<=(int)n; ++i)
#define REPI(i,x,n) for(int i=x; i<=(int)n; ++i)
#define ILP while(true)
#define FOR(i,c) for(__typeof((c).begin())!=(c).begin(); i!=(c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define mp make_pair
#pragma endregion

#pragma region TYPE_DEF
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<int, string> pis;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<long> vl;
typedef vector<long long> vll;
typedef vector<string> vs;
#pragma endregion

// Effective std
#pragma region ESTD
template<typename C, typename T>
constexpr int count(C& c, T t) { return count(ALL(c), t); }
template<typename C, typename F>
constexpr int count_if(C& c, F f) { return count_if(ALL(c), f); }
template<typename C, typename T, typename U>
constexpr void replace(C& c, T t, U u) { replace(ALL(c), t, u); }
template<typename C, typename F, typename U>
constexpr void replace_if(C& c, F f, U u) { (ALL(c), f, u); }
template<typename C>
constexpr void sort(C& c) { sort(ALL(c)); }
template<typename C, typename Pred>
constexpr void sort(C& c, Pred p) { sort(ALL(c), p); }
template<typename C>
constexpr void reverse(C& c) { reverse(ALL(c)); }
#pragma endregion

// 素数
#pragma region PRIME
bool is_prime(unsigned n) {
  switch(n) {
    case 0:
    case 1: return false;
    case 2: return true;
  }
  if (n%2==0) return false;
  for (unsigned i=3; i*i<=n; i+=2)
    if (n%i==0) return false;
  return true;
}
#pragma endregion

// 大文字/小文字変換
#pragma region TRANSFORM
void mutal_tr(string &s) {
  for(int i=s.size(); i--;) {
    if(islower(s[i])) s[i] = toupper(s[i]);
    else if (isupper(s[i])) s[i] = tolower(s[i]);
  }
}
void to_upper(string &s) { for(int i=s.size(); i--;) s[i] = toupper(s[i]); }
void to_lower(string &s) { for(int i=s.size(); i--;) s[i] = tolower(s[i]); }
#pragma endregion

// 集合
#pragma region SET
template<class T>
set<T> intersection(const set<T>& sa, const set<T>& sb) {
  set<T> ret;
  for(T a : sa) if(sb.find(a) != sb.end()) ret.insert(a);
  return ret;
}
#pragma endregion

// Union Find
#pragma region UF
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool union_set(int x, int y) {
    x = root(x); y = root(y);
    if(x!=y) {
      if(data[y] < data[x]) swap(x, y);
      data[x] += data[y]; data[y] = x;
    }
    return x != y;
  }
  bool find_set(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
#pragma endregion

// 定数
#pragma region CONST_VAL
#define PI (2*acos(0.0))
#define EPS (1e-9)
#define MOD (int)(1e9+7)
#pragma endregion

int main()
{
    return 0;
}
<|endoftext|>


<commit_before>
#define CATCH_CONFIG_RUNNER
#include <catch_ros/catch.hpp>

#include "ros_junit_reporter.h"

#include <boost/filesystem.hpp>

#include <ros/init.h>
#include <ros/node_handle.h>
#include <ros/this_node.h>

namespace fs = boost::filesystem;

int main( int argc, char** argv )
{
	ros::init(argc, argv, "catch_test");
	ros::NodeHandle nh("~");

	Catch::Session session;

	// writing to session.configData() here sets defaults
	// this is the preferred way to set them

	// Parse gtest-style output options
	std::string test_output;
	for(int i = 1; i < argc; ++i)
	{
		if(strncmp(argv[i], "--gtest_output=xml:", 19) == 0)
		{
			test_output = argv[i] + 19;

			// Remove this option from argc, argv
			int j;
			for(j = i; j < argc-1; ++j)
				argv[j] = argv[j+1];
			argc -= 1;
		}
	}

	if(!test_output.empty())
	{
		session.configData().reporterName = "ros_junit";
		session.configData().outputFilename = test_output;
	}

	int returnCode = session.applyCommandLine( argc, argv );
	if( returnCode != 0 ) // Indicates a command line error
		return returnCode;

	std::string nodeName = ros::this_node::getName();
	std::replace(nodeName.begin(), nodeName.end(), '/', '_');
	session.configData().name = session.configData().processName + nodeName;

	// The catkin scripts calling tests do not create the output directory for
	// us :-(
	if(!session.configData().outputFilename.empty())
	{
		fs::path outputPath = session.configData().outputFilename;

		fs::path outputDir = outputPath.parent_path();
		if(!fs::exists(outputDir))
		{
			fs::create_directories(outputDir);
		}
	}

	return session.run();
}
<commit_msg>rostest_main: handle weird rostest behavior on retries<commit_after>
#define CATCH_CONFIG_RUNNER
#include <catch_ros/catch.hpp>

#include "ros_junit_reporter.h"

#include <boost/filesystem.hpp>

#include <ros/init.h>
#include <ros/node_handle.h>
#include <ros/this_node.h>

namespace fs = boost::filesystem;

int main( int argc, char** argv )
{
	ros::init(argc, argv, "catch_test");
	ros::NodeHandle nh("~");

	Catch::Session session;

	// writing to session.configData() here sets defaults
	// this is the preferred way to set them

	// Parse gtest-style output options
	std::string test_output;
	for(int i = 1; i < argc; ++i)
	{
		if(strncmp(argv[i], "--gtest_output=xml:", 19) == 0)
		{
			test_output = argv[i] + 19;

			// Remove this option from argc, argv
			int j;
			for(j = i; j < argc-1; ++j)
				argv[j] = argv[j+1];
			argc -= 1;

			// Re-check the next argument, since rostest will *add* a
			// --gtest_output argument on each retry.
			// https://github.com/ros/ros_comm/blob/d9059f49d14b7baf4a58c7759deab1f019681f5b/tools/rostest/src/rostest/runner.py#L137
			i -= 1;
		}
	}

	if(!test_output.empty())
	{
		session.configData().reporterName = "ros_junit";
		session.configData().outputFilename = test_output;
	}

	int returnCode = session.applyCommandLine( argc, argv );
	if( returnCode != 0 ) // Indicates a command line error
		return returnCode;

	std::string nodeName = ros::this_node::getName();
	std::replace(nodeName.begin(), nodeName.end(), '/', '_');
	session.configData().name = session.configData().processName + nodeName;

	// The catkin scripts calling tests do not create the output directory for
	// us :-(
	if(!session.configData().outputFilename.empty())
	{
		fs::path outputPath = session.configData().outputFilename;

		fs::path outputDir = outputPath.parent_path();
		if(!fs::exists(outputDir))
		{
			fs::create_directories(outputDir);
		}
	}

	return session.run();
}
<|endoftext|>


<commit_before>#include "app/app.h"
#include <cmath>
#include <boost/python.hpp>
#include <string>
#include "render/material.h"
#include "render/model.h"
#include "render/gpuprogram.h"
#include "base/timer.h"
#include "base/py.h"
#include "math/matrix-inl.h"
#include "engine/resourceref.h"
#include "render/renderstate.h"
#include "render/texture.h"
#include "game/components/transform.h"
#include "game/components/camera.h"
#include "game/components/renderable.h"
#include "base/log.h"

using namespace base;
using namespace boost::python;

extern "C" NEGINE_EXPORT PyObject* PyInit_negine_runtime(void);

static const char vertexShader[] =
    "#version 150\n"
    "\n"
    "in vec3 position;\n"
    "in vec3 normal;\n"
    "\n"
    "uniform mat4 mvp;\n"
    "\n"
    "out vec3 n;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    n = 0.5*normalize(normal) + 0.5;\n"
    "    vec4 pos = vec4(position, 1);\n"
    "    gl_Position = mvp * pos;\n"
    "}\n"
    "";
static const char pixelShader[] =
    "#version 150\n"
    "\n"
    "in vec3 n;\n"
    "out vec4 fragColor;\n"
    "\n"
    "void main() {\n"
    "    fragColor = vec4(n, 1);\n"
    "}\n"
    "";

static const char vertexShader1[] =
    "#version 150\n"
    "\n"
    "in vec3 position;\n"
    "in vec2 uv;\n"
    "\n"
    "out vec2 tex;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    tex = uv;\n"
    "    vec4 pos = vec4(position, 1);\n"
    "    gl_Position = pos;\n"
    "}\n"
    "";
static const char pixelShader1[] =
    "#version 150\n"
    "\n"
    "uniform sampler2D atexture;\n"
    "in vec2 tex;\n"
    "out vec4 fragColor;\n"
    "\n"
    "void main() {\n"
    "    fragColor = texture(atexture, tex);\n"
    "}\n"
    "";

static Application* intstance_ = nullptr;

class GameCamera {
public:
    game::Transform transform;
    game::Camera camera;
    game::Entity object;

    GameCamera() {
        object.add(&transform);
        object.add(&camera);
    }
};

class GameObject {
public:
    game::Renderable r;
    game::Entity object;
    GameObject() {
        object.add(&r);
    }
};

class Demo : public Application
{
    base::opengl::Renderer ren;
    base::opengl::GpuProgram prog;
    base::opengl::GpuProgram prog2;

    GameObject obj;
    GameCamera cam;
    game::Entity root;
    u32 keypressed_;
    base::Timer timer_;
    opengl::Model* umesh;

    opengl::Framebuffer fbo;
    opengl::Material material;
public:
    Demo(const std::string& filename) : ren(GL), prog(GL), prog2(GL), fbo(GL) {
        intstance_ = this;
        PyImport_AppendInittab("negine_core", PyInit_negine_core);
        PyImport_AppendInittab("negine_runtime", PyInit_negine_runtime);
        Py_Initialize();
        object m = import("__main__");
        global = object(m.attr("__dict__"));

        exec_file(filename.c_str(), global, global);

        keypressed_ = 0;

        ren.init();

        prog.setAttribute("position", base::opengl::VertexAttrs::tagPosition);
        prog.setAttribute("normal", base::opengl::VertexAttrs::tagNormal);

        prog.setShaderSource(base::opengl::ShaderTypes::VERTEX, vertexShader);
        prog.setShaderSource(base::opengl::ShaderTypes::PIXEL, pixelShader);
        prog.complete();
        ResourceRef("prog1").setResource(&prog);

        prog2.setAttribute("position", opengl::VertexAttrs::tagPosition);
        prog2.setAttribute("uv", opengl::VertexAttrs::tagTexture);
        prog2.setShaderSource(base::opengl::ShaderTypes::VERTEX, vertexShader1);
        prog2.setShaderSource(base::opengl::ShaderTypes::PIXEL, pixelShader1);
        prog2.complete();
        ResourceRef("prog2").setResource(&prog2);

        cam.transform.setPosition( base::math::vec3f( 0.f, 0.f, -5.f ) );
        cam.transform.setPitch( 50 * base::math::deg_to_rad );
        cam.transform.setHead( 180 * base::math::deg_to_rad );
        cam.camera.setPerspective(width_ / ( f32 )height_, 45.0f, 1, 1000);

        ResourceRef checkers("checkers");
        checkers.loadDefault<opengl::Texture>("checker.png");
        ASSERT(checkers.resourceAs<opengl::Texture>() != nullptr);

        //fbo.addTarget(opengl::InternalTypes::RGBA8);
        fbo.addTargetTexture(checkers.resourceAs<opengl::Texture>());
        fbo.addTarget(opengl::InternalTypes::D32F);
        fbo.resizeWindow(math::vec2i(width_, height_));
        //fbo.complete();
        ResourceRef("fbo").setResource(&fbo);
        ResourceRef("default_fbo").setResource(nullptr);

        GL_ASSERT(GL);

        ResourceRef model("themodel");
        model.loadDefault<opengl::Model>("trunk.obj");
        umesh = model.resourceAs<opengl::Model>();

        obj.r.model_ = model;
        root.addChild(&obj.object);
        root.addChild(&cam.object);

        material.modeMap["normal"] = ResourceRef("prog1");
        ResourceRef maa("material");
        maa.setResource(&material);
        const_cast<opengl::Mesh&>(umesh->surfaceAt(0).mesh).material_ = maa;

        ren.root = &root;
        ren.camera = &cam.camera;

        opengl::RenderPass rp;
        rp.target = ResourceRef("fbo");
        rp.mode = "normal";
        rp.generator = "scene";
        rp.viewport = math::vec4f(0, 0, 640, 480);
        rp.clear = true;
        rp.depthTest = true;
        rp.depthWrite = true;
        rp.cullBackFace = false;
        rp.blend = false;
        rp.clearColor = math::vec4f(1.0f, 0.0f, 0.0f, 1.0f);
        ren.passesList.push_back(rp);

        opengl::RenderPass rp2;
        rp2.target = ResourceRef("default_fbo");
        rp2.mode = "prog2";
        rp2.generator = "fullscreen";
        rp2.viewport = math::vec4f(0, 0, 640, 480);
        rp2.clear = true;
        rp2.depthTest = false;
        rp2.depthWrite = false;
        rp2.cullBackFace = false;
        rp2.blend = false;
        rp2.clearColor = math::vec4f(1.0f, 0.0f, 0.0f, 1.0f);
        ren.passesList.push_back(rp2);
    }
    virtual ~Demo() {
    }
protected:
    void OnFrame() {
        UpdateWorld();
        ren.rendering();
        GL_ASSERT(GL);
        SDLApp::OnFrame();
    }

    void OnKeyboardDown( u8 key ) {
        if ( key == 'w' ) {
            keypressed_ |= 1;
        } else if ( key == 's' ) {
            keypressed_ |= 2;
        } else if ( key == 'a' ) {
            keypressed_ |= 4;
        } else if ( key == 'd' ) {
            keypressed_ |= 8;
        } else if ( key == 'j' ) {
            keypressed_ |= 16;
        } else if ( key == 'k' ) {
            keypressed_ |= 32;
        } else if ( key == 'h' ) {
            keypressed_ |= 64;
        } else if ( key == 'l' ) {
            keypressed_ |= 128;
        }
    }
    void OnKeyboardUp( u8 key ) {
        if ( key == 'w' ) {
            keypressed_ ^= 1;
        } else if ( key == 's' ) {
            keypressed_ ^= 2;
        } else if ( key == 'a' ) {
            keypressed_ ^= 4;
        } else if ( key == 'd' ) {
            keypressed_ ^= 8;
        } else if ( key == 'j' ) {
            keypressed_ ^= 16;
        } else if ( key == 'k' ) {
            keypressed_ ^= 32;
        } else if ( key == 'h' ) {
            keypressed_ ^= 64;
        } else if ( key == 'l' ) {
            keypressed_ ^= 128;
        }
    }

    void OnMotion( i32 x, i32 y, i32 dx, i32 dy ) {
        cam.transform.turnHead( math::deg_to_rad * dx);

        if (fabs (cam.transform.pitch() + math::deg_to_rad * dy ) < base::math::pi/2.0f ) {
            cam.transform.turnPitch( math::deg_to_rad * dy );
        } else if (dy != 0 ) {
            cam.transform.setPitch( base::math::pi/2.0f * dy / fabs( (f32)dy ) );
        }
    }

    void UpdateWorld() {
        const f32 speed = 0.1f;

        if ( keypressed_ & 1 ) {
            cam.transform.moveForward( speed );
        }

        if ( keypressed_ & 2 ) {
            cam.transform.moveBackward( speed );
        }

        if ( keypressed_ & 4 ) {
            cam.transform.moveLeft( speed );
        }

        if ( keypressed_ & 8 ) {
            cam.transform.moveRight( speed );
        }

        if ( keypressed_ & 16 ) {
            if ( fabs( cam.transform.pitch() + math::deg_to_rad ) < math::pi / 2.0f )
                cam.transform.turnPitch( math::deg_to_rad );
        }

        if ( keypressed_ & 32 ) {
            if ( fabs( cam.transform.pitch() - math::deg_to_rad ) < math::pi / 2.0f )
                cam.transform.turnPitch( -math::deg_to_rad );
        }

        if ( keypressed_ & 64 ) {
            cam.transform.turnHead( math::deg_to_rad );
        }

        if ( keypressed_ & 128 ) {
            cam.transform.turnHead( -math::deg_to_rad );
        }

        game::Transform::updateTree(&cam.object);
        game::Camera::updateTree(&cam.object);
    }

    object global;
};

int main(int argc, char* argv[])
{
    Demo app(argv[1]);
    app.Run();
    return 0;
}

static Application& globalApp() {
    ASSERT(intstance_ != nullptr);
    return *intstance_;
}

BOOST_PYTHON_MODULE(negine_runtime)
{
    def("globalApp", globalApp, return_value_policy<reference_existing_object>());
    class_<Demo, boost::noncopyable>("App", no_init)
        .add_property( "context", make_function( static_cast< opengl::DeviceContext& (Application::*)() >( &Application::context ), return_value_policy<reference_existing_object>() ) );
}<commit_msg>basic error handling for boost-python<commit_after>#include "app/app.h"
#include <cmath>
#include <boost/python.hpp>
#include <string>
#include "render/material.h"
#include "render/model.h"
#include "render/gpuprogram.h"
#include "base/timer.h"
#include "base/py.h"
#include "math/matrix-inl.h"
#include "engine/resourceref.h"
#include "render/renderstate.h"
#include "render/texture.h"
#include "game/components/transform.h"
#include "game/components/camera.h"
#include "game/components/renderable.h"
#include "base/log.h"

using namespace base;
using namespace boost::python;

extern "C" NEGINE_EXPORT PyObject* PyInit_negine_runtime(void);

static const char vertexShader[] =
    "#version 150\n"
    "\n"
    "in vec3 position;\n"
    "in vec3 normal;\n"
    "\n"
    "uniform mat4 mvp;\n"
    "\n"
    "out vec3 n;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    n = 0.5*normalize(normal) + 0.5;\n"
    "    vec4 pos = vec4(position, 1);\n"
    "    gl_Position = mvp * pos;\n"
    "}\n"
    "";
static const char pixelShader[] =
    "#version 150\n"
    "\n"
    "in vec3 n;\n"
    "out vec4 fragColor;\n"
    "\n"
    "void main() {\n"
    "    fragColor = vec4(n, 1);\n"
    "}\n"
    "";

static const char vertexShader1[] =
    "#version 150\n"
    "\n"
    "in vec3 position;\n"
    "in vec2 uv;\n"
    "\n"
    "out vec2 tex;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    tex = uv;\n"
    "    vec4 pos = vec4(position, 1);\n"
    "    gl_Position = pos;\n"
    "}\n"
    "";
static const char pixelShader1[] =
    "#version 150\n"
    "\n"
    "uniform sampler2D atexture;\n"
    "in vec2 tex;\n"
    "out vec4 fragColor;\n"
    "\n"
    "void main() {\n"
    "    fragColor = texture(atexture, tex);\n"
    "}\n"
    "";

static Application* intstance_ = nullptr;

class GameCamera {
public:
    game::Transform transform;
    game::Camera camera;
    game::Entity object;

    GameCamera() {
        object.add(&transform);
        object.add(&camera);
    }
};

class GameObject {
public:
    game::Renderable r;
    game::Entity object;
    GameObject() {
        object.add(&r);
    }
};

class Demo : public Application
{
    base::opengl::Renderer ren;
    base::opengl::GpuProgram prog;
    base::opengl::GpuProgram prog2;

    GameObject obj;
    GameCamera cam;
    game::Entity root;
    u32 keypressed_;
    base::Timer timer_;
    opengl::Model* umesh;

    opengl::Framebuffer fbo;
    opengl::Material material;
public:
    Demo(const std::string& filename) : ren(GL), prog(GL), prog2(GL), fbo(GL) {
        intstance_ = this;
        PyImport_AppendInittab("negine_core", PyInit_negine_core);
        PyImport_AppendInittab("negine_runtime", PyInit_negine_runtime);
        Py_Initialize();
        object m = import("__main__");
        global = object(m.attr("__dict__"));

        exec_file(filename.c_str(), global, global);

        keypressed_ = 0;

        ren.init();

        prog.setAttribute("position", base::opengl::VertexAttrs::tagPosition);
        prog.setAttribute("normal", base::opengl::VertexAttrs::tagNormal);

        prog.setShaderSource(base::opengl::ShaderTypes::VERTEX, vertexShader);
        prog.setShaderSource(base::opengl::ShaderTypes::PIXEL, pixelShader);
        prog.complete();
        ResourceRef("prog1").setResource(&prog);

        prog2.setAttribute("position", opengl::VertexAttrs::tagPosition);
        prog2.setAttribute("uv", opengl::VertexAttrs::tagTexture);
        prog2.setShaderSource(base::opengl::ShaderTypes::VERTEX, vertexShader1);
        prog2.setShaderSource(base::opengl::ShaderTypes::PIXEL, pixelShader1);
        prog2.complete();
        ResourceRef("prog2").setResource(&prog2);

        cam.transform.setPosition( base::math::vec3f( 0.f, 0.f, -5.f ) );
        cam.transform.setPitch( 50 * base::math::deg_to_rad );
        cam.transform.setHead( 180 * base::math::deg_to_rad );
        cam.camera.setPerspective(width_ / ( f32 )height_, 45.0f, 1, 1000);

        ResourceRef checkers("checkers");
        checkers.loadDefault<opengl::Texture>("checker.png");
        ASSERT(checkers.resourceAs<opengl::Texture>() != nullptr);

        //fbo.addTarget(opengl::InternalTypes::RGBA8);
        fbo.addTargetTexture(checkers.resourceAs<opengl::Texture>());
        fbo.addTarget(opengl::InternalTypes::D32F);
        fbo.resizeWindow(math::vec2i(width_, height_));
        //fbo.complete();
        ResourceRef("fbo").setResource(&fbo);
        ResourceRef("default_fbo").setResource(nullptr);

        GL_ASSERT(GL);

        ResourceRef model("themodel");
        model.loadDefault<opengl::Model>("trunk.obj");
        umesh = model.resourceAs<opengl::Model>();

        obj.r.model_ = model;
        root.addChild(&obj.object);
        root.addChild(&cam.object);

        material.modeMap["normal"] = ResourceRef("prog1");
        ResourceRef maa("material");
        maa.setResource(&material);
        const_cast<opengl::Mesh&>(umesh->surfaceAt(0).mesh).material_ = maa;

        ren.root = &root;
        ren.camera = &cam.camera;

        opengl::RenderPass rp;
        rp.target = ResourceRef("fbo");
        rp.mode = "normal";
        rp.generator = "scene";
        rp.viewport = math::vec4f(0, 0, 640, 480);
        rp.clear = true;
        rp.depthTest = true;
        rp.depthWrite = true;
        rp.cullBackFace = false;
        rp.blend = false;
        rp.clearColor = math::vec4f(1.0f, 0.0f, 0.0f, 1.0f);
        ren.passesList.push_back(rp);

        opengl::RenderPass rp2;
        rp2.target = ResourceRef("default_fbo");
        rp2.mode = "prog2";
        rp2.generator = "fullscreen";
        rp2.viewport = math::vec4f(0, 0, 640, 480);
        rp2.clear = true;
        rp2.depthTest = false;
        rp2.depthWrite = false;
        rp2.cullBackFace = false;
        rp2.blend = false;
        rp2.clearColor = math::vec4f(1.0f, 0.0f, 0.0f, 1.0f);
        ren.passesList.push_back(rp2);
    }
    virtual ~Demo() {
    }
protected:
    void OnFrame() {
        UpdateWorld();
        ren.rendering();
        GL_ASSERT(GL);
        SDLApp::OnFrame();
    }

    void OnKeyboardDown( u8 key ) {
        if ( key == 'w' ) {
            keypressed_ |= 1;
        } else if ( key == 's' ) {
            keypressed_ |= 2;
        } else if ( key == 'a' ) {
            keypressed_ |= 4;
        } else if ( key == 'd' ) {
            keypressed_ |= 8;
        } else if ( key == 'j' ) {
            keypressed_ |= 16;
        } else if ( key == 'k' ) {
            keypressed_ |= 32;
        } else if ( key == 'h' ) {
            keypressed_ |= 64;
        } else if ( key == 'l' ) {
            keypressed_ |= 128;
        }
    }
    void OnKeyboardUp( u8 key ) {
        if ( key == 'w' ) {
            keypressed_ ^= 1;
        } else if ( key == 's' ) {
            keypressed_ ^= 2;
        } else if ( key == 'a' ) {
            keypressed_ ^= 4;
        } else if ( key == 'd' ) {
            keypressed_ ^= 8;
        } else if ( key == 'j' ) {
            keypressed_ ^= 16;
        } else if ( key == 'k' ) {
            keypressed_ ^= 32;
        } else if ( key == 'h' ) {
            keypressed_ ^= 64;
        } else if ( key == 'l' ) {
            keypressed_ ^= 128;
        }
    }

    void OnMotion( i32 x, i32 y, i32 dx, i32 dy ) {
        cam.transform.turnHead( math::deg_to_rad * dx);

        if (fabs (cam.transform.pitch() + math::deg_to_rad * dy ) < base::math::pi/2.0f ) {
            cam.transform.turnPitch( math::deg_to_rad * dy );
        } else if (dy != 0 ) {
            cam.transform.setPitch( base::math::pi/2.0f * dy / fabs( (f32)dy ) );
        }
    }

    void UpdateWorld() {
        const f32 speed = 0.1f;

        if ( keypressed_ & 1 ) {
            cam.transform.moveForward( speed );
        }

        if ( keypressed_ & 2 ) {
            cam.transform.moveBackward( speed );
        }

        if ( keypressed_ & 4 ) {
            cam.transform.moveLeft( speed );
        }

        if ( keypressed_ & 8 ) {
            cam.transform.moveRight( speed );
        }

        if ( keypressed_ & 16 ) {
            if ( fabs( cam.transform.pitch() + math::deg_to_rad ) < math::pi / 2.0f )
                cam.transform.turnPitch( math::deg_to_rad );
        }

        if ( keypressed_ & 32 ) {
            if ( fabs( cam.transform.pitch() - math::deg_to_rad ) < math::pi / 2.0f )
                cam.transform.turnPitch( -math::deg_to_rad );
        }

        if ( keypressed_ & 64 ) {
            cam.transform.turnHead( math::deg_to_rad );
        }

        if ( keypressed_ & 128 ) {
            cam.transform.turnHead( -math::deg_to_rad );
        }

        game::Transform::updateTree(&cam.object);
        game::Camera::updateTree(&cam.object);
    }

    object global;
};

void run(const char* module) {
    Demo app(module);
    app.Run();
}

int main(int argc, char* argv[])
{
    if (handle_exception(boost::bind(run, argv[1]))) {
        if (PyErr_Occurred()) {
            PyErr_Print();
        }
    }

    return 0;
}

static Application& globalApp() {
    ASSERT(intstance_ != nullptr);
    return *intstance_;
}

BOOST_PYTHON_MODULE(negine_runtime)
{
    def("globalApp", globalApp, return_value_policy<reference_existing_object>());
    class_<Demo, boost::noncopyable>("App", no_init)
        .add_property( "context", make_function( static_cast< opengl::DeviceContext& (Application::*)() >( &Application::context ), return_value_policy<reference_existing_object>() ) );
}<|endoftext|>


<commit_before>/*
 * Copyright 2010 Google Inc.
 *
 * 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.
 */

#include "md5sum.h"
#include <new>

#include <stdio.h>

using namespace org::w3c::dom;

void MD5SumInstance::initialize() {
  md5class = new (std::nothrow) MD5Class(this);
  if (md5class) {
    window->setElement("MD5", md5class);
  }
}

MD5SumInstance::~MD5SumInstance() {
  if (md5class) {
      md5class->release();
  }
}
<commit_msg>Clean up.<commit_after>/*
 * Copyright 2010 Google Inc.
 *
 * 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.
 */

#include "md5sum.h"
#include <new>

using namespace org::w3c::dom;

void MD5SumInstance::initialize() {
  md5class = new (std::nothrow) MD5Class(this);
  if (md5class) {
    window->setElement("MD5", md5class);
  }
}

MD5SumInstance::~MD5SumInstance() {
  if (md5class) {
      md5class->release();
  }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 Stanford University
//
// 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.

#include <cassert>
#include <cmath>
#include <csignal>
#include <unistd.h>

#include "src/search/search.h"

using namespace cpputil;
using namespace std;
using namespace std::chrono;
using namespace x64asm;

namespace {

bool give_up_now = false;
void handler(int sig, siginfo_t* siginfo, void* context) {
  give_up_now = true;
}

} // namespace

namespace stoke {

Search::Search(Transforms* transforms) : transforms_(transforms) {
  set_max_instrs(16);
  set_seed(0);
  set_timeout_itr(0);
  set_timeout_sec(0);
  set_beta(1.0);
  set_progress_callback(nullptr, nullptr);
  set_statistics_callback(nullptr, nullptr);
  set_statistics_interval(100000);

  static bool once = false;
  if (!once) {
    once = true;

    struct sigaction term_act;
    memset(&term_act, '\0', sizeof(term_act));
    sigfillset(&term_act.sa_mask);
    term_act.sa_sigaction = handler;
    term_act.sa_flags = SA_ONSTACK;

    sigaction(SIGINT, &term_act, 0);
  }
}

Search& Search::set_mass(Move move, size_t mass) {
  vector<Move> new_moves;
  for (auto m : moves_) {
    if (m != move) {
      new_moves.push_back(m);
    }
  }
  for (size_t i = 0; i < mass; ++i) {
    new_moves.push_back(move);
  }
  moves_ = new_moves;
  int_ = decltype(int_)(0, moves_.size() - 1);

  return *this;
}

void Search::run(const Cfg& target, CostFunction& fxn, Init init, SearchState& state, vector<TUnit>& aux_fxns) {

  // Make sure target is correct with respect to itself
  assert(fxn(target).first);

  // Configure initial state
  configure(target, fxn, state, aux_fxns);

  if (!target.is_sound()) {
    cerr << "ERROR: the target reads undefined values, or leaves live out values undefined!" << endl;
    exit(1);
  }

  if (!state.current.is_sound()) {
    cerr << "ERROR: the initial rewrite reads undefined values, or leaves live out values undefined!" << endl;
    if (init == Init::EMPTY) {
      cerr << "Using --init zero will automatically prevent this problem." << endl;
    } else if (init == Init::ZERO) {
      cerr << "This is a bug, please report it." << endl;
    }
    exit(1);
  }

  // Make sure target and rewrite are sound to begin with
  assert(state.best_yet.is_sound());
  assert(state.best_correct.is_sound());

  // Statistics callback variables
  move_statistics = vector<Statistics>((size_t) Move::NUM_MOVES);
  num_iterations = 0;
  const auto start = chrono::steady_clock::now();

  // Early corner case bailouts
  if (state.current_cost == 0) {
    state.success = true;
    return;
  } else if (moves_.empty()) {
    state.success = false;
    return;
  }

  give_up_now = false;
  size_t iterations = 0;
  for (iterations = 0; (state.current_cost > 0) && !give_up_now; ++iterations) {
    // Invoke statistics callback if we've been running for long enough
    if ((statistics_cb_ != nullptr) && (iterations % interval_ == 0) && iterations > 0) {
      elapsed = duration_cast<duration<double>>(steady_clock::now() - start);
      num_iterations = iterations;
      statistics_cb_(get_statistics(), statistics_cb_arg_);
    }

    // This is just here to clean up the for loop; check early exit conditions
    if (timeout_itr_ > 0 && iterations >= timeout_itr_) {
      break;
    } else if (timeout_sec_ != steady_clock::duration::zero() &&
               duration_cast<duration<size_t>>(steady_clock::now() - start) >= timeout_sec_) {
      break;
    }

    const auto move_type = moves_[int_(gen_)];
    move_statistics[(size_t) move_type].num_proposed++;

    if (!transforms_->modify(state.current, move_type)) {
      continue;
    }
    move_statistics[(size_t) move_type].num_succeeded++;

    const auto p = prob_(gen_);
    const auto max = state.current_cost - (log(p) / beta_);

    const auto new_res = fxn(state.current, max + 1);
    const auto is_correct = new_res.first;
    const auto new_cost = new_res.second;

    if (new_cost > max) {
      transforms_->undo(state.current, move_type);
      continue;
    }
    move_statistics[(size_t) move_type].num_accepted++;
    state.current_cost = new_cost;

    const auto new_best_yet = new_cost < state.best_yet_cost;
    if (new_best_yet) {
      state.best_yet = state.current;
      state.best_yet_cost = new_cost;
    }
    const auto new_best_correct_yet = is_correct && ((new_cost == 0)
                                      || (new_cost < state.best_correct_cost));
    if (new_best_correct_yet) {
      state.success = true;
      state.best_correct = state.current;
      state.best_correct_cost = new_cost;
    }

    if ((progress_cb_ != nullptr) && (new_best_yet || new_best_correct_yet)) {
      progress_cb_({state}, progress_cb_arg_);
    }
  }

  // update values for statistics
  elapsed = duration_cast<duration<double>>(steady_clock::now() - start);
  num_iterations = iterations;

  if (give_up_now) {
    state.interrupted = true;
  }
}

StatisticsCallbackData Search::get_statistics() const {
  return {move_statistics, num_iterations, elapsed};
}

void Search::stop() {
  give_up_now = true;
}

void Search::configure(const Cfg& target, CostFunction& fxn, SearchState& state, vector<TUnit>& aux_fxn) const {

  state.current.recompute();
  state.best_yet.recompute();
  state.best_correct.recompute();

  // add dataflow information about function call targets
  for (const auto& fxn : aux_fxn) {
    auto code = fxn.code;
    auto lbl = code[0].get_operand<x64asm::Label>(0);
    TUnit::MayMustSets mms = {
      code.must_read_set(),
      code.must_write_set(),
      code.must_undef_set(),
      code.maybe_read_set(),
      code.maybe_write_set(),
      code.maybe_undef_set()
    };
    state.current.add_summary(lbl, fxn.get_may_must_sets(mms));
  }

  state.current_cost = fxn(state.current).second;
  state.best_yet_cost = fxn(state.best_yet).second;
  state.best_correct_cost = fxn(state.best_correct).second;
  state.success = false;

  // Invariant 3: Best correct should be correct with respect to target
  assert(fxn(state.best_correct).first);
  // Invariant 4: Best yet should be less than or equal to correct cost
  assert(state.best_yet_cost <= state.current_cost);
}

} // namespace stoke
<commit_msg>recompute liveness information after search<commit_after>// Copyright 2013-2015 Stanford University
//
// 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.

#include <cassert>
#include <cmath>
#include <csignal>
#include <unistd.h>

#include "src/search/search.h"

using namespace cpputil;
using namespace std;
using namespace std::chrono;
using namespace x64asm;

namespace {

bool give_up_now = false;
void handler(int sig, siginfo_t* siginfo, void* context) {
  give_up_now = true;
}

} // namespace

namespace stoke {

Search::Search(Transforms* transforms) : transforms_(transforms) {
  set_max_instrs(16);
  set_seed(0);
  set_timeout_itr(0);
  set_timeout_sec(0);
  set_beta(1.0);
  set_progress_callback(nullptr, nullptr);
  set_statistics_callback(nullptr, nullptr);
  set_statistics_interval(100000);

  static bool once = false;
  if (!once) {
    once = true;

    struct sigaction term_act;
    memset(&term_act, '\0', sizeof(term_act));
    sigfillset(&term_act.sa_mask);
    term_act.sa_sigaction = handler;
    term_act.sa_flags = SA_ONSTACK;

    sigaction(SIGINT, &term_act, 0);
  }
}

Search& Search::set_mass(Move move, size_t mass) {
  vector<Move> new_moves;
  for (auto m : moves_) {
    if (m != move) {
      new_moves.push_back(m);
    }
  }
  for (size_t i = 0; i < mass; ++i) {
    new_moves.push_back(move);
  }
  moves_ = new_moves;
  int_ = decltype(int_)(0, moves_.size() - 1);

  return *this;
}

void Search::run(const Cfg& target, CostFunction& fxn, Init init, SearchState& state, vector<TUnit>& aux_fxns) {

  // Make sure target is correct with respect to itself
  assert(fxn(target).first);

  // Configure initial state
  configure(target, fxn, state, aux_fxns);

  if (!target.is_sound()) {
    cerr << "ERROR: the target reads undefined values, or leaves live out values undefined!" << endl;
    exit(1);
  }

  if (!state.current.is_sound()) {
    cerr << "ERROR: the initial rewrite reads undefined values, or leaves live out values undefined!" << endl;
    if (init == Init::EMPTY) {
      cerr << "Using --init zero will automatically prevent this problem." << endl;
    } else if (init == Init::ZERO) {
      cerr << "This is a bug, please report it." << endl;
    }
    exit(1);
  }

  // Make sure target and rewrite are sound to begin with
  assert(state.best_yet.is_sound());
  assert(state.best_correct.is_sound());

  // Statistics callback variables
  move_statistics = vector<Statistics>((size_t) Move::NUM_MOVES);
  num_iterations = 0;
  const auto start = chrono::steady_clock::now();

  // Early corner case bailouts
  if (state.current_cost == 0) {
    state.success = true;
    return;
  } else if (moves_.empty()) {
    state.success = false;
    return;
  }

  give_up_now = false;
  size_t iterations = 0;
  for (iterations = 0; (state.current_cost > 0) && !give_up_now; ++iterations) {
    // Invoke statistics callback if we've been running for long enough
    if ((statistics_cb_ != nullptr) && (iterations % interval_ == 0) && iterations > 0) {
      elapsed = duration_cast<duration<double>>(steady_clock::now() - start);
      num_iterations = iterations;
      statistics_cb_(get_statistics(), statistics_cb_arg_);
    }

    // This is just here to clean up the for loop; check early exit conditions
    if (timeout_itr_ > 0 && iterations >= timeout_itr_) {
      break;
    } else if (timeout_sec_ != steady_clock::duration::zero() &&
               duration_cast<duration<size_t>>(steady_clock::now() - start) >= timeout_sec_) {
      break;
    }

    const auto move_type = moves_[int_(gen_)];
    move_statistics[(size_t) move_type].num_proposed++;

    if (!transforms_->modify(state.current, move_type)) {
      continue;
    }
    move_statistics[(size_t) move_type].num_succeeded++;

    const auto p = prob_(gen_);
    const auto max = state.current_cost - (log(p) / beta_);

    const auto new_res = fxn(state.current, max + 1);
    const auto is_correct = new_res.first;
    const auto new_cost = new_res.second;

    if (new_cost > max) {
      transforms_->undo(state.current, move_type);
      continue;
    }
    move_statistics[(size_t) move_type].num_accepted++;
    state.current_cost = new_cost;

    const auto new_best_yet = new_cost < state.best_yet_cost;
    if (new_best_yet) {
      state.best_yet = state.current;
      state.best_yet_cost = new_cost;
    }
    const auto new_best_correct_yet = is_correct && ((new_cost == 0)
                                      || (new_cost < state.best_correct_cost));
    if (new_best_correct_yet) {
      state.success = true;
      state.best_correct = state.current;
      state.best_correct_cost = new_cost;
    }

    if ((progress_cb_ != nullptr) && (new_best_yet || new_best_correct_yet)) {
      progress_cb_({state}, progress_cb_arg_);
    }
  }

  // update values for statistics
  elapsed = duration_cast<duration<double>>(steady_clock::now() - start);
  num_iterations = iterations;

  if (give_up_now) {
    state.interrupted = true;
  }

  // make sure Cfg's are in a valid state (e.g. liveness information, which we
  // do not update during search)
  state.current.recompute();
  state.best_correct.recompute();
  state.best_yet.recompute();
}

StatisticsCallbackData Search::get_statistics() const {
  return {move_statistics, num_iterations, elapsed};
}

void Search::stop() {
  give_up_now = true;
}

void Search::configure(const Cfg& target, CostFunction& fxn, SearchState& state, vector<TUnit>& aux_fxn) const {

  state.current.recompute();
  state.best_yet.recompute();
  state.best_correct.recompute();

  // add dataflow information about function call targets
  for (const auto& fxn : aux_fxn) {
    auto code = fxn.code;
    auto lbl = code[0].get_operand<x64asm::Label>(0);
    TUnit::MayMustSets mms = {
      code.must_read_set(),
      code.must_write_set(),
      code.must_undef_set(),
      code.maybe_read_set(),
      code.maybe_write_set(),
      code.maybe_undef_set()
    };
    state.current.add_summary(lbl, fxn.get_may_must_sets(mms));
  }

  state.current_cost = fxn(state.current).second;
  state.best_yet_cost = fxn(state.best_yet).second;
  state.best_correct_cost = fxn(state.best_correct).second;
  state.success = false;

  // Invariant 3: Best correct should be correct with respect to target
  assert(fxn(state.best_correct).first);
  // Invariant 4: Best yet should be less than or equal to correct cost
  assert(state.best_yet_cost <= state.current_cost);
}

} // namespace stoke
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  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.
 *
 * $Id$
 *
 */

#ifndef PCL_SURFACE_IMPL_MLS_H_
#define PCL_SURFACE_IMPL_MLS_H_

#include "pcl/surface/mls.h"
#include <pcl/common/io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/kdtree/organized_data.h>
#include <pcl/common/centroid.h>
#include <pcl/common/eigen.h>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename NormalOutT> void
pcl::MovingLeastSquares<PointInT, NormalOutT>::reconstruct (PointCloudIn &output)
{
  // check if normals have to be computed/saved
  if (normals_)
  {
    // Copy the header
    normals_->header = input_->header;
    // Clear the fields in case the method exits before computation
    normals_->width = normals_->height = 0;
    normals_->points.clear ();
  }

  // Copy the header
  output.header = input_->header;

  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  if (!tree_)
  {
    if (input_->isOrganized ())
      tree_.reset (new pcl::OrganizedDataIndex<PointInT> ());
    else
      tree_.reset (new pcl::KdTreeFLANN<PointInT> (false));
  }

  // Send the surface dataset to the spatial locator
  tree_->setInputCloud (input_, indices_);

  // Perform the actual surface reconstruction
  performReconstruction (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename NormalOutT> void
pcl::MovingLeastSquares<PointInT, NormalOutT>::performReconstruction (PointCloudIn &output)
{
  if (search_radius_ <= 0 || sqr_gauss_param_ <= 0)
  {
    PCL_ERROR ("[pcl::%s::performReconstruction] Invalid search radius (%f) or Gaussian parameter (%f)!\n", getClassName ().c_str (), search_radius_, sqr_gauss_param_);
    output.width = output.height = 0;
    output.points.clear ();
    if (normals_)
    {
      normals_->width = normals_->height = 0;
      normals_->points.clear ();
    }
    return;
  }

  // Compute the number of coefficients
  nr_coeff_ = (order_ + 1) * (order_ + 2) / 2;

  // Allocate enough space to hold the results of nearest neighbor searches
  // \note resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices;
  std::vector<float> nn_sqr_dists;

  // Use original point positions for fitting
  // \note no up/down/adapting-sampling or hole filling possible like this
  output.points.resize (indices_->size ());
  // Check if fake indices were used, otherwise the output loses its organized structure
  if (!fake_indices_)
    pcl::copyPointCloud (*input_, *indices_, output);
  else
    output = *input_;

  // Resize the output normal dataset
  if (normals_)
  {
    normals_->points.resize (output.points.size ());
    normals_->width    = output.width;
    normals_->height   = output.height;
    normals_->is_dense = output.is_dense;
  }

  // For all points
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    // Get the initial estimates of point positions and their neighborhoods
    ///////////////////////////////////////////////////////////////////////

    // Search for the nearest neighbors
    if (!searchForNeighbors ((*indices_)[cp], nn_indices, nn_sqr_dists))
    {
      if (normals_)
        normals_->points[cp].normal[0] = normals_->points[cp].normal[1] = normals_->points[cp].normal[2] = normals_->points[cp].curvature = std::numeric_limits<float>::quiet_NaN ();
      continue;
    }

    // Check the number of nearest neighbors for normal estimation (and later
    // for polynomial fit as well)
    int k = nn_indices.size ();
    if (k < 3)
      continue;

    // Get a plane approximating the local surface's tangent and project point onto it
    //////////////////////////////////////////////////////////////////////////////////

    // Compute the plane coefficients
    Eigen::Vector4f model_coefficients;
    //pcl::computePointNormal<PointInT> (*input_, nn_indices, model_coefficients, curvature);
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    Eigen::Vector4f xyz_centroid;

    // Estimate the XYZ centroid
    pcl::compute3DCentroid (*input_, nn_indices, xyz_centroid);

    // Compute the 3x3 covariance matrix
    pcl::computeCovarianceMatrix (*input_, nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal
    EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
    EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
    pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

    // The normalization is not necessary, since the eigenvectors from libeigen are already normalized
    model_coefficients[0] = eigen_vectors (0, 0);
    model_coefficients[1] = eigen_vectors (1, 0);
    model_coefficients[2] = eigen_vectors (2, 0);
    model_coefficients[3] = 0;
    // Hessian form (D = nc . p_plane (centroid here) + p)
    model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid);

    float curvature = 0;
    // Compute the curvature surface change
    float eig_sum = eigen_values.sum ();
    if (eig_sum != 0)
      curvature = fabs (eigen_values[0] / eig_sum);

    // Projected point
    Eigen::Vector3f point = output.points[cp].getVector3fMap ();
    float distance = point.dot (model_coefficients.head<3> ()) + model_coefficients[3];
    point -= distance * model_coefficients.head<3> ();

    // Perform polynomial fit to update point and normal
    ////////////////////////////////////////////////////
    if (polynomial_fit_ && k >= nr_coeff_)
    {
      // For easy change between float and double
      typedef Eigen::Vector3d Evector3;
      typedef Eigen::VectorXd Evector;
      typedef Eigen::MatrixXd Ematrix;
      // Get a copy of the plane normal easy access
      Evector3 plane_normal = model_coefficients.head<3> ().cast<double> ();

      // Update neighborhood, since point was projected, and computing relative
      // positions. Note updating only distances for the weights for speed
      std::vector<Evector3> de_meaned (k);
      for (int ni = 0; ni < k; ++ni)
      {
        de_meaned[ni][0] = input_->points[nn_indices[ni]].x - point[0];
        de_meaned[ni][1] = input_->points[nn_indices[ni]].y - point[1];
        de_meaned[ni][2] = input_->points[nn_indices[ni]].z - point[2];
        nn_sqr_dists[ni] = de_meaned[ni].dot (de_meaned[ni]);
      }

      // Allocate matrices and vectors to hold the data used for the polynomial
      // fit
      Evector weight_vec_ (k);
      Ematrix P_ (nr_coeff_, k);
      Evector f_vec_ (k);
      Evector c_vec_;
      Ematrix P_weight_; // size will be (nr_coeff_, k);
      Ematrix P_weight_Pt_ (nr_coeff_, nr_coeff_);

      // Get local coordinate system (Darboux frame)
      Evector3 v = plane_normal.unitOrthogonal ();
      Evector3 u = plane_normal.cross (v);

      // Go through neighbors, transform them in the local coordinate system,
      // save height and the evaluation of the polynome's terms
      double u_coord, v_coord, u_pow, v_pow;
      for (int ni = 0; ni < k; ++ni)
      {
        // (re-)compute weights
        weight_vec_ (ni) = exp (-nn_sqr_dists[ni] / sqr_gauss_param_);

        // transforming coordinates
        u_coord = de_meaned[ni].dot (u);
        v_coord = de_meaned[ni].dot (v);
        f_vec_(ni) = de_meaned[ni].dot (plane_normal);

        // compute the polynomial's terms at the current point
        int j = 0;
        u_pow = 1;
        for (int ui = 0; ui <= order_; ++ui)
        {
          v_pow = 1;
          for (int vi = 0; vi <= order_ - ui; ++vi)
          {
            P_ (j++, ni) = u_pow * v_pow;
            v_pow *= v_coord;
          }
          u_pow *= u_coord;
        }
      }

      // Computing coefficients
      P_weight_ = P_ * weight_vec_.asDiagonal ();
      P_weight_Pt_ = P_weight_ * P_.transpose ();
      c_vec_ = P_weight_ * f_vec_;
      P_weight_Pt_.llt ().solveInPlace (c_vec_);

      // Projection onto MLS surface along Darboux normal to the height at (0,0)
      if (pcl_isfinite (c_vec_[0]))
      {
        point += (c_vec_[0] * plane_normal).cast<float> ();

        // Compute tangent vectors using the partial derivates evaluated at (0,0) which is c_vec_[order_+1] and c_vec_[1]
        if (normals_)
        {
          Evector3 n_a = u + plane_normal * c_vec_[order_ + 1];
          Evector3 n_b = v + plane_normal * c_vec_[1];
          model_coefficients.head<3> () = n_a.cross (n_b).cast<float> ();
          model_coefficients.head<3> ().normalize ();
        }
      }
    }

    // Save results to output cloud
    ///////////////////////////////
    output.points[cp].x = point[0];
    output.points[cp].y = point[1];
    output.points[cp].z = point[2];
    if (normals_)
    {
      normals_->points[cp].normal[0] = model_coefficients[0];
      normals_->points[cp].normal[1] = model_coefficients[1];
      normals_->points[cp].normal[2] = model_coefficients[2];
      normals_->points[cp].curvature = curvature;
    }
  }
}

#define PCL_INSTANTIATE_MovingLeastSquares(T,OutT) template class PCL_EXPORTS pcl::MovingLeastSquares<T,OutT>;

#endif    // PCL_SURFACE_IMPL_MLS_H_

<commit_msg>fixed bug in surface/mls: when no search interface and no tree is given, mls creates its' own tree, but didn'tupdate the search method to use <commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  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.
 *
 * $Id$
 *
 */

#ifndef PCL_SURFACE_IMPL_MLS_H_
#define PCL_SURFACE_IMPL_MLS_H_

#include "pcl/surface/mls.h"
#include <pcl/common/io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/kdtree/organized_data.h>
#include <pcl/common/centroid.h>
#include <pcl/common/eigen.h>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename NormalOutT> void
pcl::MovingLeastSquares<PointInT, NormalOutT>::reconstruct (PointCloudIn &output)
{
  // check if normals have to be computed/saved
  if (normals_)
  {
    // Copy the header
    normals_->header = input_->header;
    // Clear the fields in case the method exits before computation
    normals_->width = normals_->height = 0;
    normals_->points.clear ();
  }

  // Copy the header
  output.header = input_->header;

  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  if (!tree_)
  {
    KdTreePtr tree;
    if (input_->isOrganized ())
      tree.reset (new pcl::OrganizedDataIndex<PointInT> ());
    else
      tree.reset (new pcl::KdTreeFLANN<PointInT> (false));
    setSearchMethod (tree);
  }

  // Send the surface dataset to the spatial locator
  tree_->setInputCloud (input_, indices_);

  // Perform the actual surface reconstruction
  performReconstruction (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename NormalOutT> void
pcl::MovingLeastSquares<PointInT, NormalOutT>::performReconstruction (PointCloudIn &output)
{
  if (search_radius_ <= 0 || sqr_gauss_param_ <= 0)
  {
    PCL_ERROR ("[pcl::%s::performReconstruction] Invalid search radius (%f) or Gaussian parameter (%f)!\n", getClassName ().c_str (), search_radius_, sqr_gauss_param_);
    output.width = output.height = 0;
    output.points.clear ();
    if (normals_)
    {
      normals_->width = normals_->height = 0;
      normals_->points.clear ();
    }
    return;
  }

  // Compute the number of coefficients
  nr_coeff_ = (order_ + 1) * (order_ + 2) / 2;

  // Allocate enough space to hold the results of nearest neighbor searches
  // \note resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices;
  std::vector<float> nn_sqr_dists;

  // Use original point positions for fitting
  // \note no up/down/adapting-sampling or hole filling possible like this
  output.points.resize (indices_->size ());
  // Check if fake indices were used, otherwise the output loses its organized structure
  if (!fake_indices_)
    pcl::copyPointCloud (*input_, *indices_, output);
  else
    output = *input_;

  // Resize the output normal dataset
  if (normals_)
  {
    normals_->points.resize (output.points.size ());
    normals_->width    = output.width;
    normals_->height   = output.height;
    normals_->is_dense = output.is_dense;
  }

  // For all points
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    // Get the initial estimates of point positions and their neighborhoods
    ///////////////////////////////////////////////////////////////////////

    // Search for the nearest neighbors
    if (!searchForNeighbors ((*indices_)[cp], nn_indices, nn_sqr_dists))
    {
      if (normals_)
        normals_->points[cp].normal[0] = normals_->points[cp].normal[1] = normals_->points[cp].normal[2] = normals_->points[cp].curvature = std::numeric_limits<float>::quiet_NaN ();
      continue;
    }

    // Check the number of nearest neighbors for normal estimation (and later
    // for polynomial fit as well)
    int k = nn_indices.size ();
    if (k < 3)
      continue;

    // Get a plane approximating the local surface's tangent and project point onto it
    //////////////////////////////////////////////////////////////////////////////////

    // Compute the plane coefficients
    Eigen::Vector4f model_coefficients;
    //pcl::computePointNormal<PointInT> (*input_, nn_indices, model_coefficients, curvature);
    EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
    Eigen::Vector4f xyz_centroid;

    // Estimate the XYZ centroid
    pcl::compute3DCentroid (*input_, nn_indices, xyz_centroid);

    // Compute the 3x3 covariance matrix
    pcl::computeCovarianceMatrix (*input_, nn_indices, xyz_centroid, covariance_matrix);

    // Get the plane normal
    EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
    EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
    pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

    // The normalization is not necessary, since the eigenvectors from libeigen are already normalized
    model_coefficients[0] = eigen_vectors (0, 0);
    model_coefficients[1] = eigen_vectors (1, 0);
    model_coefficients[2] = eigen_vectors (2, 0);
    model_coefficients[3] = 0;
    // Hessian form (D = nc . p_plane (centroid here) + p)
    model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid);

    float curvature = 0;
    // Compute the curvature surface change
    float eig_sum = eigen_values.sum ();
    if (eig_sum != 0)
      curvature = fabs (eigen_values[0] / eig_sum);

    // Projected point
    Eigen::Vector3f point = output.points[cp].getVector3fMap ();
    float distance = point.dot (model_coefficients.head<3> ()) + model_coefficients[3];
    point -= distance * model_coefficients.head<3> ();

    // Perform polynomial fit to update point and normal
    ////////////////////////////////////////////////////
    if (polynomial_fit_ && k >= nr_coeff_)
    {
      // For easy change between float and double
      typedef Eigen::Vector3d Evector3;
      typedef Eigen::VectorXd Evector;
      typedef Eigen::MatrixXd Ematrix;
      // Get a copy of the plane normal easy access
      Evector3 plane_normal = model_coefficients.head<3> ().cast<double> ();

      // Update neighborhood, since point was projected, and computing relative
      // positions. Note updating only distances for the weights for speed
      std::vector<Evector3> de_meaned (k);
      for (int ni = 0; ni < k; ++ni)
      {
        de_meaned[ni][0] = input_->points[nn_indices[ni]].x - point[0];
        de_meaned[ni][1] = input_->points[nn_indices[ni]].y - point[1];
        de_meaned[ni][2] = input_->points[nn_indices[ni]].z - point[2];
        nn_sqr_dists[ni] = de_meaned[ni].dot (de_meaned[ni]);
      }

      // Allocate matrices and vectors to hold the data used for the polynomial
      // fit
      Evector weight_vec_ (k);
      Ematrix P_ (nr_coeff_, k);
      Evector f_vec_ (k);
      Evector c_vec_;
      Ematrix P_weight_; // size will be (nr_coeff_, k);
      Ematrix P_weight_Pt_ (nr_coeff_, nr_coeff_);

      // Get local coordinate system (Darboux frame)
      Evector3 v = plane_normal.unitOrthogonal ();
      Evector3 u = plane_normal.cross (v);

      // Go through neighbors, transform them in the local coordinate system,
      // save height and the evaluation of the polynome's terms
      double u_coord, v_coord, u_pow, v_pow;
      for (int ni = 0; ni < k; ++ni)
      {
        // (re-)compute weights
        weight_vec_ (ni) = exp (-nn_sqr_dists[ni] / sqr_gauss_param_);

        // transforming coordinates
        u_coord = de_meaned[ni].dot (u);
        v_coord = de_meaned[ni].dot (v);
        f_vec_(ni) = de_meaned[ni].dot (plane_normal);

        // compute the polynomial's terms at the current point
        int j = 0;
        u_pow = 1;
        for (int ui = 0; ui <= order_; ++ui)
        {
          v_pow = 1;
          for (int vi = 0; vi <= order_ - ui; ++vi)
          {
            P_ (j++, ni) = u_pow * v_pow;
            v_pow *= v_coord;
          }
          u_pow *= u_coord;
        }
      }

      // Computing coefficients
      P_weight_ = P_ * weight_vec_.asDiagonal ();
      P_weight_Pt_ = P_weight_ * P_.transpose ();
      c_vec_ = P_weight_ * f_vec_;
      P_weight_Pt_.llt ().solveInPlace (c_vec_);

      // Projection onto MLS surface along Darboux normal to the height at (0,0)
      if (pcl_isfinite (c_vec_[0]))
      {
        point += (c_vec_[0] * plane_normal).cast<float> ();

        // Compute tangent vectors using the partial derivates evaluated at (0,0) which is c_vec_[order_+1] and c_vec_[1]
        if (normals_)
        {
          Evector3 n_a = u + plane_normal * c_vec_[order_ + 1];
          Evector3 n_b = v + plane_normal * c_vec_[1];
          model_coefficients.head<3> () = n_a.cross (n_b).cast<float> ();
          model_coefficients.head<3> ().normalize ();
        }
      }
    }

    // Save results to output cloud
    ///////////////////////////////
    output.points[cp].x = point[0];
    output.points[cp].y = point[1];
    output.points[cp].z = point[2];
    if (normals_)
    {
      normals_->points[cp].normal[0] = model_coefficients[0];
      normals_->points[cp].normal[1] = model_coefficients[1];
      normals_->points[cp].normal[2] = model_coefficients[2];
      normals_->points[cp].curvature = curvature;
    }
  }
}

#define PCL_INSTANTIATE_MovingLeastSquares(T,OutT) template class PCL_EXPORTS pcl::MovingLeastSquares<T,OutT>;

#endif    // PCL_SURFACE_IMPL_MLS_H_

<|endoftext|>