<commit_before>/**
   MiracleGrue - Model Generator for toolpathing. <http://www.grue.makerbot.com>
   Copyright (C) 2011 Far McKon <Far@makerbot.com>, Hugo Boyer (hugo@makerbot.com)

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.

*/

#include <iostream>
#include <string>

#include <stdlib.h>
#include <boost/filesystem.hpp>

#include "mgl/abstractable.h"
#include "mgl/configuration.h"
#include "mgl/miracle.h"

#include "Vector2.h"
#include <clpp/parser.hpp>

using namespace std;
using namespace mgl;

int intFromCharEqualsStr(const std::string& str)
{
	string nb = str.substr(2, str.length()-2);
	int val = atoi(nb.c_str());
	return val;
}

double doubleFromCharEqualsStr(const std::string& str)
{
	string nb = str.substr(2, str.length()-2);
	double val = atof(nb.c_str());
	return val;
}

class ConfigSetter {
	typedef enum {NONE, INT, STR, DBL, BOOL} configtype;
public:
	ConfigSetter(Configuration &c, const string &s, const string &n):
		config(c), section(s), name(n), set(NONE) {};
	void set_s(const string val) {
		sval = val;
		set = STR;
	};
	void set_d(const double val) {
		dval = val;
		set = DBL;
	};
	void set_i(const int val) {
		ival = val;
		set = INT;
	};
	void set_b() {
		set = BOOL;
	};
	~ConfigSetter() {
		if (set == NONE)
			return;

		cout << section + "." + name + " = ";

		if (set == INT) {
			config[section.c_str()][name.c_str()] = ival;
			cout << ival << endl;
		}
		else if (set == DBL) {
			config[section.c_str()][name.c_str()] = dval;
			cout << dval << endl;
		}
		else if (set == STR) {
			config[section.c_str()][name.c_str()] = sval;
			cout << sval << endl;
		}
		else if (set == BOOL) {
			config[section.c_str()][name.c_str()] = true;
			cout << "true"<< endl;
		}
	};
private:
	Configuration &config;
	const string &section;
	const string &name;
	configtype set;
	string sval;
	double dval;
	int ival;
};

void usage() {
	cout << endl;
	cout << endl;
	cout << "This program translates a 3d model file in STL format to GCODE toolpath for a 3D printer "<< endl;
	cout << "It also generates an OpenScad file for visualization"<< endl;
	cout << endl;
	cout << "usage: miracle-grue [OPTIONS] STL FILE" << endl;
	cout << "options: " << endl;
	cout << "  -c --config        : set the configuration file (default is local miracle.config)" << endl;
	cout << "  -f --firstLayerZ   : override the first layer height" << endl;
	cout << "  -l --layerH        : override the layer height" << endl;
	cout << "  -w --layerW        : override layer width" << endl;
	cout << "  -t --tubeSpacing   : override the infill grid width" << endl;
	cout << "  -a --angle         : override the infill grid inter slice angle (radians)" << endl;
	cout << "  -s --nbOfShells    : override the number of shells" << endl;
	cout << "  -n --firstSliceIdx : slice from a specific slice" << endl;
	cout << "  -m --lastSliceIdx  : stop slicing at specific slice" << endl;
	cout << "  -d --writeDebug    : debug mode (creates scad files for each inset error)" << endl;
	cout << endl;
	cout << "It is pitch black. You are likely to be eaten by a grue." << endl;
}

void exitUsage() {
	usage();
	exit(0);
}

void parseArgs(Configuration &config,
				int argc,
				char *argv[],
				string &modelFile,
				string &configFileName,
				int &firstSliceIdx,
				int &lastSliceIdx)
{
	firstSliceIdx = -1;
	lastSliceIdx = -1;

	//first get the config parameter and parse the file so that other params can override the
	//config
	clpp::command_line_parameters_parser parser;

	parser.add_parameter("-h", "--help", &exitUsage);

	parser.add_parameter("-c", "--config", &config, &Configuration::readFromFile)
	    .default_value("miracle.config");

	ConfigSetter f(config, "slicer", "firstLayerZ");
	parser.add_parameter("-f", "--firstLayerZ", &f, &ConfigSetter::set_d);

	ConfigSetter l(config, "slicer", "layerH");
	parser.add_parameter("-l", "--layerH", &l, &ConfigSetter::set_d);

	ConfigSetter w(config, "slicer", "layerW");
	parser.add_parameter("-w", "--layerW", &w, &ConfigSetter::set_d);

	ConfigSetter t(config, "slicer", "tubeSpacing");
	parser.add_parameter("-t", "--tubeSpacing", &t, &ConfigSetter::set_d);

	ConfigSetter a(config, "slicer", "angle");
	parser.add_parameter("-a", "--angle", &a, &ConfigSetter::set_d);

	ConfigSetter s(config, "slicer", "nbOfShells");
	parser.add_parameter("-s", "--nbOfShells", &s, &ConfigSetter::set_d);

	ConfigSetter d(config, "slicer", "writeDebugScadFiles");
	parser.add_parameter("-d", "--writeDebug", &d, &ConfigSetter::set_b);

	ConfigSetter n(config, "slicer", "firstSliceIdx");
	parser.add_parameter("-n", "--firstSliceIdx", &n, &ConfigSetter::set_i);

	firstSliceIdx = config["slicer"]["firstSliceIdx"].asInt();

	ConfigSetter m(config, "slicer", "lastSliceIdx");
	parser.add_parameter("-m", "--lastSliceIdx", &m, &ConfigSetter::set_i);

	lastSliceIdx = config["slicer"]["lastSliceIdx"].asInt();

	try {
		parser.parse(argc - 1, argv);
	}
	catch (std::exception &exp) {
		usage();
		throw mgl::Exception(exp.what());
	}
	catch (mgl::Exception &exp) {
		usage();
		throw exp;
	}

	//handle the unnamed parameter separately
	modelFile = argv[argc  - 1];
	if (!boost::filesystem::is_regular_file(modelFile)) {
		usage();
		throw mgl::Exception(("Invalid model file [" + modelFile + "]").c_str());
	}
}

int preConditionsOrShowUsage(int argc, char *argv[])
{
	cout << endl;
	cout << "Miracle-Grue "<< getMiracleGrueVersionStr() << endl;
	cout << "Makerbot Industries 2012"  << endl;
	cout << endl;

	cout << endl;

	if (argc < 2)
	{
		usage();
		return (-1);
	}
	return 0;
}

int main(int argc, char *argv[], char *envp[])
{

	// design by contract ;-)
	int checks = preConditionsOrShowUsage(argc, argv);
	if(checks != 0)
	{
		return checks;
	}

	string modelFile;
	string configFileName = "miracle.config";

    Configuration config;
    try
    {

		config.readFromFile(configFileName.c_str());

		int firstSliceIdx, lastSliceIdx;
		parseArgs(config, argc, argv, modelFile, configFileName, firstSliceIdx, lastSliceIdx);
		// cout << config.asJson() << endl;

		MyComputer computer;
		cout << endl;
		cout << endl;
		cout << "behold!" << endl;
		cout << "Materialization of \"" << modelFile << "\" has begun at " << computer.clock.now() << endl;

		std::string scadFile = "."; // outDir
		scadFile += computer.fileSystem.getPathSeparatorCharacter();
		scadFile = computer.fileSystem.ChangeExtension(computer.fileSystem.ExtractFilename(modelFile.c_str()).c_str(), ".scad" );

		std::string gcodeFile = ".";
		gcodeFile += computer.fileSystem.getPathSeparatorCharacter();
		gcodeFile = computer.fileSystem.ChangeExtension(computer.fileSystem.ExtractFilename(modelFile.c_str()).c_str(), ".gcode" );

		cout << endl << endl;
		cout << modelFile << " to \"" << gcodeFile << "\" and \"" << scadFile << "\"" << endl;

		GCoder gcoder;
		loadGCoderData(config, gcoder);

		Slicer slicer;
		loadSlicerData(config, slicer);
		std::vector<mgl::SliceData> slices;
		std::vector<Scalar> zIndicies;
		const char* scad = NULL;

		if (scadFile.size() > 0 )
			scad = scadFile.c_str();

	//	Meshy mesh(slicer.firstLayerZ, slicer.layerH);
	//	mesh.readStlFile(modelFile.c_str());

		miracleGrue(gcoder, slicer, modelFile.c_str(),
					scad, gcodeFile.c_str(),
					firstSliceIdx, lastSliceIdx, slices);

    }
    catch(mgl::Exception &mixup)
    {
    	cout << "ERROR: "<< mixup.error << endl;
    	return -1;
    }
}
<commit_msg>Fixed the fancy new command line parser so it actually saves values<commit_after>/**
   MiracleGrue - Model Generator for toolpathing. <http://www.grue.makerbot.com>
   Copyright (C) 2011 Far McKon <Far@makerbot.com>, Hugo Boyer (hugo@makerbot.com)

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.

*/

#include <iostream>
#include <string>

#include <stdlib.h>
#include <boost/filesystem.hpp>

#include "mgl/abstractable.h"
#include "mgl/configuration.h"
#include "mgl/miracle.h"

#include "Vector2.h"
#include <clpp/parser.hpp>

using namespace std;
using namespace mgl;

int intFromCharEqualsStr(const std::string& str)
{
	string nb = str.substr(2, str.length()-2);
	int val = atoi(nb.c_str());
	return val;
}

double doubleFromCharEqualsStr(const std::string& str)
{
	string nb = str.substr(2, str.length()-2);
	double val = atof(nb.c_str());
	return val;
}

class ConfigSetter {
	typedef enum {NONE, INT, STR, DBL, BOOL} configtype;
public:
	ConfigSetter(Configuration &c, const char *s, const char *n):
		config(c), section(s), name(n), set(NONE) {
	};
	void set_s(const string val) {
		sval = val;
		set = STR;
	};
	void set_d(const double val) {
		dval = val;
		set = DBL;
	};
	void set_i(const int val) {
		ival = val;
		set = INT;
	};
	void set_b() {
		set = BOOL;
	};
	~ConfigSetter() {
		if (set == NONE)
			return;

		if (set == INT) {
			config[section][name] = ival;
		}
		else if (set == DBL) {
			config[section][name] = dval;
		}
		else if (set == STR) {
			config[section][name] = sval;
		}
		else if (set == BOOL) {
			config[section][name] = true;
		}
	};
private:
	Configuration &config;
	configtype set;
	string sval;
	double dval;
	int ival;
	const char *section;
	const char *name;
};

