<commit_before>#include <iostream>
#include <stdlib.h>
#include <string>

#include "utils.h"
#include "command.h"

/***************************************************
 * Custom commands logic
 ***************************************************/

class InvalidCommand : public Command {
  public:
    InvalidCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = name + ": command not found";
    }

    bool validate() {
      return false;
    }
};

class ExitCommand : public Command {
  public:
    ExitCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem&) {
      exit(0); // TODO: this may cause memory leaks. lets change it if we can help it
    }
};

class InitCommand : public Command {
  public:
    InitCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem& fs) {
      std::cout << "=> Initializing file system...";
      int result = fs.init();
      if (result != RET_OK){
        die("Error initializing file system", result);
      } else {
        std::cout << " DONE!" << std::endl;
      }
    }
};

class LoadCommand : public Command {
  public:
    LoadCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem& fs) {
      std::cout << "=> Loading filesystem...";
      int result = fs.load();
      if (result != RET_OK){
        die("Error loading file system", result);
      } else {
        std::cout << " DONE!" << std::endl;
      }
    }
};

class MakeDirCommand : public Command {
  public:
    MakeDirCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `mkdir /path/to/dir`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      int result = fs.makedir(opts[0]);
      if (result == RET_OK) {
        std::cout << "=> Directory created." << std::endl;
      } else if (result == RET_DIR_ALREADY_EXISTS) {
        std::cout << "[ERROR] Directory already exists!" << std::endl;
      } else if (result == RET_FAT_FULL) {
        std::cout << "[ERROR] FAT is full!" << std::endl;
      }
    }
};

class CreateCommand : public Command {
  public:
    CreateCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `create /path/to/file`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will create file `" + opts[0] + "`");
      // TODO: fs.createfile(opts[0], filesout);
    }
};

class ListCommand : public Command {
  public:
    ListCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `ls /path/to/dir`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will list `" + opts[0] + "`");
      // TODO: fs.listdir(opts[0], filesout);
    }
};

class UnlinkCommand : public Command {
  public:
    UnlinkCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `unlink /path/to/dir` (or file)";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will unlink `" + opts[0] + "`");
      // TODO: fs.listdir(opts[0], filesout);
    }
};

class WriteCommand : public Command {
  public:
    WriteCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `write \"contents-to\" /path/to/file`";
    }

    bool validate() {
      return opts.size() == 2;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will write \"" + opts[0] + "\" to `" + opts[1] + "`");
      // TODO: fs.listdir(opts[0], filesout);
    }
};

class AppendCommand : public Command {
  public:
    AppendCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `append \"contents-to\" /path/to/file`";
    }

    bool validate() {
      return opts.size() == 2;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will append \"" + opts[0] + "\" to `" + opts[1] + "`");
      // TODO: fs.append(opts[0], filesout);
    }
};

class ReadCommand : public Command {
  public:
    ReadCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `read /path/to/file`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will read `" + opts[0] + "`");
      // TODO: fs.read(opts[0], fileout);
    }
};

/***************************************************
 * Command "factory"
 ***************************************************/

Command *Command::parse(const std::string& input) {
  std::string cmd_name = input;
  std::string raw_opts;

  if (cmd_name.find(' ') != std::string::npos) {
    std::string cmd = cmd_name;
    cmd_name = cmd.substr(0, cmd.find(' '));
    raw_opts = cmd.substr(cmd_name.length()+1, cmd.length());
  }

  if (cmd_name == "exit")
    return new ExitCommand(cmd_name, raw_opts);

  if (cmd_name == "init")
    return new InitCommand(cmd_name, raw_opts);

  if (cmd_name == "load")
    return new LoadCommand(cmd_name, raw_opts);

  if (cmd_name == "ls")
    return new ListCommand(cmd_name, raw_opts);

  if (cmd_name == "mkdir")
    return new MakeDirCommand(cmd_name, raw_opts);

  if (cmd_name == "create")
    return new CreateCommand(cmd_name, raw_opts);

  if (cmd_name == "unlink")
    return new UnlinkCommand(cmd_name, raw_opts);

  if (cmd_name == "write")
    return new WriteCommand(cmd_name, raw_opts);

  if (cmd_name == "append")
    return new AppendCommand(cmd_name, raw_opts);

  if (cmd_name == "read")
    return new ReadCommand(cmd_name, raw_opts);

  return new InvalidCommand(cmd_name, raw_opts);
}

/***************************************************
 * Logic common to all commands
 ***************************************************/

Command::Command(const std::string &n, const std::string &o) : name(n), help_text(), opts() {
  // fgtodo: Tratar `write "foo  bar" /dir/file` corretamente, split nao vai ser suficiente
  opts = split(o, ' ');
}
Command::~Command() {}

bool Command::validate() {
  return true;
}

void Command::run(FileSystem&) {
  std::cout << " => Will execute: '" << name << "'" << std::endl;
  std::cout << "    -> Arguments provided: ";
  if (opts.size() > 0) {
    std::cout << "['" << join(opts, "', '") << "']";
  }
  std::cout << std::endl;
}
<commit_msg>Implement list and create commands<commit_after>#include <iostream>
#include <stdlib.h>
#include <string>

#include "utils.h"
#include "command.h"
#include "fsexcept.h"

/***************************************************
 * Custom commands logic
 ***************************************************/

class InvalidCommand : public Command {
  public:
    InvalidCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = name + ": command not found";
    }

    bool validate() {
      return false;
    }
};

class ExitCommand : public Command {
  public:
    ExitCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem&) {
      exit(0); // TODO: this may cause memory leaks. lets change it if we can help it
    }
};

class InitCommand : public Command {
  public:
    InitCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem& fs) {
      std::cout << "=> Initializing file system...";
      int result = fs.init();
      if (result != RET_OK){
        die("Error initializing file system", result);
      } else {
        std::cout << " DONE!" << std::endl;
      }
    }
};

class LoadCommand : public Command {
  public:
    LoadCommand(const std::string &n, const std::string& o) : Command(n, o) {}

    void run(FileSystem& fs) {
      std::cout << "=> Loading filesystem...";
      int result = fs.load();
      if (result != RET_OK){
        die("Error loading file system", result);
      } else {
        std::cout << " DONE!" << std::endl;
      }
    }
};

class MakeDirCommand : public Command {
  public:
    MakeDirCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `mkdir /path/to/dir`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      int result = fs.makedir(opts[0]);
      if (result == RET_OK) {
        std::cout << "=> Directory created." << std::endl;
      } else if (result == RET_NOT_INITIALIZED) {
        std::cout << "[ERROR] Filesystem not loaded!" << std::endl;
      } else if (result == RET_DIR_ALREADY_EXISTS) {
        std::cout << "[ERROR] Directory already exists!" << std::endl;
      } else if (result == RET_FAT_FULL) {
        std::cout << "[ERROR] FAT is full!" << std::endl;
      } else {
        die("Error creating directory", result);
      }
    }
};

class CreateCommand : public Command {
  public:
    CreateCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `create /path/to/file`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      try {
        int result = fs.createfile(opts[0]);
        if (result == RET_OK) {
        } else if (result == RET_FAT_FULL) {
          std::cout << "[ERROR] FAT is full!" << std::endl;
        } else if (result == RET_DIR_ALREADY_EXISTS) {
          std::cout << "[ERROR] Directory already exists!" << std::endl;
        } else if (result == RET_NOT_INITIALIZED) {
          std::cout << "[ERROR] Filesystem not loaded!" << std::endl;
        } else {
          die("Error creating file", result);
        }
      } catch(FSExcept &e) {
        die("Error creating file: " + e.message, e.code);
      }
    }
};

class ListCommand : public Command {
  public:
    ListCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `ls /path/to/dir`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      std::vector<std::string> resp;
      try {
        int result = fs.listdir(opts[0], resp);
        if (result == RET_OK) {
          if (resp.size() == 0) {
            std::cout << "=> Directory is empty" << std::endl;
          } else {
            for (unsigned int i=0; i<resp.size(); i++){
              std::cout << "- " << resp[i] << std::endl;
            }
          }
        } else if (result == RET_NOT_INITIALIZED) {
          std::cout << "[ERROR] Filesystem not loaded!" << std::endl;
        } else {
          die("Error listing directory", result);
        }
      } catch(FSExcept &e) {
        die("Error listing directory: " + e.message, e.code);
      }
    }
};

class UnlinkCommand : public Command {
  public:
    UnlinkCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `unlink /path/to/dir` (or file)";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will unlink `" + opts[0] + "`");
      // TODO: fs.listdir(opts[0], filesout);
    }
};

class WriteCommand : public Command {
  public:
    WriteCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `write \"contents-to\" /path/to/file`";
    }

    bool validate() {
      return opts.size() == 2;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will write \"" + opts[0] + "\" to `" + opts[1] + "`");
      // TODO: fs.listdir(opts[0], filesout);
    }
};

class AppendCommand : public Command {
  public:
    AppendCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `append \"contents-to\" /path/to/file`";
    }

    bool validate() {
      return opts.size() == 2;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will append \"" + opts[0] + "\" to `" + opts[1] + "`");
      // TODO: fs.append(opts[0], filesout);
    }
};

class ReadCommand : public Command {
  public:
    ReadCommand(const std::string &n, const std::string& o) : Command(n, o) {
      help_text = "USAGE: `read /path/to/file`";
    }

    bool validate() {
      return opts.size() == 1;
    }

    void run(FileSystem& fs) {
      (void)fs;
      debug("Will read `" + opts[0] + "`");
      // TODO: fs.read(opts[0], fileout);
    }
};

/***************************************************
 * Command "factory"
 ***************************************************/

