<commit_before>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * exnetperf -- Shows how to use the statistical functions in GNE.  This
 * example should serve well for GNE to measure network performance, as best
 * as is possible with the GNE and HawkNL APIs.  This example uses event-
 * driven networking since that is what is most likely to be used once the
 * game has started, and the method that most likely has the largest impact
 * on performace.  (SyncConnection will most likely be used only while
 * connecting).
 * This example could also be used to test the bandwidth throttling.
 */

#include "../../include/gnelib.h"
#include <iostream>

using namespace std;
using namespace GNE;
using namespace GNE::PacketParser;
using namespace GNE::Console;

void updateGlobalStats();
void errorExit(const char* error);
int getPort(const char* prompt);
void doServer(int outRate, int inRate, int port);
void doClient(int outRate, int inRate, int port);

//This keeps track of some screen positions when can write to.
//Essentially makes tiles out of the screen.
struct Pos {
  int x, y;
  bool taken;
};
static Pos gpos = {0, 8, false}; //global stats position
static Pos positions[] = {{0, 17, false}};

const Pos& getNextPos() {
  return positions[0];
}

//The PerfTester class works on both the client and the server side.
class PerfTester : public ConnectionListener {
public:
  PerfTester(const Pos& ourPos2) : packetsIn(0), ourPos(ourPos2),
    packetsOut(0), conn(NULL) {}
  ~PerfTester() {}

  void onDisconnect() {
    delete this;
  }

  void onConnect(SyncConnection& conn2) {
    conn = conn2.getConnection();
    writePackets(); //Send an initial batch of data.
  }

  void onNewConn(SyncConnection& conn2) {
    conn = conn2.getConnection();
    conn2.release();
    writePackets();
  }

  void onReceive() {
    Packet* next = conn->stream().getNextPacket();
    while (next != NULL) {
      delete next;
      packetsIn++;
      next = conn->stream().getNextPacket();
    }
    //We don't need to do anything to the data we are being sent.  The low-
    //level routines will keep track of the stats for us.
    updateStats();
  }

  void onFailure(const Error& error) {
    mlprintf(0, 0, "Socket failure: %s   ", error.toString().c_str());
    //No need to disconnect, this has already happened on a failure.
  }

  void onError(const Error& error) {
    mlprintf(0, 0, "Socket error: %s   ", error.toString().c_str());
    conn->disconnect();//For simplicity we treat even normal errors as fatal.
  }

  void onConnectFailure(const Error& error) {
    mlprintf(0, 0, "Connection to server failed.   ");
    mlprintf(0, 1, "  GNE reported error: %s   ", error.toString().c_str());
  }

  void onDoneWriting() {
    writePackets();
  }

  //Try to send out some more packets.
  void writePackets() {
    CustomPacket temp;
    temp.getData() << "Hello World!";
    conn->stream().writePacket(temp, true);
    packetsOut++;

    updateStats();
  }

  //write the stats out to our position.
  void updateStats() {
    updateGlobalStats();
    ConnectionStats all = conn->getStats(-1);
    ConnectionStats rel = conn->getStats(1);
    ConnectionStats unrel = conn->getStats(0);
    //Printfs are so much nicer in this case, eh?
    mlprintf(ourPos.x, ourPos.y, "%-20s%10s%10s%10s",
      conn->getRemoteAddress(true).toString().c_str(), "tot =" , "rel +", "unrel");
    mlprintf(ourPos.x, ourPos.y+1, "%-20s%10d", "HiLvlPkts in", packetsIn);
    mlprintf(ourPos.x, ourPos.y+2, "%-20s%10d", "HiLvlPkts out", packetsOut);
    mlprintf(ourPos.x, ourPos.y+3, "%-20s%10d%10d%10d",
      "bytesin", all.bytesRecv, rel.bytesRecv, unrel.bytesRecv);
    mlprintf(ourPos.x, ourPos.y+4, "%-20s%10d%10d%10d",
      "bytesout", all.bytesSent, rel.bytesSent, unrel.bytesSent);
    mlprintf(ourPos.x, ourPos.y+5, "%-20s%10d%10d%10d",
      "inRate", all.avgBytesRecv, rel.avgBytesRecv, unrel.avgBytesRecv);
    mlprintf(ourPos.x, ourPos.y+6, "%-20s%10d%10d%10d",
      "outRate", all.avgBytesSent, rel.avgBytesSent, unrel.avgBytesSent);
    mlprintf(ourPos.x, ourPos.y+7, "%-20s%10d%10d%10d",
      "maxInRate", all.maxAvgBytesRecv, rel.maxAvgBytesRecv, unrel.maxAvgBytesRecv);
    mlprintf(ourPos.x, ourPos.y+8, "%-20s%10d%10d%10d",
      "maxOutRate", all.maxAvgBytesSent, rel.maxAvgBytesSent, unrel.maxAvgBytesSent);
    mlprintf(ourPos.x, ourPos.y+9, "%-20s%10d%10d%10d",
      "sockets", all.openSockets, rel.openSockets, unrel.openSockets);
  }
private:
  int packetsIn;
  int packetsOut;
  Pos ourPos;
  Connection* conn;
};

class OurListener : public ServerConnectionListener {
public:
  OurListener()
    : ServerConnectionListener() {
  }

  virtual ~OurListener() {}

  void onListenFailure(const Error& error, const Address& from, ConnectionListener* listener) {
    mlprintf(0, 0, "Connection error: %s   ", error.toString().c_str());
    mlprintf(0, 1, "  Error received from %s   ", from.toString().c_str());
    delete listener;
  }

  void getNewConnectionParams(int& inRate, int& outRate, ConnectionListener*& listener) {
    inRate = outRate = 0; //0 meaning no limits on rates.
    listener = new PerfTester(getNextPos());
  }

private:
};

void updateGlobalStats() {
  ConnectionStats all = GNE::getGlobalStats();
  mlprintf(gpos.x, gpos.y, "%-20s%10s", "global", "tot");
  mlprintf(gpos.x, gpos.y+1, "%-20s%10d", "bytesin", all.bytesRecv);
  mlprintf(gpos.x, gpos.y+2, "%-20s%10d", "bytesout", all.bytesSent);
  mlprintf(gpos.x, gpos.y+3, "%-20s%10d", "inRate", all.avgBytesRecv);
  mlprintf(gpos.x, gpos.y+4, "%-20s%10d", "outRate", all.avgBytesSent);
  mlprintf(gpos.x, gpos.y+5, "%-20s%10d", "maxInRate", all.maxAvgBytesRecv);
  mlprintf(gpos.x, gpos.y+6, "%-20s%10d", "maxOutRate", all.maxAvgBytesSent);
}

void errorExit(const char* error) {
  shutdownConsole();
  cout << "Error: " << error << endl;
  exit(1);
}

int getPort(const char* prompt) {
  int port;
  gout << "Which port should we " << prompt << ": ";
  gin >> port;
  while ((port < 1) || (port > 65535)) {
    gout << "Ports range from 1 to 65535, please select one in this range: ";
    gin >> port;
  }
  return port;
}