void usage() {
	cout << endl;
	cout << endl;
	cout << "This program translates a 3d model file in STL format to GCODE toolpath for a 3D printer "<< endl;
	cout << "It also generates an OpenScad file for visualization"<< endl;
	cout << endl;
	cout << "usage: miracle-grue [OPTIONS] STL FILE" << endl;
	cout << "options: " << endl;
	cout << "  -c --config        : set the configuration file (default is local miracle.config)" << endl;
	cout << "  -f --firstLayerZ   : override the first layer height" << endl;
	cout << "  -l --layerH        : override the layer height" << endl;
	cout << "  -w --layerW        : override layer width" << endl;
	cout << "  -t --tubeSpacing   : override the infill grid width" << endl;
	cout << "  -a --angle         : override the infill grid inter slice angle (radians)" << endl;
	cout << "  -s --nbOfShells    : override the number of shells" << endl;
	cout << "  -n --firstSliceIdx : slice from a specific slice" << endl;
	cout << "  -m --lastSliceIdx  : stop slicing at specific slice" << endl;
	cout << "  -d --writeDebug    : debug mode (creates scad files for each inset error)" << endl;
	cout << endl;
	cout << "It is pitch black. You are likely to be eaten by a grue." << endl;
}

void exitUsage() {
	usage();
	exit(0);
}

void parseArgs(Configuration &config,
				int argc,
				char *argv[],
				string &modelFile,
				string &configFileName,
				int &firstSliceIdx,
				int &lastSliceIdx)
{
	firstSliceIdx = -1;
	lastSliceIdx = -1;

	//first get the config parameter and parse the file so that other params can override the
	//config
	try {
		clpp::command_line_parameters_parser parser;

		parser.add_parameter("-h", "--help", &exitUsage);

		parser.add_parameter("-c", "--config", &config, &Configuration::readFromFile)
			.default_value("miracle.config");

		ConfigSetter f(config, "slicer", "firstLayerZ");
		parser.add_parameter("-f", "--firstLayerZ", &f, &ConfigSetter::set_d);

		ConfigSetter l(config, "slicer", "layerH");
		parser.add_parameter("-l", "--layerH", &l, &ConfigSetter::set_d);

		ConfigSetter w(config, "slicer", "layerW");
		parser.add_parameter("-w", "--layerW", &w, &ConfigSetter::set_d);

		ConfigSetter t(config, "slicer", "tubeSpacing");
		parser.add_parameter("-t", "--tubeSpacing", &t, &ConfigSetter::set_d);

		ConfigSetter a(config, "slicer", "angle");
		parser.add_parameter("-a", "--angle", &a, &ConfigSetter::set_d);

		ConfigSetter s(config, "slicer", "nbOfShells");
		parser.add_parameter("-s", "--nbOfShells", &s, &ConfigSetter::set_d);

		ConfigSetter d(config, "slicer", "writeDebugScadFiles");
		parser.add_parameter("-d", "--writeDebug", &d, &ConfigSetter::set_b);

		ConfigSetter n(config, "slicer", "firstSliceIdx");
		parser.add_parameter("-n", "--firstSliceIdx", &n, &ConfigSetter::set_i);

		ConfigSetter m(config, "slicer", "lastSliceIdx");
		parser.add_parameter("-m", "--lastSliceIdx", &m, &ConfigSetter::set_i)
			.default_value(-1);

		parser.parse(argc - 1, argv);
	}
	catch (std::exception &exp) {
		usage();
		throw mgl::Exception(exp.what());
	}
	catch (mgl::Exception &exp) {
		usage();
		throw exp;
	}

	firstSliceIdx = config["slicer"]["firstSliceIdx"].asInt();
	lastSliceIdx = config["slicer"]["lastSliceIdx"].asInt();

	//handle the unnamed parameter separately
	modelFile = argv[argc  - 1];
	if (!boost::filesystem::is_regular_file(modelFile)) {
		usage();
		throw mgl::Exception(("Invalid model file [" + modelFile + "]").c_str());
	}
}

int preConditionsOrShowUsage(int argc, char *argv[])
{
	cout << endl;
	cout << "Miracle-Grue "<< getMiracleGrueVersionStr() << endl;
	cout << "Makerbot Industries 2012"  << endl;
	cout << endl;

	cout << endl;

	if (argc < 2)
	{
		usage();
		return (-1);
	}
	return 0;
}