Command *Command::parse(const std::string& input) {
  std::string cmd_name = input;
  std::string raw_opts;

  if (cmd_name.find(' ') != std::string::npos) {
    std::string cmd = cmd_name;
    cmd_name = cmd.substr(0, cmd.find(' '));
    raw_opts = cmd.substr(cmd_name.length()+1, cmd.length());
  }

  if (cmd_name == "exit")
    return new ExitCommand(cmd_name, raw_opts);

  if (cmd_name == "init")
    return new InitCommand(cmd_name, raw_opts);

  if (cmd_name == "load")
    return new LoadCommand(cmd_name, raw_opts);

  if (cmd_name == "ls")
    return new ListCommand(cmd_name, raw_opts);

  if (cmd_name == "mkdir")
    return new MakeDirCommand(cmd_name, raw_opts);

  if (cmd_name == "create")
    return new CreateCommand(cmd_name, raw_opts);

  if (cmd_name == "unlink")
    return new UnlinkCommand(cmd_name, raw_opts);

  if (cmd_name == "write")
    return new WriteCommand(cmd_name, raw_opts);

  if (cmd_name == "append")
    return new AppendCommand(cmd_name, raw_opts);

  if (cmd_name == "read")
    return new ReadCommand(cmd_name, raw_opts);

  return new InvalidCommand(cmd_name, raw_opts);
}

/***************************************************
 * Logic common to all commands
 ***************************************************/

Command::Command(const std::string &n, const std::string &o) : name(n), help_text(), opts() {
  // fgtodo: Tratar `write "foo  bar" /dir/file` corretamente, split nao vai ser suficiente
  opts = split(o, ' ');
}
Command::~Command() {}

bool Command::validate() {
  return true;
}

void Command::run(FileSystem&) {
  std::cout << " => Will execute: '" << name << "'" << std::endl;
  std::cout << "    -> Arguments provided: ";
  if (opts.size() > 0) {
    std::cout << "['" << join(opts, "', '") << "']";
  }
  std::cout << std::endl;
}
<|endoftext|>


<commit_before>#include "ceres/ceres.h"
#include "ceres/rotation.h"

#include "opencv2/core.hpp"

#include "util.hpp"
#include "Pipeline.hpp"

using namespace cv;

/*
	structure to evaluate residual and jacobian
*/
struct ErrorFunctor {

	// constructor measurements as argument
	ErrorFunctor(const float observed_x, const float observed_y,
		const float observed_depth,const Mat& cameraMatrix)
	:
	observed_x((double) observed_x),
	observed_y((double) observed_y),
	observed_depth((double) observed_depth){
		cameraMatrix.convertTo(inv_cameraMatrix,CV_64F);
		inv_cameraMatrix = inv_cameraMatrix.inv();
	}

	double observed_x;
	double observed_y;
	double observed_depth;
	Mat inv_cameraMatrix;
	/*
		method to compute residual given rotation vector and translation vector of camera i
		and 3D point j
	*/
    template <typename T>
    bool operator()(const T* const r,
    				const T* const t,
              		const T* const p,
              		T* residuals) const {

    	/*
		angular term
    	*/
    	// observed 3D point is back projected pixel
    	T localPoint3D_obs[3];
    	double c00 = inv_cameraMatrix.at<double>(0,0);
    	double c01 = inv_cameraMatrix.at<double>(0,1);
    	double c02 = inv_cameraMatrix.at<double>(0,2);
    	double c10 = inv_cameraMatrix.at<double>(1,0);
    	double c11 = inv_cameraMatrix.at<double>(1,1);
    	double c12 = inv_cameraMatrix.at<double>(1,2);
    	double c20 = inv_cameraMatrix.at<double>(2,0);
    	double c21 = inv_cameraMatrix.at<double>(2,1);
    	double c22 = inv_cameraMatrix.at<double>(2,2);

    	double tmp0 = c00 * observed_x + c01 * observed_y + c02*1.0;
    	double tmp1 = c10 * observed_x + c11 * observed_y + c12*1.0;
    	double tmp2 = c20 * observed_x + c21 * observed_y + c22*1.0;

    	double len = sqrt(tmp0*tmp0 + tmp1*tmp1 + tmp2*tmp2);

    	localPoint3D_obs[0] = T(tmp0/len);
    	localPoint3D_obs[1] = T(tmp1/len);
    	localPoint3D_obs[2] = T(tmp2/len);

    	// estimated 3D point is estimated point3D transformed in local camera
    	T localPoint3D_est[3];
    	T point3D[3];
    	ceres::AngleAxisRotatePoint(r,p,point3D);
    	localPoint3D_est[0] += t[0];
    	localPoint3D_est[1] += t[1];
    	localPoint3D_est[2] += t[2];

		T norm = sqrt(localPoint3D_est[0]*localPoint3D_est[0]
    		+ localPoint3D_est[1]*localPoint3D_est[1]
    		+ localPoint3D_est[2]*localPoint3D_est[2]);

		localPoint3D_est[0] = localPoint3D_est[0]/norm;
    	localPoint3D_est[1] = localPoint3D_est[1]/norm;
    	localPoint3D_est[2] = localPoint3D_est[2]/norm;

    	residuals[0] = T(1.0) -
    	(localPoint3D_est[0]*localPoint3D_obs[0] +
		 localPoint3D_est[1]*localPoint3D_obs[1] +
		 localPoint3D_est[2]*localPoint3D_obs[2] );

    	/*
		depth term
    	*/
    	T depth_est = sqrt((p[0] - t[0])*(p[0] - t[0])
    	 + (p[1] - t[1])*(p[1] - t[1])
    	 + (p[2] - t[2])*(p[2] - t[2]));
		T depth_obs = T(observed_depth);
    	residuals[1] = depth_est - depth_obs;

     return true;
    }

    // Factory to hide the construction of the CostFunction object from
		// the client code.
		static ceres::CostFunction* Create(const double observed_x,
                                  const double observed_y,
                                  const double observed_depth,
                                  const Mat& cameraMatrix)
		{
 			return (new ceres::AutoDiffCostFunction<ErrorFunctor, 2, 3, 3, 3>(
             new ErrorFunctor(observed_x, observed_y,observed_depth,cameraMatrix)));
		}

};

void Pipeline::bundle_adjustment(
	const PointMap& pointMap,
	const CameraPoses& poses,
	const CamFrames& camFrames,
	PointCloud pointCloud)
{
	Logger _log("Step 8 (BA)");
	// number of parameters per camera and per point
	const int pCamera_num = 6;			// rotation vector 3x1 + translation vector 3x1
	const int pPoint_num = 3;			// point 3x1
	const double huberParam = 16.0;
	const int camera_num = poses.size();
	/*
		set initial parameter
	*/
	double cameras[pCamera_num*camera_num];
	double points[pointCloud.size()];

	ceres::Problem problem;
	// ceres::LossFunction* loss_function = new ceres::HuberLoss(huberParam);
	for (auto it = pointMap.begin();it != pointMap.end(); it++)
	{
		// parameters associated to 3Dpoint
		int pointIdx = it -> second;
		Point3d point3D = Point3_<double>(pointCloud[pointIdx]);

		int pPoint_idx = pointIdx*camera_num;
		points[pPoint_idx] = point3D.x; 		pPoint_idx++;
		points[pPoint_idx] = point3D.y; 		pPoint_idx++;
		points[pPoint_idx] = point3D.z;			pPoint_idx++;

		// parameters associated to cameras
		int camIdx = (it-> first).first;
		int kpIdx = (it-> first).second;

		// camera pose
		Mat r;
		Rodrigues(poses[camIdx].R,r);
		Mat t = poses[camIdx].t;
		// convert to array
		std::cout << t << std::endl;
		std::cout << r << std::endl;
		int pCamera_idx = pCamera_num * camera_num;
		for(int i =0; i<3;i++){
			cameras[pCamera_idx+i] = (double) t.at<float>(i,0);
			cameras[pCamera_idx+i+3] = (double) r.at<float>(i,0);
		}

		// observed pixel
		float observed_x = camFrames[camIdx].key_points[kpIdx].pt.x;
		float observed_y = camFrames[camIdx].key_points[kpIdx].pt.y;
		float observed_depth = camFrames[camIdx].depths[kpIdx];
		ceres::CostFunction* cost_function =
      		ErrorFunctor::Create(
           		observed_x,observed_y,observed_depth,cameraMatrix);
  		problem.AddResidualBlock(cost_function,NULL,cameras+pCamera_idx,points+pPoint_idx)
  		break;
	}

}<commit_msg>bundle fix<commit_after>#include "ceres/ceres.h"
#include "ceres/rotation.h"

#include "opencv2/core.hpp"

#include "util.hpp"
#include "Pipeline.hpp"

using namespace cv;

/*
	structure to evaluate residual and jacobian
*/
struct ErrorFunctor {

	// constructor measurements as argument
	ErrorFunctor(const float observed_x, const float observed_y,
		const float observed_depth,const Mat& cameraMatrix)
	:
	observed_x((double) observed_x),
	observed_y((double) observed_y),
	observed_depth((double) observed_depth){
		cameraMatrix.convertTo(inv_cameraMatrix,CV_64F);
		inv_cameraMatrix = inv_cameraMatrix.inv();
	}