int main() {
  if (initGNE(NL_IP, atexit)) {
    cout << "Unable to initialize GNE" << endl;
    exit(2);
  }
  enableStats();     //By default, stats are disabled.  This turns stat
                     //collection on.
  setUserVersion(1); //Sets our user protocol version number, used in
                     //the connection process by GNE to version check.
  if (initConsole(atexit)) {
    cout << "Unable to initialize GNE Console" << endl;
    exit(3);
  }
  setTitle("GNE Net Performance Tester");

  gout << "GNE Net Performance Tester for " << GNE::VER_STR << endl;
  gout << "Local address: " << getLocalAddress() << endl;
  gout << "Should we act as the server, or the client?" << endl;
  gout << "Type 1 for client, 2 for server: ";
  int type;
  gin >> type;

  int port;
  if (type != 1) {
    setTitle("GNE Net Performance Tester -- Server");
    gout << "Reminder: ports <= 1024 on UNIX can only be used by the superuser." << endl;
    port = getPort("listen on");
    doServer(0, 0, port);
  } else {
    setTitle("GNE Net Performance Tester -- Client");
    port = getPort("connect to");
    doClient(0, 0, port);
  }

  return 0;
}

void doServer(int outRate, int inRate, int port) {
#ifdef _DEBUG
  //Generate debugging logs to server.log if in debug mode.
  initDebug(DLEVEL1 | DLEVEL2 | DLEVEL3 | DLEVEL5, "server.log");
#endif
  OurListener server;
  if (server.open(port))
    errorExit("Cannot open server socket.");
  if (server.listen())
    errorExit("Cannot listen on server socket.");

  gout << "Server is listening on: " << server.getLocalAddress() << endl;
  gout << "Press a key to shutdown server." << endl;
  getch();
  //When the server class is destructed, it will stop listening and shutdown.
}

void doClient(int outRate, int inRate, int port) {
#ifdef _DEBUG
  initDebug(DLEVEL1 | DLEVEL2 | DLEVEL3 | DLEVEL5, "client.log");
#endif
  string host;
  gout << "Enter hostname or IP address: ";
  gin >> host;

  Address address(host);
  address.setPort(port);
  if (!address)
    errorExit("Invalid address.");
  gout << "Connecting to: " << address << endl;
  gout << "Press a key to stop the testing. " << endl;

  ClientConnection client(outRate, inRate, new PerfTester(getNextPos()));
  if (client.open(address, 0)) //localPort = 0, for any local port.
    errorExit("Cannot open client socket.");

  client.connect();
  client.join();

  getch(); //Wait for user keypress
  client.disconnectSendAll();
}
<commit_msg>Forgot to delete ServerConnection.<commit_after>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * exnetperf -- Shows how to use the statistical functions in GNE.  This
 * example should serve well for GNE to measure network performance, as best
 * as is possible with the GNE and HawkNL APIs.  This example uses event-
 * driven networking since that is what is most likely to be used once the
 * game has started, and the method that most likely has the largest impact
 * on performace.  (SyncConnection will most likely be used only while
 * connecting).
 * This example could also be used to test the bandwidth throttling.
 */

#include "../../include/gnelib.h"
#include <iostream>

using namespace std;
using namespace GNE;
using namespace GNE::PacketParser;
using namespace GNE::Console;

void updateGlobalStats();
void errorExit(const char* error);
int getPort(const char* prompt);
void doServer(int outRate, int inRate, int port);
void doClient(int outRate, int inRate, int port);

//This keeps track of some screen positions when can write to.
//Essentially makes tiles out of the screen.
struct Pos {
  int x, y;
  bool taken;
};
static Pos gpos = {0, 8, false}; //global stats position
static Pos positions[] = {{0, 17, false}};

const Pos& getNextPos() {
  return positions[0];
}

//The PerfTester class works on both the client and the server side.
class PerfTester : public ConnectionListener {
public:
  PerfTester(const Pos& ourPos2) : packetsIn(0), ourPos(ourPos2),
    packetsOut(0), conn(NULL) {}
  ~PerfTester() {}

  void onDisconnect() {
    if (serverSide) {
      //see serverSide declaration for more info
      delete conn;
    }
    delete this;
  }

  void onConnect(SyncConnection& conn2) {
    serverSide = false;
    conn = conn2.getConnection();
    writePackets(); //Send an initial batch of data.
  }

  void onNewConn(SyncConnection& conn2) {
    serverSide = true;
    conn = conn2.getConnection();
    conn2.release();
    writePackets();
  }

  void onReceive() {
    Packet* next = conn->stream().getNextPacket();
    while (next != NULL) {
      delete next;
      packetsIn++;
      next = conn->stream().getNextPacket();
    }
    //We don't need to do anything to the data we are being sent.  The low-
    //level routines will keep track of the stats for us.
    updateStats();
  }

  void onFailure(const Error& error) {
    mlprintf(0, 0, "Socket failure: %s   ", error.toString().c_str());
    //No need to disconnect, this has already happened on a failure.
  }

  void onError(const Error& error) {
    mlprintf(0, 0, "Socket error: %s   ", error.toString().c_str());
    conn->disconnect();//For simplicity we treat even normal errors as fatal.
  }

  void onConnectFailure(const Error& error) {
    mlprintf(0, 0, "Connection to server failed.   ");
    mlprintf(0, 1, "  GNE reported error: %s   ", error.toString().c_str());
  }

  void onDoneWriting() {
    writePackets();
  }

  //Try to send out some more packets.
  void writePackets() {
    CustomPacket temp;
    temp.getData() << "Hello World!";
    conn->stream().writePacket(temp, true);
    packetsOut++;

    updateStats();
  }

  //write the stats out to our position.
  void updateStats() {
    updateGlobalStats();
    ConnectionStats all = conn->getStats(-1);
    ConnectionStats rel = conn->getStats(1);
    ConnectionStats unrel = conn->getStats(0);
    //Printfs are so much nicer in this case, eh?
    mlprintf(ourPos.x, ourPos.y, "%-20s%10s%10s%10s",
      conn->getRemoteAddress(true).toString().c_str(), "tot =" , "rel +", "unrel");
    mlprintf(ourPos.x, ourPos.y+1, "%-20s%10d", "HiLvlPkts in", packetsIn);
    mlprintf(ourPos.x, ourPos.y+2, "%-20s%10d", "HiLvlPkts out", packetsOut);
    mlprintf(ourPos.x, ourPos.y+3, "%-20s%10d%10d%10d",
      "bytesin", all.bytesRecv, rel.bytesRecv, unrel.bytesRecv);
    mlprintf(ourPos.x, ourPos.y+4, "%-20s%10d%10d%10d",
      "bytesout", all.bytesSent, rel.bytesSent, unrel.bytesSent);
    mlprintf(ourPos.x, ourPos.y+5, "%-20s%10d%10d%10d",
      "inRate", all.avgBytesRecv, rel.avgBytesRecv, unrel.avgBytesRecv);
    mlprintf(ourPos.x, ourPos.y+6, "%-20s%10d%10d%10d",
      "outRate", all.avgBytesSent, rel.avgBytesSent, unrel.avgBytesSent);
    mlprintf(ourPos.x, ourPos.y+7, "%-20s%10d%10d%10d",
      "maxInRate", all.maxAvgBytesRecv, rel.maxAvgBytesRecv, unrel.maxAvgBytesRecv);
    mlprintf(ourPos.x, ourPos.y+8, "%-20s%10d%10d%10d",
      "maxOutRate", all.maxAvgBytesSent, rel.maxAvgBytesSent, unrel.maxAvgBytesSent);
    mlprintf(ourPos.x, ourPos.y+9, "%-20s%10d%10d%10d",
      "sockets", all.openSockets, rel.openSockets, unrel.openSockets);
  }
private:
  int packetsIn;
  int packetsOut;
  Pos ourPos;
  Connection* conn;

