<commit_before>#include "Genes/Sphere_of_Influence_Gene.h"

#include <algorithm>

#include "Game/Board.h"
#include "Moves/Complete_Move.h"

#include "Utility.h"

Sphere_of_Influence_Gene::Sphere_of_Influence_Gene() : legal_bonus(1.0)
{
}

Sphere_of_Influence_Gene::~Sphere_of_Influence_Gene()
{
}

void Sphere_of_Influence_Gene::reset_properties() const
{
    Gene::reset_properties();
    properties["Legal Bonus"] = legal_bonus;
}

void Sphere_of_Influence_Gene::load_properties()
{
    Gene::load_properties();
    legal_bonus = properties["Legal Bonus"];
}

Sphere_of_Influence_Gene* Sphere_of_Influence_Gene::duplicate() const
{
    return new Sphere_of_Influence_Gene(*this);
}

std::string Sphere_of_Influence_Gene::name() const
{
    return "Sphere of Influence Gene";
}

// Count all squares potentially attacked by all pieces with bonus points if
// the attacking move is legal.
double Sphere_of_Influence_Gene::score_board(const Board& board, Color perspective) const
{
    std::map<Square, double> square_score;
    auto temp = board;
    temp.set_turn(perspective);

    double score_to_add = 1.0;
    for(const auto& move_list : {temp.other_moves(), temp.legal_moves()})
    {
        for(const auto& cm : move_list)
        {
            // Only potentially capturing moves are counted
            if( ! cm.can_capture())
            {
                continue;
            }

            char final_file = cm.end_file();
            int  final_rank = cm.end_rank();

            if(cm.name().front() == 'E')
            {
                if(temp.is_en_passant_targetable(final_file, final_rank))
                {
                    final_rank += (temp.whose_turn() == WHITE ? -1 : 1);
                }
                else
                {
                    continue;
                }
            }

            square_score[{final_file, final_rank}] = score_to_add;
        }

        score_to_add = legal_bonus; // now on legal move list
    }

    double score = 0;
    for(const auto& square_value : square_score)
    {
        score += square_value.second;
    }

    // normalizing to make maximum score near 1
    return score/64.0;
}

void Sphere_of_Influence_Gene::gene_specific_mutation()
{
    legal_bonus += Random::random_normal(0.2);
}
<commit_msg>Lower mutation rate on Legal Bonus<commit_after>#include "Genes/Sphere_of_Influence_Gene.h"

#include <algorithm>

#include "Game/Board.h"
#include "Moves/Complete_Move.h"

#include "Utility.h"

Sphere_of_Influence_Gene::Sphere_of_Influence_Gene() : legal_bonus(1.0)
{
}

Sphere_of_Influence_Gene::~Sphere_of_Influence_Gene()
{
}

void Sphere_of_Influence_Gene::reset_properties() const
{
    Gene::reset_properties();
    properties["Legal Bonus"] = legal_bonus;
}

void Sphere_of_Influence_Gene::load_properties()
{
    Gene::load_properties();
    legal_bonus = properties["Legal Bonus"];
}

Sphere_of_Influence_Gene* Sphere_of_Influence_Gene::duplicate() const
{
    return new Sphere_of_Influence_Gene(*this);
}

std::string Sphere_of_Influence_Gene::name() const
{
    return "Sphere of Influence Gene";
}

// Count all squares potentially attacked by all pieces with bonus points if
// the attacking move is legal.
double Sphere_of_Influence_Gene::score_board(const Board& board, Color perspective) const
{
    std::map<Square, double> square_score;
    auto temp = board;
    temp.set_turn(perspective);

    double score_to_add = 1.0;
    for(const auto& move_list : {temp.other_moves(), temp.legal_moves()})
    {
        for(const auto& cm : move_list)
        {
            // Only potentially capturing moves are counted
            if( ! cm.can_capture())
            {
                continue;
            }

            char final_file = cm.end_file();
            int  final_rank = cm.end_rank();

            if(cm.name().front() == 'E')
            {
                if(temp.is_en_passant_targetable(final_file, final_rank))
                {
                    final_rank += (temp.whose_turn() == WHITE ? -1 : 1);
                }
                else
                {
                    continue;
                }
            }

            square_score[{final_file, final_rank}] = score_to_add;
        }

        score_to_add = legal_bonus; // now on legal move list
    }

    double score = 0;
    for(const auto& square_value : square_score)
    {
        score += square_value.second;
    }

    // normalizing to make maximum score near 1
    return score/64.0;
}

void Sphere_of_Influence_Gene::gene_specific_mutation()
{
    legal_bonus += Random::random_normal(0.05);
}
<|endoftext|>


<commit_before>#include "Genes/Sphere_of_Influence_Gene.h"

#include <algorithm>
#include <array>
#include <memory>

#include "Genes/Gene.h"
#include "Game/Board.h"
#include "Game/Square.h"
#include "Moves/Move.h"

#include "Utility.h"

Sphere_of_Influence_Gene::Sphere_of_Influence_Gene() :
    legal_square_score(1.0),
    illegal_square_score(1.0),
    king_target_factor(0.0)
{
}

void Sphere_of_Influence_Gene::reset_properties() const
{
    Gene::reset_properties();
    properties["Legal Square Score"] = legal_square_score;
    properties["Illegal Square Score"] = illegal_square_score;
    properties["King Target Factor"] = king_target_factor;
}

void Sphere_of_Influence_Gene::load_properties()
{
    Gene::load_properties();
    legal_square_score = properties["Legal Square Score"];
    illegal_square_score = properties["Illegal Square Score"];
    king_target_factor = properties["King Target Factor"];
}

std::unique_ptr<Gene> Sphere_of_Influence_Gene::duplicate() const
{
    return std::make_unique<Sphere_of_Influence_Gene>(*this);
}

std::string Sphere_of_Influence_Gene::name() const
{
    return "Sphere of Influence Gene";
}

// Count all squares potentially attacked by all pieces with bonus points if
// the attacking move is legal.
double Sphere_of_Influence_Gene::score_board(const Board& board, const Board&, size_t) const
{
    std::array<double, 64> square_score{};
    std::array<size_t, 64> distance_to_king{};
    auto opponent_king_square = board.find_king(opposite(board.whose_turn()));
    for(char file = 'a'; file <= 'h'; ++file)
    {
        for(int rank = 1; rank <= 8; ++rank)
        {
            distance_to_king[Board::board_index(file, rank)] =
                king_distance({file, rank}, opponent_king_square);
        }
    }

    double score_to_add = illegal_square_score;
    for(const auto& attack_list : {board.other_square_indices_attacked(), board.all_square_indices_attacked()})
    {
        for(size_t i = 0; i < attack_list.size(); ++i)
        {
            if(attack_list[i])
            {
                square_score[i] = score_to_add;
            }
        }

        score_to_add = legal_square_score; // now on legal move list
    }

    double score = 0;
    for(size_t i = 0; i < square_score.size(); ++i)
    {
        auto king_bonus = king_target_factor/(1 + distance_to_king[i]);
        score += square_score[i]*(1 + king_bonus);
    }

    // normalizing to make maximum score near 1
    return score/(64*(std::abs(legal_square_score) + std::abs(illegal_square_score)));
}

void Sphere_of_Influence_Gene::gene_specific_mutation()
{
    switch(Random::random_integer(1, 3))
    {
        case 1:
            legal_square_score += Random::random_laplace(0.5);
            break;
        case 2:
            illegal_square_score += Random::random_laplace(0.5);
            break;
        case 3:
            king_target_factor += Random::random_laplace(0.5);
            break;
        default:
            throw std::runtime_error("Bad range in Sphere_of_Influence_Gene::gene_specific_mutation()");
    }
}
<commit_msg>Make Sphere of Influence Gene priority non-negative<commit_after>#include "Genes/Sphere_of_Influence_Gene.h"

#include <algorithm>
#include <array>
#include <memory>

#include "Genes/Gene.h"
#include "Game/Board.h"
#include "Game/Square.h"
#include "Moves/Move.h"

#include "Utility.h"

Sphere_of_Influence_Gene::Sphere_of_Influence_Gene() :
    legal_square_score(1.0),
    illegal_square_score(1.0),
    king_target_factor(0.0)
{
}

void Sphere_of_Influence_Gene::reset_properties() const
{
    Gene::reset_properties();
    properties["Legal Square Score"] = legal_square_score;
    properties["Illegal Square Score"] = illegal_square_score;
    properties["King Target Factor"] = king_target_factor;
}

void Sphere_of_Influence_Gene::load_properties()
{
    Gene::load_properties();
    legal_square_score = properties["Legal Square Score"];
    illegal_square_score = properties["Illegal Square Score"];
    king_target_factor = properties["King Target Factor"];
}

std::unique_ptr<Gene> Sphere_of_Influence_Gene::duplicate() const
{
    return std::make_unique<Sphere_of_Influence_Gene>(*this);
}

std::string Sphere_of_Influence_Gene::name() const
{
    return "Sphere of Influence Gene";
}

// Count all squares potentially attacked by all pieces with bonus points if
// the attacking move is legal.
double Sphere_of_Influence_Gene::score_board(const Board& board, const Board&, size_t) const
{
    std::array<double, 64> square_score{};
    std::array<size_t, 64> distance_to_king{};
    auto opponent_king_square = board.find_king(opposite(board.whose_turn()));
    for(char file = 'a'; file <= 'h'; ++file)
    {
        for(int rank = 1; rank <= 8; ++rank)
        {
            distance_to_king[Board::board_index(file, rank)] =
                king_distance({file, rank}, opponent_king_square);
        }
    }

    double score_to_add = illegal_square_score;
    for(const auto& attack_list : {board.other_square_indices_attacked(), board.all_square_indices_attacked()})
    {
        for(size_t i = 0; i < attack_list.size(); ++i)
        {
            if(attack_list[i])
            {
                square_score[i] = score_to_add;
            }
        }

        score_to_add = legal_square_score; // now on legal move list
    }

    double score = 0;
    for(size_t i = 0; i < square_score.size(); ++i)
    {
        auto king_bonus = king_target_factor/(1 + distance_to_king[i]);
        score += square_score[i]*(1 + king_bonus);
    }

    // normalizing to make maximum score near 1
    return score/(64*(std::abs(legal_square_score) + std::abs(illegal_square_score)));
}