	double observed_x;
	double observed_y;
	double observed_depth;
	Mat inv_cameraMatrix;
	/*
		method to compute residual given rotation vector and translation vector of camera i
		and 3D point j
	*/
    template <typename T>
    bool operator()(const T* const r,
    				const T* const t,
              		const T* const p,
              		T* residuals) const {

    	/*
		angular term
    	*/
    	// observed 3D point is back projected pixel
    	T localPoint3D_obs[3];
    	double c00 = inv_cameraMatrix.at<double>(0,0);
    	double c01 = inv_cameraMatrix.at<double>(0,1);
    	double c02 = inv_cameraMatrix.at<double>(0,2);
    	double c10 = inv_cameraMatrix.at<double>(1,0);
    	double c11 = inv_cameraMatrix.at<double>(1,1);
    	double c12 = inv_cameraMatrix.at<double>(1,2);
    	double c20 = inv_cameraMatrix.at<double>(2,0);
    	double c21 = inv_cameraMatrix.at<double>(2,1);
    	double c22 = inv_cameraMatrix.at<double>(2,2);

    	double tmp0 = c00 * observed_x + c01 * observed_y + c02*1.0;
    	double tmp1 = c10 * observed_x + c11 * observed_y + c12*1.0;
    	double tmp2 = c20 * observed_x + c21 * observed_y + c22*1.0;

    	double len = sqrt(tmp0*tmp0 + tmp1*tmp1 + tmp2*tmp2);

    	localPoint3D_obs[0] = T(tmp0/len);
    	localPoint3D_obs[1] = T(tmp1/len);
    	localPoint3D_obs[2] = T(tmp2/len);

    	// estimated 3D point is estimated point3D transformed in local camera
    	T localPoint3D_est[3];
    	T point3D[3];
    	ceres::AngleAxisRotatePoint(r,p,point3D);
    	localPoint3D_est[0] += t[0];
    	localPoint3D_est[1] += t[1];
    	localPoint3D_est[2] += t[2];

		T norm = sqrt(localPoint3D_est[0]*localPoint3D_est[0]
    		+ localPoint3D_est[1]*localPoint3D_est[1]
    		+ localPoint3D_est[2]*localPoint3D_est[2]);

		localPoint3D_est[0] = localPoint3D_est[0]/norm;
    	localPoint3D_est[1] = localPoint3D_est[1]/norm;
    	localPoint3D_est[2] = localPoint3D_est[2]/norm;

    	residuals[0] = T(1.0) -
    	(localPoint3D_est[0]*localPoint3D_obs[0] +
		 localPoint3D_est[1]*localPoint3D_obs[1] +
		 localPoint3D_est[2]*localPoint3D_obs[2] );

    	/*
		depth term
    	*/
    	T depth_est = sqrt((p[0] - t[0])*(p[0] - t[0])
    	 + (p[1] - t[1])*(p[1] - t[1])
    	 + (p[2] - t[2])*(p[2] - t[2]));
		T depth_obs = T(observed_depth);
    	residuals[1] = depth_est - depth_obs;

     return true;
    }

    // Factory to hide the construction of the CostFunction object from
		// the client code.
		static ceres::CostFunction* Create(const double observed_x,
                                  const double observed_y,
                                  const double observed_depth,
                                  const Mat& cameraMatrix)
		{
 			return (new ceres::AutoDiffCostFunction<ErrorFunctor, 2, 3, 3, 3>(
             new ErrorFunctor(observed_x, observed_y,observed_depth,cameraMatrix)));
		}

};

void Pipeline::bundle_adjustment(
	const PointMap& pointMap,
	const CameraPoses& poses,
	const CamFrames& camFrames,
	PointCloud pointCloud)
{
	Logger _log("Step 8 (BA)");
	// number of parameters per camera and per point
	const int pCamera_num = 6;			// rotation vector 3x1 + translation vector 3x1
	const int pPoint_num = 3;			// point 3x1
	const double huberParam = 16.0;
	const int camera_num = poses.size();
	/*
		set initial parameter
	*/
	double cameras[pCamera_num*camera_num];
	double points[pointCloud.size()];

	ceres::Problem problem;
	// ceres::LossFunction* loss_function = new ceres::HuberLoss(huberParam);
	for (auto it = pointMap.begin();it != pointMap.end(); it++)
	{
		// parameters associated to 3Dpoint
		int pointIdx = it -> second;
		Point3d point3D = Point3_<double>(pointCloud[pointIdx]);

		int pPoint_idx = pointIdx*camera_num;
		points[pPoint_idx] = point3D.x; 		pPoint_idx++;
		points[pPoint_idx] = point3D.y; 		pPoint_idx++;
		points[pPoint_idx] = point3D.z;			pPoint_idx++;

		// parameters associated to cameras
		int camIdx = (it-> first).first;
		int kpIdx = (it-> first).second;

		// camera pose
		Mat r;
		Rodrigues(poses[camIdx].R,r);
		Mat t = poses[camIdx].t;
		// convert to array
		std::cout << t << std::endl;
		std::cout << r << std::endl;
		int pCamera_idx = pCamera_num * camera_num;
		for(int i =0; i<3;i++){
			cameras[pCamera_idx+i] = (double) t.at<float>(i,0);
			cameras[pCamera_idx+i+3] = (double) r.at<float>(i,0);
		}

		// observed pixel
		float observed_x = camFrames[camIdx].key_points[kpIdx].pt.x;
		float observed_y = camFrames[camIdx].key_points[kpIdx].pt.y;
		float observed_depth = camFrames[camIdx].depths[kpIdx];
		ceres::CostFunction* cost_function =
      		ErrorFunctor::Create(
           		observed_x,observed_y,observed_depth,cameraMatrix);
  		// problem.AddResidualBlock(cost_function,NULL,cameras+pCamera_idx,points+pPoint_idx);
  		break;
	}

}<|endoftext|>


<commit_before>#pragma once

#include <bts/blockchain/config.hpp>
#include <bts/blockchain/types.hpp>

#include <fc/io/json.hpp>
#include <fc/reflect/reflect.hpp>
#include <fc/time.hpp>

#include <set>
#include <vector>

const static char*                                          WEB_UPDATES_MANIFEST_URL = "http://dacplay.org/manifest.json";
const static uint8_t                                        WEB_UPDATES_SIGNATURE_REQUIREMENT = 2;
const static std::unordered_set<bts::blockchain::address>   WEB_UPDATES_SIGNING_KEYS ({
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "4ucXsqrD7uvPF4oaQGZtyapdbgZfGMrcP" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "HmsVUBDcWxM1hR3VZ6UCeXFUdgy9u9XLx" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "88fzLmtm2ahKdFQYhgmHWynXkoMKYmZmd" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "Q3axJzb5S9ZNizH7hJoZFQQpeWmvq5Qtu" ) )
});

struct WebUpdateManifest
{
    struct UpdateDetails
    {
        //The version number; must be unique within the manifest.
        //An update will only be installed in a client whose major, fork, and
        //minor versions match those of the update.
        uint8_t majorVersion;
        uint8_t forkVersion;
        uint8_t minorVersion;
        //Patch version is formatted as a char.
        uint8_t patchVersion;

        //Set of signatures for this update; must contain signatures
        //corresponding to at least WEB_UPDATES_SIGNATURE_REQUIREMENT unique
        //keys in WEB_UPDATES_SIGNING_KEYS.
        std::unordered_set<fc::ecc::compact_signature> signatures;

        //Human-readable description of update. May include description,
        //changelog, known issues, etc.
        std::string releaseNotes;

        //Full URL (i.e. https://bitshares.org/toolkit/updates/0.2.4-c.pak)
        //to update package.
        std::string updatePackageUrl;

        //Timestamp of update
        fc::time_point_sec timestamp;

        UpdateDetails()
            : majorVersion(0),
              forkVersion(4),
              minorVersion(16),
              patchVersion('a')
        {}

        bool operator< (const UpdateDetails& other) const
        {
            if (majorVersion != other.majorVersion) return majorVersion < other.majorVersion;
            if (forkVersion != other.forkVersion) return forkVersion < other.forkVersion;
            if (minorVersion != other.minorVersion) return minorVersion < other.minorVersion;
            return patchVersion < other.patchVersion;
        }

        std::string signable_string() {
            UpdateDetails ud = *this;
            ud.signatures.clear();
            return fc::json::to_string(ud);
        }
    };

    std::set<UpdateDetails> updates;
};

FC_REFLECT(WebUpdateManifest::UpdateDetails, (majorVersion)(forkVersion)(minorVersion)(patchVersion)(signatures)(releaseNotes)(updatePackageUrl)(timestamp))
FC_REFLECT(WebUpdateManifest, (updates))
<commit_msg>update manifest url change<commit_after>#pragma once

#include <bts/blockchain/config.hpp>
#include <bts/blockchain/types.hpp>

#include <fc/io/json.hpp>
#include <fc/reflect/reflect.hpp>
#include <fc/time.hpp>

#include <set>
#include <vector>

const static char*                                          WEB_UPDATES_MANIFEST_URL = "https://dacplay.org/manifest.json";
const static uint8_t                                        WEB_UPDATES_SIGNATURE_REQUIREMENT = 2;
const static std::unordered_set<bts::blockchain::address>   WEB_UPDATES_SIGNING_KEYS ({
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "4ucXsqrD7uvPF4oaQGZtyapdbgZfGMrcP" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "HmsVUBDcWxM1hR3VZ6UCeXFUdgy9u9XLx" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "88fzLmtm2ahKdFQYhgmHWynXkoMKYmZmd" ) ),
    bts::blockchain::address( BTS_ADDRESS_PREFIX + std::string( "Q3axJzb5S9ZNizH7hJoZFQQpeWmvq5Qtu" ) )
});

struct WebUpdateManifest
{
    struct UpdateDetails
    {
        //The version number; must be unique within the manifest.
        //An update will only be installed in a client whose major, fork, and
        //minor versions match those of the update.
        uint8_t majorVersion;
        uint8_t forkVersion;
        uint8_t minorVersion;
        //Patch version is formatted as a char.
        uint8_t patchVersion;

        //Set of signatures for this update; must contain signatures
        //corresponding to at least WEB_UPDATES_SIGNATURE_REQUIREMENT unique
        //keys in WEB_UPDATES_SIGNING_KEYS.
        std::unordered_set<fc::ecc::compact_signature> signatures;

        //Human-readable description of update. May include description,
        //changelog, known issues, etc.
        std::string releaseNotes;

        //Full URL (i.e. https://bitshares.org/toolkit/updates/0.2.4-c.pak)
        //to update package.
        std::string updatePackageUrl;

        //Timestamp of update
        fc::time_point_sec timestamp;

        UpdateDetails()
            : majorVersion(0),
              forkVersion(4),
              minorVersion(16),
              patchVersion('a')
        {}

        bool operator< (const UpdateDetails& other) const
        {
            if (majorVersion != other.majorVersion) return majorVersion < other.majorVersion;
            if (forkVersion != other.forkVersion) return forkVersion < other.forkVersion;
            if (minorVersion != other.minorVersion) return minorVersion < other.minorVersion;
            return patchVersion < other.patchVersion;
        }

        std::string signable_string() {
            UpdateDetails ud = *this;
            ud.signatures.clear();
            return fc::json::to_string(ud);
        }
    };

    std::set<UpdateDetails> updates;
};