  //We use this because this class can be client or server.  In the client
  //side, the ClientConnection is on the stack and is automatically
  //destroyed but on the server side the ServerConnection is on the heap and
  //needs to be deleted.
  //Normially the recommended way is to have in onDisconnect report to the
  //main thread or some other responsible thread to control the creation or
  //deletion of the listener and connection, and have that thread check and
  //do the deletes, rather than use "delete conn; delete this;."  But in a
  //small program such as this, it is probably acceptable (at least much
  //easier to program!).
  bool serverSide;
};

class OurListener : public ServerConnectionListener {
public:
  OurListener()
    : ServerConnectionListener() {
  }

  virtual ~OurListener() {}

  void onListenFailure(const Error& error, const Address& from, ConnectionListener* listener) {
    mlprintf(0, 0, "Connection error: %s   ", error.toString().c_str());
    mlprintf(0, 1, "  Error received from %s   ", from.toString().c_str());
    delete listener;
  }

  void getNewConnectionParams(int& inRate, int& outRate, ConnectionListener*& listener) {
    inRate = outRate = 0; //0 meaning no limits on rates.
    listener = new PerfTester(getNextPos());
  }

private:
};

void updateGlobalStats() {
  ConnectionStats all = GNE::getGlobalStats();
  mlprintf(gpos.x, gpos.y, "%-20s%10s", "global", "tot");
  mlprintf(gpos.x, gpos.y+1, "%-20s%10d", "bytesin", all.bytesRecv);
  mlprintf(gpos.x, gpos.y+2, "%-20s%10d", "bytesout", all.bytesSent);
  mlprintf(gpos.x, gpos.y+3, "%-20s%10d", "inRate", all.avgBytesRecv);
  mlprintf(gpos.x, gpos.y+4, "%-20s%10d", "outRate", all.avgBytesSent);
  mlprintf(gpos.x, gpos.y+5, "%-20s%10d", "maxInRate", all.maxAvgBytesRecv);
  mlprintf(gpos.x, gpos.y+6, "%-20s%10d", "maxOutRate", all.maxAvgBytesSent);
}

void errorExit(const char* error) {
  shutdownConsole();
  cout << "Error: " << error << endl;
  exit(1);
}

int getPort(const char* prompt) {
  int port;
  gout << "Which port should we " << prompt << ": ";
  gin >> port;
  while ((port < 1) || (port > 65535)) {
    gout << "Ports range from 1 to 65535, please select one in this range: ";
    gin >> port;
  }
  return port;
}

int main() {
  if (initGNE(NL_IP, atexit)) {
    cout << "Unable to initialize GNE" << endl;
    exit(2);
  }
  enableStats();     //By default, stats are disabled.  This turns stat
                     //collection on.
  setUserVersion(1); //Sets our user protocol version number, used in
                     //the connection process by GNE to version check.
  if (initConsole(atexit)) {
    cout << "Unable to initialize GNE Console" << endl;
    exit(3);
  }
  setTitle("GNE Net Performance Tester");

  gout << "GNE Net Performance Tester for " << GNE::VER_STR << endl;
  gout << "Local address: " << getLocalAddress() << endl;
  gout << "Should we act as the server, or the client?" << endl;
  gout << "Type 1 for client, 2 for server: ";
  int type;
  gin >> type;

  int port;
  if (type != 1) {
    setTitle("GNE Net Performance Tester -- Server");
    gout << "Reminder: ports <= 1024 on UNIX can only be used by the superuser." << endl;
    port = getPort("listen on");
    doServer(0, 0, port);
  } else {
    setTitle("GNE Net Performance Tester -- Client");
    port = getPort("connect to");
    doClient(0, 0, port);
  }

  return 0;
}

void doServer(int outRate, int inRate, int port) {
#ifdef _DEBUG
  //Generate debugging logs to server.log if in debug mode.
  initDebug(DLEVEL1 | DLEVEL2 | DLEVEL3 | DLEVEL5, "server.log");
#endif
  OurListener server;
  if (server.open(port))
    errorExit("Cannot open server socket.");
  if (server.listen())
    errorExit("Cannot listen on server socket.");

  gout << "Server is listening on: " << server.getLocalAddress() << endl;
  gout << "Press a key to shutdown server." << endl;
  getch();
  //When the server class is destructed, it will stop listening and shutdown.
}

void doClient(int outRate, int inRate, int port) {
#ifdef _DEBUG
  initDebug(DLEVEL1 | DLEVEL2 | DLEVEL3 | DLEVEL5, "client.log");
#endif
  string host;
  gout << "Enter hostname or IP address: ";
  gin >> host;

  Address address(host);
  address.setPort(port);
  if (!address)
    errorExit("Invalid address.");
  gout << "Connecting to: " << address << endl;
  gout << "Press a key to stop the testing. " << endl;

  ClientConnection client(outRate, inRate, new PerfTester(getNextPos()));
  if (client.open(address, 0)) //localPort = 0, for any local port.
    errorExit("Cannot open client socket.");

  client.connect();
  client.join();

  getch(); //Wait for user keypress
  client.disconnectSendAll();
}
<|endoftext|>


<commit_before>/**
 * @file gaussian_distribution.cpp
 * @author Ryan Curtin
 * @author Michael Fox
 *
 * Implementation of Gaussian distribution class.
 */
#include "gaussian_distribution.hpp"

using namespace mlpack;
using namespace mlpack::distribution;

GaussianDistribution::GaussianDistribution(const arma::vec& mean,
                                           const arma::mat& covariance)
  : mean(mean)
{
  Covariance(covariance);
}

void GaussianDistribution::Covariance(const arma::mat& covariance)
{
  this->covariance = covariance;
  FactorCovariance();
}

void GaussianDistribution::Covariance(arma::mat&& covariance)
{
  this->covariance = std::move(covariance);
  FactorCovariance();
}

void GaussianDistribution::FactorCovariance()
{
  covLower = arma::chol(covariance, "lower");
  // tell arma that this is lower triangular matrix (for faster inversion)
  covLower = arma::trimatl(covLower);
  const arma::mat invCovLower = covLower.i();
  invCov = invCovLower.t() * invCovLower;
  double sign = 0.;
  arma::log_det(logDetCov, sign, covLower);
  logDetCov *= 2;
}

double GaussianDistribution::LogProbability(const arma::vec& observation) const
{
  const size_t k = observation.n_elem;
  const arma::vec diff = mean - observation;
  const arma::vec v = (diff.t() * invCov * diff);
  return -0.5 * k * log2pi - 0.5 * logDetCov - 0.5 * v(0);
}

arma::vec GaussianDistribution::Random() const
{
  return covLower * arma::randn<arma::vec>(mean.n_elem) + mean;
}