void Sphere_of_Influence_Gene::gene_specific_mutation()
{
    make_priority_minimum_zero();

    switch(Random::random_integer(1, 3))
    {
        case 1:
            legal_square_score += Random::random_laplace(0.5);
            break;
        case 2:
            illegal_square_score += Random::random_laplace(0.5);
            break;
        case 3:
            king_target_factor += Random::random_laplace(0.5);
            break;
        default:
            throw std::runtime_error("Bad range in Sphere_of_Influence_Gene::gene_specific_mutation()");
    }
}
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

using namespace std;

#include "config.h"

#include "common/ConfUtils.h"
#include "common/common_init.h"
#include "auth/Crypto.h"
#include "auth/Auth.h"
#include "auth/KeyRing.h"

void usage()
{
  cout << " usage: [--create-keyring] [--gen-key] [--name=<name>] [--caps=<filename>] [--list] [--print-key] <filename>" << std::endl;
  exit(1);
}

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

  const char *me = argv[0];

  const char *fn = 0;
  bool gen_key = false;
  const char *add_key = 0;
  bool list = false;
  bool print_key = false;
  bool create_keyring = false;
  const char *name = "";
  const char *caps_fn = NULL;
  const char *import_keyring = NULL;

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("gen-key", 'g')) {
      CONF_SAFE_SET_ARG_VAL(&gen_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("add-key", 'a')) {
      CONF_SAFE_SET_ARG_VAL(&add_key, OPT_STR);
    } else if (CONF_ARG_EQ("name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&name, OPT_STR);
    } else if (CONF_ARG_EQ("list", 'l')) {
      CONF_SAFE_SET_ARG_VAL(&list, OPT_BOOL);
    } else if (CONF_ARG_EQ("caps", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&caps_fn, OPT_STR);
    } else if (CONF_ARG_EQ("print-key", 'p')) {
      CONF_SAFE_SET_ARG_VAL(&print_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("create-keyring", 'c')) {
      CONF_SAFE_SET_ARG_VAL(&create_keyring, OPT_BOOL);
    } else if (CONF_ARG_EQ("import-keyring", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&import_keyring, OPT_STR);
    } else if (!fn) {
      fn = args[i];
    } else
      usage();
  }
  if (!fn) {
    cerr << me << ": must specify filename" << std::endl;
    usage();
  }
  if (!(gen_key ||
	add_key ||
	list ||
	caps_fn ||
	print_key ||
	create_keyring ||
	import_keyring)) {
    cerr << "no command specified" << std::endl;
    usage();
  }
  if (gen_key && add_key) {
    cerr << "can't both gen_key and add_key" << std::endl;
    usage();
  }
  if (caps_fn || add_key || gen_key || print_key) {
    if (!name || !(*name)) {
      cerr << "must specify entity name" << std::endl;
      usage();
    }
  }

  // keyring --------
  bool modified = false;
  KeyRing keyring;
  string s = name;
  EntityName ename;
  if (name[0] && !ename.from_str(s)) {
    cerr << "'" << s << "' is not a valid entity name" << std::endl;
    exit(1);
  }

  bufferlist bl;
  int r = 0;
  if (create_keyring) {
    cout << "creating " << fn << std::endl;
    modified = true;
  } else {
    r = bl.read_file(fn, true);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = bl.begin();
	::decode(keyring, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << fn << std::endl;
	exit(1);
      }
    } else {
      cerr << "can't open " << fn << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }

  // write commands
  if (import_keyring) {
    KeyRing other;
    bufferlist obl;
    int r = obl.read_file(import_keyring);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = obl.begin();
	::decode(other, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << import_keyring << std::endl;
	exit(1);
      }

      cout << "importing contents of " << import_keyring << " into " << fn << std::endl;
      //other.print(cout);
      keyring.import(other);
      modified = true;
    } else {
      cerr << "can't open " << import_keyring << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }
  if (gen_key) {
    EntityAuth eauth;
    eauth.key.create(CEPH_CRYPTO_AES);
    keyring.add(ename, eauth);
    modified = true;
  }
  if (add_key) {
    if (!name) {
      cerr << "must speicfy a name to add a key" << std::endl;
      exit(1);
    }
    EntityAuth eauth;
    string ekey(add_key);
    try {
      eauth.key.decode_base64(ekey);
    } catch (buffer::error *err) {
      cerr << "can't decode key '" << add_key << "'" << std::endl;
      exit(1);
    }
    keyring.add(ename, eauth);
    modified = true;
    cout << "added entity " << ename << " auth " << eauth << std::endl;
  }
  if (caps_fn) {
    ConfFile *cf = new ConfFile(caps_fn);
    if (!cf->parse()) {
      cerr << "could not parse caps file " << caps_fn << std::endl;
      exit(1);
    }
    map<string, bufferlist> caps;
    const char *key_names[] = { "mon", "osd", "mds", NULL };
    for (int i=0; key_names[i]; i++) {
      char *val;
      cf->read("global", key_names[i], &val, NULL);
      if (val) {
        bufferlist bl;
        ::encode(val, bl);
        string s(key_names[i]);
        caps[s] = bl;
        free(val);
      }
    }
    keyring.set_caps(ename, caps);
    modified = true;
  }

  // read commands
  if (list) {
    keyring.print(cout);
  }
  if (print_key) {
    CryptoKey key;
    if (keyring.get_secret(ename, key)) {
      string a;
      key.encode_base64(a);
      cout << a << std::endl;
    } else {
      cerr << "entity " << ename << " not found" << std::endl;
    }
  }

  // write result?
  if (modified) {
    bufferlist bl;
    ::encode(keyring, bl);
    r = bl.write_file(fn, 0600);
    if (r < 0) {
      cerr << "could not write " << fn << std::endl;
    }
    //cout << "wrote " << bl.length() << " bytes to " << fn << std::endl;
  }

  return 0;
}
<commit_msg>authtool: give generated key specific uid if one is provided on the cli.<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

using namespace std;

#include "config.h"

#include "common/ConfUtils.h"
#include "common/common_init.h"
#include "auth/Crypto.h"
#include "auth/Auth.h"
#include "auth/KeyRing.h"

void usage()
{
  cout << " usage: [--create-keyring] [--gen-key [--set-uid=x]] [--name=<name>] [--caps=<filename>] [--list] [--print-key] <filename>" << std::endl;
  exit(1);
}

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

  const char *me = argv[0];

  const char *fn = 0;
  bool gen_key = false;
  const char *add_key = 0;
  bool list = false;
  bool print_key = false;
  bool create_keyring = false;
  const char *name = "";
  const char *caps_fn = NULL;
  const char *import_keyring = NULL;
  const char *auth_uid_string = NULL;

  FOR_EACH_ARG(args) {
    if (CONF_ARG_EQ("gen-key", 'g')) {
      CONF_SAFE_SET_ARG_VAL(&gen_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("add-key", 'a')) {
      CONF_SAFE_SET_ARG_VAL(&add_key, OPT_STR);
    } else if (CONF_ARG_EQ("name", 'n')) {
      CONF_SAFE_SET_ARG_VAL(&name, OPT_STR);
    } else if (CONF_ARG_EQ("list", 'l')) {
      CONF_SAFE_SET_ARG_VAL(&list, OPT_BOOL);
    } else if (CONF_ARG_EQ("caps", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&caps_fn, OPT_STR);
    } else if (CONF_ARG_EQ("print-key", 'p')) {
      CONF_SAFE_SET_ARG_VAL(&print_key, OPT_BOOL);
    } else if (CONF_ARG_EQ("create-keyring", 'c')) {
      CONF_SAFE_SET_ARG_VAL(&create_keyring, OPT_BOOL);
    } else if (CONF_ARG_EQ("import-keyring", '\0')) {
      CONF_SAFE_SET_ARG_VAL(&import_keyring, OPT_STR);
    } else if (CONF_ARG_EQ("set-uid", 'u')) {
      CONF_SAFE_SET_ARG_VAL(&auth_uid_string, OPT_STR);
    } else if (!fn) {
      fn = args[i];
    } else
      usage();
  }
  if (!fn) {
    cerr << me << ": must specify filename" << std::endl;
    usage();
  }
  if (!(gen_key ||
	add_key ||
	list ||
	caps_fn ||
	print_key ||
	create_keyring ||
	import_keyring)) {
    cerr << "no command specified" << std::endl;
    usage();
  }
  if (gen_key && add_key) {
    cerr << "can't both gen_key and add_key" << std::endl;
    usage();
  }
  if (caps_fn || add_key || gen_key || print_key) {
    if (!name || !(*name)) {
      cerr << "must specify entity name" << std::endl;
      usage();
    }
  }

  // keyring --------
  bool modified = false;
  KeyRing keyring;
  string s = name;
  EntityName ename;
  if (name[0] && !ename.from_str(s)) {
    cerr << "'" << s << "' is not a valid entity name" << std::endl;
    exit(1);
  }

  bufferlist bl;
  int r = 0;
  if (create_keyring) {
    cout << "creating " << fn << std::endl;
    modified = true;
  } else {
    r = bl.read_file(fn, true);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = bl.begin();
	::decode(keyring, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << fn << std::endl;
	exit(1);
      }
    } else {
      cerr << "can't open " << fn << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }

  // write commands
  if (import_keyring) {
    KeyRing other;
    bufferlist obl;
    int r = obl.read_file(import_keyring);
    if (r >= 0) {
      try {
	bufferlist::iterator iter = obl.begin();
	::decode(other, iter);
      } catch (buffer::error *err) {
	cerr << "error reading file " << import_keyring << std::endl;
	exit(1);
      }

      cout << "importing contents of " << import_keyring << " into " << fn << std::endl;
      //other.print(cout);
      keyring.import(other);
      modified = true;
    } else {
      cerr << "can't open " << import_keyring << ": " << strerror(-r) << std::endl;
      exit(1);
    }
  }
  if (gen_key) {
    EntityAuth eauth;
    eauth.key.create(CEPH_CRYPTO_AES);
    keyring.add(ename, eauth);
    modified = true;
  }
  if (add_key) {
    if (!name) {
      cerr << "must specify a name to add a key" << std::endl;
      exit(1);
    }
    EntityAuth eauth;
    string ekey(add_key);
    try {
      eauth.key.decode_base64(ekey);
    } catch (buffer::error *err) {
      cerr << "can't decode key '" << add_key << "'" << std::endl;
      exit(1);
    }
    keyring.add(ename, eauth);
    modified = true;
    cout << "added entity " << ename << " auth " << eauth << std::endl;
  }
  if (caps_fn) {
    ConfFile *cf = new ConfFile(caps_fn);
    if (!cf->parse()) {
      cerr << "could not parse caps file " << caps_fn << std::endl;
      exit(1);
    }
    map<string, bufferlist> caps;
    const char *key_names[] = { "mon", "osd", "mds", NULL };
    for (int i=0; key_names[i]; i++) {
      char *val;
      cf->read("global", key_names[i], &val, NULL);
      if (val) {
        bufferlist bl;
        ::encode(val, bl);
        string s(key_names[i]);
        caps[s] = bl;
        free(val);
      }
    }
    keyring.set_caps(ename, caps);
    modified = true;
  }
  if (auth_uid_string) { //better add it!
    EntityAuth auth;
    keyring.get_auth(ename, auth); //if there's nothing caps will be left blank
    bufferlist bl;
    ::encode(auth_uid_string, bl);
    auth.caps[string("auth_uid")] = bl;
    keyring.set_caps(ename, auth.caps);
  }

  // read commands
  if (list) {
    keyring.print(cout);
  }
  if (print_key) {
    CryptoKey key;
    if (keyring.get_secret(ename, key)) {
      string a;
      key.encode_base64(a);
      cout << a << std::endl;
    } else {
      cerr << "entity " << ename << " not found" << std::endl;
    }
  }

  // write result?
  if (modified) {
    bufferlist bl;
    ::encode(keyring, bl);
    r = bl.write_file(fn, 0600);
    if (r < 0) {
      cerr << "could not write " << fn << std::endl;
    }
    //cout << "wrote " << bl.length() << " bytes to " << fn << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>/* cclive
 * Copyright (C) 2013  Toni Gundogdu <legatvs@gmail.com>
 *
 * This file is part of cclive <http://cclive.sourceforge.net/>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#include <ccinternal>

#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <glib.h>

#ifndef foreach
#define foreach BOOST_FOREACH
#endif

#include <ccoptions>
#include <ccinput>

namespace cc
{

namespace po = boost::program_options;

typedef std::vector<std::string> vst;
typedef po::variables_map pvm;

static bool _has_uri_scheme(const std::string& s)
{
  gchar *p = g_uri_parse_scheme(s.c_str());
  const bool r = (p != NULL);
  g_free(p);
  return r;
}

static bool _push(vst& dst, const std::string& s)
{
  gchar *u = g_uri_unescape_string(s.c_str(), NULL);
  bool r = _has_uri_scheme(u);
  if (r)
    dst.push_back(u);
  g_free(u);
  return r;
}

static void _extract_uris(vst& dst, const std::string& s)
{
  gchar **r = g_uri_list_extract_uris(s.c_str());
  gint i = 0;
  while (r[i] != NULL)
    _push(dst, r[i++]);
  g_strfreev(r);
}

static std::string _read_file(const std::string& fpath)
{
  GError *e = NULL;
  gchar *c = NULL;
  std::string r;

  if (g_file_get_contents(fpath.c_str(), &c, NULL, &e) ==FALSE)
    {
      if (e != NULL)
        {
          static const char E[] = "error: %s: while reading file: %s";
          std::clog << (boost::format(E) % fpath % e->message).str()
                    << std::endl;
          g_error_free(e);
        }
    }
  else
    r = c;
  g_free(c);
  return r;
}

static void _unable_determine(const std::string& s)
{
  static const char E[] =
    "error: ignoring input value `%s': not an URL or a file";
  std::clog << (boost::format(E) % s).str() << std::endl;
}

static void _have_rargs(vst& dst, const pvm& m)
{
  const vst &args = m["url"].as<vst>();
  foreach (const std::string &a, args)
  {
    if (g_file_test(a.c_str(), G_FILE_TEST_IS_REGULAR) ==TRUE)
      _extract_uris(dst, _read_file(a));
    else
      {
        if (!_push(dst, a))
          _unable_determine(a);
      }
  }
}

static std::string _read_from(std::istream& is)
{
  std::string s;
  char c;
  while (is.get(c))
    s += c;
  return s;
}

static void _no_rargs(vst& dst, const pvm& m)
{
  _extract_uris(dst, _read_from(std::cin));
}

template<class T> static T _duplicates(T first, T last)
{
  while (first != last)
    {
      T next(first);
      last = std::remove(++next, last, *first);
      first = next;
    }
  return last;
}

void input::_parse()
{
  const po::variables_map m = cc::opts.map();

  if (m.count("url") ==0)
    _no_rargs(_urls, m);
  else
    _have_rargs(_urls, m);

  _urls.erase(_duplicates(_urls.begin(), _urls.end()), _urls.end());

  if (_urls.size() ==0)
    throw std::runtime_error("no input URL");
}

} // namespace cc

// vim: set ts=2 sw=2 tw=72 expandtab:
<commit_msg>FIX: cc/input.cpp: error: "clog" is not a member of "std"<commit_after>/* cclive
 * Copyright (C) 2013  Toni Gundogdu <legatvs@gmail.com>
 *
 * This file is part of cclive <http://cclive.sourceforge.net/>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#include <ccinternal>

#include <iostream>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <glib.h>

#ifndef foreach
#define foreach BOOST_FOREACH
#endif

#include <ccoptions>
#include <ccinput>

namespace cc
{

namespace po = boost::program_options;

typedef std::vector<std::string> vst;
typedef po::variables_map pvm;

static bool _has_uri_scheme(const std::string& s)
{
  gchar *p = g_uri_parse_scheme(s.c_str());
  const bool r = (p != NULL);
  g_free(p);
  return r;
}

static bool _push(vst& dst, const std::string& s)
{
  gchar *u = g_uri_unescape_string(s.c_str(), NULL);
  bool r = _has_uri_scheme(u);
  if (r)
    dst.push_back(u);
  g_free(u);
  return r;
}

static void _extract_uris(vst& dst, const std::string& s)
{
  gchar **r = g_uri_list_extract_uris(s.c_str());
  gint i = 0;
  while (r[i] != NULL)
    _push(dst, r[i++]);
  g_strfreev(r);
}

static std::string _read_file(const std::string& fpath)
{
  GError *e = NULL;
  gchar *c = NULL;
  std::string r;

  if (g_file_get_contents(fpath.c_str(), &c, NULL, &e) ==FALSE)
    {
      if (e != NULL)
        {
          static const char E[] = "error: %s: while reading file: %s";
          std::clog << (boost::format(E) % fpath % e->message).str()
                    << std::endl;
          g_error_free(e);
        }
    }
  else
    r = c;
  g_free(c);
  return r;
}

static void _unable_determine(const std::string& s)
{
  static const char E[] =
    "error: ignoring input value `%s': not an URL or a file";
  std::clog << (boost::format(E) % s).str() << std::endl;
}

static void _have_rargs(vst& dst, const pvm& m)
{
  const vst &args = m["url"].as<vst>();
  foreach (const std::string &a, args)
  {
    if (g_file_test(a.c_str(), G_FILE_TEST_IS_REGULAR) ==TRUE)
      _extract_uris(dst, _read_file(a));
    else
      {
        if (!_push(dst, a))
          _unable_determine(a);
      }
  }
}

static std::string _read_from(std::istream& is)
{
  std::string s;
  char c;
  while (is.get(c))
    s += c;
  return s;
}

static void _no_rargs(vst& dst, const pvm& m)
{
  _extract_uris(dst, _read_from(std::cin));
}

template<class T> static T _duplicates(T first, T last)
{
  while (first != last)
    {
      T next(first);
      last = std::remove(++next, last, *first);
      first = next;
    }
  return last;
}

void input::_parse()
{
  const po::variables_map m = cc::opts.map();

  if (m.count("url") ==0)
    _no_rargs(_urls, m);
  else
    _have_rargs(_urls, m);

  _urls.erase(_duplicates(_urls.begin(), _urls.end()), _urls.end());

  if (_urls.size() ==0)
    throw std::runtime_error("no input URL");
}

} // namespace cc

// vim: set ts=2 sw=2 tw=72 expandtab:
<|endoftext|>


<commit_before>// --------------------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// --------------------------------------------------------------------------------------------------------------------

// Malmo:
#include <AgentHost.h>
#include <ClientPool.h>
#include <MissionInitSpec.h>
#include <StringServer.h>
#include <TCPClient.h>
#include <WorldState.h>
using namespace malmo;

// Boost:
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
using namespace boost::posix_time;

// STL:
#include <iostream>
using namespace std;

const short width = 240;
const int channels = 3;
const int num_pixels = width * width * channels;
const int num_frames = 50;
const milliseconds sleep_time(100);
const int commands_port = 10030;

boost::shared_ptr<MissionInitSpec> mission_init;

void handleControlMessages(TimestampedString message)
{
    // this will do nothing due to the lack of a header.
}

void runGameShim( )
{
    boost::asio::io_service io_service;
    boost::this_thread::sleep(sleep_time);

    mission_init->setClientCommandsPort(commands_port);
    const bool pretty_print = false;
    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentMissionControlPort(), mission_init->getAsXML(pretty_print), true);

    vector<unsigned char> buffer(num_pixels);
    for (int i = 0; i < num_frames; i++){
        for (int r = 0, p = 0; r < width; r++){
            for (int c = 0; c < width; c++, p += 3){
                buffer[p] = r;
                buffer[p + 2] = width - c;
            }
        }

        int boxPos = (i * 200) / num_frames;
        for (int r = 0; r < 40; r++){
            for (int c = 0; c < 40; c++){
                int p = (boxPos + r) * width * 3 + (boxPos + c) * 3;
                buffer[p] = 255;
                buffer[p + 1] = 255;
                buffer[p + 2] = 255;
            }
        }

        buffer[0] = i;
        SendOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentVideoPort(), buffer, true);
        {
            std::stringstream observation;
            observation << "{" << '"' << "frame" << '"' << ":" << i << ", " << '"' << "step" << '"' << " : 0 }";
            SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentObservationsPort(), observation.str(), true);
        }

        boost::this_thread::sleep(sleep_time / 2);

        {
            std::stringstream observation;
            observation << "{" << '"' << "frame" << '"' << ":" << i << ", " << '"' << "step" << '"' << " : 1 }";
            SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentObservationsPort(), observation.str(), true);
        }

        boost::this_thread::sleep(sleep_time / 2);
    }

    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentRewardsPort(), "{\"Reward\" : 100 }", true);

    std::stringstream end_xml;
    end_xml << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><MissionEnded xmlns=\"http://ProjectMalmo.microsoft.com\"><Status>ENDED</Status><HumanReadableStatus>Mission ended normally</HumanReadableStatus><FinalReward>123.58</FinalReward></MissionEnded>";
    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentMissionControlPort(), end_xml.str(), true);

    io_service.run();
}

void handleCommandMessages(TimestampedString message)
{
    cout << message.text << endl;
}

int runAgentHost(std::string filename)
{
    // Specify a (hopefully) non-existant location:
    bool threwError = false;
    try{
        MissionRecordSpec mission_record("c://path//that//probably//does//not//exist//output.tgz");
    }
    catch (const exception&){
        threwError = true;
    }

    if (!threwError){
        cout << "Was able to create MissionRecordSpec with bad path." << endl;
        return EXIT_FAILURE;
    }

    MissionSpec mission;
    mission.timeLimitInSeconds( 10 );
    mission.requestVideo( 240, 240 );

    MissionRecordSpec mission_record(filename);
    mission_record.recordMP4(10, 400000);
    mission_record.recordObservations();
    mission_record.recordRewards();
    mission_record.recordCommands();

    {
        MissionRecord deleteTest(mission_record);
    }
    {
        MissionRecord deleteTest(mission_record);
    }

    threwError = false;
    try{
        std::string temp_dir = mission_record.getTemporaryDirectory();
    }
    catch (const exception&){
        threwError = true;
    }

    if (!threwError){
        cout << "Was able to access temporary directory before record creation." << endl;
        return EXIT_FAILURE;
    }

    ClientInfo client_info( "127.0.0.1" );

    boost::asio::io_service io_service;

    StringServer clientMissionControlServer(io_service, client_info.port, handleControlMessages);
    clientMissionControlServer.confirmWithFixedReply( "MALMOOK" );
    clientMissionControlServer.expectSizeHeader(false);
    clientMissionControlServer.start();

    StringServer clientCommandsServer( io_service, commands_port, handleCommandMessages);
    clientCommandsServer.expectSizeHeader(false);
    clientCommandsServer.start();

    boost::thread bt(boost::bind(&boost::asio::io_service::run, &io_service));

    boost::this_thread::sleep(sleep_time);

    AgentHost agent_host;
    try {
        agent_host.startMission(mission, mission_record);
    }
    catch (const exception& e) {
        cout << "Error starting mission: " << e.what() << "\n" << endl;
        return EXIT_FAILURE;
    }

    try{
        std::string temp_dir = mission_record.getTemporaryDirectory();
    }
    catch (const exception&){
        cout << "Unable to access temporary directory after mission start.";
        return EXIT_FAILURE;
    }

    mission_init = agent_host.getMissionInit();

    boost::thread gameShim(runGameShim);

    boost::shared_ptr<WorldState> world_state;

    cout << "Waiting for the mission to start" << flush;
    do {
        cout << "." << flush;
        boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        world_state = agent_host.getWorldState();
        for (auto e : world_state->errors)
            cout << "Error: " << e.text << endl;
    } while (!world_state->is_mission_running);
    cout << endl;

    do {
        {
            ostringstream oss;
            oss << "turn " << rand() / float(RAND_MAX) << "\n";
            agent_host.sendCommand(oss.str());
        }
        {
            ostringstream oss;
            oss << "move " << rand() / float(RAND_MAX) << "\n";
            agent_host.sendCommand(oss.str());
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(500));
        world_state = agent_host.getWorldState();
        cout << "video,observations,rewards received: "
            << world_state->number_of_video_frames_since_last_state << ","
            << world_state->number_of_observations_since_last_state << ","
            << world_state->number_of_rewards_since_last_state << endl;
        cout << "video,observations,rewards stored: "
            << world_state->video_frames.size() << ","
            << world_state->observations.size() << ","
            << world_state->rewards.size() << endl;
        if (!world_state->rewards.empty())
            cout << "Summed reward: " << world_state->rewards.front().value << endl;
        for (auto e : world_state->errors)
            cout << "Error: " << e.text << endl;
    } while (world_state->is_mission_running);

    cout << "Mission has stopped." << endl;

    gameShim.join();
    io_service.stop();
    bt.join();

    return EXIT_SUCCESS;
}

int main()
{
    std::string filename = "persistence.tgz";
    boost::filesystem::remove(filename);
    int code = runAgentHost(filename);

    if (code != EXIT_SUCCESS){
        return code;
    }

    if (boost::filesystem::exists(filename)){
        return EXIT_SUCCESS;
    }

    return EXIT_FAILURE;
}
<commit_msg>Fix: test_persistence.cpp can no longer assume 10000 is free, since using for integration tests.<commit_after>// --------------------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// --------------------------------------------------------------------------------------------------------------------

// Malmo:
#include <AgentHost.h>
#include <ClientPool.h>
#include <MissionInitSpec.h>
#include <StringServer.h>
#include <TCPClient.h>
#include <WorldState.h>
using namespace malmo;

// Boost:
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
using namespace boost::posix_time;

// STL:
#include <iostream>
using namespace std;

const short width = 240;
const int channels = 3;
const int num_pixels = width * width * channels;
const int num_frames = 50;
const milliseconds sleep_time(100);
const int commands_port = 10030;

boost::shared_ptr<MissionInitSpec> mission_init;

void handleControlMessages(TimestampedString message)
{
    // this will do nothing due to the lack of a header.
}

void runGameShim( )
{
    boost::asio::io_service io_service;
    boost::this_thread::sleep(sleep_time);

    mission_init->setClientCommandsPort(commands_port);
    const bool pretty_print = false;
    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentMissionControlPort(), mission_init->getAsXML(pretty_print), true);

    vector<unsigned char> buffer(num_pixels);
    for (int i = 0; i < num_frames; i++){
        for (int r = 0, p = 0; r < width; r++){
            for (int c = 0; c < width; c++, p += 3){
                buffer[p] = r;
                buffer[p + 2] = width - c;
            }
        }

        int boxPos = (i * 200) / num_frames;
        for (int r = 0; r < 40; r++){
            for (int c = 0; c < 40; c++){
                int p = (boxPos + r) * width * 3 + (boxPos + c) * 3;
                buffer[p] = 255;
                buffer[p + 1] = 255;
                buffer[p + 2] = 255;
            }
        }

        buffer[0] = i;
        SendOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentVideoPort(), buffer, true);
        {
            std::stringstream observation;
            observation << "{" << '"' << "frame" << '"' << ":" << i << ", " << '"' << "step" << '"' << " : 0 }";
            SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentObservationsPort(), observation.str(), true);
        }

        boost::this_thread::sleep(sleep_time / 2);

        {
            std::stringstream observation;
            observation << "{" << '"' << "frame" << '"' << ":" << i << ", " << '"' << "step" << '"' << " : 1 }";
            SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentObservationsPort(), observation.str(), true);
        }

        boost::this_thread::sleep(sleep_time / 2);
    }

    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentRewardsPort(), "{\"Reward\" : 100 }", true);

    std::stringstream end_xml;
    end_xml << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><MissionEnded xmlns=\"http://ProjectMalmo.microsoft.com\"><Status>ENDED</Status><HumanReadableStatus>Mission ended normally</HumanReadableStatus><FinalReward>123.58</FinalReward></MissionEnded>";
    SendStringOverTCP(io_service, mission_init->getAgentAddress(), mission_init->getAgentMissionControlPort(), end_xml.str(), true);

    io_service.run();
}

void handleCommandMessages(TimestampedString message)
{
    cout << message.text << endl;
}

int runAgentHost(std::string filename)
{
    // Specify a (hopefully) non-existant location:
    bool threwError = false;
    try{
        MissionRecordSpec mission_record("c://path//that//probably//does//not//exist//output.tgz");
    }
    catch (const exception&){
        threwError = true;
    }

    if (!threwError){
        cout << "Was able to create MissionRecordSpec with bad path." << endl;
        return EXIT_FAILURE;
    }

    MissionSpec mission;
    mission.timeLimitInSeconds( 10 );
    mission.requestVideo( 240, 240 );

    MissionRecordSpec mission_record(filename);
    mission_record.recordMP4(10, 400000);
    mission_record.recordObservations();
    mission_record.recordRewards();
    mission_record.recordCommands();

    {
        MissionRecord deleteTest(mission_record);
    }
    {
        MissionRecord deleteTest(mission_record);
    }

    threwError = false;
    try{
        std::string temp_dir = mission_record.getTemporaryDirectory();
    }
    catch (const exception&){
        threwError = true;
    }

    if (!threwError){
        cout << "Was able to access temporary directory before record creation." << endl;
        return EXIT_FAILURE;
    }

    ClientInfo client_info( "127.0.0.1", 10031 );
    ClientPool client_pool;
    client_pool.add( client_info );

    boost::asio::io_service io_service;

    StringServer clientMissionControlServer(io_service, client_info.port, handleControlMessages);
    clientMissionControlServer.confirmWithFixedReply( "MALMOOK" );
    clientMissionControlServer.expectSizeHeader(false);
    clientMissionControlServer.start();

    StringServer clientCommandsServer( io_service, commands_port, handleCommandMessages);
    clientCommandsServer.expectSizeHeader(false);
    clientCommandsServer.start();

    boost::thread bt(boost::bind(&boost::asio::io_service::run, &io_service));

    boost::this_thread::sleep(sleep_time);

    AgentHost agent_host;
    try {
        agent_host.startMission( mission, client_pool, mission_record, 0, "" );
    }
    catch (const exception& e) {
        cout << "Error starting mission: " << e.what() << "\n" << endl;
        return EXIT_FAILURE;
    }

    try{
        std::string temp_dir = mission_record.getTemporaryDirectory();
    }
    catch (const exception&){
        cout << "Unable to access temporary directory after mission start.";
        return EXIT_FAILURE;
    }

    mission_init = agent_host.getMissionInit();

    boost::thread gameShim(runGameShim);

    boost::shared_ptr<WorldState> world_state;

    cout << "Waiting for the mission to start" << flush;
    do {
        cout << "." << flush;
        boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        world_state = agent_host.getWorldState();
        for (auto e : world_state->errors)
            cout << "Error: " << e.text << endl;
    } while (!world_state->is_mission_running);
    cout << endl;

    do {
        {
            ostringstream oss;
            oss << "turn " << rand() / float(RAND_MAX) << "\n";
            agent_host.sendCommand(oss.str());
        }
        {
            ostringstream oss;
            oss << "move " << rand() / float(RAND_MAX) << "\n";
            agent_host.sendCommand(oss.str());
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(500));
        world_state = agent_host.getWorldState();
        cout << "video,observations,rewards received: "
            << world_state->number_of_video_frames_since_last_state << ","
            << world_state->number_of_observations_since_last_state << ","
            << world_state->number_of_rewards_since_last_state << endl;
        cout << "video,observations,rewards stored: "
            << world_state->video_frames.size() << ","
            << world_state->observations.size() << ","
            << world_state->rewards.size() << endl;
        if (!world_state->rewards.empty())
            cout << "Summed reward: " << world_state->rewards.front().value << endl;
        for (auto e : world_state->errors)
            cout << "Error: " << e.text << endl;
    } while (world_state->is_mission_running);

    cout << "Mission has stopped." << endl;

    gameShim.join();
    io_service.stop();
    bt.join();

    return EXIT_SUCCESS;
}

int main()
{
    std::string filename = "persistence.tgz";
    boost::filesystem::remove(filename);
    int code = runAgentHost(filename);

    if (code != EXIT_SUCCESS){
        return code;
    }

    if (boost::filesystem::exists(filename)){
        return EXIT_SUCCESS;
    }

    return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>#include "libircppclient.hpp"

/*
 * TODO: These functions should return a value instead
 * of nothing.
 * Put returned errors in some kind of error stream?
 */

/*
 * While there shouldn't be a reason to not pass an
 * argument to a command that requires it, it may still happen.
 * Return errors for those exceptions?
 */

namespace irc {

void client::nick(const std::string &nick)
{
    if (nick.empty())
        return;

    con.write("NICK " + nick);
}

void client::join(const std::string &chan, const std::string &key)
{
    if (chan.empty())
        return;

    if (key.empty())
        con.write("JOIN " + chan);
    else
        con.write("JOIN " + chan + ' ' + key);
}

void client::msg(const std::string &target, const std::string &message)
{
    if (message.empty() || target.empty())
        return;

    /* Applies to channels and nicks */
    con.write("PRIVMSG " + target + " :" + message);
}

void client::quit(const std::string &message)
{
    if (message.empty())
        con.write("QUIT");
    else
        con.write("QUIT :" + message);

    stop();
}

/* ns irc */
}
<commit_msg>Variable names to match command abilities<commit_after>#include "libircppclient.hpp"

/*
 * TODO: These functions should return a value instead
 * of nothing.
 * Put returned errors in some kind of error stream?
 */

/*
 * While there shouldn't be a reason to not pass an
 * argument to a command that requires it, it may still happen.
 * Return errors for those exceptions?
 */

namespace irc {

void client::nick(const std::string &nick)
{
    if (nick.empty())
        return;

    con.write("NICK " + nick);
}

void client::join(const std::string &chans, const std::string &keys)
{
    if (keys.empty())
        con.write("JOIN " + chans);
    else
        con.write("JOIN " + chans + ' ' + keys);
}

void client::msg(const std::string &target, const std::string &message)
{
    if (message.empty() || target.empty())
        return;

    /* Applies to channels and nicks */
    con.write("PRIVMSG " + target + " :" + message);
}

void client::quit(const std::string &message)
{
    if (message.empty())
        con.write("QUIT");
    else
        con.write("QUIT :" + message);

    stop();
}

/* ns irc */
}
<|endoftext|>


<commit_before>
/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 <aws/core/utils/stream/SimpleStreamBuf.h>

#include <algorithm>
#include <cassert>

namespace Aws
{
namespace Utils
{
namespace Stream
{

static const uint32_t DEFAULT_BUFFER_SIZE = 100;
static const char* SIMPLE_STREAMBUF_ALLOCATION_TAG = "SimpleStreamBufTag";

SimpleStreamBuf::SimpleStreamBuf() :
    m_buffer(nullptr),
    m_bufferSize(0)
{
    m_buffer = Aws::NewArray<char>(DEFAULT_BUFFER_SIZE, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    m_bufferSize = DEFAULT_BUFFER_SIZE;

    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin, end);
    setg(begin, begin, begin);
}

SimpleStreamBuf::SimpleStreamBuf(const Aws::String& value) :
    m_buffer(nullptr),
    m_bufferSize(0)
{
    size_t baseSize = std::max(value.size(), static_cast<std::size_t>(DEFAULT_BUFFER_SIZE));

    m_buffer = Aws::NewArray<char>(baseSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    m_bufferSize = baseSize;

    memcpy(m_buffer, value.c_str(), value.size());

    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin + value.size(), end);
    setg(begin, begin, begin);
}

SimpleStreamBuf::~SimpleStreamBuf()
{
    if(m_buffer)
    {
        Aws::DeleteArray<char>(m_buffer);
        m_buffer = nullptr;
    }

    m_bufferSize = 0;
}

std::streampos SimpleStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which)
{
    if (dir == std::ios_base::beg)
    {
        return seekpos(off, which);
    }
    else if (dir == std::ios_base::end)
    {
        return seekpos((pptr() - m_buffer) - off, which);
    }
    else if (dir == std::ios_base::cur)
    {
        if(which == std::ios_base::in)
        {
            return seekpos((gptr() - m_buffer) + off, which);
        }
        else
        {
            return seekpos((pptr() - m_buffer) + off, which);
        }
    }

    return off_type(-1);
}

std::streampos SimpleStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which)
{
    size_t maxSeek = pptr() - m_buffer;
    assert(static_cast<size_t>(pos) <= maxSeek);
    if (static_cast<size_t>(pos) > maxSeek)
    {
        return pos_type(off_type(-1));
    }

    if (which == std::ios_base::in)
    {
        setg(m_buffer, m_buffer + static_cast<size_t>(pos), pptr());
    }

    if (which == std::ios_base::out)
    {
        setp(m_buffer + static_cast<size_t>(pos), epptr());
    }

    return pos;
}

bool SimpleStreamBuf::GrowBuffer()
{
    size_t currentSize = m_bufferSize;
    size_t newSize = currentSize * 2;

    char* newBuffer = Aws::NewArray<char>(newSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    if(newBuffer == nullptr)
    {
        return false;
    }

    if(currentSize > 0)
    {
        memcpy(newBuffer, m_buffer, currentSize);
    }

    if(m_buffer)
    {
        Aws::DeleteArray<char>(m_buffer);
    }

    m_buffer = newBuffer;
    m_bufferSize = newSize;

    return true;
}

int SimpleStreamBuf::overflow (int c)
{
    auto endOfFile = std::char_traits< char >::eof();
    if(c == endOfFile)
    {
        return endOfFile;
    }

    char* old_begin = m_buffer;

    char *old_pptr = pptr();
    char *old_gptr = gptr();
    char *old_egptr = egptr();

    size_t currentWritePosition = m_bufferSize;

    if(!GrowBuffer())
    {
        return endOfFile;
    }

    char* new_begin = m_buffer;
    char* new_end = new_begin + m_bufferSize;

    setp(new_begin + (old_pptr - old_begin) + 1, new_end);
    setg(new_begin, new_begin + (old_gptr - old_begin), new_begin + (old_egptr - old_begin));

    auto val = std::char_traits< char >::to_char_type(c);
    *(new_begin + currentWritePosition) = val;

    return c;
}

std::streamsize SimpleStreamBuf::xsputn(const char* s, std::streamsize n)
{
    std::streamsize writeCount = 0;
    while(writeCount < n)
    {
        char* current_pptr = pptr();
        char* current_epptr = epptr();

        if (current_pptr < current_epptr)
        {
            std::size_t copySize = std::min(static_cast< std::size_t >(n - writeCount),
                                            static_cast< std::size_t >(current_epptr - current_pptr));

            memcpy(current_pptr, s + writeCount, copySize);
            writeCount += copySize;
            setp(current_pptr + copySize, current_epptr);
            setg(m_buffer, gptr(), pptr());
        }
        else if (overflow(std::char_traits< char >::to_int_type(*(s + writeCount))) != std::char_traits<char>::eof())
        {
            writeCount++;
        }
        else
        {
            return writeCount;
        }
    }

    return writeCount;
}

Aws::String SimpleStreamBuf::str()
{
    return Aws::String(m_buffer, pptr());
}

int SimpleStreamBuf::underflow()
{
    if(egptr() != pptr())
    {
        setg(m_buffer, gptr(), pptr());
    }

    if(gptr() != egptr())
    {
        return std::char_traits< char >::to_int_type(*gptr());
    }
    else
    {
        return std::char_traits< char >::eof();
    }
}

void SimpleStreamBuf::str(const Aws::String& value)
{
    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin, end);
    setg(begin, begin, begin);

    xsputn(value.c_str(), value.size());
}

}
}
}<commit_msg>Fix platform-dependent build issues related to memcpy<commit_after>
/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 <aws/core/utils/stream/SimpleStreamBuf.h>

#include <algorithm>
#include <cassert>
#include <cstring>

namespace Aws
{
namespace Utils
{
namespace Stream
{

static const uint32_t DEFAULT_BUFFER_SIZE = 100;
static const char* SIMPLE_STREAMBUF_ALLOCATION_TAG = "SimpleStreamBufTag";

SimpleStreamBuf::SimpleStreamBuf() :
    m_buffer(nullptr),
    m_bufferSize(0)
{
    m_buffer = Aws::NewArray<char>(DEFAULT_BUFFER_SIZE, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    m_bufferSize = DEFAULT_BUFFER_SIZE;

    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin, end);
    setg(begin, begin, begin);
}

SimpleStreamBuf::SimpleStreamBuf(const Aws::String& value) :
    m_buffer(nullptr),
    m_bufferSize(0)
{
    size_t baseSize = std::max(value.size(), static_cast<std::size_t>(DEFAULT_BUFFER_SIZE));

    m_buffer = Aws::NewArray<char>(baseSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    m_bufferSize = baseSize;

    std::memcpy(m_buffer, value.c_str(), value.size());

    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin + value.size(), end);
    setg(begin, begin, begin);
}

SimpleStreamBuf::~SimpleStreamBuf()
{
    if(m_buffer)
    {
        Aws::DeleteArray<char>(m_buffer);
        m_buffer = nullptr;
    }

    m_bufferSize = 0;
}

std::streampos SimpleStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which)
{
    if (dir == std::ios_base::beg)
    {
        return seekpos(off, which);
    }
    else if (dir == std::ios_base::end)
    {
        return seekpos((pptr() - m_buffer) - off, which);
    }
    else if (dir == std::ios_base::cur)
    {
        if(which == std::ios_base::in)
        {
            return seekpos((gptr() - m_buffer) + off, which);
        }
        else
        {
            return seekpos((pptr() - m_buffer) + off, which);
        }
    }

    return off_type(-1);
}

std::streampos SimpleStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which)
{
    size_t maxSeek = pptr() - m_buffer;
    assert(static_cast<size_t>(pos) <= maxSeek);
    if (static_cast<size_t>(pos) > maxSeek)
    {
        return pos_type(off_type(-1));
    }

    if (which == std::ios_base::in)
    {
        setg(m_buffer, m_buffer + static_cast<size_t>(pos), pptr());
    }

    if (which == std::ios_base::out)
    {
        setp(m_buffer + static_cast<size_t>(pos), epptr());
    }

    return pos;
}

bool SimpleStreamBuf::GrowBuffer()
{
    size_t currentSize = m_bufferSize;
    size_t newSize = currentSize * 2;

    char* newBuffer = Aws::NewArray<char>(newSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
    if(newBuffer == nullptr)
    {
        return false;
    }

    if(currentSize > 0)
    {
        std::memcpy(newBuffer, m_buffer, currentSize);
    }

    if(m_buffer)
    {
        Aws::DeleteArray<char>(m_buffer);
    }

    m_buffer = newBuffer;
    m_bufferSize = newSize;

    return true;
}

int SimpleStreamBuf::overflow (int c)
{
    auto endOfFile = std::char_traits< char >::eof();
    if(c == endOfFile)
    {
        return endOfFile;
    }

    char* old_begin = m_buffer;

    char *old_pptr = pptr();
    char *old_gptr = gptr();
    char *old_egptr = egptr();

    size_t currentWritePosition = m_bufferSize;

    if(!GrowBuffer())
    {
        return endOfFile;
    }

    char* new_begin = m_buffer;
    char* new_end = new_begin + m_bufferSize;

    setp(new_begin + (old_pptr - old_begin) + 1, new_end);
    setg(new_begin, new_begin + (old_gptr - old_begin), new_begin + (old_egptr - old_begin));

    auto val = std::char_traits< char >::to_char_type(c);
    *(new_begin + currentWritePosition) = val;

    return c;
}

std::streamsize SimpleStreamBuf::xsputn(const char* s, std::streamsize n)
{
    std::streamsize writeCount = 0;
    while(writeCount < n)
    {
        char* current_pptr = pptr();
        char* current_epptr = epptr();

        if (current_pptr < current_epptr)
        {
            std::size_t copySize = std::min(static_cast< std::size_t >(n - writeCount),
                                            static_cast< std::size_t >(current_epptr - current_pptr));

            std::memcpy(current_pptr, s + writeCount, copySize);
            writeCount += copySize;
            setp(current_pptr + copySize, current_epptr);
            setg(m_buffer, gptr(), pptr());
        }
        else if (overflow(std::char_traits< char >::to_int_type(*(s + writeCount))) != std::char_traits<char>::eof())
        {
            writeCount++;
        }
        else
        {
            return writeCount;
        }
    }

    return writeCount;
}

Aws::String SimpleStreamBuf::str()
{
    return Aws::String(m_buffer, pptr());
}

int SimpleStreamBuf::underflow()
{
    if(egptr() != pptr())
    {
        setg(m_buffer, gptr(), pptr());
    }

    if(gptr() != egptr())
    {
        return std::char_traits< char >::to_int_type(*gptr());
    }
    else
    {
        return std::char_traits< char >::eof();
    }
}

void SimpleStreamBuf::str(const Aws::String& value)
{
    char* begin = m_buffer;
    char* end = begin + m_bufferSize;

    setp(begin, end);
    setg(begin, begin, begin);

    xsputn(value.c_str(), value.size());
}

}
}
}<|endoftext|>