FC_REFLECT(WebUpdateManifest::UpdateDetails, (majorVersion)(forkVersion)(minorVersion)(patchVersion)(signatures)(releaseNotes)(updatePackageUrl)(timestamp))
FC_REFLECT(WebUpdateManifest, (updates))
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include <list>
#include <string>

#include "base/refcnt.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
#include "mem/packet_impl.hh"
#include "sim/byteswap.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"

#if FULL_SYSTEM
#include "arch/vtophys.hh"
#endif // FULL_SYSTEM

using namespace std;
//The CheckerCPU does alpha only
using namespace AlphaISA;

template <class DynInstPtr>
void
Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
{
    DynInstPtr inst;

    // Either check this instruction, or add it to a list of
    // instructions waiting to be checked.  Instructions must be
    // checked in program order, so if a store has committed yet not
    // completed, there may be some instructions that are waiting
    // behind it that have completed and must be checked.
    if (!instList.empty()) {
        if (youngestSN < completed_inst->seqNum) {
            DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
                    completed_inst->seqNum, completed_inst->readPC());
            instList.push_back(completed_inst);
            youngestSN = completed_inst->seqNum;
        }

        if (!instList.front()->isCompleted()) {
            return;
        } else {
            inst = instList.front();
            instList.pop_front();
        }
    } else {
        if (!completed_inst->isCompleted()) {
            if (youngestSN < completed_inst->seqNum) {
                DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
                        completed_inst->seqNum, completed_inst->readPC());
                instList.push_back(completed_inst);
                youngestSN = completed_inst->seqNum;
            }
            return;
        } else {
            if (youngestSN < completed_inst->seqNum) {
                inst = completed_inst;
                youngestSN = completed_inst->seqNum;
            } else {
                return;
            }
        }
    }

    // Try to check all instructions that are completed, ending if we
    // run out of instructions to check or if an instruction is not
    // yet completed.
    while (1) {
        DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
                inst->seqNum, inst->readPC());
        unverifiedResult.integer = inst->readIntResult();
        unverifiedReq = inst->req;
        unverifiedMemData = inst->memData;
        numCycles++;

        Fault fault = NoFault;

        // maintain $r0 semantics
        thread->setIntReg(ZeroReg, 0);
#ifdef TARGET_ALPHA
        thread->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA

        // Check if any recent PC changes match up with anything we
        // expect to happen.  This is mostly to check if traps or
        // PC-based events have occurred in both the checker and CPU.
        if (changedPC) {
            DPRINTF(Checker, "Changed PC recently to %#x\n",
                    thread->readPC());
            if (willChangePC) {
                if (newPC == thread->readPC()) {
                    DPRINTF(Checker, "Changed PC matches expected PC\n");
                } else {
                    warn("%lli: Changed PC does not match expected PC, "
                         "changed: %#x, expected: %#x",
                         curTick, thread->readPC(), newPC);
                    CheckerCPU::handleError();
                }
                willChangePC = false;
            }
            changedPC = false;
        }
        if (changedNextPC) {
            DPRINTF(Checker, "Changed NextPC recently to %#x\n",
                    thread->readNextPC());
            changedNextPC = false;
        }

        // Try to fetch the instruction

#if FULL_SYSTEM
#define IFETCH_FLAGS(pc)	((pc) & 1) ? PHYSICAL : 0
#else
#define IFETCH_FLAGS(pc)	0
#endif

        uint64_t fetch_PC = thread->readPC() & ~3;

        // set up memory request for instruction fetch
        memReq = new Request(inst->threadNumber, fetch_PC,
                             sizeof(uint32_t),
                             IFETCH_FLAGS(thread->readPC()),
                             fetch_PC, thread->readCpuId(), inst->threadNumber);

        bool succeeded = translateInstReq(memReq);

        if (!succeeded) {
            if (inst->getFault() == NoFault) {
                // In this case the instruction was not a dummy
                // instruction carrying an ITB fault.  In the single
                // threaded case the ITB should still be able to
                // translate this instruction; in the SMT case it's
                // possible that its ITB entry was kicked out.
                warn("%lli: Instruction PC %#x was not found in the ITB!",
                     curTick, thread->readPC());
                handleError(inst);

                // go to the next instruction
                thread->setPC(thread->readNextPC());
                thread->setNextPC(thread->readNextPC() + sizeof(MachInst));

                return;
            } else {
                // The instruction is carrying an ITB fault.  Handle
                // the fault and see if our results match the CPU on
                // the next tick().
                fault = inst->getFault();
            }
        }

        if (fault == NoFault) {
            Packet *pkt = new Packet(memReq, Packet::ReadReq,
                                     Packet::Broadcast);

            pkt->dataStatic(&machInst);

            icachePort->sendFunctional(pkt);

            delete pkt;

            // keep an instruction count
            numInst++;

            // decode the instruction
            machInst = gtoh(machInst);
            // Checks that the instruction matches what we expected it to be.
            // Checks both the machine instruction and the PC.
            validateInst(inst);

            curStaticInst = StaticInst::decode(makeExtMI(machInst,
                                                         thread->readPC()));

#if FULL_SYSTEM
            thread->setInst(machInst);
#endif // FULL_SYSTEM

            fault = inst->getFault();
        }

        // Discard fetch's memReq.
        delete memReq;
        memReq = NULL;

        // Either the instruction was a fault and we should process the fault,
        // or we should just go ahead execute the instruction.  This assumes
        // that the instruction is properly marked as a fault.
        if (fault == NoFault) {

            thread->funcExeInst++;

            fault = curStaticInst->execute(this, NULL);

            // Checks to make sure instrution results are correct.
            validateExecution(inst);

            if (curStaticInst->isLoad()) {
                ++numLoad;
            }
        }

        if (fault != NoFault) {
#if FULL_SYSTEM
            fault->invoke(tc);
            willChangePC = true;
            newPC = thread->readPC();
            DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);
#else // !FULL_SYSTEM
            fatal("fault (%d) detected @ PC 0x%08p", fault, thread->readPC());
#endif // FULL_SYSTEM
        } else {
#if THE_ISA != MIPS_ISA
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#else
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextNPC());
            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif

        }

#if FULL_SYSTEM
        // @todo: Determine if these should happen only if the
        // instruction hasn't faulted.  In the SimpleCPU case this may
        // not be true, but in the O3 or Ozone case this may be true.
        Addr oldpc;
        int count = 0;
        do {
            oldpc = thread->readPC();
            system->pcEventQueue.service(tc);
            count++;
        } while (oldpc != thread->readPC());
        if (count > 1) {
            willChangePC = true;
            newPC = thread->readPC();
            DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
        }