/**
 * Estimate the Gaussian distribution directly from the given observations.
 *
 * @param observations List of observations.
 */
void GaussianDistribution::Estimate(const arma::mat& observations)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): why do we allow this case? why not throw an error?
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  // Calculate the mean.
  for (size_t i = 0; i < observations.n_cols; i++)
    mean += observations.col(i);

  // Normalize the mean.
  mean /= observations.n_cols;

  // Now calculate the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += obsNoMean * trans(obsNoMean);
  }

  // Finish estimating the covariance by normalizing, with the (1 / (n - 1)) so
  // that it is the unbiased estimator.
  covariance /= (observations.n_cols - 1);

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Estimate(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }

  FactorCovariance();
}

/**
 * Estimate the Gaussian distribution from the given observations, taking into
 * account the probability of each observation actually being from this
 * distribution.
 */
void GaussianDistribution::Estimate(const arma::mat& observations,
                                    const arma::vec& probabilities)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): same as above
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  double sumProb = 0;

  // First calculate the mean, and save the sum of all the probabilities for
  // later normalization.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    mean += probabilities[i] * observations.col(i);
    sumProb += probabilities[i];
  }

  if (sumProb == 0)
  {
    // Nothing in this Gaussian!  At least set the covariance so that it's
    // invertible.
    covariance.diag() += 1e-50;
    // TODO(stephentu): why do we allow this case?
    return;
  }

  // Normalize.
  mean /= sumProb;

  // Now find the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += probabilities[i] * (obsNoMean * trans(obsNoMean));
  }

  // This is probably biased, but I don't know how to unbias it.
  covariance /= sumProb;

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Estimate(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }

  FactorCovariance();
}

/**
 * Returns a string representation of this object.
 */
std::string GaussianDistribution::ToString() const
{
  std::ostringstream convert;
  convert << "GaussianDistribution [" << this << "]" << std::endl;

  // Secondary ostringstream so things can be indented right.
  std::ostringstream data;
  data << "Mean: " << std::endl << mean;
  data << "Covariance: " << std::endl << covariance;

  convert << util::Indent(data.str());
  return convert.str();
}

/*&
 * Save to SaveRestoreUtility.
 */
void GaussianDistribution::Save(util::SaveRestoreUtility& sr) const
{
  sr.SaveParameter(Type(), "type");
  sr.SaveParameter(mean, "mean");
  sr.SaveParameter(covariance, "covariance");
}

/**
 * Load from SaveRestoreUtility.
 */
void GaussianDistribution::Load(const util::SaveRestoreUtility& sr)
{
  sr.LoadParameter(mean, "mean");
  sr.LoadParameter(covariance, "covariance");
  FactorCovariance();
}
<commit_msg>invert the lower triangular matrix the right way<commit_after>/**
 * @file gaussian_distribution.cpp
 * @author Ryan Curtin
 * @author Michael Fox
 *
 * Implementation of Gaussian distribution class.
 */
#include "gaussian_distribution.hpp"

using namespace mlpack;
using namespace mlpack::distribution;

GaussianDistribution::GaussianDistribution(const arma::vec& mean,
                                           const arma::mat& covariance)
  : mean(mean)
{
  Covariance(covariance);
}

void GaussianDistribution::Covariance(const arma::mat& covariance)
{
  this->covariance = covariance;
  FactorCovariance();
}

void GaussianDistribution::Covariance(arma::mat&& covariance)
{
  this->covariance = std::move(covariance);
  FactorCovariance();
}

void GaussianDistribution::FactorCovariance()
{
  covLower = arma::chol(covariance, "lower");

  // Comment from rcurtin:
  //
  // I think the use of the word "interpret" in the Armadillo documentation
  // about trimatl and trimatu is somewhat misleading. What the function will
  // actually do, when used in that context, is loop over the upper triangular
  // part of the matrix and set it all to 0, so this ends up actually just
  // burning cycles---also because the operator=() evaluates the expression and
  // strips the knowledge that it's a lower triangular matrix. So then the call
  // to .i() doesn't actually do anything smarter.
  //
  // But perusing fn_inv.hpp more closely, there is a specialization that will
  // work when called like this: inv(trimatl(covLower)), and will use LAPACK's
  // ?trtri functions. However, it will still set the upper triangular part to
  // 0 after the method. That last part is unnecessary, but baked into
  // Armadillo, so there's not really much that can be done about that without
  // discussion with the Armadillo maintainer.
  const arma::mat invCovLower = arma::inv(arma::trimatl(covLower));

  invCov = invCovLower.t() * invCovLower;
  double sign = 0.;
  arma::log_det(logDetCov, sign, covLower);
  logDetCov *= 2;
}

double GaussianDistribution::LogProbability(const arma::vec& observation) const
{
  const size_t k = observation.n_elem;
  const arma::vec diff = mean - observation;
  const arma::vec v = (diff.t() * invCov * diff);
  return -0.5 * k * log2pi - 0.5 * logDetCov - 0.5 * v(0);
}

arma::vec GaussianDistribution::Random() const
{
  return covLower * arma::randn<arma::vec>(mean.n_elem) + mean;
}

/**
 * Estimate the Gaussian distribution directly from the given observations.
 *
 * @param observations List of observations.
 */
void GaussianDistribution::Estimate(const arma::mat& observations)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): why do we allow this case? why not throw an error?
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  // Calculate the mean.
  for (size_t i = 0; i < observations.n_cols; i++)
    mean += observations.col(i);

  // Normalize the mean.
  mean /= observations.n_cols;

  // Now calculate the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += obsNoMean * trans(obsNoMean);
  }

  // Finish estimating the covariance by normalizing, with the (1 / (n - 1)) so
  // that it is the unbiased estimator.
  covariance /= (observations.n_cols - 1);

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Estimate(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }

  FactorCovariance();
}

/**
 * Estimate the Gaussian distribution from the given observations, taking into
 * account the probability of each observation actually being from this
 * distribution.
 */
void GaussianDistribution::Estimate(const arma::mat& observations,
                                    const arma::vec& probabilities)
{
  if (observations.n_cols > 0)
  {
    mean.zeros(observations.n_rows);
    covariance.zeros(observations.n_rows, observations.n_rows);
  }
  else // This will end up just being empty.
  {
    // TODO(stephentu): same as above
    mean.zeros(0);
    covariance.zeros(0);
    return;
  }

  double sumProb = 0;

  // First calculate the mean, and save the sum of all the probabilities for
  // later normalization.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    mean += probabilities[i] * observations.col(i);
    sumProb += probabilities[i];
  }

  if (sumProb == 0)
  {
    // Nothing in this Gaussian!  At least set the covariance so that it's
    // invertible.
    covariance.diag() += 1e-50;
    FactorCovariance();
    return;
  }

  // Normalize.
  mean /= sumProb;

  // Now find the covariance.
  for (size_t i = 0; i < observations.n_cols; i++)
  {
    arma::vec obsNoMean = observations.col(i) - mean;
    covariance += probabilities[i] * (obsNoMean * trans(obsNoMean));
  }

  // This is probably biased, but I don't know how to unbias it.
  covariance /= sumProb;

  // Ensure that the covariance is positive definite.
  if (det(covariance) <= 1e-50)
  {
    Log::Debug << "GaussianDistribution::Estimate(): Covariance matrix is not "
        << "positive definite. Adding perturbation." << std::endl;

    double perturbation = 1e-30;
    while (det(covariance) <= 1e-50)
    {
      covariance.diag() += perturbation;
      perturbation *= 10; // Slow, but we don't want to add too much.
    }
  }

  FactorCovariance();
}