<commit_before>#ifndef __PROXY_HPP__
#define __PROXY_HPP__
#include <string>

class Proxy : public Notifier , public IProxy
{

    public:
        //static const std::string NAME = "Proxy";

        /**
         * Constructor
         */
        Proxy( const std::string & proxyName, void * data = NULL )
        {
            this->m_proxyName = (!proxyName.empty())?proxyName:"Proxy";
            if (data != NULL)
                setData(data);
        }

        /**
         * Get the proxy name
         */
        virtual std::string getName() const
        {
            return m_proxyName;
        }

        /**
         * Set the data object
         */
        virtual void setData(IProxy::Context  data )
        {
            m_data = data;
        }

        /**
         * Get the data object
         */
        virtual IProxy::Context getData()
        {
            return m_data;
        }

        /**
         * Called by the Model when the Proxy is registered
         */
        void onRegister( ) {}

        /**
         * Called by the Model when the Proxy is removed
         */
        void onRemove( ) {}

        // the proxy name
    protected:
        std::string m_proxyName;

        // the data object
		IProxy::Context  m_data;
};

#endif //

<commit_msg> update proxy data<commit_after>#ifndef __PROXY_HPP__
#define __PROXY_HPP__
#include <string>

class Proxy : public Notifier , public IProxy
{