#endif

        // @todo:  Optionally can check all registers. (Or just those
        // that have been modified).
        validateState();

        if (memReq) {
            delete memReq;
            memReq = NULL;
        }

        // Continue verifying instructions if there's another completed
        // instruction waiting to be verified.
        if (instList.empty()) {
            break;
        } else if (instList.front()->isCompleted()) {
            inst = instList.front();
            instList.pop_front();
        } else {
            break;
        }
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::switchOut(Sampler *s)
{
    instList.clear();
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU)
{
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
{
    if (inst->readPC() != thread->readPC()) {
        warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
             curTick, inst->readPC(), thread->readPC());
        if (changedPC) {
            warn("%lli: Changed PCs recently, may not be an error",
                 curTick);
        } else {
            handleError(inst);
        }
    }

    MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);

    if (mi != machInst) {
        warn("%lli: Binary instructions do not match! Inst: %#x, "
             "checker: %#x",
             curTick, mi, machInst);
        handleError(inst);
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
{
    bool result_mismatch = false;
    if (inst->numDestRegs()) {
        // @todo: Support more destination registers.
        if (inst->isUnverifiable()) {
            // Unverifiable instructions assume they were executed
            // properly by the CPU. Grab the result from the
            // instruction and write it to the register.
            copyResult(inst);
        } else if (result.integer != inst->readIntResult()) {
            result_mismatch = true;
        }
    }

    if (result_mismatch) {
        warn("%lli: Instruction results do not match! (Values may not "
             "actually be integers) Inst: %#x, checker: %#x",
             curTick, inst->readIntResult(), result.integer);

        // It's useful to verify load values from memory, but in MP
        // systems the value obtained at execute may be different than
        // the value obtained at completion.  Similarly DMA can
        // present the same problem on even UP systems.  Thus there is
        // the option to only warn on loads having a result error.
        if (inst->isLoad() && warnOnlyOnLoadError) {
            copyResult(inst);
        } else {
            handleError(inst);
        }
    }

    if (inst->readNextPC() != thread->readNextPC()) {
        warn("%lli: Instruction next PCs do not match! Inst: %#x, "
             "checker: %#x",
             curTick, inst->readNextPC(), thread->readNextPC());
        handleError(inst);
    }

    // Checking side effect registers can be difficult if they are not
    // checked simultaneously with the execution of the instruction.
    // This is because other valid instructions may have modified
    // these registers in the meantime, and their values are not
    // stored within the DynInst.
    while (!miscRegIdxs.empty()) {
        int misc_reg_idx = miscRegIdxs.front();
        miscRegIdxs.pop();

        if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
            thread->readMiscReg(misc_reg_idx)) {
            warn("%lli: Misc reg idx %i (side effect) does not match! "
                 "Inst: %#x, checker: %#x",
                 curTick, misc_reg_idx,
                 inst->tcBase()->readMiscReg(misc_reg_idx),
                 thread->readMiscReg(misc_reg_idx));
            handleError(inst);
        }
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateState()
{
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
{
    RegIndex idx = inst->destRegIdx(0);
    if (idx < TheISA::FP_Base_DepTag) {
        thread->setIntReg(idx, inst->readIntResult());
    } else if (idx < TheISA::Fpcr_DepTag) {
        thread->setFloatRegBits(idx, inst->readIntResult());
    } else {
        thread->setMiscReg(idx, inst->readIntResult());
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpAndExit(DynInstPtr &inst)
{
    cprintf("Error detected, instruction information:\n");
    cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
            "Completed:%i\n",
            inst->readPC(),
            inst->readNextPC(),
            inst->seqNum,
            inst->threadNumber,
            inst->isCompleted());
    inst->dump();
    CheckerCPU::dumpAndExit();
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpInsts()
{
    int num = 0;

    InstListIt inst_list_it = --(instList.end());

    cprintf("Inst list size: %i\n", instList.size());

    while (inst_list_it != instList.end())
    {
        cprintf("Instruction:%i\n",
                num);

        cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
                "Completed:%i\n",
                (*inst_list_it)->readPC(),
                (*inst_list_it)->seqNum,
                (*inst_list_it)->threadNumber,
                (*inst_list_it)->isCompleted());

        cprintf("\n");

        inst_list_it--;
        ++num;
    }

}
<commit_msg>Checker ignores any faults that occur in syscall emulation mode for now.<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include <list>
#include <string>

#include "base/refcnt.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
#include "mem/packet_impl.hh"
#include "sim/byteswap.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"

#if FULL_SYSTEM
#include "arch/vtophys.hh"
#endif // FULL_SYSTEM

using namespace std;
//The CheckerCPU does alpha only
using namespace AlphaISA;

template <class DynInstPtr>
void
Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
{
    DynInstPtr inst;

    // Either check this instruction, or add it to a list of
    // instructions waiting to be checked.  Instructions must be
    // checked in program order, so if a store has committed yet not
    // completed, there may be some instructions that are waiting
    // behind it that have completed and must be checked.
    if (!instList.empty()) {
        if (youngestSN < completed_inst->seqNum) {
            DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
                    completed_inst->seqNum, completed_inst->readPC());
            instList.push_back(completed_inst);
            youngestSN = completed_inst->seqNum;
        }

        if (!instList.front()->isCompleted()) {
            return;
        } else {
            inst = instList.front();
            instList.pop_front();
        }
    } else {
        if (!completed_inst->isCompleted()) {
            if (youngestSN < completed_inst->seqNum) {
                DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
                        completed_inst->seqNum, completed_inst->readPC());
                instList.push_back(completed_inst);
                youngestSN = completed_inst->seqNum;
            }
            return;
        } else {
            if (youngestSN < completed_inst->seqNum) {
                inst = completed_inst;
                youngestSN = completed_inst->seqNum;
            } else {
                return;
            }
        }
    }

    // Try to check all instructions that are completed, ending if we
    // run out of instructions to check or if an instruction is not
    // yet completed.
    while (1) {
        DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
                inst->seqNum, inst->readPC());
        unverifiedResult.integer = inst->readIntResult();
        unverifiedReq = inst->req;
        unverifiedMemData = inst->memData;
        numCycles++;

        Fault fault = NoFault;

        // maintain $r0 semantics
        thread->setIntReg(ZeroReg, 0);
#ifdef TARGET_ALPHA
        thread->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA

        // Check if any recent PC changes match up with anything we
        // expect to happen.  This is mostly to check if traps or
        // PC-based events have occurred in both the checker and CPU.
        if (changedPC) {
            DPRINTF(Checker, "Changed PC recently to %#x\n",
                    thread->readPC());
            if (willChangePC) {
                if (newPC == thread->readPC()) {
                    DPRINTF(Checker, "Changed PC matches expected PC\n");
                } else {
                    warn("%lli: Changed PC does not match expected PC, "
                         "changed: %#x, expected: %#x",
                         curTick, thread->readPC(), newPC);
                    CheckerCPU::handleError();
                }
                willChangePC = false;
            }
            changedPC = false;
        }
        if (changedNextPC) {
            DPRINTF(Checker, "Changed NextPC recently to %#x\n",
                    thread->readNextPC());
            changedNextPC = false;
        }

        // Try to fetch the instruction

#if FULL_SYSTEM
#define IFETCH_FLAGS(pc)	((pc) & 1) ? PHYSICAL : 0
#else
#define IFETCH_FLAGS(pc)	0
#endif

        uint64_t fetch_PC = thread->readPC() & ~3;

        // set up memory request for instruction fetch
        memReq = new Request(inst->threadNumber, fetch_PC,
                             sizeof(uint32_t),
                             IFETCH_FLAGS(thread->readPC()),
                             fetch_PC, thread->readCpuId(), inst->threadNumber);

        bool succeeded = translateInstReq(memReq);

        if (!succeeded) {
            if (inst->getFault() == NoFault) {
                // In this case the instruction was not a dummy
                // instruction carrying an ITB fault.  In the single
                // threaded case the ITB should still be able to
                // translate this instruction; in the SMT case it's
                // possible that its ITB entry was kicked out.
                warn("%lli: Instruction PC %#x was not found in the ITB!",
                     curTick, thread->readPC());
                handleError(inst);

                // go to the next instruction
                thread->setPC(thread->readNextPC());
                thread->setNextPC(thread->readNextPC() + sizeof(MachInst));

                return;
            } else {
                // The instruction is carrying an ITB fault.  Handle
                // the fault and see if our results match the CPU on
                // the next tick().
                fault = inst->getFault();
            }
        }

        if (fault == NoFault) {
            Packet *pkt = new Packet(memReq, Packet::ReadReq,
                                     Packet::Broadcast);

            pkt->dataStatic(&machInst);

            icachePort->sendFunctional(pkt);

            delete pkt;

            // keep an instruction count
            numInst++;

            // decode the instruction
            machInst = gtoh(machInst);
            // Checks that the instruction matches what we expected it to be.
            // Checks both the machine instruction and the PC.
            validateInst(inst);

            curStaticInst = StaticInst::decode(makeExtMI(machInst,
                                                         thread->readPC()));

#if FULL_SYSTEM
            thread->setInst(machInst);
#endif // FULL_SYSTEM

            fault = inst->getFault();
        }

        // Discard fetch's memReq.
        delete memReq;
        memReq = NULL;

        // Either the instruction was a fault and we should process the fault,
        // or we should just go ahead execute the instruction.  This assumes
        // that the instruction is properly marked as a fault.
        if (fault == NoFault) {

            thread->funcExeInst++;

            fault = curStaticInst->execute(this, NULL);

            // Checks to make sure instrution results are correct.
            validateExecution(inst);

            if (curStaticInst->isLoad()) {
                ++numLoad;
            }
        }

        if (fault != NoFault) {
#if FULL_SYSTEM
            fault->invoke(tc);
            willChangePC = true;
            newPC = thread->readPC();
            DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);
#endif
        } else {
#if THE_ISA != MIPS_ISA
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#else
            // go to the next instruction
            thread->setPC(thread->readNextPC());
            thread->setNextPC(thread->readNextNPC());
            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif

        }

#if FULL_SYSTEM
        // @todo: Determine if these should happen only if the
        // instruction hasn't faulted.  In the SimpleCPU case this may
        // not be true, but in the O3 or Ozone case this may be true.
        Addr oldpc;
        int count = 0;
        do {
            oldpc = thread->readPC();
            system->pcEventQueue.service(tc);
            count++;
        } while (oldpc != thread->readPC());
        if (count > 1) {
            willChangePC = true;
            newPC = thread->readPC();
            DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
        }
#endif

        // @todo:  Optionally can check all registers. (Or just those
        // that have been modified).
        validateState();

        if (memReq) {
            delete memReq;
            memReq = NULL;
        }

        // Continue verifying instructions if there's another completed
        // instruction waiting to be verified.
        if (instList.empty()) {
            break;
        } else if (instList.front()->isCompleted()) {
            inst = instList.front();
            instList.pop_front();
        } else {
            break;
        }
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::switchOut(Sampler *s)
{
    instList.clear();
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU)
{
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
{
    if (inst->readPC() != thread->readPC()) {
        warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
             curTick, inst->readPC(), thread->readPC());
        if (changedPC) {
            warn("%lli: Changed PCs recently, may not be an error",
                 curTick);
        } else {
            handleError(inst);
        }
    }

    MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);

    if (mi != machInst) {
        warn("%lli: Binary instructions do not match! Inst: %#x, "
             "checker: %#x",
             curTick, mi, machInst);
        handleError(inst);
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
{
    bool result_mismatch = false;
    if (inst->numDestRegs()) {
        // @todo: Support more destination registers.
        if (inst->isUnverifiable()) {
            // Unverifiable instructions assume they were executed
            // properly by the CPU. Grab the result from the
            // instruction and write it to the register.
            copyResult(inst);
        } else if (result.integer != inst->readIntResult()) {
            result_mismatch = true;
        }
    }

    if (result_mismatch) {
        warn("%lli: Instruction results do not match! (Values may not "
             "actually be integers) Inst: %#x, checker: %#x",
             curTick, inst->readIntResult(), result.integer);

        // It's useful to verify load values from memory, but in MP
        // systems the value obtained at execute may be different than
        // the value obtained at completion.  Similarly DMA can
        // present the same problem on even UP systems.  Thus there is
        // the option to only warn on loads having a result error.
        if (inst->isLoad() && warnOnlyOnLoadError) {
            copyResult(inst);
        } else {
            handleError(inst);
        }
    }

    if (inst->readNextPC() != thread->readNextPC()) {
        warn("%lli: Instruction next PCs do not match! Inst: %#x, "
             "checker: %#x",
             curTick, inst->readNextPC(), thread->readNextPC());
        handleError(inst);
    }

    // Checking side effect registers can be difficult if they are not
    // checked simultaneously with the execution of the instruction.
    // This is because other valid instructions may have modified
    // these registers in the meantime, and their values are not
    // stored within the DynInst.
    while (!miscRegIdxs.empty()) {
        int misc_reg_idx = miscRegIdxs.front();
        miscRegIdxs.pop();

        if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
            thread->readMiscReg(misc_reg_idx)) {
            warn("%lli: Misc reg idx %i (side effect) does not match! "
                 "Inst: %#x, checker: %#x",
                 curTick, misc_reg_idx,
                 inst->tcBase()->readMiscReg(misc_reg_idx),
                 thread->readMiscReg(misc_reg_idx));
            handleError(inst);
        }
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::validateState()
{
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
{
    RegIndex idx = inst->destRegIdx(0);
    if (idx < TheISA::FP_Base_DepTag) {
        thread->setIntReg(idx, inst->readIntResult());
    } else if (idx < TheISA::Fpcr_DepTag) {
        thread->setFloatRegBits(idx, inst->readIntResult());
    } else {
        thread->setMiscReg(idx, inst->readIntResult());
    }
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpAndExit(DynInstPtr &inst)
{
    cprintf("Error detected, instruction information:\n");
    cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
            "Completed:%i\n",
            inst->readPC(),
            inst->readNextPC(),
            inst->seqNum,
            inst->threadNumber,
            inst->isCompleted());
    inst->dump();
    CheckerCPU::dumpAndExit();
}

template <class DynInstPtr>
void
Checker<DynInstPtr>::dumpInsts()
{
    int num = 0;

    InstListIt inst_list_it = --(instList.end());

    cprintf("Inst list size: %i\n", instList.size());

    while (inst_list_it != instList.end())
    {
        cprintf("Instruction:%i\n",
                num);

        cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
                "Completed:%i\n",
                (*inst_list_it)->readPC(),
                (*inst_list_it)->seqNum,
                (*inst_list_it)->threadNumber,
                (*inst_list_it)->isCompleted());

        cprintf("\n");

        inst_list_it--;
        ++num;
    }

}
<|endoftext|>


<commit_before>#pragma once

#include <set>

// TODO use move semantics

namespace simple_graph {

int creations = 0;
int copies = 0;
int moves = 0;
int assigns = 0;

template<typename T>
class Vertex {
public:
    Vertex() : idx_(0), data_() {
        ++creations;
    }
    Vertex(const Vertex<T> &v) {
        ++copies;
        idx_ = v.idx_;
        data_ = v.data_;
    }
    Vertex(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        idx_ = v.idx_;
        std::swap(data_, v.data_);
    }
    explicit Vertex(size_t idx) : idx_(idx), data_() {
        ++creations;
    }
    Vertex(size_t idx, const T &data) : idx_(idx), data_(data) {}
    virtual ~Vertex() = default;

    size_t idx() const { return idx_; }
    T data() const { return data_; }

    bool operator<(const Vertex<T> &vertex) const {
        return idx_ < vertex.idx_;
    }

    Vertex &operator=(const Vertex<T> &v) {
        ++assigns;
        if (this != &v) {
            idx_ = v.idx_;
            data_ = v.data_;
        }
        return *this;
    }

    Vertex &operator=(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &v) {
            idx_ = v.idx_;
            std::swap(data_, v.data_);
        }
        return *this;
    }

private:
    size_t idx_;
    T data_;
};

// TODO limit possible types of T
template<typename T>
class Edge {
public:
    Edge() : idx1_(0), idx2_(0), weight_() {}
    Edge(size_t idx1, size_t idx2) : idx1_(idx1), idx2_(idx2), weight_(1) {}
    Edge(size_t idx1, size_t idx2, const T &weight) : idx1_(idx1), idx2_(idx2), weight_(weight) {}

    virtual ~Edge() = default;
    size_t idx1() const { return idx1_; }
    size_t idx2() const { return idx2_; }
    const T &weight() const { return weight_; }

private:
    size_t idx1_;
    size_t idx2_;
    T weight_;
};

template<typename T>
class IteratorImplBase {
public:
    virtual ~IteratorImplBase() = default;
    virtual bool operator==(const IteratorImplBase<T> &it) const = 0;
    virtual bool operator!=(const IteratorImplBase<T> &it) const = 0;
    virtual IteratorImplBase<T> &operator++() = 0;
    virtual T &operator*() = 0;
};

template<typename T>
class iterator {
public:
    iterator(IteratorImplBase<T> *b) : base_impl(b) {}

    bool operator==(const iterator<T> &it) const {
        return base_impl->operator==(*it.base_impl);
    }

    bool operator!=(const iterator<T> &it) const {
        return !operator==(it);
    }

    iterator &operator++() {
        base_impl->operator++();
        return *this;
    }

    T &operator*() {
        return base_impl->operator*();
    }

private:
    IteratorImplBase<T> *base_impl;
};

template<typename V, typename E>
class Graph {
protected:
    class EdgesWrapper {
    public:
        virtual iterator<Edge<E>> begin() = 0;
        virtual iterator<Edge<E>> end() = 0;
    };

public:
    // TODO add constructor from std::initializer_list
    virtual ~Graph() = default;

    virtual int add_vertex(const Vertex<V> &vertex) = 0;
    virtual int add_vertex(Vertex<V> &&vertex) = 0;
    virtual int set_vertex(const Vertex<V> &vertex) = 0;
    virtual void rm_vertex(const Vertex<V> &vertex) = 0;
    // TODO measure performance
    virtual const std::set<size_t> &adjacent_vertices(size_t idx) const = 0;

    virtual const Vertex<V> &vertex(size_t idx) const = 0;
    virtual size_t vertex_num() const = 0;

    virtual int add_edge(const Edge<E> &edge) = 0;
    virtual const Edge<E> &edge(size_t idx1, size_t idx2) const = 0;
    virtual int rm_edge(const Edge<E> &edge) = 0;

    virtual EdgesWrapper &edges() = 0;
};

}  // namespace simple_graph
<commit_msg>Limit edge weight types<commit_after>#pragma once

#include <set>

// TODO use move semantics

namespace simple_graph {

int creations = 0;
int copies = 0;
int moves = 0;
int assigns = 0;

template<typename T>
class Vertex {
public:
    Vertex() : idx_(0), data_() {
        ++creations;
    }
    Vertex(const Vertex<T> &v) {
        ++copies;
        idx_ = v.idx_;
        data_ = v.data_;
    }
    Vertex(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        idx_ = v.idx_;
        std::swap(data_, v.data_);
    }
    explicit Vertex(size_t idx) : idx_(idx), data_() {
        ++creations;
    }
    Vertex(size_t idx, const T &data) : idx_(idx), data_(data) {}
    virtual ~Vertex() = default;

    size_t idx() const { return idx_; }
    T data() const { return data_; }

    bool operator<(const Vertex<T> &vertex) const {
        return idx_ < vertex.idx_;
    }

    Vertex &operator=(const Vertex<T> &v) {
        ++assigns;
        if (this != &v) {
            idx_ = v.idx_;
            data_ = v.data_;
        }
        return *this;
    }

    Vertex &operator=(Vertex<T> &&v) noexcept(noexcept(
                std::is_nothrow_move_constructible<T>::value
                    && std::is_nothrow_move_assignable<T>::value)) {
        ++moves;
        if (this != &v) {
            idx_ = v.idx_;
            std::swap(data_, v.data_);
        }
        return *this;
    }

private:
    size_t idx_;
    T data_;
};

template<typename T>
class Edge {
    static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value,
            "Integer of floating point required.");

public:
    Edge() : idx1_(0), idx2_(0), weight_() {}
    Edge(size_t idx1, size_t idx2) : idx1_(idx1), idx2_(idx2), weight_(1) {}
    Edge(size_t idx1, size_t idx2, const T &weight) : idx1_(idx1), idx2_(idx2), weight_(weight) {}

    virtual ~Edge() = default;
    size_t idx1() const { return idx1_; }
    size_t idx2() const { return idx2_; }
    const T &weight() const { return weight_; }

private:
    size_t idx1_;
    size_t idx2_;
    T weight_;
};

template<typename T>
class IteratorImplBase {
public:
    virtual ~IteratorImplBase() = default;
    virtual bool operator==(const IteratorImplBase<T> &it) const = 0;
    virtual bool operator!=(const IteratorImplBase<T> &it) const = 0;
    virtual IteratorImplBase<T> &operator++() = 0;
    virtual T &operator*() = 0;
};

template<typename T>
class iterator {
public:
    iterator(IteratorImplBase<T> *b) : base_impl(b) {}

    bool operator==(const iterator<T> &it) const {
        return base_impl->operator==(*it.base_impl);
    }

    bool operator!=(const iterator<T> &it) const {
        return !operator==(it);
    }

    iterator &operator++() {
        base_impl->operator++();
        return *this;
    }

    T &operator*() {
        return base_impl->operator*();
    }

private:
    IteratorImplBase<T> *base_impl;
};

template<typename V, typename E>
class Graph {
protected:
    class EdgesWrapper {
    public:
        virtual iterator<Edge<E>> begin() = 0;
        virtual iterator<Edge<E>> end() = 0;
    };

public:
    // TODO add constructor from std::initializer_list
    virtual ~Graph() = default;

    virtual int add_vertex(const Vertex<V> &vertex) = 0;
    virtual int add_vertex(Vertex<V> &&vertex) = 0;
    virtual int set_vertex(const Vertex<V> &vertex) = 0;
    virtual void rm_vertex(const Vertex<V> &vertex) = 0;
    // TODO measure performance
    virtual const std::set<size_t> &adjacent_vertices(size_t idx) const = 0;

    virtual const Vertex<V> &vertex(size_t idx) const = 0;
    virtual size_t vertex_num() const = 0;

    virtual int add_edge(const Edge<E> &edge) = 0;
    virtual const Edge<E> &edge(size_t idx1, size_t idx2) const = 0;
    virtual int rm_edge(const Edge<E> &edge) = 0;

    virtual EdgesWrapper &edges() = 0;
};

}  // namespace simple_graph
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library 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.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/**
 * @file
 * For LWP filter architecture prototype
 * The file declares structures and enums used by Lwp-Drawing-Module
 */

#ifndef _LWPSDWRAWHEADER_HXX
#define _LWPSDWRAWHEADER_HXX

#include "lwpheader.hxx"
#include "lwptools.hxx"

const sal_uInt8 DRAW_FACESIZE = 32;
const double THRESHOLD = 0.0001;

enum DrawObjectType
{
    OT_UNDEFINED   = 0,

    OT_SELECT      = 0,
    OT_HAND        = 1,
    OT_LINE        = 2,
    OT_PERPLINE    = 3,
    OT_POLYLINE    = 4,
    OT_POLYGON     = 5,
    OT_RECT        = 6,
    OT_SQUARE      = 7,
    OT_RNDRECT     = 8,
    OT_RNDSQUARE   = 9,
    OT_OVAL        = 10,
    OT_CIRCLE      = 11,
    OT_ARC         = 12,
    OT_TEXT        = 13,
    OT_GROUP       = 14,
    OT_CHART       = 15,
    OT_METAFILE    = 16,
    OT_METAFILEIMG = 17,
    OT_BITMAP      = 18,
    OT_TEXTART     = 19,
    OT_BIGBITMAP   = 20
};

enum DrawFillType
{
    FT_TRANSPARENT    = 0,
    FT_VLTGRAY        = 1,
    FT_LTGRAY         = 2,
    FT_GRAY           = 3,
    FT_DKGRAY         = 4,
    FT_SOLID          = 5,
    FT_HORZHATCH      = 6,
    FT_VERTHATCH      = 7,
    FT_FDIAGHATCH     = 8,
    FT_BDIAGHATCH     = 9,
    FT_CROSSHATCH     = 10,
    FT_DIAGCROSSHATCH = 11,
    FT_PATTERN        = 12
};

enum DrawLineStyle
{
    LS_SOLID       = 0,
    LS_DASH        = 1,
    LS_DOT         = 2,
    LS_DASHDOT     = 3,
    LS_DASHDOTDOT  = 4,
    LS_NULL        = 5,
    LS_INSIDEFRAME = 6
};

// Text Attributes as stored in Draw files V1.2 and earlier
enum DrawTextAttribute
{
    TA_BOLD           = 0x0001, /* bolded font */
    TA_ITALIC         = 0x0002, /* italic font */
    TA_UNDERLINE      = 0x0004, /* underlined font */
    TA_WORDUNDERLINE  = 0x0008, /* broken underline */
    TA_ALLCAPS        = 0x0010, /* capitalized font */
    TA_SMALLCAPS      = 0x0020, /* all small capital letters */
    TA_DOUBLEUNDER    = 0x0040, /* double underline */
    TA_STRIKETHRU     = 0x0080, /* strikethru */
    TA_SUPERSCRIPT    = 0x0100, /* superscript */
    TA_SUBSCRIPT      = 0x0200  /* subscript */
};

enum DrawArrowHead
{
    AH_ARROW_NONE = 0,
    AH_ARROW_FULLARROW = 1,
    AH_ARROW_HALFARROW = 2,
    AH_ARROW_LINEARROW = 3,
    AH_ARROW_INVFULLARROW = 4,
    AH_ARROW_INVHALFARROW = 5,
    AH_ARROW_INVLINEARROW = 6,
    AH_ARROW_TEE = 7,
    AH_ARROW_SQUARE = 8,
    AH_ARROW_CIRCLE = 9
};

struct SdwPoint
{
    sal_Int16 x;
    sal_Int16 y;
    SdwPoint()
        : x(0)
        , y(0)
    {
    }
};

struct SdwColor
{
    sal_uInt8 nR;
    sal_uInt8 nG;
    sal_uInt8 nB;
    sal_uInt8 unused;
    SdwColor()
        : nR(0)
        , nG(0)
        , nB(0)
        , unused(0)
    {
    }
};

struct SdwClosedObjStyleRec
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    SdwColor aForeColor;
    SdwColor aBackColor;
    sal_uInt16 nFillType;
    sal_uInt8 pFillPattern[8];
};

struct SdwDrawObjHeader
{
//  sal_uInt8 nType
//  sal_uInt8 nFlags;
    sal_uInt16 nRecLen;
    sal_Int16 nLeft;
    sal_Int16 nTop;
    sal_Int16 nRight;
    sal_Int16 nBottom;
//  sal_uInt16 nextObj;
//  sal_uInt16 prevObj;
};

struct SdwLineRecord
{
    sal_Int16 nStartX;
    sal_Int16 nStartY;
    sal_Int16 nEndX;
    sal_Int16 nEndY;
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    SdwLineRecord()
        : nStartX(0)
        , nStartY(0)
        , nEndX(0)
        , nEndY(0)
        , nLineWidth(0)
        , nLineEnd(0)
        , nLineStyle(0)
    {
    }
};

struct SdwPolyLineRecord
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    sal_uInt16 nNumPoints;
    SdwPolyLineRecord()
        : nLineWidth(0)
        , nLineEnd(0)
        , nLineStyle(0)
        , nNumPoints(0)
    {
    }
};