/**
 * Returns a string representation of this object.
 */
std::string GaussianDistribution::ToString() const
{
  std::ostringstream convert;
  convert << "GaussianDistribution [" << this << "]" << std::endl;

  // Secondary ostringstream so things can be indented right.
  std::ostringstream data;
  data << "Mean: " << std::endl << mean;
  data << "Covariance: " << std::endl << covariance;

  convert << util::Indent(data.str());
  return convert.str();
}

/*&
 * Save to SaveRestoreUtility.
 */
void GaussianDistribution::Save(util::SaveRestoreUtility& sr) const
{
  sr.SaveParameter(Type(), "type");
  sr.SaveParameter(mean, "mean");
  sr.SaveParameter(covariance, "covariance");
}

/**
 * Load from SaveRestoreUtility.
 */
void GaussianDistribution::Load(const util::SaveRestoreUtility& sr)
{
  sr.LoadParameter(mean, "mean");
  sr.LoadParameter(covariance, "covariance");
  FactorCovariance();
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFileIOToImageFilter.txx"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int argc, char* argv )
{

  return 0;
}

<commit_msg>ENH: Updated to latest headers<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryMedianImageFilter.txx"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFileIOToImageFilter.txx"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int argc, char* argv )
{

  return 0;
}

<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkBinaryErodeImageFilter.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinomialBlurImageFilter.h"
#include "itkCannyEdgeDetectionImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkCosImageFilter.h"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.h"
#include "itkDanielssonDistanceMapImageFilter.h"
#include "itkDerivativeImageFilter.h"
#include "itkDifferenceOfGaussiansGradientImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkDivideImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.h"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkFileIOToImageFilter.h"
#include "itkFirstDerivativeRecursiveGaussianImageFilter.h"
#include "itkGaussianImageSource.h"
#include "itkGradient2DAnisotropicDiffusionFunction.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.h"
#include "itkGradientMagnitudeImageFilter.h"
#include "itkGradientNDAnisotropicDiffusionFunction.h"
#include "itkGradientRecursiveGaussianImageFilter.h"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleDilateImageFilter.h"
#include "itkGrayscaleErodeImageFilter.h"
#include "itkGrayscaleFunctionDilateImageFilter.h"
#include "itkGrayscaleFunctionErodeImageFilter.h"
#include "itkImageToMeshFilter.h"
#include "itkImageToParametricSpaceFilter.h"
#include "itkImportImageFilter.h"
#include "itkInteriorExteriorMeshFilter.h"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.h"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMirrorPadImageFilter.h"
#include "itkMorphologyImageFilter.h"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.h"
#include "itkNeighborhoodOperatorImageFilter.h"
#include "itkNonThreadedShrinkImageFilter.h"
#include "itkPadImageFilter.h"
#include "itkParametricSpaceToImageSpaceMeshFilter.h"
#include "itkPlaheImageFilter.h"
#include "itkRandomImageSource.h"
#include "itkRecursiveGaussianImageFilter.h"
#include "itkRecursiveSeparableImageFilter.h"
#include "itkReflectImageFilter.h"
#include "itkReflectiveImageRegionIterator.h"
#include "itkResampleImageFilter.h"
#include "itkScalarAnisotropicDiffusionFunction.h"
#include "itkSecondDerivativeRecursiveGaussianImageFilter.h"
#include "itkShrinkImageFilter.h"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.h"
#include "itkSpatialFunctionImageEvaluatorFilter.h"
#include "itkSqrtImageFilter.h"
#include "itkStreamingImageFilter.h"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.h"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.h"
#include "itkTransformMeshFilter.h"
#include "itkTwoOutputExampleImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkVTKImageExport.h"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.h"
#include "itkVectorAnisotropicDiffusionFunction.h"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.h"
#include "itkVectorExpandImageFilter.h"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.h"
#include "itkVectorNeighborhoodOperatorImageFilter.h"
#include "itkWarpImageFilter.h"
#include "itkWrapPadImageFilter.h"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.h"
#include "itkZeroCrossingImageFilter.h"

int main ( int argc, char* argv )
{

  return 0;
}

<commit_msg>ENH: hand update.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkBinaryErodeImageFilter.h"
#include "itkBinaryFunctorImageFilter.h"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinomialBlurImageFilter.h"
#include "itkCannyEdgeDetectionImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkConstantPadImageFilter.h"
#include "itkCosImageFilter.h"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.h"
#include "itkDanielssonDistanceMapImageFilter.h"
#include "itkDerivativeImageFilter.h"
#include "itkDifferenceOfGaussiansGradientImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkDivideImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.h"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkFileIOToImageFilter.h"
#include "itkFirstDerivativeRecursiveGaussianImageFilter.h"
#include "itkGaussianImageSource.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.h"
#include "itkGradientMagnitudeImageFilter.h"
#include "itkGradientNDAnisotropicDiffusionFunction.h"
#include "itkGradientRecursiveGaussianImageFilter.h"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleDilateImageFilter.h"
#include "itkGrayscaleErodeImageFilter.h"
#include "itkGrayscaleFunctionDilateImageFilter.h"
#include "itkGrayscaleFunctionErodeImageFilter.h"
#include "itkImageToMeshFilter.h"
#include "itkImageToParametricSpaceFilter.h"
#include "itkImportImageFilter.h"
#include "itkInteriorExteriorMeshFilter.h"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.h"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMinimumMaximumImageFilter.h"
#include "itkMirrorPadImageFilter.h"
#include "itkMorphologyImageFilter.h"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.h"
#include "itkNeighborhoodOperatorImageFilter.h"
#include "itkNonThreadedShrinkImageFilter.h"
#include "itkPadImageFilter.h"
#include "itkParametricSpaceToImageSpaceMeshFilter.h"
#include "itkPlaheImageFilter.h"
#include "itkRandomImageSource.h"
#include "itkRecursiveGaussianImageFilter.h"
#include "itkRecursiveSeparableImageFilter.h"
#include "itkReflectImageFilter.h"
#include "itkReflectiveImageRegionIterator.h"
#include "itkResampleImageFilter.h"
#include "itkScalarAnisotropicDiffusionFunction.h"
#include "itkSecondDerivativeRecursiveGaussianImageFilter.h"
#include "itkShrinkImageFilter.h"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.h"
#include "itkSpatialFunctionImageEvaluatorFilter.h"
#include "itkSqrtImageFilter.h"
#include "itkStreamingImageFilter.h"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.h"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.h"
#include "itkTransformMeshFilter.h"
#include "itkTwoOutputExampleImageFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkVTKImageExport.h"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.h"
#include "itkVectorAnisotropicDiffusionFunction.h"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.h"
#include "itkVectorExpandImageFilter.h"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.h"
#include "itkVectorNeighborhoodOperatorImageFilter.h"
#include "itkWarpImageFilter.h"
#include "itkWrapPadImageFilter.h"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.h"
#include "itkZeroCrossingImageFilter.h"