    public:
        //static const std::string NAME = "Proxy";

        /**
         * Constructor
         */
        Proxy( const std::string & proxyName, IProxy::Context data = IProxy::Context() )
        {
            this->m_proxyName = (!proxyName.empty())?proxyName:"Proxy";
			setData(data);
        }

        /**
         * Get the proxy name
         */
        virtual std::string getName() const
        {
            return m_proxyName;
        }

        /**
         * Set the data object
         */
        virtual void setData(IProxy::Context  data )
        {
            m_data = data;
        }

        /**
         * Get the data object
         */
        virtual IProxy::Context getData()
        {
            return m_data;
        }

        /**
         * Called by the Model when the Proxy is registered
         */
        void onRegister( ) {}

        /**
         * Called by the Model when the Proxy is removed
         */
        void onRemove( ) {}

        // the proxy name
    protected:
        std::string m_proxyName;

        // the data object
		IProxy::Context  m_data;
};

#endif //

<|endoftext|>


<commit_before><commit_msg>fix copy ctor<commit_after><|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2012 Imetric 3D GmbH                                    *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <algorithm>
#endif

#include "Segmentation.h"
#include "Algorithm.h"
#include "Approximation.h"

using namespace MeshCore;

void MeshSurfaceSegment::Initialize(unsigned long)
{
}