int main(int argc, char *argv[], char *envp[])
{

	// design by contract ;-)
	int checks = preConditionsOrShowUsage(argc, argv);
	if(checks != 0)
	{
		return checks;
	}

	string modelFile;
	string configFileName = "miracle.config";

    Configuration config;
    try
    {

		config.readFromFile(configFileName.c_str());

		int firstSliceIdx, lastSliceIdx;
		parseArgs(config, argc, argv, modelFile, configFileName, firstSliceIdx, lastSliceIdx);
		// cout << config.asJson() << endl;

		cout << "Tube spacing: " << config["slicer"]["tubeSpacing"] << endl;

		MyComputer computer;
		cout << endl;
		cout << endl;
		cout << "behold!" << endl;
		cout << "Materialization of \"" << modelFile << "\" has begun at " << computer.clock.now() << endl;

		std::string scadFile = "."; // outDir
		scadFile += computer.fileSystem.getPathSeparatorCharacter();
		scadFile = computer.fileSystem.ChangeExtension(computer.fileSystem.ExtractFilename(modelFile.c_str()).c_str(), ".scad" );

		std::string gcodeFile = ".";
		gcodeFile += computer.fileSystem.getPathSeparatorCharacter();
		gcodeFile = computer.fileSystem.ChangeExtension(computer.fileSystem.ExtractFilename(modelFile.c_str()).c_str(), ".gcode" );

		cout << endl << endl;
		cout << modelFile << " to \"" << gcodeFile << "\" and \"" << scadFile << "\"" << endl;

		GCoder gcoder;
		loadGCoderData(config, gcoder);

		Slicer slicer;
		loadSlicerData(config, slicer);
		std::vector<mgl::SliceData> slices;
		std::vector<Scalar> zIndicies;
		const char* scad = NULL;

		if (scadFile.size() > 0 )
			scad = scadFile.c_str();

	//	Meshy mesh(slicer.firstLayerZ, slicer.layerH);
	//	mesh.readStlFile(modelFile.c_str());

		miracleGrue(gcoder, slicer, modelFile.c_str(),
					scad, gcodeFile.c_str(),
					firstSliceIdx, lastSliceIdx, slices);

    }
    catch(mgl::Exception &mixup)
    {
    	cout << "ERROR: "<< mixup.error << endl;
    	return -1;
    }
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	ボタン表示と制御 @n
			・領域内で、「押した」、「離した」がある場合に「選択」と認識する。@n
			・選択時関数を使わない場合、select_id を監視する事で、状態の変化を認識できる。@n
			・選択時関数にはラムダ式を使える。
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2019 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <functional>
#include "graphics/widget.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ボタン・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct button : public widget {

		typedef button value_type;

		/// 選択される度にカ count が＋１する。
		typedef std::function<void(uint32_t count)> SELECT_FUNC_TYPE;

		static const int16_t round_radius = 6;
		static const int16_t frame_width  = 3;
		static const int16_t box_size     = 30;		///< サイズが省略された場合の標準的なサイズ
		static const int16_t edge_to_title = 4;

	private:

		SELECT_FUNC_TYPE	select_func_;
		uint32_t			select_id_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
			@param[in]	str		ボタン文字列
		*/
		//-----------------------------------------------------------------//
		button(const vtx::srect& loc = vtx::srect(0), const char* str = "") noexcept :
			widget(loc, str), select_func_(), select_id_(0)
		{
			if(get_location().size.x <= 0) {
				auto tlen = 0;
				if(str != nullptr) {
					tlen = strlen(str) * 8;
				}
				at_location().size.x = (frame_width + edge_to_title) * 2 + tlen;
			}
			if(get_location().size.y <= 0) {
				at_location().size.y = box_size;
			}
			insert_widget(this);
		}

		button(const button& th) = delete;
		button& operator = (const button& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~button() { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "Button"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::BUTTON; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
			@param[in]	slt		スライド・タイプの場合「true」
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override
		{
			update_touch_def(pos, num);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
			@param[in]	ena		無効状態にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void exec_select(bool ena = true) noexcept override
		{
			++select_id_;
			if(select_func_) {
				select_func_(select_id_);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) noexcept override
		{
			if(ena) set_state(STATE::ENABLE);
			else set_state(STATE::DISABLE);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト ID の取得
			@return	セレクト ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_id() const noexcept { return select_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト関数への参照
			@return	セレクト関数
		*/
		//-----------------------------------------------------------------//
		SELECT_FUNC_TYPE& at_select_func() noexcept { return select_func_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
			@param[in]	rdr		描画インスタンス
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
			auto r = vtx::srect(get_final_position(), get_location().size);
			rdr.set_fore_color(graphics::def_color::White);
			rdr.round_box(r, round_radius);
			if(get_touch_state().level_) {
				rdr.set_fore_color(graphics::def_color::Silver);
			} else {
				rdr.set_fore_color(graphics::def_color::Darkgray);
			}
			r.org  += frame_width;
			r.size -= frame_width * 2;
			rdr.round_box(r, round_radius - frame_width);

			rdr.set_fore_color(graphics::def_color::White);
			auto sz = rdr.at_font().get_text_size(get_title());
			rdr.draw_text(r.org + (r.size - sz) / 2, get_title());
		}
	};
}
<commit_msg>Update: base color, font color<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	ボタン表示と制御 @n
			・領域内で、「押した」、「離した」がある場合に「選択」と認識する。@n
			・選択時関数を使わない場合、select_id を監視する事で、状態の変化を認識できる。@n
			・選択時関数にはラムダ式を使える。
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2019, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <functional>
#include "graphics/widget.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	ボタン・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct button : public widget {

		typedef button value_type;

		/// 選択される度にカ count が＋１する。
		typedef std::function<void(uint32_t count)> SELECT_FUNC_TYPE;

		static const int16_t round_radius = 6;
		static const int16_t frame_width  = 3;
		static const int16_t box_size     = 30;		///< サイズが省略された場合の標準的なサイズ
		static const int16_t edge_to_title = 4;

	private:

		SELECT_FUNC_TYPE	select_func_;
		uint32_t			select_id_;

		graphics::share_color	base_color_;
		graphics::share_color	font_color_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
			@param[in]	str		ボタン文字列
		*/
		//-----------------------------------------------------------------//
		button(const vtx::srect& loc = vtx::srect(0), const char* str = "") noexcept :
			widget(loc, str), select_func_(), select_id_(0),
			base_color_(graphics::def_color::White), font_color_(graphics::def_color::White)
		{
			if(get_location().size.x <= 0) {
				auto tlen = 0;
				if(str != nullptr) {
					tlen = strlen(str) * 8;
				}
				at_location().size.x = (frame_width + edge_to_title) * 2 + tlen;
			}
			if(get_location().size.y <= 0) {
				at_location().size.y = box_size;
			}
			insert_widget(this);
		}

		button(const button& th) = delete;
		button& operator = (const button& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~button() { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "Button"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::BUTTON; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
			@param[in]	slt		スライド・タイプの場合「true」
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override
		{
			update_touch_def(pos, num);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
			@param[in]	ena		無効状態にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void exec_select(bool ena = true) noexcept override
		{
			++select_id_;
			if(select_func_) {
				select_func_(select_id_);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) noexcept override
		{
			if(ena) set_state(STATE::ENABLE);
			else set_state(STATE::DISABLE);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト ID の取得
			@return	セレクト ID
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_id() const noexcept { return select_id_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト関数への参照
			@return	セレクト関数
		*/
		//-----------------------------------------------------------------//
		SELECT_FUNC_TYPE& at_select_func() noexcept { return select_func_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ベースカラーの設定
			@param[in]	col	ベースカラー
		*/
		//-----------------------------------------------------------------//
		void set_base_color(const graphics::share_color& col) noexcept
		{
			base_color_ = col;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	フォントカラーの設定
			@param[in]	col	ベースカラー
		*/
		//-----------------------------------------------------------------//
		void set_font_color(const graphics::share_color& col) noexcept
		{
			font_color_ = col;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
			@param[in]	rdr		描画インスタンス
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
			auto r = vtx::srect(get_final_position(), get_location().size);
			rdr.set_fore_color(base_color_);
			rdr.round_box(r, round_radius);
			uint8_t inten = 64;
			if(get_touch_state().level_) {  // 0.75
				inten = 192;
			}
			graphics::color_t c;
			graphics::share_color sh(0, 0, 0);
			sh.set_color(base_color_.rgba8, inten);
			rdr.set_fore_color(sh);

			r.org  += frame_width;
			r.size -= frame_width * 2;
			rdr.round_box(r, round_radius - frame_width);

			rdr.set_fore_color(font_color_);
			auto sz = rdr.at_font().get_text_size(get_title());
			rdr.draw_text(r.org + (r.size - sz) / 2, get_title());
		}
	};
}
<|endoftext|>


<commit_before>#include <utils/unique_alias.hpp>

#include <atomic>
#include <chrono>
#include <sstream>

static std::atomic<int> __counter(0);

utils::unique_alias::unique_alias()
{
    std::ostringstream s;

    s << "benchmarks-"
      << std::chrono::duration_cast<std::chrono::seconds>(
             std::chrono::steady_clock::now().time_since_epoch())
             .count()
      << "-" << __counter++ << "-000000";

    _string = s.str();
}

void utils::unique_alias::set_watermark(unsigned long iteration)
{
    size_t index = _string.size();
    for (int digit = 0; digit < 6; digit++)
    {
        _string[--index] = '0' + (iteration & 63);
        iteration /= 64;
    }
}
<commit_msg>Use proper base 64 encoding for the watermark<commit_after>#include <utils/unique_alias.hpp>

#include <atomic>
#include <chrono>
#include <sstream>

static std::atomic<int> __counter(0);

static const char __base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

utils::unique_alias::unique_alias()
{
    std::ostringstream s;

    s << "benchmarks-"
      << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now().time_since_epoch()).count()
      << "-" << __counter++ << "-AAAAAA"; // reserve 6 chars for the watermark

    _string = s.str();
}

void utils::unique_alias::set_watermark(unsigned long iteration)
{
    size_t index = _string.size();
    for (int digit = 0; digit < 6; digit++)
    {
        _string[--index] = __base64[iteration & 63];
        iteration /= 64;
    }
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <array>
#include <queue>
#include <iostream>
#include <forward_list>
#include <fstream>
#include <ostream>

#include <boost/filesystem.hpp>

#include "config.h"

namespace manifest
{
	using namespace std;
	using namespace boost::filesystem;

	const array<path, 4> projDirs { { path("CVS"),
	                                  path(".git"),
	                                  path(".svn"),
	                                  path(".hg") } };

	bool is_project_directory (const path & p)
	{
		bool isproj = false;
		for (size_t i = 0; i < projDirs.size(); ++i) {
			isproj = exists(p / projDirs[i]);
			if (isproj) break;
		}

		return isproj;
	}

	path remove_base (const path &base, const path &p) {
		// Take the relative path from the base directory
		// Irritatingly there is no built-in method for this
		path tmp = p;
		path diff;

		while (!tmp.empty() && tmp != base) {
			diff = tmp.filename() / diff;
			tmp = tmp.parent_path();
		}

		return diff;
	}

	class manifest_printer {
	private:
		const path &base;
	public:
		manifest_printer(const path &base);
		int print (ostream &out);
	};

	manifest_printer::manifest_printer(const path &base) : base(base) {}

	int manifest_printer::print (ostream &out) {
		// Start with the empty relative path
		queue<path> frontier;
		frontier.push( this->base );

		int c = 0;

		// As long as the frontier is non-empty, keep searching
		while ( !frontier.empty() ) {
			path p = frontier.front();
			frontier.pop();

			if (exists(p)) {
				// For project directories, output and escape immediately
				if ( is_project_directory(p) ) {
					++c;
					out << ( remove_base(this->base, p).string() ) << endl;
				}
				else {
					// Add all children to the frontier
					directory_iterator end_it;
					for (directory_iterator it(p); it != end_it; ++it) {
						if ( is_directory(it->status()) ) {
							frontier.push(it->path());
						}
					}
				}
			}
		}

		return c;
	}
}

int main(int argc, char *argv[])
{
	if (argc < 2) {
    std::cout << PACKAGE_STRING << " <" << PACKAGE_URL << ">" << std::endl;
		std::cout << "usage: " << argv[0] << " /path/to/directory" << std::endl;
		return 1;
	}
	boost::filesystem::path projDir(argv[1]);

	auto m = manifest::manifest_printer(projDir);
	m.print(std::cout);
  return 0;
}
<commit_msg>Fix indentation with spaces rather than tabs<commit_after>#include <algorithm>
#include <array>
#include <queue>
#include <iostream>
#include <forward_list>
#include <fstream>
#include <ostream>

#include <boost/filesystem.hpp>

#include "config.h"

namespace manifest
{
	using namespace std;
	using namespace boost::filesystem;

	const array<path, 4> projDirs { { path("CVS"),
	                                  path(".git"),
	                                  path(".svn"),
	                                  path(".hg") } };

	bool is_project_directory (const path & p)
	{
		bool isproj = false;
		for (size_t i = 0; i < projDirs.size(); ++i) {
			isproj = exists(p / projDirs[i]);
			if (isproj) break;
		}

		return isproj;
	}

	path remove_base (const path &base, const path &p) {
		// Take the relative path from the base directory
		// Irritatingly there is no built-in method for this
		path tmp = p;
		path diff;

		while (!tmp.empty() && tmp != base) {
			diff = tmp.filename() / diff;
			tmp = tmp.parent_path();
		}

		return diff;
	}

	class manifest_printer {
	private:
		const path &base;
	public:
		manifest_printer(const path &base);
		int print (ostream &out);
	};

	manifest_printer::manifest_printer(const path &base) : base(base) {}

	int manifest_printer::print (ostream &out) {
		// Start with the empty relative path
		queue<path> frontier;
		frontier.push( this->base );

		int c = 0;

		// As long as the frontier is non-empty, keep searching
		while ( !frontier.empty() ) {
			path p = frontier.front();
			frontier.pop();

			if (exists(p)) {
				// For project directories, output and escape immediately
				if ( is_project_directory(p) ) {
					++c;
					out << ( remove_base(this->base, p).string() ) << endl;
				}
				else {
					// Add all children to the frontier
					directory_iterator end_it;
					for (directory_iterator it(p); it != end_it; ++it) {
						if ( is_directory(it->status()) ) {
							frontier.push(it->path());
						}
					}
				}
			}
		}

		return c;
	}
}

int main(int argc, char *argv[])
{
	if (argc < 2) {
		std::cout << PACKAGE_STRING << " <" << PACKAGE_URL << ">" << std::endl;
		std::cout << "usage: " << argv[0] << " /path/to/directory" << std::endl;
		return 1;
	}
	boost::filesystem::path projDir(argv[1]);

	auto m = manifest::manifest_printer(projDir);
	m.print(std::cout);
	return 0;
}
<|endoftext|>


<commit_before>#include "property.h"

#include <iostream>
#include <xmmintrin.h>

#define MAX_STRING_LENGTH 0x200

uint32_t read_int(Bitstream &stream, const SendProp *prop) {
  if (prop->flags & SP_EncodedAgainstTickcount) {
    if (prop->flags & SP_Unsigned) {
      return stream.read_var_35();
    } else {
      uint32_t value = stream.read_var_35();
      return (-(value & 1)) ^ (value >> 1);
    }
  } else {
    uint32_t value = stream.get_bits(prop->num_bits);
    uint32_t signer = (0x80000000 >> (32 - prop->num_bits)) & ((prop->flags & SP_Unsigned) - 1);

    value = value ^ signer;
    return value - signer;
  }
}

float read_float_coord(Bitstream &stream) {
  uint32_t first = stream.get_bits(1);
  uint32_t second = stream.get_bits(1);

  __m128 a = (__m128)_mm_setzero_si128();
  __m128 b = (__m128)_mm_setzero_si128();

  if (first || second) {
    uint32_t third = stream.get_bits(1);

    if (first) {
      first = stream.get_bits(0x0E) + 1;
    }

    if (second) {
      second = stream.get_bits(5);
    }

    b = (__m128)_mm_cvtsi32_si128(first);
    a = _mm_cvtsi32_ss(a, second);

    __m128 special = (__m128)_mm_setr_epi32(0x3D000000, 0, 0, 0);
    a = _mm_mul_ss(a, special);
    a = (__m128)_mm_cvtps_pd(a);

    b = (__m128)_mm_cvtepi32_pd((__m128i)b);

    a = (__m128)_mm_add_sd((__m128d)a, (__m128d)b);
    a = (__m128)_mm_cvtpd_ps((__m128d)a);

    if (third) {
      __m128 mask = (__m128)_mm_set1_epi32(0x80000000);
      a = _mm_xor_ps(a, mask);
    }
  }

  float f;
  _mm_store_ss(&f, a);
  return f;
}

enum FloatType {
  FT_None,
  FT_LowPrecision,
  FT_Integral,
};

float read_float_coord_mp(Bitstream &stream, FloatType type) {
  uint32_t value;

  if (type == FT_LowPrecision || type == FT_None) {
    uint32_t a = stream.get_bits(1);
    uint32_t b = stream.get_bits(1);
    uint32_t c = stream.get_bits(1);

    value = 4 * c + 2 * b + a;

    XERROR("please no");

  } else if (type == FT_Integral) {
    uint32_t a = stream.get_bits(1);
    uint32_t b = stream.get_bits(1);
    a = a + 2 * b;

    if (!b) {
      return 0;
    } else {
      if (a) {
        value = stream.get_bits(12);
      } else {
        value = stream.get_bits(15);
      }

      if (value & 1) {
        value = -((value >> 1) + 1);
      } else {
        value = (value >> 1) + 1;
      }
    }
  } else {
    XERROR("Unknown coord type.");
  }

  __m128 a = (__m128)_mm_setzero_si128();
  a = _mm_cvtsi32_ss(a, value);
  float f;
  _mm_store_ss(&f, a);

  return f;
}

float read_float_no_scale(Bitstream &stream) {
  uint32_t value = stream.get_bits(32);

  __m128 a = (__m128)_mm_setzero_si128();
  a = _mm_cvtsi32_ss(a, value);
  float f;
  _mm_store_ss(&f, a);

  return f;
}

float read_float_normal(Bitstream &stream) {
  uint32_t first = stream.get_bits(1);
  uint32_t second = stream.get_bits(11);

  float f = second;

  if (second >> 31) {
    f += 4.2949673e9;
  }

  f *= 4.885197850512946e-4;

  __m128 a = _mm_load_ss(&f);
  __m128 mask = (__m128)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
  a = _mm_xor_ps(a, mask);

  _mm_store_ss(&f, a);

  return f;
}

float read_float_cell_coord(Bitstream &stream, FloatType type, uint32_t bits) {
  uint32_t value = stream.get_bits(bits);

  if (type == FT_None || type == FT_LowPrecision) {
    bool lp = type  == FT_LowPrecision;

    uint32_t second;
    if (!lp) {
      second = stream.get_bits(5);
    } else {
      second = stream.get_bits(3);
    }

    __m128 a;
    if (!lp) {
      a = (__m128)_mm_setr_epi32(0x3FA00000, 0, 0, 0);
    } else {
      a = (__m128)_mm_setr_epi32(0x3FC00000, 0, 0, 0);
    }

    __m128 b = (__m128)_mm_setzero_si128();
    b = _mm_cvtsi32_ss(b, second);
    b = (__m128)_mm_cvtps_pd(b);
    b = (__m128)_mm_mul_sd((__m128d)b, (__m128d)a);

    a = (__m128)_mm_setzero_si128();
    a = _mm_cvtsi32_ss(a, value);

    b = (__m128)_mm_add_sd((__m128d)b, (__m128d)a);
    a = (__m128)_mm_cvtpd_ps((__m128d)b);

    float f;
    _mm_store_ss(&f, a);

    return f;
  } else if (type == FT_Integral) {
    __m128 a = (__m128)_mm_setzero_si128();
    a = _mm_cvtsi32_ss(a, value);
    float f;
    _mm_store_ss(&f, a);

    if (value >> 31) {
      f += 4.2949673e9;
    }

    return f;
  } else {
    XERROR("Unknown float type");
    return 0;
  }
}

float read_float(Bitstream &stream, const SendProp *prop) {
  if (prop->flags & SP_Coord) {
    return read_float_coord(stream);
  } else if (prop->flags & SP_CoordMp) {
    return read_float_coord_mp(stream, FT_None);
  } else if (prop->flags & SP_CoordMpLowPrecision) {
    return read_float_coord_mp(stream, FT_LowPrecision);
  } else if (prop->flags & SP_CoordMpIntegral) {
    return read_float_coord_mp(stream, FT_Integral);
  } else if (prop->flags & SP_NoScale) {
    return read_float_no_scale(stream);
  } else if (prop->flags & SP_Normal) {
    return read_float_normal(stream);
  } else if (prop->flags & SP_CellCoord) {
    return read_float_cell_coord(stream, FT_None, prop->num_bits);
  } else if (prop->flags & SP_CellCoordLowPrecision) {
    return read_float_cell_coord(stream, FT_LowPrecision, prop->num_bits);
  } else if (prop->flags & SP_CellCoordIntegral) {
    return read_float_cell_coord(stream, FT_Integral, prop->num_bits);
  } else {
    unsigned int value = stream.get_bits(prop->num_bits);
    __m128 a = (__m128)_mm_setzero_si128();
    a = _mm_cvtsi32_ss(a, value);

    __m128 b = (__m128)_mm_setzero_si128();
    b = _mm_cvtsi32_ss(b, (1 << prop->num_bits) - 1);

    a = _mm_div_ss(a, b);

    float range = prop->high_value - prop->low_value;
    b = _mm_load_ss(&range);
    a = _mm_mul_ss(a, b);

    range = prop->low_value;
    b = _mm_load_ss(&range);
    a = _mm_add_ss(a, b);

    float f;
    _mm_store_ss(&f, a);

    return f;
  }
}

void read_vector(float vector[3], Bitstream &stream, const SendProp *prop) {
  vector[0] = read_float(stream, prop);
  vector[1] = read_float(stream, prop);

  if (prop->flags & SP_Normal) {
    uint32_t first = stream.get_bits(1);

    __m128 a = _mm_load_ss(&vector[0]);
    __m128 b = _mm_load_ss(&vector[1]);

    a = _mm_mul_ss(a, a);
    b = _mm_mul_ss(b, b);

    a = _mm_add_ss(a, b);

    b = (__m128)_mm_setr_epi32(0x3D000000, 0, 0, 0);

    if (_mm_comile_ss(b, a)) {
      a = (__m128)_mm_setzero_si128();
    } else {
      b = _mm_sub_ss(b, a);
      a = _mm_sqrt_ss(b);
    }

    if (first) {
      __m128 special = (__m128)_mm_setr_epi32(0x3D000000, 0, 0, 0);
      a = _mm_mul_ss(a, special);
    }

    _mm_store_ss(&vector[2], a);
  } else {
    vector[2] = read_float(stream, prop);
  }
}

void read_vector_xy(float vector[2], Bitstream &stream, const SendProp *prop) {
  vector[0] = read_float(stream, prop);
  vector[1] = read_float(stream, prop);
}

size_t read_string(char *buf, size_t max_length, Bitstream &stream, const SendProp *prop) {
  uint32_t length = stream.get_bits(9);
  XASSERT(length <= max_length, "String too long %d > %d", length, max_length);

  stream.read_bits(buf, 8 * length);

  return length;
}

uint32_t get_array_length_bits(const SendProp *prop) {
  uint32_t n = prop->num_elements;
  uint32_t bits = 0;

  while (n) {
    ++bits;
    n >>= 1;
  }

  return bits;
}

void read_array(std::vector<ArrayPropertyElement> &elements, Bitstream &stream,
    const SendProp *prop) {
  XASSERT(prop->array_prop, "Array prop has no inner prop.");

  uint32_t count = stream.get_bits(get_array_length_bits(prop));

  for (uint32_t i = 0; i < count; ++i) {
    elements.push_back(Property::read_prop(stream, prop->array_prop));
  }
}

uint64_t read_int64(Bitstream &stream, const SendProp *prop) {
  if (SP_EncodedAgainstTickcount & prop->flags) {
    XERROR("this sounds scary");
  } else {
    bool negate = false;
    size_t second_bits = prop->num_bits - 32;

    if (!(SP_Unsigned & prop->flags)) {
      --second_bits;

      if (stream.get_bits(1)) {
        negate = true;
      }
    }

    XASSERT(prop->num_bits >= second_bits, "Invalid number of bits");

    uint64_t a = stream.get_bits(32);
    uint64_t b = stream.get_bits(second_bits);
    uint64_t value = (a << 32) | b;

    if (negate) {
      value *= -1;
    }

    return value;
  }
}

std::shared_ptr<Property> Property::read_prop(Bitstream &stream, const SendProp *prop) {
  Property *out;

  std::string var_name = prop->in_table->net_table_name + "." + prop->var_name;

  if (prop->type == SP_Int) {
    out = new IntProperty(var_name, read_int(stream, prop));
  } else if (prop->type == SP_Float) {
    out = new FloatProperty(var_name, read_float(stream, prop));
  } else if (prop->type == SP_Vector) {
    float value[3];
    read_vector(value, stream, prop);

    out = new VectorProperty(var_name, value);
  } else if (prop->type == SP_VectorXY) {
    float value[2];
    read_vector_xy(value, stream, prop);

    out = new VectorXYProperty(var_name, value);
  } else if (prop->type == SP_String) {
    char str[MAX_STRING_LENGTH + 1];
    size_t length = read_string(str, MAX_STRING_LENGTH, stream, prop);

    out = new StringProperty(var_name, std::string(str, length));
  } else if (prop->type == SP_Array) {
    std::vector<ArrayPropertyElement> elements;
    read_array(elements, stream, prop);

    out = new ArrayProperty(var_name, elements, prop->array_prop->type);
  } else if (prop->type == SP_Int64) {
    out = new Int64Property(var_name, read_int64(stream, prop));
  } else {
    XERROR("Unknown send prop type %d", prop->type);
  }

  return std::shared_ptr<Property>(out);
}

Property::Property(const std::string &_name, SP_Types _type) : name(_name), type(_type) {
}

Property::~Property() {
}

<commit_msg>Removed sse stuff and fixed several bugs<commit_after>#include "property.h"

#include <cmath>

#define MAX_STRING_LENGTH 0x200

uint32_t read_int(Bitstream &stream, const SendProp *prop) {
  if (prop->flags & SP_EncodedAgainstTickcount) {
    if (prop->flags & SP_Unsigned) {
      return stream.read_var_35();
    } else {
      uint32_t value = stream.read_var_35();
      return (-(value & 1)) ^ (value >> 1);
    }
  } else {
    uint32_t value = stream.get_bits(prop->num_bits);
    uint32_t signer = (0x80000000 >> (32 - prop->num_bits)) & ((prop->flags & SP_Unsigned) - 1);

    value = value ^ signer;
    return value - signer;
  }
}

float read_float_coord(Bitstream &stream) {
  uint32_t integer = stream.get_bits(1);
  uint32_t fraction = stream.get_bits(1);

  if (integer || fraction) {
    uint32_t sign = stream.get_bits(1);

    if (integer) {
      integer = stream.get_bits(0x0E) + 1;
    }

    if (fraction) {
      fraction = stream.get_bits(5);
    }

    double d = 0.03125 * fraction;
    d += integer;

    if (sign) {
      d *= -1;
    }

    return (float) d;
  } else {
    return 0;
  }
}

enum FloatType {
  FT_None,
  FT_LowPrecision,
  FT_Integral,
};

float read_float_coord_mp(Bitstream &stream, FloatType type) {
  uint32_t value;

  if (type == FT_LowPrecision || type == FT_None) {
    uint32_t a = stream.get_bits(1);
    uint32_t b = stream.get_bits(1);
    uint32_t c = stream.get_bits(1);

    value = 4 * c + 2 * b + a;

    XERROR("please no");
  } else if (type == FT_Integral) {
    uint32_t a = stream.get_bits(1);
    uint32_t b = stream.get_bits(1);
    a = a + 2 * b;

    if (!b) {
      return 0;
    } else {
      if (a) {
        value = stream.get_bits(12);
      } else {
        value = stream.get_bits(15);
      }

      if (value & 1) {
        value = -((value >> 1) + 1);
      } else {
        value = (value >> 1) + 1;
      }

      return value;
    }
  } else {
    XERROR("Unknown coord type.");
  }
}

float read_float_no_scale(Bitstream &stream) {
  return stream.get_bits(32);
}

float read_float_normal(Bitstream &stream) {
  uint32_t sign = stream.get_bits(1);
  uint32_t value = stream.get_bits(11);

  float f = value;

  if (value >> 31) {
    f += 4.2949673e9;
  }

  f *= 4.885197850512946e-4;

  if (sign) {
    f = -1 * f;
  }

  return f;
}

float read_float_cell_coord(Bitstream &stream, FloatType type, uint32_t bits) {
  uint32_t value = stream.get_bits(bits);

  if (type == FT_None || type == FT_LowPrecision) {
    bool lp = type == FT_LowPrecision;

    uint32_t fraction;
    if (!lp) {
      fraction = stream.get_bits(5);
    } else {
      fraction = stream.get_bits(3);
    }

    double d = value + (lp ? 1.5 : 1.25) * fraction;
    return (float) d;
  } else if (type == FT_Integral) {
    double d = value;

    if (value >> 31) {
      d += 4.2949673e9;
    }

    return (float) d;
  } else {
    XERROR("Unknown float type");
    return 0;
  }
}

float read_float(Bitstream &stream, const SendProp *prop) {
  if (prop->flags & SP_Coord) {
    return read_float_coord(stream);
  } else if (prop->flags & SP_CoordMp) {
    return read_float_coord_mp(stream, FT_None);
  } else if (prop->flags & SP_CoordMpLowPrecision) {
    return read_float_coord_mp(stream, FT_LowPrecision);
  } else if (prop->flags & SP_CoordMpIntegral) {
    return read_float_coord_mp(stream, FT_Integral);
  } else if (prop->flags & SP_NoScale) {
    return read_float_no_scale(stream);
  } else if (prop->flags & SP_Normal) {
    return read_float_normal(stream);
  } else if (prop->flags & SP_CellCoord) {
    return read_float_cell_coord(stream, FT_None, prop->num_bits);
  } else if (prop->flags & SP_CellCoordLowPrecision) {
    return read_float_cell_coord(stream, FT_LowPrecision, prop->num_bits);
  } else if (prop->flags & SP_CellCoordIntegral) {
    return read_float_cell_coord(stream, FT_Integral, prop->num_bits);
  } else {
    uint32_t dividend = stream.get_bits(prop->num_bits);
    uint32_t divisor = (1 << prop->num_bits) - 1;

    float f = ((float) dividend) / divisor;
    float range = prop->high_value - prop->low_value;

    return f * range + prop->low_value;
  }
}

void read_vector(float vector[3], Bitstream &stream, const SendProp *prop) {
  vector[0] = read_float(stream, prop);
  vector[1] = read_float(stream, prop);

  if (prop->flags & SP_Normal) {
    uint32_t sign = stream.get_bits(1);

    float f = vector[0] * vector[0] + vector[1] * vector[1];

    if (1 >= f) {
      vector[2] = 0;
    } else {
      vector[2] = sqrt(1 - f);
    }

    if (sign) {
      vector[2] = -1 * vector[2];
    }
  } else {
    vector[2] = read_float(stream, prop);
  }
}

void read_vector_xy(float vector[2], Bitstream &stream, const SendProp *prop) {
  vector[0] = read_float(stream, prop);
  vector[1] = read_float(stream, prop);
}

size_t read_string(char *buf, size_t max_length, Bitstream &stream, const SendProp *prop) {
  uint32_t length = stream.get_bits(9);
  XASSERT(length <= max_length, "String too long %d > %d", length, max_length);

  stream.read_bits(buf, 8 * length);

  return length;
}

uint32_t get_array_length_bits(const SendProp *prop) {
  uint32_t n = prop->num_elements;
  uint32_t bits = 0;

  while (n) {
    ++bits;
    n >>= 1;
  }

  return bits;
}

void read_array(std::vector<ArrayPropertyElement> &elements, Bitstream &stream,
    const SendProp *prop) {
  XASSERT(prop->array_prop, "Array prop has no inner prop.");

  uint32_t count = stream.get_bits(get_array_length_bits(prop));

  for (uint32_t i = 0; i < count; ++i) {
    elements.push_back(Property::read_prop(stream, prop->array_prop));
  }
}

uint64_t read_int64(Bitstream &stream, const SendProp *prop) {
  if (SP_EncodedAgainstTickcount & prop->flags) {
    XERROR("this sounds scary");
  } else {
    bool negate = false;
    size_t second_bits = prop->num_bits - 32;

    if (!(SP_Unsigned & prop->flags)) {
      --second_bits;

      if (stream.get_bits(1)) {
        negate = true;
      }
    }

    XASSERT(prop->num_bits >= second_bits, "Invalid number of bits");

    uint64_t a = stream.get_bits(32);
    uint64_t b = stream.get_bits(second_bits);
    uint64_t value = (a << 32) | b;

    if (negate) {
      value *= -1;
    }

    return value;
  }
}

std::shared_ptr<Property> Property::read_prop(Bitstream &stream, const SendProp *prop) {
  Property *out;

  std::string var_name = prop->in_table->net_table_name + "." + prop->var_name;

  if (prop->type == SP_Int) {
    out = new IntProperty(var_name, read_int(stream, prop));
  } else if (prop->type == SP_Float) {
    out = new FloatProperty(var_name, read_float(stream, prop));
  } else if (prop->type == SP_Vector) {
    float value[3];
    read_vector(value, stream, prop);

    out = new VectorProperty(var_name, value);
  } else if (prop->type == SP_VectorXY) {
    float value[2];
    read_vector_xy(value, stream, prop);

    out = new VectorXYProperty(var_name, value);
  } else if (prop->type == SP_String) {
    char str[MAX_STRING_LENGTH + 1];
    size_t length = read_string(str, MAX_STRING_LENGTH, stream, prop);

    out = new StringProperty(var_name, std::string(str, length));
  } else if (prop->type == SP_Array) {
    std::vector<ArrayPropertyElement> elements;
    read_array(elements, stream, prop);

    out = new ArrayProperty(var_name, elements, prop->array_prop->type);
  } else if (prop->type == SP_Int64) {
    out = new Int64Property(var_name, read_int64(stream, prop));
  } else {
    XERROR("Unknown send prop type %d", prop->type);
  }

  return std::shared_ptr<Property>(out);
}

Property::Property(const std::string &_name, SP_Types _type) : name(_name), type(_type) {
}

Property::~Property() {
}

<|endoftext|>


<commit_before>// Module:  Log4CPLUS
// File:    property.cxx
// Created: 2/2002
// Author:  Tad E. Smith
//
//
// Copyright 2002-2010 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/config.hxx>

#include <cstring>
#if defined (UNICODE)
#  include <cwctype>
#else
#  include <cctype>
#endif
#if defined (LOG4CPLUS_HAVE_CODECVT_UTF8_FACET) \
    || defined (LOG4CPLUS_HAVE_CODECVT_UTF16_FACET) \
    || defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET)
#  include <codecvt>
#endif
#include <locale>
#include <fstream>
#include <sstream>
#include <log4cplus/streams.h>
#include <log4cplus/fstreams.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/internal/internal.h>
#include <log4cplus/internal/env.h>
#include <log4cplus/helpers/loglog.h>

namespace log4cplus { namespace helpers {

const tchar Properties::PROPERTIES_COMMENT_CHAR = LOG4CPLUS_TEXT('#');

namespace
{

static
int
is_space (tchar ch)
{
#if defined (UNICODE)
    return std::iswspace (ch);
#else
    return std::isspace (static_cast<unsigned char>(ch));
#endif
}

static
void
trim_leading_ws (tstring & str)
{
    tstring::iterator it = str.begin ();
    for (; it != str.end (); ++it)
    {
        if (! is_space (*it))
            break;
    }
    str.erase (str.begin (), it);
}

static
void
trim_trailing_ws (tstring & str)
{
    tstring::reverse_iterator rit = str.rbegin ();
    for (; rit != str.rend (); ++rit)
    {
        if (! is_space (*rit))
            break;
    }
    str.erase (rit.base (), str.end ());
}

static
void
trim_ws (tstring & str)
{
    trim_trailing_ws (str);
    trim_leading_ws (str);
}

void
imbue_file_from_flags (tistream & file, unsigned flags)
{
    switch (flags & (Properties::fEncodingMask << Properties::fEncodingShift))
    {
#if defined (LOG4CPLUS_HAVE_CODECVT_UTF8_FACET) && defined (UNICODE)
    case Properties::fUTF8:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf8<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;
#endif

#if defined (LOG4CPLUS_HAVE_CODECVT_UTF16_FACET) && defined (UNICODE)
    case Properties::fUTF16:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf16<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;

#elif defined (UNICODE) && defined (WIN32)
    case Properties::fUTF16:
        file.imbue (
            std::locale (file.getloc (),
                // TODO: This should actually be a custom "null" facet
                // that just copies the chars to wchar_t buffer.
                new std::codecvt<wchar_t, char, std::mbstate_t>));
    break;

#endif

#if defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET) && defined (UNICODE)
    case Properties::fUTF32:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf32<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;
#endif

    case Properties::fUnspecEncoding:;
    default:
        // Do nothing.
        ;
    }
}

} // namespace

///////////////////////////////////////////////////////////////////////////////
// Properties ctors and dtor
///////////////////////////////////////////////////////////////////////////////

Properties::Properties()
    : flags (0)
{
}

Properties::Properties(tistream& input)
    : flags (0)
{
    init(input);
}

Properties::Properties(const tstring& inputFile, unsigned f)
    : flags (f)
{
    if (inputFile.empty ())
        return;

    tifstream file;
    imbue_file_from_flags (file, flags);

    file.open(LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(inputFile).c_str(),
        std::ios::binary);
    if (! file.good ())
        helpers::getLogLog ().error (LOG4CPLUS_TEXT ("could not open file ")
            + inputFile);

    init(file);
}

void
Properties::init(tistream& input)
{
    if (! input)
        return;

    tstring buffer;
    while (std::getline (input, buffer))
    {
        trim_leading_ws (buffer);

        tstring::size_type const buffLen = buffer.size ();
        if (buffLen == 0 || buffer[0] == PROPERTIES_COMMENT_CHAR)
            continue;

        // Check if we have a trailing \r because we are
        // reading a properties file produced on Windows.
        if (buffer[buffLen-1] == LOG4CPLUS_TEXT('\r'))
            // Remove trailing 'Windows' \r.
            buffer.resize (buffLen - 1);

        tstring::size_type const idx = buffer.find('=');
        if (idx != tstring::npos)
        {
            tstring key = buffer.substr(0, idx);
            tstring value = buffer.substr(idx + 1);
            trim_trailing_ws (key);
            trim_ws (value);
            setProperty(key, value);
        }
        else if (buffer.compare (0, 7, LOG4CPLUS_TEXT ("include")) == 0
            && buffer.size () >= 7 + 1 + 1
            && is_space (buffer[7]))
        {
            tstring included (buffer, 8) ;
            trim_ws (included);

            tifstream file;
            imbue_file_from_flags (file, flags);

            file.open (LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(included).c_str(),
                std::ios::binary);
            if (! file.good ())
                helpers::getLogLog ().error (
                    LOG4CPLUS_TEXT ("could not open file ") + included);

            init (file);
        }
    }
}

Properties::~Properties()
{
}

///////////////////////////////////////////////////////////////////////////////
// helpers::Properties public methods
///////////////////////////////////////////////////////////////////////////////

bool
Properties::exists(const log4cplus::tstring& key) const
{
    return data.find(key) != data.end();
}

bool
Properties::exists(tchar const * key) const
{
    return data.find(key) != data.end();
}

tstring const &
Properties::getProperty(const tstring& key) const
{
    return get_property_worker (key);
}

log4cplus::tstring const &
Properties::getProperty(tchar const * key) const
{
    return get_property_worker (key);
}

tstring
Properties::getProperty(const tstring& key, const tstring& defaultVal) const
{
    StringMap::const_iterator it (data.find (key));
    if (it == data.end ())
        return defaultVal;
    else
        return it->second;
}

std::vector<tstring>
Properties::propertyNames() const
{
    std::vector<tstring> tmp;
    for (StringMap::const_iterator it=data.begin(); it!=data.end(); ++it)
        tmp.push_back(it->first);

    return tmp;
}

void
Properties::setProperty(const log4cplus::tstring& key,
    const log4cplus::tstring& value)
{
    data[key] = value;
}

bool
Properties::removeProperty(const log4cplus::tstring& key)
{
    return data.erase(key) > 0;
}

Properties
Properties::getPropertySubset(const log4cplus::tstring& prefix) const
{
    Properties ret;
    std::size_t const prefix_len = prefix.size ();
    std::vector<tstring> keys = propertyNames();
    for (std::vector<tstring>::iterator it=keys.begin(); it!=keys.end(); ++it)
    {
        int result = it->compare (0, prefix_len, prefix);
        if (result == 0)
            ret.setProperty (it->substr (prefix_len), getProperty(*it));
    }

    return ret;
}

bool
Properties::getInt (int & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getUInt (unsigned & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getLong (long & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getULong (unsigned long & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getBool (bool & val, log4cplus::tstring const & key) const
{
    if (! exists (key))
        return false;

    log4cplus::tstring const & prop_val = getProperty (key);
    return internal::parse_bool (val, prop_val);
}

template <typename StringType>
log4cplus::tstring const &
Properties::get_property_worker (StringType const & key) const
{
    StringMap::const_iterator it (data.find (key));
    if (it == data.end ())
        return log4cplus::internal::empty_str;
    else
        return it->second;
}

template <typename ValType>
bool
Properties::get_type_val_worker (ValType & val, log4cplus::tstring const & key)
    const
{
    if (! exists (key))
        return false;

    log4cplus::tstring const & prop_val = getProperty (key);
    log4cplus::tistringstream iss (prop_val);
    ValType tmp_val;
    tchar ch;

    iss >> tmp_val;
    if (! iss)
        return false;
    iss >> ch;
    if (iss)
        return false;

    val = tmp_val;
    return true;
}

} } // namespace log4cplus { namespace helpers {
<commit_msg>property.cxx: Fix EOLs.<commit_after>// Module:  Log4CPLUS
// File:    property.cxx
// Created: 2/2002
// Author:  Tad E. Smith
//
//
// Copyright 2002-2010 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/config.hxx>

#include <cstring>
#if defined (UNICODE)
#  include <cwctype>
#else
#  include <cctype>
#endif
#if defined (LOG4CPLUS_HAVE_CODECVT_UTF8_FACET) \
    || defined (LOG4CPLUS_HAVE_CODECVT_UTF16_FACET) \
    || defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET)
#  include <codecvt>
#endif
#include <locale>
#include <fstream>
#include <sstream>
#include <log4cplus/streams.h>
#include <log4cplus/fstreams.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/internal/internal.h>
#include <log4cplus/internal/env.h>
#include <log4cplus/helpers/loglog.h>

namespace log4cplus { namespace helpers {

const tchar Properties::PROPERTIES_COMMENT_CHAR = LOG4CPLUS_TEXT('#');

namespace
{

static
int
is_space (tchar ch)
{
#if defined (UNICODE)
    return std::iswspace (ch);
#else
    return std::isspace (static_cast<unsigned char>(ch));
#endif
}

static
void
trim_leading_ws (tstring & str)
{
    tstring::iterator it = str.begin ();
    for (; it != str.end (); ++it)
    {
        if (! is_space (*it))
            break;
    }
    str.erase (str.begin (), it);
}

static
void
trim_trailing_ws (tstring & str)
{
    tstring::reverse_iterator rit = str.rbegin ();
    for (; rit != str.rend (); ++rit)
    {
        if (! is_space (*rit))
            break;
    }
    str.erase (rit.base (), str.end ());
}

static
void
trim_ws (tstring & str)
{
    trim_trailing_ws (str);
    trim_leading_ws (str);
}

void
imbue_file_from_flags (tistream & file, unsigned flags)
{
    switch (flags & (Properties::fEncodingMask << Properties::fEncodingShift))
    {
#if defined (LOG4CPLUS_HAVE_CODECVT_UTF8_FACET) && defined (UNICODE)
    case Properties::fUTF8:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf8<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;
#endif

#if defined (LOG4CPLUS_HAVE_CODECVT_UTF16_FACET) && defined (UNICODE)
    case Properties::fUTF16:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf16<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;

#elif defined (UNICODE) && defined (WIN32)
    case Properties::fUTF16:
        file.imbue (
            std::locale (file.getloc (),
                // TODO: This should actually be a custom "null" facet
                // that just copies the chars to wchar_t buffer.
                new std::codecvt<wchar_t, char, std::mbstate_t>));
    break;

#endif

#if defined (LOG4CPLUS_HAVE_CODECVT_UTF32_FACET) && defined (UNICODE)
    case Properties::fUTF32:
        file.imbue (
            std::locale (file.getloc (),
                new std::codecvt_utf32<tchar, 0x10FFFF,
                    static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)>));
        break;
#endif

    case Properties::fUnspecEncoding:;
    default:
        // Do nothing.
        ;
    }
}

} // namespace

///////////////////////////////////////////////////////////////////////////////
// Properties ctors and dtor
///////////////////////////////////////////////////////////////////////////////

Properties::Properties()
    : flags (0)
{
}

Properties::Properties(tistream& input)
    : flags (0)
{
    init(input);
}

Properties::Properties(const tstring& inputFile, unsigned f)
    : flags (f)
{
    if (inputFile.empty ())
        return;

    tifstream file;
    imbue_file_from_flags (file, flags);

    file.open(LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(inputFile).c_str(),
        std::ios::binary);
    if (! file.good ())
        helpers::getLogLog ().error (LOG4CPLUS_TEXT ("could not open file ")
            + inputFile);

    init(file);
}

void
Properties::init(tistream& input)
{
    if (! input)
        return;

    tstring buffer;
    while (std::getline (input, buffer))
    {
        trim_leading_ws (buffer);

        tstring::size_type const buffLen = buffer.size ();
        if (buffLen == 0 || buffer[0] == PROPERTIES_COMMENT_CHAR)
            continue;

        // Check if we have a trailing \r because we are
        // reading a properties file produced on Windows.
        if (buffer[buffLen-1] == LOG4CPLUS_TEXT('\r'))
            // Remove trailing 'Windows' \r.
            buffer.resize (buffLen - 1);

        tstring::size_type const idx = buffer.find('=');
        if (idx != tstring::npos)
        {
            tstring key = buffer.substr(0, idx);
            tstring value = buffer.substr(idx + 1);
            trim_trailing_ws (key);
            trim_ws (value);
            setProperty(key, value);
        }
        else if (buffer.compare (0, 7, LOG4CPLUS_TEXT ("include")) == 0
            && buffer.size () >= 7 + 1 + 1
            && is_space (buffer[7]))
        {
            tstring included (buffer, 8) ;
            trim_ws (included);

            tifstream file;
            imbue_file_from_flags (file, flags);

            file.open (LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(included).c_str(),
                std::ios::binary);
            if (! file.good ())
                helpers::getLogLog ().error (
                    LOG4CPLUS_TEXT ("could not open file ") + included);

            init (file);
        }
    }
}

Properties::~Properties()
{
}

///////////////////////////////////////////////////////////////////////////////
// helpers::Properties public methods
///////////////////////////////////////////////////////////////////////////////

bool
Properties::exists(const log4cplus::tstring& key) const
{
    return data.find(key) != data.end();
}

bool
Properties::exists(tchar const * key) const
{
    return data.find(key) != data.end();
}

tstring const &
Properties::getProperty(const tstring& key) const
{
    return get_property_worker (key);
}

log4cplus::tstring const &
Properties::getProperty(tchar const * key) const
{
    return get_property_worker (key);
}

tstring
Properties::getProperty(const tstring& key, const tstring& defaultVal) const
{
    StringMap::const_iterator it (data.find (key));
    if (it == data.end ())
        return defaultVal;
    else
        return it->second;
}

std::vector<tstring>
Properties::propertyNames() const
{
    std::vector<tstring> tmp;
    for (StringMap::const_iterator it=data.begin(); it!=data.end(); ++it)
        tmp.push_back(it->first);

    return tmp;
}

void
Properties::setProperty(const log4cplus::tstring& key,
    const log4cplus::tstring& value)
{
    data[key] = value;
}

bool
Properties::removeProperty(const log4cplus::tstring& key)
{
    return data.erase(key) > 0;
}

Properties
Properties::getPropertySubset(const log4cplus::tstring& prefix) const
{
    Properties ret;
    std::size_t const prefix_len = prefix.size ();
    std::vector<tstring> keys = propertyNames();
    for (std::vector<tstring>::iterator it=keys.begin(); it!=keys.end(); ++it)
    {
        int result = it->compare (0, prefix_len, prefix);
        if (result == 0)
            ret.setProperty (it->substr (prefix_len), getProperty(*it));
    }

    return ret;
}

bool
Properties::getInt (int & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getUInt (unsigned & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getLong (long & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getULong (unsigned long & val, log4cplus::tstring const & key) const
{
    return get_type_val_worker (val, key);
}

bool
Properties::getBool (bool & val, log4cplus::tstring const & key) const
{
    if (! exists (key))
        return false;

    log4cplus::tstring const & prop_val = getProperty (key);
    return internal::parse_bool (val, prop_val);
}

template <typename StringType>
log4cplus::tstring const &
Properties::get_property_worker (StringType const & key) const
{
    StringMap::const_iterator it (data.find (key));
    if (it == data.end ())
        return log4cplus::internal::empty_str;
    else
        return it->second;
}

template <typename ValType>
bool
Properties::get_type_val_worker (ValType & val, log4cplus::tstring const & key)
    const
{
    if (! exists (key))
        return false;

    log4cplus::tstring const & prop_val = getProperty (key);
    log4cplus::tistringstream iss (prop_val);
    ValType tmp_val;
    tchar ch;

    iss >> tmp_val;
    if (! iss)
        return false;
    iss >> ch;
    if (iss)
        return false;

    val = tmp_val;
    return true;
}

} } // namespace log4cplus { namespace helpers {
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkStarbasePolyDataMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdlib.h>
#include <math.h>
#include "vtkStarbasePolyDataMapper.h"
#include "vtkStarbaseRenderer.h"
#include "vtkPolyData.h"

// Description:
// Construct empty object.
vtkStarbasePolyDataMapper::vtkStarbasePolyDataMapper()
{
  this->Data = NULL;
  this->Colors = NULL;
  this->Prim = NULL;
}

vtkStarbasePolyDataMapper::~vtkStarbasePolyDataMapper()
{
  // if Prim is set the free it
  if (this->Prim)
    {
    delete [] this->Prim;
    }
}

//
// Receives from Actor -> maps data to primitives
//
void vtkStarbasePolyDataMapper::Render(vtkRenderer *ren, vtkActor *act)
{
  int numPts;
  vtkPolyData *input= (vtkPolyData *)this->Input;
//
// make sure that we've been properly initialized
//
  if ( input == NULL )
    {
    vtkErrorMacro(<< "No input!");
    return;
    }
  else
    {
    input->Update();
    numPts = input->GetNumberOfPoints();
    }

  if (numPts == 0)
    {
    vtkDebugMacro(<< "No points!");
    return;
    }

  if ( this->LookupTable == NULL ) this->CreateDefaultLookupTable();

  //
  // if something has changed regenrate colors and display lists
  // if required
  //
  if ( this->GetMTime() > this->BuildTime ||
       input->GetMTime() > this->BuildTime ||
       this->LookupTable->GetMTime() > this->BuildTime ||
       act->GetProperty()->GetMTime() > this->BuildTime)
    {
    // sets this->Colors as side effect
    this->GetColors();
    this->Build(input,this->Colors);
    this->BuildTime.Modified();
    }

  // want to draw the primitives here
  this->Draw(ren,act);
}

// Description:
// Build the data structure for the starbase polygon PolyDataMapper.
void vtkStarbasePolyDataMapper::Build(vtkPolyData *data, vtkColorScalars *c)
{
  vtkNormals *normals;
  vtkTCoords *t;
  int maxSize;

  this->Data = data;
  this->Colors = c;

  normals = this->Data->GetPointData()->GetNormals();
  t = this->Data->GetPointData()->GetTCoords();

  this->DataFlag = 0;
  if (this->Colors)
    {
    this->DataFlag += 3;
    }
  if (normals)
    {
    this->DataFlag += 3;
    }
  if (t)
    {
    this->DataFlag += 2;
    }

  // allocate storage
  if (this->Prim)
    {
    delete [] this->Prim;
    }

  maxSize = data->GetVerts()->GetMaxCellSize();
  if (maxSize < data->GetLines()->GetMaxCellSize())
    maxSize = data->GetLines()->GetMaxCellSize();
  if (maxSize < data->GetPolys()->GetMaxCellSize())
    maxSize = data->GetPolys()->GetMaxCellSize();
  if (maxSize < data->GetStrips()->GetMaxCellSize())
    maxSize = data->GetStrips()->GetMaxCellSize();

  this->Prim =
    new float [(this->DataFlag+4) * maxSize];

  return;
}

// Description:
// Load polydata into starbase graphics library.
void vtkStarbasePolyDataMapper::Draw(vtkRenderer *aren, vtkActor *act)
{
  vtkStarbaseRenderer *ren = (vtkStarbaseRenderer *)aren;
  int npts, j;
  float tran;
  vtkProperty *prop;
  vtkPoints *p;
  vtkCellArray *prims[4], *aPrim;
  vtkColorScalars *c;
  vtkNormals *n;
  int *pts;
  int fd, primType;
  float *poly;
  unsigned char *rgb;
  float clr[3];
  vtkTCoords *t;
  int vflags = 0;

  // get the fd
  fd = ren->GetFd();

  // get the property
  prop = act->GetProperty();

  // get the transparency
  tran = prop->GetOpacity();

  // if the polygons are invisable then get out of here
  if (tran <= 0.0) return;

  // and draw the display list
  p = this->Data->GetPoints();
  c = this->Colors;
  n = this->Data->GetPointData()->GetNormals();
  prims[0] = this->Data->GetVerts();
  prims[1] = this->Data->GetLines();
  prims[2] = this->Data->GetStrips();
  prims[3] = this->Data->GetPolys();

  t = this->Data->GetPointData()->GetTCoords();
  if ( t )
    {
    if (t->GetDimension() != 2)
      {
      vtkDebugMacro(<< "Currently only 2d textures are supported.\n");
      t = NULL;
      }
    }

  // set the flags
  if (c)
    {
    vflags |= VERTEX_COLOR;
    }
  if (n)
    {
    vflags |= VERTEX_NORMAL;
    }
  if (t)
    {
    vflags |= TEXTURE_MAP;
    }

  // due to a bug in starbase, if we have vertex colors and we want
  // two sided lighting then we must do it the wrong way in order
  // to see the vertex coloring
  if (c && ren->GetTwoSidedLighting())
    {
    bf_control(fd, TRUE, FALSE);
    }

  for (primType = 0; primType < 4; primType++)
    {
    aPrim = prims[primType];
    if (primType == 1) vflags |= MD_FLAGS;
    if (primType == 2) vflags = vflags & (~MD_FLAGS);

    for (aPrim->InitTraversal(); aPrim->GetNextCell(npts,pts); )
      {
      poly = this->Prim;

      for (j = 0; j < npts; j++)
	{
	memcpy(poly,p->GetPoint(pts[j]),sizeof(float)*3);
	poly += 3;

	if (c)
	  {
	  rgb = c->GetColor(pts[j]);
	  clr[0] = rgb[0]/255.0;
	  clr[1] = rgb[1]/255.0;
	  clr[2] = rgb[2]/255.0;
	  memcpy(poly,clr,sizeof(float)*3);
	  poly += 3;
	  }

	if (n)
	  {
	  memcpy(poly,n->GetNormal(pts[j]),sizeof(float)*3);
	  poly += 3;
	  }

	if (t)
	  {
	  memcpy(poly,t->GetTCoord(pts[j]),sizeof(float)*2);
	  poly += 2;
	  }

	// set move/draw flag
	if (primType == 1)
	  {
	  if (!j)
	    {
	    *poly = 0.0;
	    }
	  else
	    {
	    *poly = 1.0;
	    }
	  poly++;
	  }
	}

      switch (primType)
	{
	case 0:
	  polymarker_with_data3d(fd, this->Prim, npts, this->DataFlag, vflags);
	  break;
	case 1:
	  polyline_with_data3d(fd, this->Prim, npts, this->DataFlag + 1,
			       vflags, 0);
	  break;
	case 2:
	  triangular_strip_with_data(fd, this->Prim, npts, NULL,
				     this->DataFlag, vflags, 0);
	  break;
	case 3:
	  polygon_with_data3d (fd, this->Prim, npts, this->DataFlag,
			       vflags, 0);
	  break;
	}
      }
    }

  // reset the lighting to how it was before
  if (c && ren->GetTwoSidedLighting())
    {
    bf_control(fd, FALSE, TRUE);
    }
}
<commit_msg>Removed this->Data code. (Lisa)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkStarbasePolyDataMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdlib.h>
#include <math.h>
#include "vtkStarbasePolyDataMapper.h"
#include "vtkStarbaseRenderer.h"
#include "vtkPolyData.h"

// Description:
// Construct empty object.
vtkStarbasePolyDataMapper::vtkStarbasePolyDataMapper()
{
  this->Colors = NULL;
  this->Prim = NULL;
}

vtkStarbasePolyDataMapper::~vtkStarbasePolyDataMapper()
{
  // if Prim is set the free it
  if (this->Prim)
    {
    delete [] this->Prim;
    }
}

//
// Receives from Actor -> maps data to primitives
//
void vtkStarbasePolyDataMapper::Render(vtkRenderer *ren, vtkActor *act)
{
  int numPts;
  vtkPolyData *input= (vtkPolyData *)this->Input;
//
// make sure that we've been properly initialized
//
  if ( input == NULL )
    {
    vtkErrorMacro(<< "No input!");
    return;
    }
  else
    {
    input->Update();
    numPts = input->GetNumberOfPoints();
    }

  if (numPts == 0)
    {
    vtkDebugMacro(<< "No points!");
    return;
    }

  if ( this->LookupTable == NULL ) this->CreateDefaultLookupTable();

  //
  // if something has changed regenrate colors and display lists
  // if required
  //
  if ( this->GetMTime() > this->BuildTime ||
       input->GetMTime() > this->BuildTime ||
       this->LookupTable->GetMTime() > this->BuildTime ||
       act->GetProperty()->GetMTime() > this->BuildTime)
    {
    // sets this->Colors as side effect
    this->GetColors();
    this->Build(input,this->Colors);
    this->BuildTime.Modified();
    }

  // want to draw the primitives here
  this->Draw(ren,act);
}

// Description:
// Build the data structure for the starbase polygon PolyDataMapper.
void vtkStarbasePolyDataMapper::Build(vtkPolyData *data, vtkColorScalars *c)
{
  vtkNormals *normals;
  vtkTCoords *t;
  int maxSize;
  vtkPolyData *input= (vtkPolyData *)this->Input;

  this->Colors = c;

  normals = input->GetPointData()->GetNormals();
  t = input->GetPointData()->GetTCoords();

  this->DataFlag = 0;
  if (this->Colors)
    {
    this->DataFlag += 3;
    }
  if (normals)
    {
    this->DataFlag += 3;
    }
  if (t)
    {
    this->DataFlag += 2;
    }

  // allocate storage
  if (this->Prim)
    {
    delete [] this->Prim;
    }

  maxSize = data->GetVerts()->GetMaxCellSize();
  if (maxSize < data->GetLines()->GetMaxCellSize())
    maxSize = data->GetLines()->GetMaxCellSize();
  if (maxSize < data->GetPolys()->GetMaxCellSize())
    maxSize = data->GetPolys()->GetMaxCellSize();
  if (maxSize < data->GetStrips()->GetMaxCellSize())
    maxSize = data->GetStrips()->GetMaxCellSize();

  this->Prim =
    new float [(this->DataFlag+4) * maxSize];

  return;
}

// Description:
// Load polydata into starbase graphics library.
void vtkStarbasePolyDataMapper::Draw(vtkRenderer *aren, vtkActor *act)
{
  vtkStarbaseRenderer *ren = (vtkStarbaseRenderer *)aren;
  int npts, j;
  float tran;
  vtkProperty *prop;
  vtkPoints *p;
  vtkCellArray *prims[4], *aPrim;
  vtkColorScalars *c;
  vtkNormals *n;
  int *pts;
  int fd, primType;
  float *poly;
  unsigned char *rgb;
  float clr[3];
  vtkTCoords *t;
  int vflags = 0;
  vtkPolyData *input= (vtkPolyData *)this->Input;

  // get the fd
  fd = ren->GetFd();

  // get the property
  prop = act->GetProperty();

  // get the transparency
  tran = prop->GetOpacity();

  // if the polygons are invisable then get out of here
  if (tran <= 0.0) return;

  // and draw the display list
  p = input->GetPoints();
  c = this->Colors;
  n = input->GetPointData()->GetNormals();
  prims[0] = input->GetVerts();
  prims[1] = input->GetLines();
  prims[2] = input->GetStrips();
  prims[3] = input->GetPolys();

  t = input->GetPointData()->GetTCoords();
  if ( t )
    {
    if (t->GetDimension() != 2)
      {
      vtkDebugMacro(<< "Currently only 2d textures are supported.\n");
      t = NULL;
      }
    }

  // set the flags
  if (c)
    {
    vflags |= VERTEX_COLOR;
    }
  if (n)
    {
    vflags |= VERTEX_NORMAL;
    }
  if (t)
    {
    vflags |= TEXTURE_MAP;
    }

  // due to a bug in starbase, if we have vertex colors and we want
  // two sided lighting then we must do it the wrong way in order
  // to see the vertex coloring
  if (c && ren->GetTwoSidedLighting())
    {
    bf_control(fd, TRUE, FALSE);
    }

  for (primType = 0; primType < 4; primType++)
    {
    aPrim = prims[primType];
    if (primType == 1) vflags |= MD_FLAGS;
    if (primType == 2) vflags = vflags & (~MD_FLAGS);

    for (aPrim->InitTraversal(); aPrim->GetNextCell(npts,pts); )
      {
      poly = this->Prim;

      for (j = 0; j < npts; j++)
	{
	memcpy(poly,p->GetPoint(pts[j]),sizeof(float)*3);
	poly += 3;

	if (c)
	  {
	  rgb = c->GetColor(pts[j]);
	  clr[0] = rgb[0]/255.0;
	  clr[1] = rgb[1]/255.0;
	  clr[2] = rgb[2]/255.0;
	  memcpy(poly,clr,sizeof(float)*3);
	  poly += 3;
	  }

	if (n)
	  {
	  memcpy(poly,n->GetNormal(pts[j]),sizeof(float)*3);
	  poly += 3;
	  }

	if (t)
	  {
	  memcpy(poly,t->GetTCoord(pts[j]),sizeof(float)*2);
	  poly += 2;
	  }

	// set move/draw flag
	if (primType == 1)
	  {
	  if (!j)
	    {
	    *poly = 0.0;
	    }
	  else
	    {
	    *poly = 1.0;
	    }
	  poly++;
	  }
	}

      switch (primType)
	{
	case 0:
	  polymarker_with_data3d(fd, this->Prim, npts, this->DataFlag, vflags);
	  break;
	case 1:
	  polyline_with_data3d(fd, this->Prim, npts, this->DataFlag + 1,
			       vflags, 0);
	  break;
	case 2:
	  triangular_strip_with_data(fd, this->Prim, npts, NULL,
				     this->DataFlag, vflags, 0);
	  break;
	case 3:
	  polygon_with_data3d (fd, this->Prim, npts, this->DataFlag,
			       vflags, 0);
	  break;
	}
      }
    }

  // reset the lighting to how it was before
  if (c && ren->GetTwoSidedLighting())
    {
    bf_control(fd, FALSE, TRUE);
    }
}
<|endoftext|>