int main ( int argc, char* argv )
{

  return 0;
}

<|endoftext|>


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

#include <gtest/gtest.h>

#include <QDateTime>
#include <QJsonDocument>
#include <QVector>

#include "OrbitGgp/Error.h"
#include "OrbitGgp/Instance.h"

namespace orbit_ggp {

TEST(InstanceTests, GetListFromJson) {
  {
    // invalid json
    const auto json = QString("json").toUtf8();
    EXPECT_FALSE(Instance::GetListFromJson(json));
  }

  {
    // empty json
    const auto json = QString("[]").toUtf8();
    const auto empty_instances = Instance::GetListFromJson(json);
    ASSERT_TRUE(empty_instances);
    EXPECT_TRUE(empty_instances.value().empty());
  }

  {
    // one empty json object
    const auto json = QString("[{}]").toUtf8();
    EXPECT_FALSE(Instance::GetListFromJson(json));
  }

  {
    // one element with invalid date
    // pretty json:
    // [
    //  {
    //   "displayName": "a display name",
    //   "id": "instance id",
    //   "ipAddress": "1.1.0.1",
    //   "lastUpdated": "2020-29-09T09:55:20Z",
    //   "owner": "a username",
    //   "pool": "a pool",
    //   "other key": "other value",
    //   "other complex object": {
    //    "object key": "object value"
    //   },
    //  }
    // ]
    const auto json = QString(
                          "[{\"displayName\":\"a display name\",\"id\":\"instance "
                          "id\",\"ipAddress\":\"1.1.0.1\",\"lastUpdated\":\"2020-29-09T09:"
                          "55:20Z\",\"owner\":\"a username\",\"pool\":\"a pool\",\"other "
                          "key\":\"other value\",\"other complex object\":{\"object "
                          "key\":\"object value\"}}]")
                          .toUtf8();
    const auto result = Instance::GetListFromJson(json);
    ASSERT_FALSE(result);
    EXPECT_EQ(result.error().value(), static_cast<int>(orbit_ggp::Error::kUnableToParseJson));
  }

  {
    // one full json object
    // pretty json:
    // [
    //  {
    //   "displayName": "a display name",
    //   "id": "instance id",
    //   "ipAddress": "1.1.0.1",
    //   "lastUpdated": "2020-04-09T09:55:20Z",
    //   "owner": "a username",
    //   "pool": "a pool",
    //   "other key": "other value",
    //   "other complex object": {
    //    "object key": "object value"
    //   },
    //  }
    // ]
    const auto json = QString(
                          "[{\"displayName\":\"a display name\",\"id\":\"instance "
                          "id\",\"ipAddress\":\"1.1.0.1\",\"lastUpdated\":\"2020-04-09T09:"
                          "55:20Z\",\"owner\":\"a username\",\"pool\":\"a pool\",\"other "
                          "key\":\"other value\",\"other complex object\":{\"object "
                          "key\":\"object value\"}}]")
                          .toUtf8();
    const auto result = Instance::GetListFromJson(json);
    ASSERT_TRUE(result);
    const QVector<Instance> instances = std::move(result.value());
    ASSERT_EQ(instances.size(), 1);
    const Instance instance = instances[0];
    EXPECT_EQ(instance.display_name, QString{"a display name"});
    EXPECT_EQ(instance.id, QString{"instance id"});
    EXPECT_EQ(instance.ip_address, QString{"1.1.0.1"});
    EXPECT_EQ(instance.last_updated,
              QDateTime::fromString(QString{"2020-04-09T09:55:20Z"}, Qt::ISODate));
    EXPECT_EQ(instance.owner, QString{"a username"});
    EXPECT_EQ(instance.pool, QString{"a pool"});
  }
}

TEST(InstanceTests, CmpById) {
  Instance test_instance_0;
  Instance test_instance_1;

  // Empty id
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));

  // Same id
  test_instance_0.id = QString{"id"};
  test_instance_1.id = QString{"id"};
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));

  // first < second
  test_instance_0.id = QString{"id a"};
  test_instance_1.id = QString{"id b"};
  EXPECT_TRUE(Instance::CmpById(test_instance_0, test_instance_1));

  // first > second
  test_instance_0.id = QString{"id b"};
  test_instance_1.id = QString{"id a"};
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));
}

TEST(InstanceTests, EqualToOperator) {
  Instance test_instance_0;
  Instance test_instance_1;

  EXPECT_EQ(test_instance_0, test_instance_1);

  test_instance_0.display_name = "a display name";
  test_instance_0.id = "a id";
  test_instance_0.ip_address = "1.1.0.1";
  test_instance_0.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_0.owner = "a username";
  test_instance_0.pool = "a pool";

  EXPECT_NE(test_instance_0, test_instance_1);

  test_instance_1.display_name = "a display name";
  test_instance_1.id = "a id";
  test_instance_1.ip_address = "1.1.0.1";
  test_instance_1.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_1.owner = "a username";
  test_instance_1.pool = "a pool";

  EXPECT_EQ(test_instance_0, test_instance_1);
}

TEST(InstanceTests, NotEqualToOperator) {
  Instance test_instance_0;
  Instance test_instance_1;

  EXPECT_FALSE(test_instance_0 != test_instance_1);

  test_instance_0.display_name = "a display name";
  test_instance_0.id = "a id";
  test_instance_0.ip_address = "1.1.0.1";
  test_instance_0.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_0.owner = "a username";
  test_instance_0.pool = "a pool";

  EXPECT_TRUE(test_instance_0 != test_instance_1);

  test_instance_1.display_name = "a display name";
  test_instance_1.id = "a id";
  test_instance_1.ip_address = "1.1.0.1";
  test_instance_1.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_1.owner = "a username";
  test_instance_1.pool = "a pool";

  EXPECT_FALSE(test_instance_0 != test_instance_1);
}

TEST(InstanceTests, QMetaTypeId) {
  EXPECT_STREQ("OrbitGgp::Instance", QMetaType::typeName(qMetaTypeId<Instance>()));
}

}  // namespace orbit_ggp
<commit_msg>Fixed InstanceTests.QMetaTypeId (Failed).<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtest/gtest.h>

#include <QDateTime>
#include <QJsonDocument>
#include <QVector>

#include "OrbitGgp/Error.h"
#include "OrbitGgp/Instance.h"