struct SdwArcRecord
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
};

struct SdwTextBoxRecord
{
    sal_Int16 nTextWidth;
    sal_Int16 nTextHeight;
    sal_Int16 nTextSize;
    SdwColor aTextColor;
    sal_uInt8 tmpTextFaceName[DRAW_FACESIZE];
    sal_uInt16 nTextAttrs;
    sal_uInt16 nTextCharacterSet;
    sal_Int16 nTextRotation;
    sal_Int16 nTextExtraSpacing;
    sal_uInt8* pTextString;
};

struct SdwFMPATH
{
    sal_uInt16 n;
    SdwPoint* pPts;
    SdwFMPATH()
        : n(0)
        , pPts(NULL)
    {
    }
};

struct SdwTextArt : public SdwTextBoxRecord
{
    sal_uInt8 nIndex;
    sal_Int16 nRotation;
    sal_uInt16 nTextLen;
    SdwFMPATH aPath[2];
    SdwTextArt()
        : nIndex(0)
        , nRotation(0)
        , nTextLen(0)
    {
    }
};

struct SdwBmpRecord
{
    sal_uInt16 nTranslation;
    sal_uInt16 nRotation;
    sal_uInt32 nFileSize;
    SdwBmpRecord()
        : nTranslation(0)
        , nRotation(0)
        , nFileSize(0)
    {
    }
};