bool MeshSurfaceSegment::TestInitialFacet(unsigned long) const
{
    return true;
}

void MeshSurfaceSegment::AddFacet(const MeshFacet&)
{
}

void MeshSurfaceSegment::AddSegment(const std::vector<unsigned long>& segm)
{
    if (segm.size() >= minFacets) {
        segments.push_back(segm);
    }
}

MeshSegment MeshSurfaceSegment::FindSegment(unsigned long index) const
{
    for (std::vector<MeshSegment>::const_iterator it = segments.begin(); it != segments.end(); ++it) {
        if (std::find(it->begin(), it->end(), index) != it->end())
            return *it;
    }

    return MeshSegment();
}

// --------------------------------------------------------

MeshDistancePlanarSegment::MeshDistancePlanarSegment(const MeshKernel& mesh, unsigned long minFacets, float tol)
  : MeshDistanceSurfaceSegment(mesh, minFacets, tol), fitter(new PlaneFit)
{
}

MeshDistancePlanarSegment::~MeshDistancePlanarSegment()
{
    delete fitter;
}

void MeshDistancePlanarSegment::Initialize(unsigned long index)
{
    fitter->Clear();

    MeshGeomFacet triangle = kernel.GetFacet(index);
    basepoint = triangle.GetGravityPoint();
    normal = triangle.GetNormal();
    fitter->AddPoint(triangle._aclPoints[0]);
    fitter->AddPoint(triangle._aclPoints[1]);
    fitter->AddPoint(triangle._aclPoints[2]);
}