namespace orbit_ggp {

TEST(InstanceTests, GetListFromJson) {
  {
    // invalid json
    const auto json = QString("json").toUtf8();
    EXPECT_FALSE(Instance::GetListFromJson(json));
  }

  {
    // empty json
    const auto json = QString("[]").toUtf8();
    const auto empty_instances = Instance::GetListFromJson(json);
    ASSERT_TRUE(empty_instances);
    EXPECT_TRUE(empty_instances.value().empty());
  }

  {
    // one empty json object
    const auto json = QString("[{}]").toUtf8();
    EXPECT_FALSE(Instance::GetListFromJson(json));
  }

  {
    // one element with invalid date
    // pretty json:
    // [
    //  {
    //   "displayName": "a display name",
    //   "id": "instance id",
    //   "ipAddress": "1.1.0.1",
    //   "lastUpdated": "2020-29-09T09:55:20Z",
    //   "owner": "a username",
    //   "pool": "a pool",
    //   "other key": "other value",
    //   "other complex object": {
    //    "object key": "object value"
    //   },
    //  }
    // ]
    const auto json = QString(
                          "[{\"displayName\":\"a display name\",\"id\":\"instance "
                          "id\",\"ipAddress\":\"1.1.0.1\",\"lastUpdated\":\"2020-29-09T09:"
                          "55:20Z\",\"owner\":\"a username\",\"pool\":\"a pool\",\"other "
                          "key\":\"other value\",\"other complex object\":{\"object "
                          "key\":\"object value\"}}]")
                          .toUtf8();
    const auto result = Instance::GetListFromJson(json);
    ASSERT_FALSE(result);
    EXPECT_EQ(result.error().value(), static_cast<int>(orbit_ggp::Error::kUnableToParseJson));
  }

  {
    // one full json object
    // pretty json:
    // [
    //  {
    //   "displayName": "a display name",
    //   "id": "instance id",
    //   "ipAddress": "1.1.0.1",
    //   "lastUpdated": "2020-04-09T09:55:20Z",
    //   "owner": "a username",
    //   "pool": "a pool",
    //   "other key": "other value",
    //   "other complex object": {
    //    "object key": "object value"
    //   },
    //  }
    // ]
    const auto json = QString(
                          "[{\"displayName\":\"a display name\",\"id\":\"instance "
                          "id\",\"ipAddress\":\"1.1.0.1\",\"lastUpdated\":\"2020-04-09T09:"
                          "55:20Z\",\"owner\":\"a username\",\"pool\":\"a pool\",\"other "
                          "key\":\"other value\",\"other complex object\":{\"object "
                          "key\":\"object value\"}}]")
                          .toUtf8();
    const auto result = Instance::GetListFromJson(json);
    ASSERT_TRUE(result);
    const QVector<Instance> instances = std::move(result.value());
    ASSERT_EQ(instances.size(), 1);
    const Instance instance = instances[0];
    EXPECT_EQ(instance.display_name, QString{"a display name"});
    EXPECT_EQ(instance.id, QString{"instance id"});
    EXPECT_EQ(instance.ip_address, QString{"1.1.0.1"});
    EXPECT_EQ(instance.last_updated,
              QDateTime::fromString(QString{"2020-04-09T09:55:20Z"}, Qt::ISODate));
    EXPECT_EQ(instance.owner, QString{"a username"});
    EXPECT_EQ(instance.pool, QString{"a pool"});
  }
}

TEST(InstanceTests, CmpById) {
  Instance test_instance_0;
  Instance test_instance_1;

  // Empty id
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));

  // Same id
  test_instance_0.id = QString{"id"};
  test_instance_1.id = QString{"id"};
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));

  // first < second
  test_instance_0.id = QString{"id a"};
  test_instance_1.id = QString{"id b"};
  EXPECT_TRUE(Instance::CmpById(test_instance_0, test_instance_1));

  // first > second
  test_instance_0.id = QString{"id b"};
  test_instance_1.id = QString{"id a"};
  EXPECT_FALSE(Instance::CmpById(test_instance_0, test_instance_1));
}

TEST(InstanceTests, EqualToOperator) {
  Instance test_instance_0;
  Instance test_instance_1;

  EXPECT_EQ(test_instance_0, test_instance_1);

  test_instance_0.display_name = "a display name";
  test_instance_0.id = "a id";
  test_instance_0.ip_address = "1.1.0.1";
  test_instance_0.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_0.owner = "a username";
  test_instance_0.pool = "a pool";

  EXPECT_NE(test_instance_0, test_instance_1);

  test_instance_1.display_name = "a display name";
  test_instance_1.id = "a id";
  test_instance_1.ip_address = "1.1.0.1";
  test_instance_1.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_1.owner = "a username";
  test_instance_1.pool = "a pool";

  EXPECT_EQ(test_instance_0, test_instance_1);
}

TEST(InstanceTests, NotEqualToOperator) {
  Instance test_instance_0;
  Instance test_instance_1;

  EXPECT_FALSE(test_instance_0 != test_instance_1);

  test_instance_0.display_name = "a display name";
  test_instance_0.id = "a id";
  test_instance_0.ip_address = "1.1.0.1";
  test_instance_0.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_0.owner = "a username";
  test_instance_0.pool = "a pool";

  EXPECT_TRUE(test_instance_0 != test_instance_1);

  test_instance_1.display_name = "a display name";
  test_instance_1.id = "a id";
  test_instance_1.ip_address = "1.1.0.1";
  test_instance_1.last_updated = QDateTime::fromString("2020-01-01T00:42:42Z", Qt::ISODate);
  test_instance_1.owner = "a username";
  test_instance_1.pool = "a pool";

  EXPECT_FALSE(test_instance_0 != test_instance_1);
}

TEST(InstanceTests, QMetaTypeId) {
  EXPECT_STREQ("orbit_ggp::Instance", QMetaType::typeName(qMetaTypeId<Instance>()));
}

}  // namespace orbit_ggp
<|endoftext|>


<commit_before>#include "modelLoader.h"

/**
 * @brief       Loads a UV-based model based on a file path.
 *
 * @param[in]   filePath      The full path to the model source.
 * @param[out]  geometry      The geometry data of the uv model loaded.
 * @param[out]  numVertices   The number of vertices within the uv model.
 *
 * @return     True of the model loaded successfully, false otherwise.
 */
bool ModelLoader::loadUVModel( QString filePath, UVVertex*& geometry,
    int& numVertices )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh** mesh = new aiMesh*[scene->mNumMeshes];

    for( unsigned int i = 0; i < scene->mNumMeshes; i++ )
    {
        mesh[i] = scene->mMeshes[i];
        for( unsigned int j = 0; j < mesh[i]->mNumFaces; j++ )
        {
            numVertices += mesh[i]->mFaces[j].mNumIndices;
        }
    }

    UVVertex* geo = new UVVertex[ numVertices ];

    for( unsigned int h = 0; h < scene->mNumMeshes; h++ )
    {
        for( unsigned int i = 0; i < mesh[h]->mNumFaces; i++ )
        {
            const aiFace& face = mesh[h]->mFaces[i];

            for( unsigned int j = 0; j < 3; j++ )
            {
                aiVector3D pos = mesh[h]->mVertices[ face.mIndices[j] ];
                QVector3D position( pos.x, pos.y, pos.z) ;

                aiVector3D uv = mesh[h]->mTextureCoords[0][face.mIndices[j]];
                QVector2D uv_coords( uv.x, uv.y );

                geo->setPosition( position );
                geo->setUV( uv_coords );

                geo++;
            }
        }
    }

    geo -= numVertices;

    geometry = geo;
    return true;
}

/**
 * @brief       Loads a material-based model based on a file path.
 *
 * @param[in]   filePath      The full path to the model source.
 * @param[out]  geometry      The geometry data of the color model loaded.
 * @param[out]  numVertices   The number of vertices within the color model.
 *
 * @return     True of the model loaded successfully, false otherwise.
 */