struct BmpInfoHeader
{
    sal_uInt32 nHeaderLen;
    sal_uInt16 nWidth;
    sal_uInt16 nHeight;
    sal_uInt16 nPlanes;
    sal_uInt16 nBitCount;
};

struct BmpInfoHeader2
{
    sal_uInt32 nHeaderLen;
    sal_uInt32 nWidth;
    sal_uInt32 nHeight;
    sal_uInt16 nPlanes;
    sal_uInt16 nBitCount;
};

struct DrawingOffsetAndScale
{
    double fOffsetX;
    double fOffsetY;
    double fScaleX;
    double fScaleY;
    double fLeftMargin;
    double fTopMargin;

    DrawingOffsetAndScale()
    {
        fOffsetX = 0.00;
        fOffsetY = 0.00;
        fScaleX = 1.00;
        fScaleY = 1.00;
        fLeftMargin = 0.00;
        fTopMargin = 0.00;
    }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#738697 Uninitialized scalar field<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library 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.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/**
 * @file
 * For LWP filter architecture prototype
 * The file declares structures and enums used by Lwp-Drawing-Module
 */

#ifndef _LWPSDWRAWHEADER_HXX
#define _LWPSDWRAWHEADER_HXX

#include "lwpheader.hxx"
#include "lwptools.hxx"

const sal_uInt8 DRAW_FACESIZE = 32;
const double THRESHOLD = 0.0001;

enum DrawObjectType
{
    OT_UNDEFINED   = 0,

    OT_SELECT      = 0,
    OT_HAND        = 1,
    OT_LINE        = 2,
    OT_PERPLINE    = 3,
    OT_POLYLINE    = 4,
    OT_POLYGON     = 5,
    OT_RECT        = 6,
    OT_SQUARE      = 7,
    OT_RNDRECT     = 8,
    OT_RNDSQUARE   = 9,
    OT_OVAL        = 10,
    OT_CIRCLE      = 11,
    OT_ARC         = 12,
    OT_TEXT        = 13,
    OT_GROUP       = 14,
    OT_CHART       = 15,
    OT_METAFILE    = 16,
    OT_METAFILEIMG = 17,
    OT_BITMAP      = 18,
    OT_TEXTART     = 19,
    OT_BIGBITMAP   = 20
};

enum DrawFillType
{
    FT_TRANSPARENT    = 0,
    FT_VLTGRAY        = 1,
    FT_LTGRAY         = 2,
    FT_GRAY           = 3,
    FT_DKGRAY         = 4,
    FT_SOLID          = 5,
    FT_HORZHATCH      = 6,
    FT_VERTHATCH      = 7,
    FT_FDIAGHATCH     = 8,
    FT_BDIAGHATCH     = 9,
    FT_CROSSHATCH     = 10,
    FT_DIAGCROSSHATCH = 11,
    FT_PATTERN        = 12
};

enum DrawLineStyle
{
    LS_SOLID       = 0,
    LS_DASH        = 1,
    LS_DOT         = 2,
    LS_DASHDOT     = 3,
    LS_DASHDOTDOT  = 4,
    LS_NULL        = 5,
    LS_INSIDEFRAME = 6
};

// Text Attributes as stored in Draw files V1.2 and earlier
enum DrawTextAttribute
{
    TA_BOLD           = 0x0001, /* bolded font */
    TA_ITALIC         = 0x0002, /* italic font */
    TA_UNDERLINE      = 0x0004, /* underlined font */
    TA_WORDUNDERLINE  = 0x0008, /* broken underline */
    TA_ALLCAPS        = 0x0010, /* capitalized font */
    TA_SMALLCAPS      = 0x0020, /* all small capital letters */
    TA_DOUBLEUNDER    = 0x0040, /* double underline */
    TA_STRIKETHRU     = 0x0080, /* strikethru */
    TA_SUPERSCRIPT    = 0x0100, /* superscript */
    TA_SUBSCRIPT      = 0x0200  /* subscript */
};

enum DrawArrowHead
{
    AH_ARROW_NONE = 0,
    AH_ARROW_FULLARROW = 1,
    AH_ARROW_HALFARROW = 2,
    AH_ARROW_LINEARROW = 3,
    AH_ARROW_INVFULLARROW = 4,
    AH_ARROW_INVHALFARROW = 5,
    AH_ARROW_INVLINEARROW = 6,
    AH_ARROW_TEE = 7,
    AH_ARROW_SQUARE = 8,
    AH_ARROW_CIRCLE = 9
};

struct SdwPoint
{
    sal_Int16 x;
    sal_Int16 y;
    SdwPoint()
        : x(0)
        , y(0)
    {
    }
};

struct SdwColor
{
    sal_uInt8 nR;
    sal_uInt8 nG;
    sal_uInt8 nB;
    sal_uInt8 unused;
    SdwColor()
        : nR(0)
        , nG(0)
        , nB(0)
        , unused(0)
    {
    }
};

struct SdwClosedObjStyleRec
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    SdwColor aForeColor;
    SdwColor aBackColor;
    sal_uInt16 nFillType;
    sal_uInt8 pFillPattern[8];
    SdwClosedObjStyleRec()
        : nLineWidth(0)
        , nLineStyle(0)
        , nFillType(0)
    {
        memset(pFillPattern, 0, sizeof(pFillPattern));
    }
};