bool MeshDistancePlanarSegment::TestFacet (const MeshFacet& face) const
{
    if (!fitter->Done())
        fitter->Fit();
    MeshGeomFacet triangle = kernel.GetFacet(face);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToPlane(triangle._aclPoints[i])) > tolerance)
            return false;
    }

    return true;
}

void MeshDistancePlanarSegment::AddFacet(const MeshFacet& face)
{
    MeshGeomFacet triangle = kernel.GetFacet(face);
    fitter->AddPoint(triangle.GetGravityPoint());
}

// --------------------------------------------------------

PlaneSurfaceFit::PlaneSurfaceFit()
    : fitter(new PlaneFit)
{
}

PlaneSurfaceFit::PlaneSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& n)
    : basepoint(b)
    , normal(n)
    , fitter(nullptr)
{
}

PlaneSurfaceFit::~PlaneSurfaceFit()
{
    delete fitter;
}

void PlaneSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();

        basepoint = tria.GetGravityPoint();
        normal = tria.GetNormal();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool PlaneSurfaceFit::TestTriangle(const MeshGeomFacet&) const
{
    return true;
}

void PlaneSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter)
        fitter->AddPoint(tria.GetGravityPoint());
}

bool PlaneSurfaceFit::Done() const
{
    if (!fitter)
        return true;
    else
        return fitter->Done();
}

float PlaneSurfaceFit::Fit()
{
    if (!fitter)
        return 0;
    else
        return fitter->Fit();
}

float PlaneSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    if (!fitter)
        return pnt.DistanceToPlane(basepoint, normal);
    else
        return fitter->GetDistanceToPlane(pnt);
}

// --------------------------------------------------------

CylinderSurfaceFit::CylinderSurfaceFit()
    : fitter(new CylinderFit)
{
    axis.Set(0,0,0);
    radius = FLOAT_MAX;
}

/*!
 * \brief CylinderSurfaceFit::CylinderSurfaceFit
 * Set a pre-defined cylinder. Internal cylinder fits are not done, then.
 */
CylinderSurfaceFit::CylinderSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& a, float r)
    : basepoint(b)
    , axis(a)
    , radius(r)
    , fitter(nullptr)
{
}

CylinderSurfaceFit::~CylinderSurfaceFit()
{
    delete fitter;
}

void CylinderSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

void CylinderSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool CylinderSurfaceFit::TestTriangle(const MeshGeomFacet& tria) const
{
    // This is to filter out triangles whose points lie on the cylinder and
    // that whose normals are more or less parallel to the cylinder axis
    float dot = axis.Dot(tria.GetNormal());
    return fabs(dot) < 0.5f;
}

bool CylinderSurfaceFit::Done() const
{
    if (fitter) {
        return fitter->Done();
    }

    return true;
}

float CylinderSurfaceFit::Fit()
{
    if (!fitter)
        return 0;

    float fit = fitter->Fit();
    if (fit < FLOAT_MAX) {
        basepoint = fitter->GetBase();
        axis = fitter->GetAxis();
        radius = fitter->GetRadius();
    }
    return fit;
}

float CylinderSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    if (fitter && !fitter->Done()) {
        // collect some points
        return 0;
    }
    float dist = pnt.DistanceToLine(basepoint, axis);
    return (dist - radius);
}

// --------------------------------------------------------

SphereSurfaceFit::SphereSurfaceFit()
    : fitter(new SphereFit)
{
    center.Set(0,0,0);
    radius = FLOAT_MAX;
}

SphereSurfaceFit::SphereSurfaceFit(const Base::Vector3f& c, float r)
    : center(c)
    , radius(r)
    , fitter(0)
{

}

SphereSurfaceFit::~SphereSurfaceFit()
{
    delete fitter;
}

void SphereSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

void SphereSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool SphereSurfaceFit::TestTriangle(const MeshGeomFacet&) const
{
    // Already handled by GetDistanceToSurface
    return true;
}

bool SphereSurfaceFit::Done() const
{
    if (fitter) {
        return fitter->Done();
    }

    return true;
}

float SphereSurfaceFit::Fit()
{
    if (!fitter)
        return 0;

    float fit = fitter->Fit();
    if (fit < FLOAT_MAX) {
        center = fitter->GetCenter();
        radius = fitter->GetRadius();
    }
    return fit;
}

float SphereSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    float dist = Base::Distance(pnt, center);
    return (dist - radius);
}

// --------------------------------------------------------

MeshDistanceGenericSurfaceFitSegment::MeshDistanceGenericSurfaceFitSegment(AbstractSurfaceFit* fit,
                                                                           const MeshKernel& mesh,
                                                                           unsigned long minFacets,
                                                                           float tol)
  : MeshDistanceSurfaceSegment(mesh, minFacets, tol)
  , fitter(fit)
{
}

MeshDistanceGenericSurfaceFitSegment::~MeshDistanceGenericSurfaceFitSegment()
{
    delete fitter;
}

void MeshDistanceGenericSurfaceFitSegment::Initialize(unsigned long index)
{
    MeshGeomFacet triangle = kernel.GetFacet(index);
    fitter->Initialize(triangle);
}

bool MeshDistanceGenericSurfaceFitSegment::TestInitialFacet(unsigned long index) const
{
    MeshGeomFacet triangle = kernel.GetFacet(index);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToSurface(triangle._aclPoints[i])) > tolerance)
            return false;
    }
    return fitter->TestTriangle(triangle);
}

bool MeshDistanceGenericSurfaceFitSegment::TestFacet (const MeshFacet& face) const
{
    if (!fitter->Done())
        fitter->Fit();
    MeshGeomFacet triangle = kernel.GetFacet(face);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToSurface(triangle._aclPoints[i])) > tolerance)
            return false;
    }

    return fitter->TestTriangle(triangle);
}

void MeshDistanceGenericSurfaceFitSegment::AddFacet(const MeshFacet& face)
{
    MeshGeomFacet triangle = kernel.GetFacet(face);
    fitter->AddTriangle(triangle);
}

// --------------------------------------------------------

bool MeshCurvaturePlanarSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (fabs(ci.fMinCurvature) > tolerance)
            return false;
        if (fabs(ci.fMaxCurvature) > tolerance)
            return false;
    }

    return true;
}

bool MeshCurvatureCylindricalSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        float fMax = std::max<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
        float fMin = std::min<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
        if (fMin > toleranceMin)
            return false;
        if (fabs(fMax - curvature) > toleranceMax)
            return false;
    }

    return true;
}

bool MeshCurvatureSphericalSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (ci.fMaxCurvature * ci.fMinCurvature < 0)
            return false;
        float diff;
        diff = fabs(ci.fMinCurvature) - curvature;
        if (fabs(diff) > tolerance)
            return false;
        diff = fabs(ci.fMaxCurvature) - curvature;
        if (fabs(diff) > tolerance)
            return false;
    }

    return true;
}

bool MeshCurvatureFreeformSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (fabs(ci.fMinCurvature-c2) > toleranceMin)
            return false;
        if (fabs(ci.fMaxCurvature-c1) > toleranceMax)
            return false;
    }

    return true;
}

// --------------------------------------------------------

MeshSurfaceVisitor::MeshSurfaceVisitor (MeshSurfaceSegment& segm, std::vector<unsigned long> &indices)
  : indices(indices), segm(segm)
{
}

MeshSurfaceVisitor::~MeshSurfaceVisitor ()
{
}

bool MeshSurfaceVisitor::AllowVisit (const MeshFacet& face, const MeshFacet&,
                                     unsigned long, unsigned long, unsigned short)
{
    return segm.TestFacet(face);
}

bool MeshSurfaceVisitor::Visit (const MeshFacet & face, const MeshFacet &,
                                unsigned long ulFInd, unsigned long)
{
    indices.push_back(ulFInd);
    segm.AddFacet(face);
    return true;
}

// --------------------------------------------------------

void MeshSegmentAlgorithm::FindSegments(std::vector<MeshSurfaceSegment*>& segm)
{
    // reset VISIT flags
    unsigned long startFacet;
    MeshCore::MeshAlgorithm cAlgo(myKernel);
    cAlgo.ResetFacetFlag(MeshCore::MeshFacet::VISIT);

    const MeshCore::MeshFacetArray& rFAry = myKernel.GetFacets();
    MeshCore::MeshFacetArray::_TConstIterator iCur = rFAry.begin();
    MeshCore::MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
    MeshCore::MeshFacetArray::_TConstIterator iEnd = rFAry.end();

    // start from the first not visited facet
    cAlgo.CountFacetFlag(MeshCore::MeshFacet::VISIT);
    std::vector<unsigned long> resetVisited;

    for (std::vector<MeshSurfaceSegment*>::iterator it = segm.begin(); it != segm.end(); ++it) {
        cAlgo.ResetFacetsFlag(resetVisited, MeshCore::MeshFacet::VISIT);
        resetVisited.clear();

        iCur = std::find_if(iBeg, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
            MeshCore::MeshFacet::VISIT));
        startFacet = iCur - iBeg;
        while (startFacet != ULONG_MAX) {
            // collect all facets of the same geometry
            std::vector<unsigned long> indices;
            (*it)->Initialize(startFacet);
            if ((*it)->TestInitialFacet(startFacet))
                indices.push_back(startFacet);
            MeshSurfaceVisitor pv(**it, indices);
            myKernel.VisitNeighbourFacets(pv, startFacet);

            // add or discard the segment
            if (indices.size() <= 1) {
                resetVisited.push_back(startFacet);
            }
            else {
                (*it)->AddSegment(indices);
            }

            // search for the next start facet
            iCur = std::find_if(iCur, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
                MeshCore::MeshFacet::VISIT));
            if (iCur < iEnd)
                startFacet = iCur - iBeg;
            else
                startFacet = ULONG_MAX;
        }
    }
}
<commit_msg>Mesh: [skip ci] fix crash in mesh segmentation<commit_after>/***************************************************************************
 *   Copyright (c) 2012 Imetric 3D GmbH                                    *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <algorithm>
#endif

#include "Segmentation.h"
#include "Algorithm.h"
#include "Approximation.h"

using namespace MeshCore;

void MeshSurfaceSegment::Initialize(unsigned long)
{
}

bool MeshSurfaceSegment::TestInitialFacet(unsigned long) const
{
    return true;
}

void MeshSurfaceSegment::AddFacet(const MeshFacet&)
{
}

void MeshSurfaceSegment::AddSegment(const std::vector<unsigned long>& segm)
{
    if (segm.size() >= minFacets) {
        segments.push_back(segm);
    }
}

MeshSegment MeshSurfaceSegment::FindSegment(unsigned long index) const
{
    for (std::vector<MeshSegment>::const_iterator it = segments.begin(); it != segments.end(); ++it) {
        if (std::find(it->begin(), it->end(), index) != it->end())
            return *it;
    }

    return MeshSegment();
}

// --------------------------------------------------------

MeshDistancePlanarSegment::MeshDistancePlanarSegment(const MeshKernel& mesh, unsigned long minFacets, float tol)
  : MeshDistanceSurfaceSegment(mesh, minFacets, tol), fitter(new PlaneFit)
{
}

MeshDistancePlanarSegment::~MeshDistancePlanarSegment()
{
    delete fitter;
}

void MeshDistancePlanarSegment::Initialize(unsigned long index)
{
    fitter->Clear();

    MeshGeomFacet triangle = kernel.GetFacet(index);
    basepoint = triangle.GetGravityPoint();
    normal = triangle.GetNormal();
    fitter->AddPoint(triangle._aclPoints[0]);
    fitter->AddPoint(triangle._aclPoints[1]);
    fitter->AddPoint(triangle._aclPoints[2]);
}

bool MeshDistancePlanarSegment::TestFacet (const MeshFacet& face) const
{
    if (!fitter->Done())
        fitter->Fit();
    MeshGeomFacet triangle = kernel.GetFacet(face);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToPlane(triangle._aclPoints[i])) > tolerance)
            return false;
    }

    return true;
}

void MeshDistancePlanarSegment::AddFacet(const MeshFacet& face)
{
    MeshGeomFacet triangle = kernel.GetFacet(face);
    fitter->AddPoint(triangle.GetGravityPoint());
}

// --------------------------------------------------------

PlaneSurfaceFit::PlaneSurfaceFit()
    : fitter(new PlaneFit)
{
}

PlaneSurfaceFit::PlaneSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& n)
    : basepoint(b)
    , normal(n)
    , fitter(nullptr)
{
}

PlaneSurfaceFit::~PlaneSurfaceFit()
{
    delete fitter;
}

void PlaneSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();

        basepoint = tria.GetGravityPoint();
        normal = tria.GetNormal();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool PlaneSurfaceFit::TestTriangle(const MeshGeomFacet&) const
{
    return true;
}

void PlaneSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter)
        fitter->AddPoint(tria.GetGravityPoint());
}

bool PlaneSurfaceFit::Done() const
{
    if (!fitter)
        return true;
    else
        return fitter->Done();
}

float PlaneSurfaceFit::Fit()
{
    if (!fitter)
        return 0;
    else
        return fitter->Fit();
}

float PlaneSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    if (!fitter)
        return pnt.DistanceToPlane(basepoint, normal);
    else
        return fitter->GetDistanceToPlane(pnt);
}

// --------------------------------------------------------

CylinderSurfaceFit::CylinderSurfaceFit()
    : fitter(new CylinderFit)
{
    axis.Set(0,0,0);
    radius = FLOAT_MAX;
}

/*!
 * \brief CylinderSurfaceFit::CylinderSurfaceFit
 * Set a pre-defined cylinder. Internal cylinder fits are not done, then.
 */