bool ModelLoader::loadColorModel( QString filePath, ColorVertex*& geometry,
    int& numVertices )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh** mesh = new aiMesh*[scene->mNumMeshes];

    for( unsigned int i = 0; i < scene->mNumMeshes; i++ )
    {
        mesh[i] = scene->mMeshes[i];
        for( unsigned int j = 0; j < mesh[i]->mNumFaces; j++ )
        {
            numVertices += mesh[i]->mFaces[j].mNumIndices;
        }
    }

    ColorVertex* geo = new ColorVertex[ numVertices ];

    for( unsigned int h = 0; h < scene->mNumMeshes; h++ )
    {
        for( unsigned int i = 0; i < mesh[h]->mNumFaces; i++ )
        {
            const aiFace& face = mesh[h]->mFaces[i];
            const aiMaterial* mtl = scene->mMaterials[
                mesh[h]->mMaterialIndex ];

            for( unsigned int j = 0; j < 3; j++ )
            {
                aiVector3D pos = mesh[h]->mVertices[ face.mIndices[j] ];
                QVector3D position( pos.x, pos.y, pos.z) ;

                QVector4D color( 255.0, 165.0, 0.0, 1.0 );
                aiColor4D diffuse;
                if( AI_SUCCESS == aiGetMaterialColor(
                    mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse ) )
                {
                    color.setW( diffuse.a );
                    color.setX( diffuse.r );
                    color.setY( diffuse.g );
                    color.setZ( diffuse.b );
                }

                geo->setPosition( position );
                geo->setColor( color );

                geo++;
            }
        }
    }

    geo -= numVertices;

    geometry = geo;
    return true;
}

bool ModelLoader::loadTriMesh( QString filePath, btTriangleMesh*& triMesh )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh* mesh = scene->mMeshes[0];

    btTriangleMesh* tempTriMesh = new btTriangleMesh();
    btVector3* triMeshVertices = new btVector3[3];

    for( unsigned int i = 0; i < mesh->mNumFaces; i++ )
    {
        const aiFace& face = mesh->mFaces[i];

        for( unsigned int j = 0; j < 3; j++ )
        {
            aiVector3D pos = mesh->mVertices[ face.mIndices[j] ];
            triMeshVertices[j] = btVector3( pos.x, pos.y, pos.z );
        }

        tempTriMesh->addTriangle( triMeshVertices[0], triMeshVertices[1],
            triMeshVertices[2] );
    }

    triMesh = tempTriMesh;
    return true;
}

<commit_msg>fixed colorModel<commit_after>#include "modelLoader.h"

/**
 * @brief       Loads a UV-based model based on a file path.
 *
 * @param[in]   filePath      The full path to the model source.
 * @param[out]  geometry      The geometry data of the uv model loaded.
 * @param[out]  numVertices   The number of vertices within the uv model.
 *
 * @return     True of the model loaded successfully, false otherwise.
 */
bool ModelLoader::loadUVModel( QString filePath, UVVertex*& geometry,
    int& numVertices )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh** mesh = new aiMesh*[scene->mNumMeshes];

    for( unsigned int i = 0; i < scene->mNumMeshes; i++ )
    {
        mesh[i] = scene->mMeshes[i];
        for( unsigned int j = 0; j < mesh[i]->mNumFaces; j++ )
        {
            numVertices += mesh[i]->mFaces[j].mNumIndices;
        }
    }

    UVVertex* geo = new UVVertex[ numVertices ];

    for( unsigned int h = 0; h < scene->mNumMeshes; h++ )
    {
        for( unsigned int i = 0; i < mesh[h]->mNumFaces; i++ )
        {
            const aiFace& face = mesh[h]->mFaces[i];

            for( unsigned int j = 0; j < 3; j++ )
            {
                aiVector3D pos = mesh[h]->mVertices[ face.mIndices[j] ];
                QVector3D position( pos.x, pos.y, pos.z) ;

                aiVector3D uv = mesh[h]->mTextureCoords[0][face.mIndices[j]];
                QVector2D uv_coords( uv.x, uv.y );

                geo->setPosition( position );
                geo->setUV( uv_coords );

                geo++;
            }
        }
    }

    geo -= numVertices;

    geometry = geo;
    return true;
}

/**
 * @brief       Loads a material-based model based on a file path.
 *
 * @param[in]   filePath      The full path to the model source.
 * @param[out]  geometry      The geometry data of the color model loaded.
 * @param[out]  numVertices   The number of vertices within the color model.
 *
 * @return     True of the model loaded successfully, false otherwise.
 */
bool ModelLoader::loadColorModel( QString filePath, ColorVertex*& geometry,
    int& numVertices )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh** mesh = new aiMesh*[scene->mNumMeshes];

    for( unsigned int i = 0; i < scene->mNumMeshes; i++ )
    {
        mesh[i] = scene->mMeshes[i];
        for( unsigned int j = 0; j < mesh[i]->mNumFaces; j++ )
        {
            numVertices += mesh[i]->mFaces[j].mNumIndices;
        }
    }

    ColorVertex* geo = new ColorVertex[ numVertices ];

    for( unsigned int h = 0; h < scene->mNumMeshes; h++ )
    {
        for( unsigned int i = 0; i < mesh[h]->mNumFaces; i++ )
        {
            const aiFace& face = mesh[h]->mFaces[i];
            const aiMaterial* mtl = scene->mMaterials[
                mesh[h]->mMaterialIndex ];

            for( unsigned int j = 0; j < 3; j++ )
            {
                aiVector3D pos = mesh[h]->mVertices[ face.mIndices[j] ];
                QVector3D position( pos.x, pos.y, pos.z) ;

                QVector4D color( 255.0, 165.0, 0.0, 1.0 );
                aiColor4D diffuse;
                if( AI_SUCCESS == aiGetMaterialColor(
                    mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse ) )
                {
                    color.setW( diffuse.a );
                    color.setX( diffuse.r );
                    color.setY( diffuse.g );
                    color.setZ( diffuse.b );
                }

                geo->setPosition( position );
                geo->setColor( color );
                geo++;
            }
        }
    }

    geo -= numVertices;

    geometry = geo;
    return true;
}

bool ModelLoader::loadTriMesh( QString filePath, btTriangleMesh*& triMesh )
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile( filePath.toStdString(),
        aiProcess_GenSmoothNormals |
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType );

    if( scene == NULL )
    {
        qDebug() << importer.GetErrorString();
        return false;
    }

    aiMesh* mesh = scene->mMeshes[0];

    btTriangleMesh* tempTriMesh = new btTriangleMesh();
    btVector3* triMeshVertices = new btVector3[3];

    for( unsigned int i = 0; i < mesh->mNumFaces; i++ )
    {
        const aiFace& face = mesh->mFaces[i];

        for( unsigned int j = 0; j < 3; j++ )
        {
            aiVector3D pos = mesh->mVertices[ face.mIndices[j] ];
            triMeshVertices[j] = btVector3( pos.x, pos.y, pos.z );
        }

        tempTriMesh->addTriangle( triMeshVertices[0], triMeshVertices[1],
            triMeshVertices[2] );
    }

    triMesh = tempTriMesh;
    return true;
}

<|endoftext|>