struct SdwDrawObjHeader
{
    sal_uInt16 nRecLen;
    sal_Int16 nLeft;
    sal_Int16 nTop;
    sal_Int16 nRight;
    sal_Int16 nBottom;
    SdwDrawObjHeader()
        : nRecLen(0)
        , nLeft(0)
        , nTop(0)
        , nRight(0)
        , nBottom(0)
    {
    }
};

struct SdwLineRecord
{
    sal_Int16 nStartX;
    sal_Int16 nStartY;
    sal_Int16 nEndX;
    sal_Int16 nEndY;
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    SdwLineRecord()
        : nStartX(0)
        , nStartY(0)
        , nEndX(0)
        , nEndY(0)
        , nLineWidth(0)
        , nLineEnd(0)
        , nLineStyle(0)
    {
    }
};

struct SdwPolyLineRecord
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
    sal_uInt16 nNumPoints;
    SdwPolyLineRecord()
        : nLineWidth(0)
        , nLineEnd(0)
        , nLineStyle(0)
        , nNumPoints(0)
    {
    }
};

struct SdwArcRecord
{
    sal_uInt8 nLineWidth;
    sal_uInt8 nLineEnd;
    sal_uInt8 nLineStyle;
    SdwColor aPenColor;
};

struct SdwTextBoxRecord
{
    sal_Int16 nTextWidth;
    sal_Int16 nTextHeight;
    sal_Int16 nTextSize;
    SdwColor aTextColor;
    sal_uInt8 tmpTextFaceName[DRAW_FACESIZE];
    sal_uInt16 nTextAttrs;
    sal_uInt16 nTextCharacterSet;
    sal_Int16 nTextRotation;
    sal_Int16 nTextExtraSpacing;
    sal_uInt8* pTextString;
};

struct SdwFMPATH
{
    sal_uInt16 n;
    SdwPoint* pPts;
    SdwFMPATH()
        : n(0)
        , pPts(NULL)
    {
    }
};

struct SdwTextArt : public SdwTextBoxRecord
{
    sal_uInt8 nIndex;
    sal_Int16 nRotation;
    sal_uInt16 nTextLen;
    SdwFMPATH aPath[2];
    SdwTextArt()
        : nIndex(0)
        , nRotation(0)
        , nTextLen(0)
    {
    }
};

struct SdwBmpRecord
{
    sal_uInt16 nTranslation;
    sal_uInt16 nRotation;
    sal_uInt32 nFileSize;
    SdwBmpRecord()
        : nTranslation(0)
        , nRotation(0)
        , nFileSize(0)
    {
    }
};

struct BmpInfoHeader
{
    sal_uInt32 nHeaderLen;
    sal_uInt16 nWidth;
    sal_uInt16 nHeight;
    sal_uInt16 nPlanes;
    sal_uInt16 nBitCount;
};

struct BmpInfoHeader2
{
    sal_uInt32 nHeaderLen;
    sal_uInt32 nWidth;
    sal_uInt32 nHeight;
    sal_uInt16 nPlanes;
    sal_uInt16 nBitCount;
};

struct DrawingOffsetAndScale
{
    double fOffsetX;
    double fOffsetY;
    double fScaleX;
    double fScaleY;
    double fLeftMargin;
    double fTopMargin;

    DrawingOffsetAndScale()
    {
        fOffsetX = 0.00;
        fOffsetY = 0.00;
        fScaleX = 1.00;
        fScaleY = 1.00;
        fLeftMargin = 0.00;
        fTopMargin = 0.00;
    }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#ifndef slic3r_GLModel_hpp_
#define slic3r_GLModel_hpp_

#include "libslic3r/Point.hpp"
#include "libslic3r/BoundingBox.hpp"
#include <vector>
#include <string>

namespace Slic3r {

class TriangleMesh;
class Polygon;
using Polygons = std::vector<Polygon>;

namespace GUI {

    class GLModel
    {
    public:
        enum class PrimitiveType : unsigned char
        {
            Triangles,
            Lines,
            LineStrip,
            LineLoop
        };

        struct RenderData
        {
            PrimitiveType type;
            unsigned int vbo_id{ 0 };
            unsigned int ibo_id{ 0 };
            size_t indices_count{ 0 };
            std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
        };

        struct InitializationData
        {
            struct Entity
            {
                PrimitiveType type;
                std::vector<Vec3f> positions;
                std::vector<Vec3f> normals;
                std::vector<unsigned int> indices;
                std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
            };

            std::vector<Entity> entities;

#if ENABLE_SEAMS_USING_BATCHED_MODELS
            size_t vertices_count() const;
            size_t vertices_size_floats() const { return vertices_count() * 6; }
            size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }

            size_t indices_count() const;
            size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
        };

    private:
        std::vector<RenderData> m_render_data;

        BoundingBoxf3 m_bounding_box;
        std::string m_filename;

    public:
        GLModel() = default;
        virtual ~GLModel() { reset(); }

        void init_from(const InitializationData& data);
        void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
        void init_from(const indexed_triangle_set& its);
        void init_from(const Polygons& polygons, float z);
        bool init_from_file(const std::string& filename);

        // if entity_id == -1 set the color of all entities
        void set_color(int entity_id, const std::array<float, 4>& color);

        void reset();
        void render() const;
#if ENABLE_SEAMS_USING_MODELS
        void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
#endif // ENABLE_SEAMS_USING_MODELS

        bool is_initialized() const { return !m_render_data.empty(); }

        const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
        const std::string& get_filename() const { return m_filename; }

    private:
        void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
    };

    // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
    // the origin of the arrow is in the center of the stem cap
    // the arrow has its axis of symmetry along the Z axis and is pointing upward
    // used to render bed axes and sequential marker
    GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);

    // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
    // the origin of the arrow is in the center of the circle
    // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
    // used to render sidebar hints for rotations
    GLModel::InitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);

    // create an arrow with the given dimensions
    // the origin of the arrow is in the center of the stem cap
    // the arrow is contained in XY plane and has its main axis along the Y axis
    // used to render sidebar hints for position and scale
    GLModel::InitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness);

    // create a diamond with the given resolution
    // the origin of the diamond is in its center
    // the diamond is contained into a box with size [1, 1, 1]
    GLModel::InitializationData diamond(int resolution);

} // namespace GUI
} // namespace Slic3r

#endif // slic3r_GLModel_hpp_

<commit_msg>Added a forward declaration needed on GCC 9.4.0<commit_after>#ifndef slic3r_GLModel_hpp_
#define slic3r_GLModel_hpp_

#include "libslic3r/Point.hpp"
#include "libslic3r/BoundingBox.hpp"
#include <vector>
#include <string>

struct indexed_triangle_set;

namespace Slic3r {

class TriangleMesh;
class Polygon;
using Polygons = std::vector<Polygon>;

namespace GUI {

    class GLModel
    {
    public:
        enum class PrimitiveType : unsigned char
        {
            Triangles,
            Lines,
            LineStrip,
            LineLoop
        };

        struct RenderData
        {
            PrimitiveType type;
            unsigned int vbo_id{ 0 };
            unsigned int ibo_id{ 0 };
            size_t indices_count{ 0 };
            std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
        };

        struct InitializationData
        {
            struct Entity
            {
                PrimitiveType type;
                std::vector<Vec3f> positions;
                std::vector<Vec3f> normals;
                std::vector<unsigned int> indices;
                std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
            };

            std::vector<Entity> entities;

#if ENABLE_SEAMS_USING_BATCHED_MODELS
            size_t vertices_count() const;
            size_t vertices_size_floats() const { return vertices_count() * 6; }
            size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }

            size_t indices_count() const;
            size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
#endif // ENABLE_SEAMS_USING_BATCHED_MODELS
        };

    private:
        std::vector<RenderData> m_render_data;

        BoundingBoxf3 m_bounding_box;
        std::string m_filename;

    public:
        GLModel() = default;
        virtual ~GLModel() { reset(); }

        void init_from(const InitializationData& data);
        void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
        void init_from(const indexed_triangle_set& its);
        void init_from(const Polygons& polygons, float z);
        bool init_from_file(const std::string& filename);

        // if entity_id == -1 set the color of all entities
        void set_color(int entity_id, const std::array<float, 4>& color);

        void reset();
        void render() const;
#if ENABLE_SEAMS_USING_MODELS
        void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
#endif // ENABLE_SEAMS_USING_MODELS

        bool is_initialized() const { return !m_render_data.empty(); }

        const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
        const std::string& get_filename() const { return m_filename; }

    private:
        void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
    };

    // create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
    // the origin of the arrow is in the center of the stem cap
    // the arrow has its axis of symmetry along the Z axis and is pointing upward
    // used to render bed axes and sequential marker
    GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);

    // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
    // the origin of the arrow is in the center of the circle
    // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
    // used to render sidebar hints for rotations
    GLModel::InitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);

    // create an arrow with the given dimensions
    // the origin of the arrow is in the center of the stem cap
    // the arrow is contained in XY plane and has its main axis along the Y axis
    // used to render sidebar hints for position and scale
    GLModel::InitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness);

    // create a diamond with the given resolution
    // the origin of the diamond is in its center
    // the diamond is contained into a box with size [1, 1, 1]
    GLModel::InitializationData diamond(int resolution);

} // namespace GUI
} // namespace Slic3r

#endif // slic3r_GLModel_hpp_

<|endoftext|>