CylinderSurfaceFit::CylinderSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& a, float r)
    : basepoint(b)
    , axis(a)
    , radius(r)
    , fitter(nullptr)
{
}

CylinderSurfaceFit::~CylinderSurfaceFit()
{
    delete fitter;
}

void CylinderSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

void CylinderSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool CylinderSurfaceFit::TestTriangle(const MeshGeomFacet& tria) const
{
    // This is to filter out triangles whose points lie on the cylinder and
    // that whose normals are more or less parallel to the cylinder axis
    float dot = axis.Dot(tria.GetNormal());
    return fabs(dot) < 0.5f;
}

bool CylinderSurfaceFit::Done() const
{
    if (fitter) {
        return fitter->Done();
    }

    return true;
}

float CylinderSurfaceFit::Fit()
{
    if (!fitter)
        return 0;

    float fit = fitter->Fit();
    if (fit < FLOAT_MAX) {
        basepoint = fitter->GetBase();
        axis = fitter->GetAxis();
        radius = fitter->GetRadius();
    }
    return fit;
}

float CylinderSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    if (fitter && !fitter->Done()) {
        // collect some points
        return 0;
    }
    float dist = pnt.DistanceToLine(basepoint, axis);
    return (dist - radius);
}

// --------------------------------------------------------

SphereSurfaceFit::SphereSurfaceFit()
    : fitter(new SphereFit)
{
    center.Set(0,0,0);
    radius = FLOAT_MAX;
}

SphereSurfaceFit::SphereSurfaceFit(const Base::Vector3f& c, float r)
    : center(c)
    , radius(r)
    , fitter(0)
{

}

SphereSurfaceFit::~SphereSurfaceFit()
{
    delete fitter;
}

void SphereSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->Clear();
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

void SphereSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
{
    if (fitter) {
        fitter->AddPoint(tria._aclPoints[0]);
        fitter->AddPoint(tria._aclPoints[1]);
        fitter->AddPoint(tria._aclPoints[2]);
    }
}

bool SphereSurfaceFit::TestTriangle(const MeshGeomFacet&) const
{
    // Already handled by GetDistanceToSurface
    return true;
}

bool SphereSurfaceFit::Done() const
{
    if (fitter) {
        return fitter->Done();
    }

    return true;
}

float SphereSurfaceFit::Fit()
{
    if (!fitter)
        return 0;

    float fit = fitter->Fit();
    if (fit < FLOAT_MAX) {
        center = fitter->GetCenter();
        radius = fitter->GetRadius();
    }
    return fit;
}

float SphereSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
{
    float dist = Base::Distance(pnt, center);
    return (dist - radius);
}

// --------------------------------------------------------

MeshDistanceGenericSurfaceFitSegment::MeshDistanceGenericSurfaceFitSegment(AbstractSurfaceFit* fit,
                                                                           const MeshKernel& mesh,
                                                                           unsigned long minFacets,
                                                                           float tol)
  : MeshDistanceSurfaceSegment(mesh, minFacets, tol)
  , fitter(fit)
{
}

MeshDistanceGenericSurfaceFitSegment::~MeshDistanceGenericSurfaceFitSegment()
{
    delete fitter;
}

void MeshDistanceGenericSurfaceFitSegment::Initialize(unsigned long index)
{
    MeshGeomFacet triangle = kernel.GetFacet(index);
    fitter->Initialize(triangle);
}

bool MeshDistanceGenericSurfaceFitSegment::TestInitialFacet(unsigned long index) const
{
    MeshGeomFacet triangle = kernel.GetFacet(index);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToSurface(triangle._aclPoints[i])) > tolerance)
            return false;
    }
    return fitter->TestTriangle(triangle);
}

bool MeshDistanceGenericSurfaceFitSegment::TestFacet (const MeshFacet& face) const
{
    if (!fitter->Done())
        fitter->Fit();
    MeshGeomFacet triangle = kernel.GetFacet(face);
    for (int i=0; i<3; i++) {
        if (fabs(fitter->GetDistanceToSurface(triangle._aclPoints[i])) > tolerance)
            return false;
    }

    return fitter->TestTriangle(triangle);
}

void MeshDistanceGenericSurfaceFitSegment::AddFacet(const MeshFacet& face)
{
    MeshGeomFacet triangle = kernel.GetFacet(face);
    fitter->AddTriangle(triangle);
}

// --------------------------------------------------------

bool MeshCurvaturePlanarSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (fabs(ci.fMinCurvature) > tolerance)
            return false;
        if (fabs(ci.fMaxCurvature) > tolerance)
            return false;
    }

    return true;
}

bool MeshCurvatureCylindricalSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        float fMax = std::max<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
        float fMin = std::min<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
        if (fMin > toleranceMin)
            return false;
        if (fabs(fMax - curvature) > toleranceMax)
            return false;
    }

    return true;
}

bool MeshCurvatureSphericalSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (ci.fMaxCurvature * ci.fMinCurvature < 0)
            return false;
        float diff;
        diff = fabs(ci.fMinCurvature) - curvature;
        if (fabs(diff) > tolerance)
            return false;
        diff = fabs(ci.fMaxCurvature) - curvature;
        if (fabs(diff) > tolerance)
            return false;
    }

    return true;
}

bool MeshCurvatureFreeformSegment::TestFacet (const MeshFacet &rclFacet) const
{
    for (int i=0; i<3; i++) {
        const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
        if (fabs(ci.fMinCurvature-c2) > toleranceMin)
            return false;
        if (fabs(ci.fMaxCurvature-c1) > toleranceMax)
            return false;
    }

    return true;
}

// --------------------------------------------------------

MeshSurfaceVisitor::MeshSurfaceVisitor (MeshSurfaceSegment& segm, std::vector<unsigned long> &indices)
  : indices(indices), segm(segm)
{
}

MeshSurfaceVisitor::~MeshSurfaceVisitor ()
{
}

bool MeshSurfaceVisitor::AllowVisit (const MeshFacet& face, const MeshFacet&,
                                     unsigned long, unsigned long, unsigned short)
{
    return segm.TestFacet(face);
}

bool MeshSurfaceVisitor::Visit (const MeshFacet & face, const MeshFacet &,
                                unsigned long ulFInd, unsigned long)
{
    indices.push_back(ulFInd);
    segm.AddFacet(face);
    return true;
}

// --------------------------------------------------------

void MeshSegmentAlgorithm::FindSegments(std::vector<MeshSurfaceSegment*>& segm)
{
    // reset VISIT flags
    unsigned long startFacet;
    MeshCore::MeshAlgorithm cAlgo(myKernel);
    cAlgo.ResetFacetFlag(MeshCore::MeshFacet::VISIT);

    const MeshCore::MeshFacetArray& rFAry = myKernel.GetFacets();
    MeshCore::MeshFacetArray::_TConstIterator iCur = rFAry.begin();
    MeshCore::MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
    MeshCore::MeshFacetArray::_TConstIterator iEnd = rFAry.end();

    // start from the first not visited facet
    cAlgo.CountFacetFlag(MeshCore::MeshFacet::VISIT);
    std::vector<unsigned long> resetVisited;

    for (std::vector<MeshSurfaceSegment*>::iterator it = segm.begin(); it != segm.end(); ++it) {
        cAlgo.ResetFacetsFlag(resetVisited, MeshCore::MeshFacet::VISIT);
        resetVisited.clear();

        iCur = std::find_if(iBeg, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
            MeshCore::MeshFacet::VISIT));
        if (iCur < iEnd)
            startFacet = iCur - iBeg;
        else
            startFacet = ULONG_MAX;
        while (startFacet != ULONG_MAX) {
            // collect all facets of the same geometry
            std::vector<unsigned long> indices;
            (*it)->Initialize(startFacet);
            if ((*it)->TestInitialFacet(startFacet))
                indices.push_back(startFacet);
            MeshSurfaceVisitor pv(**it, indices);
            myKernel.VisitNeighbourFacets(pv, startFacet);

            // add or discard the segment
            if (indices.size() <= 1) {
                resetVisited.push_back(startFacet);
            }
            else {
                (*it)->AddSegment(indices);
            }

            // search for the next start facet
            iCur = std::find_if(iCur, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
                MeshCore::MeshFacet::VISIT));
            if (iCur < iEnd)
                startFacet = iCur - iBeg;
            else
                startFacet = ULONG_MAX;
        }
    }
}
<|endoftext|>