<commit_before>#include "bvs/bvs.h"
#include "bvs/traits.h"
#include "control.h"
#include "loader.h"

#ifdef BVS_LOG_SYSTEM
#include "logsystem.h"
#endif

BVS::BVS::BVS(int argc, char** argv, std::function<void()>shutdownHandler)
	: config{"bvs", argc, argv},
	shutdownHandler(shutdownHandler),
	info(Info{config, 0, {}, {}}),
#ifdef BVS_LOG_SYSTEM
	logSystem{LogSystem::connectToLogSystem()},
	logger{"BVS"},
#endif
	loader{new Loader{info}},
	control{new Control{loader->modules, *this, info}},
	moduleStack{}
{
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif
}

BVS::BVS::~BVS()
{
	delete control;
	delete loader;
}

BVS::BVS& BVS::BVS::loadModules()
{
	// get module list from config
	std::vector<std::string> moduleList;
	config.getValue("BVS.modules", moduleList);
	std::string poolName;

	// check length
	if (moduleList.size()==0)
	{
		LOG(1, "No modules specified, nothing to load!");
		return *this;
	}

	// load all selected modules
	bool asThread;
	for (auto& it : moduleList)
	{
		asThread = false;
		poolName.clear();

		// check for thread selection ('+' prefix) and system settings
		if (it[0]=='+')
		{
			it.erase(0, 1);
			if (it[0]=='[')
			{
				LOG(0, "Cannot start module in thread AND pool!");
				exit(1);
			}
			asThread = true;
		}

		if (it[0]=='[')
		{
			size_t pos = it.find_first_of(']');
			poolName = it.substr(1, pos-1);
			it.erase(0, pos+1);
		}

		loadModule(it , asThread, poolName);
	}

	return *this;
}

BVS::BVS& BVS::BVS::loadModule(const std::string& moduleTraits, bool asThread, std::string poolName)
{
	std::string id;
	std::string library;
	std::string configuration;
	std::string options;

	// adapt to module thread/pools settings
	bool moduleThreads = config.getValue<bool>("BVS.moduleThreads", bvs_module_threads);
	bool forceModuleThreads = config.getValue<bool>("BVS.forceModuleThreads", bvs_module_force_threads);
	bool modulePools = config.getValue<bool>("BVS.modulePools", bvs_module_pools);

	if (forceModuleThreads) asThread = true;
	if (!moduleThreads) asThread = false;
	if (!modulePools) poolName.clear();

	// separate id, library, configuration and options
	size_t separator = moduleTraits.find_first_of(".()");
	if (separator==std::string::npos) id = moduleTraits;
	else if (moduleTraits.at(separator)=='.')
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else if (moduleTraits.at(separator)=='(')
	{
		size_t dot = moduleTraits.find_first_of('.');
		size_t rp = moduleTraits.find_first_of(')');
		id = moduleTraits.substr(0, separator);
		library = moduleTraits.substr(separator+1, rp-separator-1);
		options = moduleTraits.substr(rp+2<moduleTraits.size()?rp+2:rp+1, std::string::npos);
		if (dot<rp)
		{
			library = moduleTraits.substr(separator+1, dot-separator-1);
			configuration = moduleTraits.substr(dot+1, rp-dot-1);
		}
	}
	if (library.empty()) library = id;
	if (configuration.empty()) configuration = id;

	// load
	loader->load(id, library, configuration, options, asThread, poolName);
	control->startModule(id);
	moduleStack.push(id);

	return *this;
}

BVS::BVS& BVS::BVS::unloadModules()
{
	while (!moduleStack.empty())
	{
		if(loader->modules.find(moduleStack.top())!=loader->modules.end())
		{
			unloadModule(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::BVS& BVS::BVS::unloadModule(const std::string& id)
{
	SystemFlag state = control->queryActiveFlag();
	if (state!=SystemFlag::QUIT) control->sendCommand(SystemFlag::PAUSE);

	control->waitUntilInactive(id);
	control->purgeData(id);
	control->quitModule(id);
	loader->unload(id);

	if (state!=SystemFlag::QUIT) control->sendCommand(state);

	return *this;
}

BVS::BVS& BVS::BVS::loadConfigFile(const std::string& configFile)
{
	config.loadConfigFile(configFile);
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif

	return *this;
}

BVS::BVS& BVS::BVS::setLogSystemVerbosity(const unsigned short verbosity)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->setSystemVerbosity(verbosity);
#else
	(void) verbosity;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogFile(const std::string& file, bool append)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogFile(file, append);
#else
	(void) file;
	(void) append;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogFile()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogFile();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogConsole(const std::ostream& out)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogConsole(out);
#else
	(void) out;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogConsole()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogConsole();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::connectAllModules()
{
	loader->connectAllModules();

	return *this;
}

BVS::BVS& BVS::BVS::connectModule(const std::string id)
{
	loader->connectModule(id, config.getValue<bool>("BVS.connectorTypeMatching", bvs_connector_type_matching));

	return *this;
}

BVS::BVS& BVS::BVS::start(bool forkMasterController)
{
	control->masterController(forkMasterController);

	return *this;
}

BVS::BVS& BVS::BVS::run()
{
	control->sendCommand(SystemFlag::RUN);

	return *this;
}

BVS::BVS& BVS::BVS::step()
{
	control->sendCommand(SystemFlag::STEP);

	return *this;
}

BVS::BVS& BVS::BVS::pause()
{
	control->sendCommand(SystemFlag::PAUSE);

	return *this;
}

BVS::BVS& BVS::BVS::hotSwap(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	if (control->modules.find(id)!=control->modules.end())
	{
		SystemFlag state = control->queryActiveFlag();
		control->sendCommand(SystemFlag::PAUSE);
		control->waitUntilInactive(id);

		loader->hotSwapModule(id);
		control->sendCommand(state);
	}
	else
	{
		LOG(0, "'" << id << "' not found!");
	}
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::BVS& BVS::BVS::quit()
{
	control->sendCommand(SystemFlag::QUIT);
	unloadModules();

	return *this;
}
<commit_msg>bvs: purgeData needs further fixing, disable for now<commit_after>#include "bvs/bvs.h"
#include "bvs/traits.h"
#include "control.h"
#include "loader.h"

#ifdef BVS_LOG_SYSTEM
#include "logsystem.h"
#endif

BVS::BVS::BVS(int argc, char** argv, std::function<void()>shutdownHandler)
	: config{"bvs", argc, argv},
	shutdownHandler(shutdownHandler),
	info(Info{config, 0, {}, {}}),
#ifdef BVS_LOG_SYSTEM
	logSystem{LogSystem::connectToLogSystem()},
	logger{"BVS"},
#endif
	loader{new Loader{info}},
	control{new Control{loader->modules, *this, info}},
	moduleStack{}
{
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif
}

BVS::BVS::~BVS()
{
	delete control;
	delete loader;
}

BVS::BVS& BVS::BVS::loadModules()
{
	// get module list from config
	std::vector<std::string> moduleList;
	config.getValue("BVS.modules", moduleList);
	std::string poolName;

	// check length
	if (moduleList.size()==0)
	{
		LOG(1, "No modules specified, nothing to load!");
		return *this;
	}

	// load all selected modules
	bool asThread;
	for (auto& it : moduleList)
	{
		asThread = false;
		poolName.clear();

		// check for thread selection ('+' prefix) and system settings
		if (it[0]=='+')
		{
			it.erase(0, 1);
			if (it[0]=='[')
			{
				LOG(0, "Cannot start module in thread AND pool!");
				exit(1);
			}
			asThread = true;
		}

		if (it[0]=='[')
		{
			size_t pos = it.find_first_of(']');
			poolName = it.substr(1, pos-1);
			it.erase(0, pos+1);
		}

		loadModule(it , asThread, poolName);
	}

	return *this;
}

BVS::BVS& BVS::BVS::loadModule(const std::string& moduleTraits, bool asThread, std::string poolName)
{
	std::string id;
	std::string library;
	std::string configuration;
	std::string options;

	// adapt to module thread/pools settings
	bool moduleThreads = config.getValue<bool>("BVS.moduleThreads", bvs_module_threads);
	bool forceModuleThreads = config.getValue<bool>("BVS.forceModuleThreads", bvs_module_force_threads);
	bool modulePools = config.getValue<bool>("BVS.modulePools", bvs_module_pools);

	if (forceModuleThreads) asThread = true;
	if (!moduleThreads) asThread = false;
	if (!modulePools) poolName.clear();

	// separate id, library, configuration and options
	size_t separator = moduleTraits.find_first_of(".()");
	if (separator==std::string::npos) id = moduleTraits;
	else if (moduleTraits.at(separator)=='.')
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else if (moduleTraits.at(separator)=='(')
	{
		size_t dot = moduleTraits.find_first_of('.');
		size_t rp = moduleTraits.find_first_of(')');
		id = moduleTraits.substr(0, separator);
		library = moduleTraits.substr(separator+1, rp-separator-1);
		options = moduleTraits.substr(rp+2<moduleTraits.size()?rp+2:rp+1, std::string::npos);
		if (dot<rp)
		{
			library = moduleTraits.substr(separator+1, dot-separator-1);
			configuration = moduleTraits.substr(dot+1, rp-dot-1);
		}
	}
	if (library.empty()) library = id;
	if (configuration.empty()) configuration = id;

	// load
	loader->load(id, library, configuration, options, asThread, poolName);
	control->startModule(id);
	moduleStack.push(id);

	return *this;
}

BVS::BVS& BVS::BVS::unloadModules()
{
	while (!moduleStack.empty())
	{
		if(loader->modules.find(moduleStack.top())!=loader->modules.end())
		{
			unloadModule(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::BVS& BVS::BVS::unloadModule(const std::string& id)
{
	SystemFlag state = control->queryActiveFlag();
	if (state!=SystemFlag::QUIT) control->sendCommand(SystemFlag::PAUSE);

	control->waitUntilInactive(id);
	//TODO fix purgeData, eventually causes segfaults
	//control->purgeData(id);
	control->quitModule(id);
	loader->unload(id);

	if (state!=SystemFlag::QUIT) control->sendCommand(state);

	return *this;
}

BVS::BVS& BVS::BVS::loadConfigFile(const std::string& configFile)
{
	config.loadConfigFile(configFile);
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif

	return *this;
}

BVS::BVS& BVS::BVS::setLogSystemVerbosity(const unsigned short verbosity)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->setSystemVerbosity(verbosity);
#else
	(void) verbosity;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogFile(const std::string& file, bool append)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogFile(file, append);
#else
	(void) file;
	(void) append;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogFile()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogFile();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogConsole(const std::ostream& out)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogConsole(out);
#else
	(void) out;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogConsole()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogConsole();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::connectAllModules()
{
	loader->connectAllModules();

	return *this;
}

BVS::BVS& BVS::BVS::connectModule(const std::string id)
{
	loader->connectModule(id, config.getValue<bool>("BVS.connectorTypeMatching", bvs_connector_type_matching));

	return *this;
}

BVS::BVS& BVS::BVS::start(bool forkMasterController)
{
	control->masterController(forkMasterController);

	return *this;
}

BVS::BVS& BVS::BVS::run()
{
	control->sendCommand(SystemFlag::RUN);

	return *this;
}

BVS::BVS& BVS::BVS::step()
{
	control->sendCommand(SystemFlag::STEP);

	return *this;
}

BVS::BVS& BVS::BVS::pause()
{
	control->sendCommand(SystemFlag::PAUSE);

	return *this;
}

BVS::BVS& BVS::BVS::hotSwap(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	if (control->modules.find(id)!=control->modules.end())
	{
		SystemFlag state = control->queryActiveFlag();
		control->sendCommand(SystemFlag::PAUSE);
		control->waitUntilInactive(id);

		loader->hotSwapModule(id);
		control->sendCommand(state);
	}
	else
	{
		LOG(0, "'" << id << "' not found!");
	}
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::BVS& BVS::BVS::quit()
{
	control->sendCommand(SystemFlag::QUIT);
	unloadModules();

	return *this;
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_POTENTIAL_GLOBAL_IGNORE_MOLECULE_HPP
#define MJOLNIR_POTENTIAL_GLOBAL_IGNORE_MOLECULE_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <string>
#include <memory>

// In some case, we need to ignore intra- or inter-molecule interaction.
// For example, consider you have an elastic network model and charges on it
// that are tuned to reproduce the electrostatic potentials around the native
// structure. In that case, the electrostatic interaction should not be applied
// for the intra-molecule pairs to avoid double-counting because the elastic
// network potential is modeled as a sum of all the intra-molecule interactions.
//     IgnoreMolecule provides you a way to specify the rule to determine ignored
// pairs of particles. If you specify IgnoreSelf, all the intra-molecule
// interactions would be ignored. IgnoreOthers ignores inter-molecule interactions.
// Clearly, IgnoreNothing ignores nothing.

namespace mjolnir
{

template<typename MoleculeID>
struct IgnoreMoleculeBase
{
    IgnoreMoleculeBase()          = default;
    virtual ~IgnoreMoleculeBase() = default;

    virtual bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept = 0;
    virtual const char* name() const noexcept = 0;
};

template<typename MoleculeID>
struct IgnoreNothing: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreNothing()           = default;
    ~IgnoreNothing() override = default;

    bool is_ignored(const MoleculeID&, const MoleculeID&) const noexcept override
    {
        return false;
    }
    const char* name() const noexcept override {return "Nothing";}
};

template<typename MoleculeID>
struct IgnoreSelf: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreSelf()           = default;
    ~IgnoreSelf() override = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept override
    {
        return i == j;
    }
    const char* name() const noexcept override {return "Self";}
};

template<typename MoleculeID>
struct IgnoreOthers: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreOthers()           = default;
    ~IgnoreOthers() override = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept override
    {
        return i != j;
    }
    const char* name() const noexcept override {return "Others";}
};

template<typename MoleculeID>
struct IgnoreMolecule
{
    explicit IgnoreMolecule(const std::string& name): ignore_mol_(nullptr)
    {
        this->reset(name);
    }

    template<typename IgnoreSomething>
    explicit IgnoreMolecule(std::unique_ptr<IgnoreSomething>&& ptr)
        : ignore_mol_(std::move(ptr))
    {}
    ~IgnoreMolecule() = default;

    IgnoreMolecule(IgnoreMolecule const& rhs) {this->reset(rhs.name());}
    IgnoreMolecule(IgnoreMolecule&&      rhs) = default;
    IgnoreMolecule& operator=(IgnoreMolecule const& rhs) {this->reset(rhs.name()); return *this;}
    IgnoreMolecule& operator=(IgnoreMolecule&&      rhs) = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept
    {
        return ignore_mol_->is_ignored(i, j);
    }
    const char* name() const noexcept {return ignore_mol_->name();}

    void reset(const std::string& name)
    {
        if(name == "Nothing")
        {
            ignore_mol_.reset(new IgnoreNothing<MoleculeID>);
        }
        else if(name == "Self")
        {
            ignore_mol_.reset(new IgnoreSelf<MoleculeID>);
        }
        else if(name == "Others")
        {
            ignore_mol_.reset(new IgnoreOthers<MoleculeID>);
        }
        else
        {
            throw_exception<std::invalid_argument>("IgnoreMolecule::IgnoreMolecule: ",
                "unknown signeture appreaed: `" + name +
                "`. Only `Nothing`, `Self`, or `Others` are allowed.");
        }
    }

  private:

    std::unique_ptr<IgnoreMoleculeBase<MoleculeID>> ignore_mol_;
};

} // mjolnir
#endif// MJOLNIR_IGNORE_MOLECULE_HPP
<commit_msg>feat: enable to use "Intra" and "Inter"<commit_after>#ifndef MJOLNIR_POTENTIAL_GLOBAL_IGNORE_MOLECULE_HPP
#define MJOLNIR_POTENTIAL_GLOBAL_IGNORE_MOLECULE_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <string>
#include <memory>

// In some case, we need to ignore intra- or inter-molecule interaction.
// For example, consider you have an elastic network model and charges on it
// that are tuned to reproduce the electrostatic potentials around the native
// structure. In that case, the electrostatic interaction should not be applied
// for the intra-molecule pairs to avoid double-counting because the elastic
// network potential is modeled as a sum of all the intra-molecule interactions.
//     IgnoreMolecule provides you a way to specify the rule to determine ignored
// pairs of particles. If you specify IgnoreSelf, all the intra-molecule
// interactions would be ignored. IgnoreOthers ignores inter-molecule interactions.
// Clearly, IgnoreNothing ignores nothing.

namespace mjolnir
{

template<typename MoleculeID>
struct IgnoreMoleculeBase
{
    IgnoreMoleculeBase()          = default;
    virtual ~IgnoreMoleculeBase() = default;

    virtual bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept = 0;
    virtual const char* name() const noexcept = 0;
};

template<typename MoleculeID>
struct IgnoreNothing: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreNothing()           = default;
    ~IgnoreNothing() override = default;

    bool is_ignored(const MoleculeID&, const MoleculeID&) const noexcept override
    {
        return false;
    }
    const char* name() const noexcept override {return "Nothing";}
};

template<typename MoleculeID>
struct IgnoreSelf: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreSelf()           = default;
    ~IgnoreSelf() override = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept override
    {
        return i == j;
    }
    const char* name() const noexcept override {return "Self";}
};

template<typename MoleculeID>
struct IgnoreOthers: public IgnoreMoleculeBase<MoleculeID>
{
    IgnoreOthers()           = default;
    ~IgnoreOthers() override = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept override
    {
        return i != j;
    }
    const char* name() const noexcept override {return "Others";}
};

template<typename MoleculeID>
struct IgnoreMolecule
{
    explicit IgnoreMolecule(const std::string& name): ignore_mol_(nullptr)
    {
        this->reset(name);
    }

    template<typename IgnoreSomething>
    explicit IgnoreMolecule(std::unique_ptr<IgnoreSomething>&& ptr)
        : ignore_mol_(std::move(ptr))
    {}
    ~IgnoreMolecule() = default;

    IgnoreMolecule(IgnoreMolecule const& rhs) {this->reset(rhs.name());}
    IgnoreMolecule(IgnoreMolecule&&      rhs) = default;
    IgnoreMolecule& operator=(IgnoreMolecule const& rhs) {this->reset(rhs.name()); return *this;}
    IgnoreMolecule& operator=(IgnoreMolecule&&      rhs) = default;

    bool is_ignored(const MoleculeID& i, const MoleculeID& j) const noexcept
    {
        return ignore_mol_->is_ignored(i, j);
    }
    const char* name() const noexcept {return ignore_mol_->name();}

    void reset(const std::string& name)
    {
        if(name == "Nothing")
        {
            ignore_mol_.reset(new IgnoreNothing<MoleculeID>);
        }
        else if(name == "Self" || name == "Intra")
        {
            ignore_mol_.reset(new IgnoreSelf<MoleculeID>);
        }
        else if(name == "Others" || name == "Inter")
        {
            ignore_mol_.reset(new IgnoreOthers<MoleculeID>);
        }
        else
        {
            throw_exception<std::invalid_argument>("IgnoreMolecule::IgnoreMolecule: ",
                "unknown signeture appreaed: `" + name +
                "`. Only `Nothing`, `Self`, or `Others` are allowed.");
        }
    }

  private:

    std::unique_ptr<IgnoreMoleculeBase<MoleculeID>> ignore_mol_;
};

} // mjolnir
#endif// MJOLNIR_IGNORE_MOLECULE_HPP
<|endoftext|>


<commit_before>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <algorithm>
#include <boost/filesystem.hpp>

#ifdef _WIN32
#include <shlobj.h>
#endif

#include "Base.h"
#include "FS.h"
#include "Log.h"
#include "Garlic.h"

namespace i2p {
namespace fs {
  std::string appName = "i2pd";
  std::string dataDir = "";
#ifdef _WIN32
  std::string dirSep = "\\";
#else
  std::string dirSep = "/";
#endif

  const std::string & GetAppName () {
    return appName;
  }

  void SetAppName (const std::string& name) {
    appName = name;
  }

  const std::string & GetDataDir () {
    return dataDir;
  }

  void DetectDataDir(const std::string & cmdline_param, bool isService) {
    if (cmdline_param != "") {
      dataDir = cmdline_param;
      return;
    }
#if defined(WIN32) || defined(_WIN32)
    char localAppData[MAX_PATH];
    // check executable directory first
    GetModuleFileName (NULL, localAppData, MAX_PATH);
    auto execPath = boost::filesystem::path(localAppData).parent_path();
    // if config file exists in .exe's folder use it
    if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
        dataDir = execPath.string ();
    else
    {
        // otherwise %appdata%
        SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData);
        dataDir = std::string(localAppData) + "\\" + appName;
    }
    return;
#elif defined(MAC_OSX)
    char *home = getenv("HOME");
    dataDir = (home != NULL && strlen(home) > 0) ? home : "";
    dataDir += "/Library/Application Support/" + appName;
    return;
#else /* other unix */
#if defined(ANDROID)
	const char * ext = getenv("EXTERNAL_STORAGE");
	if (!ext) ext = "/sdcard";
	if (boost::filesystem::exists(ext))
	{
		dataDir = std::string (ext) + "/" + appName;
		return;
	}
	// otherwise use /data/files
#endif
    char *home = getenv("HOME");
    if (isService) {
      dataDir = "/var/lib/" + appName;
    } else if (home != NULL && strlen(home) > 0) {
      dataDir = std::string(home) + "/." + appName;
    } else {
      dataDir = "/tmp/" + appName;
    }
    return;
#endif
  }

  bool Init() {
    if (!boost::filesystem::exists(dataDir))
      boost::filesystem::create_directory(dataDir);
    std::string destinations = DataDirPath("destinations");
    if (!boost::filesystem::exists(destinations))
      boost::filesystem::create_directory(destinations);
	std::string tags = DataDirPath("tags");
    if (!boost::filesystem::exists(tags))
	boost::filesystem::create_directory(tags);
	else
		i2p::garlic::CleanUpTagsFiles ();

    return true;
  }

  bool ReadDir(const std::string & path, std::vector<std::string> & files) {
    if (!boost::filesystem::exists(path))
      return false;
    boost::filesystem::directory_iterator it(path);
    boost::filesystem::directory_iterator end;

    for ( ; it != end; it++) {
      if (!boost::filesystem::is_regular_file(it->status()))
        continue;
      files.push_back(it->path().string());
    }

    return true;
  }

  bool Exists(const std::string & path) {
    return boost::filesystem::exists(path);
  }

  uint32_t GetLastUpdateTime (const std::string & path)
  {
	 if (!boost::filesystem::exists(path)) return 0;
	 boost::system::error_code ec;
	 auto t = boost::filesystem::last_write_time (path, ec);
	 return ec ? 0 : t;
  }

  bool Remove(const std::string & path) {
    if (!boost::filesystem::exists(path))
      return false;
    return boost::filesystem::remove(path);
  }

	bool CreateDirectory (const std::string& path)
	{
		if (boost::filesystem::exists(path) &&
			boost::filesystem::is_directory (boost::filesystem::status (path))) return true;
		return boost::filesystem::create_directory(path);
	}

  void HashedStorage::SetPlace(const std::string &path) {
    root = path + i2p::fs::dirSep + name;
  }

  bool HashedStorage::Init(const char * chars, size_t count) {
    if (!boost::filesystem::exists(root)) {
      boost::filesystem::create_directories(root);
    }

    for (size_t i = 0; i < count; i++) {
      auto p = root + i2p::fs::dirSep + prefix1 + chars[i];
      if (boost::filesystem::exists(p))
        continue;
      if (boost::filesystem::create_directory(p))
        continue; /* ^ throws exception on failure */
      return false;
    }
    return true;
  }

  std::string HashedStorage::Path(const std::string & ident) const {
    std::string safe_ident = ident;
    std::replace(safe_ident.begin(), safe_ident.end(), '/',  '-');
    std::replace(safe_ident.begin(), safe_ident.end(), '\\', '-');

    std::stringstream t("");
    t << this->root << i2p::fs::dirSep;
    t << prefix1 << safe_ident[0] << i2p::fs::dirSep;
    t << prefix2 << safe_ident    << "." << suffix;

    return t.str();
  }

  void HashedStorage::Remove(const std::string & ident) {
    std::string path = Path(ident);
    if (!boost::filesystem::exists(path))
      return;
    boost::filesystem::remove(path);
  }

  void HashedStorage::Traverse(std::vector<std::string> & files) {
    Iterate([&files] (const std::string & fname) {
        files.push_back(fname);
    });
  }

  void HashedStorage::Iterate(FilenameVisitor v)
  {
    boost::filesystem::path p(root);
    boost::filesystem::recursive_directory_iterator it(p);
    boost::filesystem::recursive_directory_iterator end;

    for ( ; it != end; it++) {
      if (!boost::filesystem::is_regular_file( it->status() ))
        continue;
      const std::string & t = it->path().string();
      v(t);
    }
  }
} // fs
} // i2p
<commit_msg>[windows] handle unexpected conditions (#1185)<commit_after>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include <algorithm>
#include <boost/filesystem.hpp>

#ifdef _WIN32
#include <shlobj.h>
#include <windows.h>
#endif

#include "Base.h"
#include "FS.h"
#include "Log.h"
#include "Garlic.h"

namespace i2p {
namespace fs {
	std::string appName = "i2pd";
	std::string dataDir = "";
#ifdef _WIN32
	std::string dirSep = "\\";
#else
	std::string dirSep = "/";
#endif

	const std::string & GetAppName () {
		return appName;
	}

	void SetAppName (const std::string& name) {
		appName = name;
	}

	const std::string & GetDataDir () {
		return dataDir;
	}

	void DetectDataDir(const std::string & cmdline_param, bool isService) {
		if (cmdline_param != "") {
			dataDir = cmdline_param;
			return;
		}
#if defined(WIN32) || defined(_WIN32)
		char localAppData[MAX_PATH];

		// check executable directory first
		if(!GetModuleFileName(NULL, localAppData, MAX_PATH))
		{
#if defined(WIN32_APP)
			MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
#else
			fprintf(stderr, "Error: Unable to get application path!");
#endif
			exit(1);
		}
		else
		{
			auto execPath = boost::filesystem::path(localAppData).parent_path();

			// if config file exists in .exe's folder use it
			if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
				dataDir = execPath.string ();
			else // otherwise %appdata%
			{
				if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
				{
#if defined(WIN32_APP)
					MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
#else
					fprintf(stderr, "Error: Unable to get AppData path!");
#endif
					exit(1);
				}
				else
					dataDir = std::string(localAppData) + "\\" + appName;
			}
		}
		return;
#elif defined(MAC_OSX)
		char *home = getenv("HOME");
		dataDir = (home != NULL && strlen(home) > 0) ? home : "";
		dataDir += "/Library/Application Support/" + appName;
		return;
#else /* other unix */
#if defined(ANDROID)
		const char * ext = getenv("EXTERNAL_STORAGE");
		if (!ext) ext = "/sdcard";
		if (boost::filesystem::exists(ext))
		{
			dataDir = std::string (ext) + "/" + appName;
			return;
		}
#endif
		// otherwise use /data/files
		char *home = getenv("HOME");
		if (isService) {
			dataDir = "/var/lib/" + appName;
		} else if (home != NULL && strlen(home) > 0) {
			dataDir = std::string(home) + "/." + appName;
		} else {
			dataDir = "/tmp/" + appName;
		}
		return;
#endif
	}

	bool Init() {
		if (!boost::filesystem::exists(dataDir))
			boost::filesystem::create_directory(dataDir);

		std::string destinations = DataDirPath("destinations");
		if (!boost::filesystem::exists(destinations))
			boost::filesystem::create_directory(destinations);

		std::string tags = DataDirPath("tags");
		if (!boost::filesystem::exists(tags))
			boost::filesystem::create_directory(tags);
		else
			i2p::garlic::CleanUpTagsFiles ();

		return true;
	}

	bool ReadDir(const std::string & path, std::vector<std::string> & files) {
		if (!boost::filesystem::exists(path))
			return false;
		boost::filesystem::directory_iterator it(path);
		boost::filesystem::directory_iterator end;

		for ( ; it != end; it++) {
			if (!boost::filesystem::is_regular_file(it->status()))
				continue;
			files.push_back(it->path().string());
		}

		return true;
	}

	bool Exists(const std::string & path) {
		return boost::filesystem::exists(path);
	}

	uint32_t GetLastUpdateTime (const std::string & path)
	{
		if (!boost::filesystem::exists(path))
			return 0;
		boost::system::error_code ec;
		auto t = boost::filesystem::last_write_time (path, ec);
		return ec ? 0 : t;
	}

	bool Remove(const std::string & path) {
		if (!boost::filesystem::exists(path))
			return false;
		return boost::filesystem::remove(path);
	}

	bool CreateDirectory (const std::string& path)
	{
		if (boost::filesystem::exists(path) && boost::filesystem::is_directory (boost::filesystem::status (path)))
			return true;
		return boost::filesystem::create_directory(path);
	}

	void HashedStorage::SetPlace(const std::string &path) {
		root = path + i2p::fs::dirSep + name;
	}

	bool HashedStorage::Init(const char * chars, size_t count) {
		if (!boost::filesystem::exists(root)) {
			boost::filesystem::create_directories(root);
		}

		for (size_t i = 0; i < count; i++) {
			auto p = root + i2p::fs::dirSep + prefix1 + chars[i];
			if (boost::filesystem::exists(p))
				continue;
			if (boost::filesystem::create_directory(p))
				continue; /* ^ throws exception on failure */
			return false;
		}
		return true;
	}

	std::string HashedStorage::Path(const std::string & ident) const {
		std::string safe_ident = ident;
		std::replace(safe_ident.begin(), safe_ident.end(), '/',	'-');
		std::replace(safe_ident.begin(), safe_ident.end(), '\\', '-');

		std::stringstream t("");
		t << this->root << i2p::fs::dirSep;
		t << prefix1 << safe_ident[0] << i2p::fs::dirSep;
		t << prefix2 << safe_ident    << "." << suffix;

		return t.str();
	}

	void HashedStorage::Remove(const std::string & ident) {
		std::string path = Path(ident);
		if (!boost::filesystem::exists(path))
			return;
		boost::filesystem::remove(path);
	}

	void HashedStorage::Traverse(std::vector<std::string> & files) {
		Iterate([&files] (const std::string & fname) {
			files.push_back(fname);
		});
	}

	void HashedStorage::Iterate(FilenameVisitor v)
	{
		boost::filesystem::path p(root);
		boost::filesystem::recursive_directory_iterator it(p);
		boost::filesystem::recursive_directory_iterator end;

		for ( ; it != end; it++) {
			if (!boost::filesystem::is_regular_file( it->status() ))
				continue;
			const std::string & t = it->path().string();
			v(t);
		}
	}
} // fs
} // i2p
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: undomanager.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 11:30:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SD_UNDOMANAGER_HXX
#include "undo/undomanager.hxx"
#endif

using namespace sd;

UndoManager::UndoManager( USHORT nMaxUndoActionCount /* = 20 */ )
: SfxUndoManager( nMaxUndoActionCount )
, mnListLevel( 0 )
{
}

void UndoManager::EnterListAction(const UniString &rComment, const UniString& rRepeatComment, USHORT nId /* =0 */)
{
    if( !isInUndo() )
    {
        mnListLevel++;
        SfxUndoManager::EnterListAction( rComment, rRepeatComment, nId );
    }
}

void UndoManager::LeaveListAction()
{
    if( !isInUndo() )
    {
        SfxUndoManager::LeaveListAction();
        if( mnListLevel )
        {
            mnListLevel--;
        }
        else
        {
            DBG_ERROR("sd::UndoManager::LeaveListAction(), no open list action!" );
        }
    }
}

void UndoManager::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg /* = FALSE */ )
{
    if( !isInUndo() )
    {
        SfxUndoManager::AddUndoAction( pAction, bTryMerg );
    }
    else
    {
        delete pAction;
    }
}

BOOL UndoManager::Undo( USHORT nCount )
{
    ScopeLockGuard aGuard( maIsInUndoLock );
    return SfxUndoManager::Undo( nCount );
}

BOOL UndoManager::Redo( USHORT nCount )
{
    ScopeLockGuard aGuard( maIsInUndoLock );
    return SfxUndoManager::Redo( nCount );
}

<commit_msg>INTEGRATION: CWS changefileheader (1.4.16); FILE MERGED 2008/04/01 15:33:55 thb 1.4.16.3: #i85898# Stripping all external header guards 2008/04/01 12:38:28 thb 1.4.16.2: #i85898# Stripping all external header guards 2008/03/31 13:56:47 rt 1.4.16.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: undomanager.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include <tools/debug.hxx>
#include "undo/undomanager.hxx"

using namespace sd;

UndoManager::UndoManager( USHORT nMaxUndoActionCount /* = 20 */ )
: SfxUndoManager( nMaxUndoActionCount )
, mnListLevel( 0 )
{
}

void UndoManager::EnterListAction(const UniString &rComment, const UniString& rRepeatComment, USHORT nId /* =0 */)
{
    if( !isInUndo() )
    {
        mnListLevel++;
        SfxUndoManager::EnterListAction( rComment, rRepeatComment, nId );
    }
}

void UndoManager::LeaveListAction()
{
    if( !isInUndo() )
    {
        SfxUndoManager::LeaveListAction();
        if( mnListLevel )
        {
            mnListLevel--;
        }
        else
        {
            DBG_ERROR("sd::UndoManager::LeaveListAction(), no open list action!" );
        }
    }
}

void UndoManager::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg /* = FALSE */ )
{
    if( !isInUndo() )
    {
        SfxUndoManager::AddUndoAction( pAction, bTryMerg );
    }
    else
    {
        delete pAction;
    }
}

BOOL UndoManager::Undo( USHORT nCount )
{
    ScopeLockGuard aGuard( maIsInUndoLock );
    return SfxUndoManager::Undo( nCount );
}

BOOL UndoManager::Redo( USHORT nCount )
{
    ScopeLockGuard aGuard( maIsInUndoLock );
    return SfxUndoManager::Redo( nCount );
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SdUnoSlideView.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-03 11:54:39 $
 *
 *  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: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_UNO_SLIDE_VIEW_HXX
#define SD_UNO_SLIDE_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWVIEW_HPP_
#include <com/sun/star/drawing/XDrawView.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
#endif

#ifndef _SFX_SFXBASECONTROLLER_HXX_
#include <sfx2/sfxbasecontroller.hxx>
#endif

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif

#ifndef _CPPUHELPER_PROPTYPEHLP_HXX
#include <cppuhelper/proptypehlp.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#ifndef _SVX_UNOSHAPE_HXX
#include <svx/unoshape.hxx>
#endif

namespace sd {

class ViewShellBase;
class SlideViewShell;
class View;

/**
 * This class implements the view component for a SdOutlineViewShell
 */
class SdUnoSlideView
    : public DrawController
{
public:
    SdUnoSlideView (
        ViewShellBase& rBase,
        ViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoSlideView() throw();

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw(::com::sun::star::uno::RuntimeException);
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS impress2 (1.5.26); FILE MERGED 2004/06/18 00:18:42 af 1.5.26.2: RESYNC: (1.5-1.6); FILE MERGED 2004/02/19 10:48:44 af 1.5.26.1: #i22705# Added private data members mbDisposing and maLastVisArea.<commit_after>/*************************************************************************
 *
 *  $RCSfile: SdUnoSlideView.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 14:00:27 $
 *
 *  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: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_UNO_SLIDE_VIEW_HXX
#define SD_UNO_SLIDE_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWVIEW_HPP_
#include <com/sun/star/drawing/XDrawView.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
#endif

#ifndef _SFX_SFXBASECONTROLLER_HXX_
#include <sfx2/sfxbasecontroller.hxx>
#endif

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif

#ifndef _CPPUHELPER_PROPTYPEHLP_HXX
#include <cppuhelper/proptypehlp.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#ifndef _SVX_UNOSHAPE_HXX
#include <svx/unoshape.hxx>
#endif

namespace sd {

class ViewShellBase;
class SlideViewShell;
class View;

/**
 * This class implements the view component for a SdOutlineViewShell
 */
class SdUnoSlideView
    : public DrawController
{
public:
    SdUnoSlideView (
        ViewShellBase& rBase,
        ViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoSlideView() throw();

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw(::com::sun::star::uno::RuntimeException);

private:
    sal_Bool            mbDisposing;

    Rectangle           maLastVisArea;
};

} // end of namespace sd

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_NODE_HPP
#define LINGO_NODE_HPP

#include <cassert>
#include <vector>
#include <type_traits>

// This module provides defines a node abstraction for various
// kinds of trees used in different languages and facilities
// for working with those abstractions.

namespace lingo
{

class Token;

// The Kind_of class is a helper class that supports the definition
// of node models. This provides a static representation of the
// node kind and a static `is` function for dynamic type testing.
template<typename T, T K>
struct Kind_base
{
  static constexpr T node_kind = K;

  static bool is(T k) { return node_kind == k; }
};

// -------------------------------------------------------------------------- //
//                        Generic terms

// The Term template provides a facility for making an arbitrary
// type model the requirements of a node. This is useful for
// defining terms that do not fall into other categegories (types,
// expressions, declarations, statments, etc).
//
// The "kind" of the node can be specified by the integer template
// argument N, but it is rarely useful to define it as anything
// other.
template<int N = 0>
struct Term : Kind_base<int, N>
{
  virtual ~Term() { }

  char const* node_name() const { return "<unspecified term>"; }
  int kind() const              { return N; }
};

// -------------------------------------------------------------------------- //
//                            Special values
//
// The following functions define special values of node pointers.

// Returns true if the node is empty.
template<typename T>
inline bool
is_empty_node(T const* t)
{
  return t == nullptr;
}

// Construct a node pointer that acts as an error value.
// The type of the node is explicitly given as a template
// argument.
template<typename T>
inline T*
make_error_node()
{
  return (T*)0x01;
}

// Returns true if `t` is an error node.
template<typename T>
inline bool
is_error_node(T const* t)
{
  return t == make_error_node<T>();
}

// Returns true if `t` is neither null nor an error.
template<typename T>
inline bool
is_valid_node(T const* t)
{
  return t && !is_error_node(t);
}

// -------------------------------------------------------------------------- //
//                        Dynamic type information

// Returns true if the object pointed to by `u` has
// the dynamic type `T`.
template<typename T, typename U>
inline bool
is(U const* u)
{
  return T::is(u->kind());
}

// Statically cast a pointer to a Node of type T to a
// pointer to a Node of type U. This is not a checked
// operation (except in debug mode).
//
// Note that this allows null and error nodes to be
// interpreted as nodes of the given type (as their
// values are considered common to all).
template<typename T, typename U>
inline T*
cast(U* u)
{
  assert(is_valid_node(u) ? is<T>(u) : true);
  return static_cast<T*>(u);
}

template<typename T, typename U>
inline T const*
cast(U const* u)
{
  assert(is_valid_node(u) ? is<T>(u) : true);
  return static_cast<T const*>(u);
}

// Returns `u` with type `T*` iff the object pointed
// to by `u` has dynamic type `T`.
template<typename T, typename U>
inline T*
as(U* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

template<typename T, typename U>
inline T const*
as(U const* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

// -------------------------------------------------------------------------- //
//                              Concepts
//
// There are several concepts describing the kinds of nodes over
// which an algorithm can operate generically. The primary
// characterization // of node types is based on their arity.
//
// ## The Node concept
//
// Every node in an abstract syntax tree must provide a static
// constexpr member, node_kind that statically defines the kind
// of node.
//
// ## Node arity
//
// Nodes with fixed arity have tuple-like member names (e.g.,
// first, second, third). These accessor members correspond to
// the sub-terms of each node. Accessor members may have different
// tpyes, and are not required to be nodes.
//
// A nullary node is a Node is an empty tuple, and has no
// accessor members. A unary node has only accessor member
// `first`. A binary node has only `first` and `second`.
// A ternary node has `first`, second`, and `third`.
//
// Note that more arity nodes can be defined if needed.
//
// A k-ary has k sub-terms, and that range of terms is accessed
// by its `begin()` and `end()` members. The types of these
// sub-terms are the same.

namespace traits
{

// A helper trait used to detect substitution failures.
template<typename T>
struct is_non_void
{
  static constexpr bool value = true;
};

template<>
struct is_non_void<void>
{
  static constexpr bool value = false;
};

// Detect the existince of the member T::node_kind.
template<typename T>
struct node_kind_type
{
  template<typename U> static auto f(U* p) -> decltype(U::node_kind);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existince of the member t->first.
template<typename T>
struct first_type
{
  template<typename U> static auto f(U* p) -> decltype(p->first);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->second;
template<typename T>
struct second_type
{
  template<typename U> static auto f(U* p) -> decltype(p->second);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->third;
template<typename T>
struct third_type
{
  template<typename U> static auto f(U* p) -> decltype(p->third);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->begin().
template<typename T>
struct begin_type
{
  template<typename U> static auto f(U* p) -> decltype(p->begin());
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->end().
template<typename T>
struct end_type
{
  template<typename U> static auto f(U* p) -> decltype(p->end());
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Returns true when `T` has the static member object `node_kind`.
template<typename T>
constexpr bool
has_node_kind()
{
  return is_non_void<typename node_kind_type<T>::type>::value;
}

// Returns true when `T` has the member `first`.
template<typename T>
constexpr bool
has_first()
{
  return is_non_void<typename first_type<T>::type>::value;
}

// Returns true when `T` has the member `second`.
template<typename T>
constexpr bool
has_second()
{
  return is_non_void<typename second_type<T>::type>::value;
}

// Returns true when `T` has the member `third`.
template<typename T>
constexpr bool
has_third()
{
  return is_non_void<typename third_type<T>::type>::value;
}

// Returns true when `T` has the member `begin`.
template<typename T>
constexpr bool
has_begin()
{
  return is_non_void<typename begin_type<T>::type>::value;
}

// Returns true when `T` has the member `end`.
template<typename T>
constexpr bool
has_end()
{
  return is_non_void<typename end_type<T>::type>::value;
}

} // namesapce traits

// Returns true if T models the Node concept.
template<typename T>
constexpr bool
is_node()
{
  return traits::has_node_kind<T>();
}

// Returns true if T is a Nullary_node.
template<typename T>
constexpr bool
is_nullary_node()
{
  return is_node<T>()
      && !traits::has_first<T>()  // Not a unary node
      && !traits::has_begin<T>(); // Not a k-ary node
}

// Returns true if T is a unary node.
template<typename T>
constexpr bool
is_unary_node()
{
  return is_node<T>()
      && traits::has_first<T>()
      && !traits::has_second<T>();
}

// Returns true if T is a binary node.
template<typename T>
constexpr bool
is_binary_node()
{
  return is_node<T>()
      && traits::has_second<T>()
      && !traits::has_third<T>();
}

// Returns true if T is a ternary node.
template<typename T>
constexpr bool
is_ternary_node()
{
  return is_node<T>()
      && traits::has_first<T>()
      && traits::has_second<T>()
      && traits::has_third<T>();
}

// Returns true if T is a k-ary node.
template<typename T>
constexpr bool
is_kary_node()
{
  return is_node<T>() && traits::has_begin<T>() && traits::has_end<T>();
}

// -------------------------------------------------------------------------- //
//                        Reqiured term

// The Maybe template is typically used to declare node
// pointers within condition declarations.
//
//    if (Required<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// it is initialized to a non-null, non-error value.
template<typename T>
struct Required
{
  Required(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is valid.
  explicit operator bool() const { return is_valid_node(ptr); }

  // Returns the underlying term, even if it is an error or
  // empty term.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

// -------------------------------------------------------------------------- //
//                        Optional results

// The Optional template is typically used to declare node
// pointers within condition declarations.
//
//    if (Optional<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// it is a non-error value. Note that the term may be empty.
template<typename T>
struct Optional
{
  Optional(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is valid or empty.
  explicit operator bool() const { return !is_error_node(ptr); }

  // Returns the underlying term, even if it is an error.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

// -------------------------------------------------------------------------- //
//                        Nonempty results

// The Nonempty template is typically used to declare node
// pointers within condition declarations.
//
//    if (Nonempty<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// is non-empty. Note that error conditions are treated as
// valid results.
template<typename T>
struct Nonempty
{
  Nonempty(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is non-empty.
  explicit operator bool() const { return !is_empty_node(ptr); }

  // Returns the underlying term, even if it is a empty.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

} // namespace lingo

#endif
<commit_msg>Add a cast to non-const function.<commit_after>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_NODE_HPP
#define LINGO_NODE_HPP

#include <cassert>
#include <vector>
#include <type_traits>

// This module provides defines a node abstraction for various
// kinds of trees used in different languages and facilities
// for working with those abstractions.

namespace lingo
{

class Token;

// The Kind_of class is a helper class that supports the definition
// of node models. This provides a static representation of the
// node kind and a static `is` function for dynamic type testing.
template<typename T, T K>
struct Kind_base
{
  static constexpr T node_kind = K;

  static bool is(T k) { return node_kind == k; }
};

// -------------------------------------------------------------------------- //
//                        Generic terms

// The Term template provides a facility for making an arbitrary
// type model the requirements of a node. This is useful for
// defining terms that do not fall into other categegories (types,
// expressions, declarations, statments, etc).
//
// The "kind" of the node can be specified by the integer template
// argument N, but it is rarely useful to define it as anything
// other.
template<int N = 0>
struct Term : Kind_base<int, N>
{
  virtual ~Term() { }

  char const* node_name() const { return "<unspecified term>"; }
  int kind() const              { return N; }
};

// -------------------------------------------------------------------------- //
//                            Special values
//
// The following functions define special values of node pointers.

// Returns true if the node is empty.
template<typename T>
inline bool
is_empty_node(T const* t)
{
  return t == nullptr;
}

// Construct a node pointer that acts as an error value.
// The type of the node is explicitly given as a template
// argument.
template<typename T>
inline T*
make_error_node()
{
  return (T*)0x01;
}

// Returns true if `t` is an error node.
template<typename T>
inline bool
is_error_node(T const* t)
{
  return t == make_error_node<T>();
}

// Returns true if `t` is neither null nor an error.
template<typename T>
inline bool
is_valid_node(T const* t)
{
  return t && !is_error_node(t);
}

// -------------------------------------------------------------------------- //
//                        Dynamic type information

// Returns true if the object pointed to by `u` has
// the dynamic type `T`.
template<typename T, typename U>
inline bool
is(U const* u)
{
  return T::is(u->kind());
}

// Statically cast a pointer to a Node of type T to a
// pointer to a Node of type U. This is not a checked
// operation (except in debug mode).
//
// Note that this allows null and error nodes to be
// interpreted as nodes of the given type (as their
// values are considered common to all).
template<typename T, typename U>
inline T*
cast(U* u)
{
  assert(is_valid_node(u) ? is<T>(u) : true);
  return static_cast<T*>(u);
}

template<typename T, typename U>
inline T const*
cast(U const* u)
{
  assert(is_valid_node(u) ? is<T>(u) : true);
  return static_cast<T const*>(u);
}

// Returns `u` with type `T*` iff the object pointed
// to by `u` has dynamic type `T`.
template<typename T, typename U>
inline T*
as(U* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

template<typename T, typename U>
inline T const*
as(U const* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

// Return a non-const pointer to the term. This is used
// to modify a term post-initializatoin (which should
// be rare).
template<typename T>
inline T*
modify(T const* t)
{
  return const_cast<T*>(t);
}

// -------------------------------------------------------------------------- //
//                              Concepts
//
// There are several concepts describing the kinds of nodes over
// which an algorithm can operate generically. The primary
// characterization // of node types is based on their arity.
//
// ## The Node concept
//
// Every node in an abstract syntax tree must provide a static
// constexpr member, node_kind that statically defines the kind
// of node.
//
// ## Node arity
//
// Nodes with fixed arity have tuple-like member names (e.g.,
// first, second, third). These accessor members correspond to
// the sub-terms of each node. Accessor members may have different
// tpyes, and are not required to be nodes.
//
// A nullary node is a Node is an empty tuple, and has no
// accessor members. A unary node has only accessor member
// `first`. A binary node has only `first` and `second`.
// A ternary node has `first`, second`, and `third`.
//
// Note that more arity nodes can be defined if needed.
//
// A k-ary has k sub-terms, and that range of terms is accessed
// by its `begin()` and `end()` members. The types of these
// sub-terms are the same.

namespace traits
{

// A helper trait used to detect substitution failures.
template<typename T>
struct is_non_void
{
  static constexpr bool value = true;
};

template<>
struct is_non_void<void>
{
  static constexpr bool value = false;
};

// Detect the existince of the member T::node_kind.
template<typename T>
struct node_kind_type
{
  template<typename U> static auto f(U* p) -> decltype(U::node_kind);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existince of the member t->first.
template<typename T>
struct first_type
{
  template<typename U> static auto f(U* p) -> decltype(p->first);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->second;
template<typename T>
struct second_type
{
  template<typename U> static auto f(U* p) -> decltype(p->second);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->third;
template<typename T>
struct third_type
{
  template<typename U> static auto f(U* p) -> decltype(p->third);
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->begin().
template<typename T>
struct begin_type
{
  template<typename U> static auto f(U* p) -> decltype(p->begin());
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Detect the existence of the member t->end().
template<typename T>
struct end_type
{
  template<typename U> static auto f(U* p) -> decltype(p->end());
  static                      void f(...);

  using type = decltype(f(std::declval<T*>()));
};

// Returns true when `T` has the static member object `node_kind`.
template<typename T>
constexpr bool
has_node_kind()
{
  return is_non_void<typename node_kind_type<T>::type>::value;
}

// Returns true when `T` has the member `first`.
template<typename T>
constexpr bool
has_first()
{
  return is_non_void<typename first_type<T>::type>::value;
}

// Returns true when `T` has the member `second`.
template<typename T>
constexpr bool
has_second()
{
  return is_non_void<typename second_type<T>::type>::value;
}

// Returns true when `T` has the member `third`.
template<typename T>
constexpr bool
has_third()
{
  return is_non_void<typename third_type<T>::type>::value;
}

// Returns true when `T` has the member `begin`.
template<typename T>
constexpr bool
has_begin()
{
  return is_non_void<typename begin_type<T>::type>::value;
}

// Returns true when `T` has the member `end`.
template<typename T>
constexpr bool
has_end()
{
  return is_non_void<typename end_type<T>::type>::value;
}

} // namesapce traits

// Returns true if T models the Node concept.
template<typename T>
constexpr bool
is_node()
{
  return traits::has_node_kind<T>();
}

// Returns true if T is a Nullary_node.
template<typename T>
constexpr bool
is_nullary_node()
{
  return is_node<T>()
      && !traits::has_first<T>()  // Not a unary node
      && !traits::has_begin<T>(); // Not a k-ary node
}

// Returns true if T is a unary node.
template<typename T>
constexpr bool
is_unary_node()
{
  return is_node<T>()
      && traits::has_first<T>()
      && !traits::has_second<T>();
}

// Returns true if T is a binary node.
template<typename T>
constexpr bool
is_binary_node()
{
  return is_node<T>()
      && traits::has_second<T>()
      && !traits::has_third<T>();
}

// Returns true if T is a ternary node.
template<typename T>
constexpr bool
is_ternary_node()
{
  return is_node<T>()
      && traits::has_first<T>()
      && traits::has_second<T>()
      && traits::has_third<T>();
}

// Returns true if T is a k-ary node.
template<typename T>
constexpr bool
is_kary_node()
{
  return is_node<T>() && traits::has_begin<T>() && traits::has_end<T>();
}

// -------------------------------------------------------------------------- //
//                        Reqiured term

// The Maybe template is typically used to declare node
// pointers within condition declarations.
//
//    if (Required<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// it is initialized to a non-null, non-error value.
template<typename T>
struct Required
{
  Required(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is valid.
  explicit operator bool() const { return is_valid_node(ptr); }

  // Returns the underlying term, even if it is an error or
  // empty term.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

// -------------------------------------------------------------------------- //
//                        Optional results

// The Optional template is typically used to declare node
// pointers within condition declarations.
//
//    if (Optional<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// it is a non-error value. Note that the term may be empty.
template<typename T>
struct Optional
{
  Optional(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is valid or empty.
  explicit operator bool() const { return !is_error_node(ptr); }

  // Returns the underlying term, even if it is an error.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

// -------------------------------------------------------------------------- //
//                        Nonempty results

// The Nonempty template is typically used to declare node
// pointers within condition declarations.
//
//    if (Nonempty<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// is non-empty. Note that error conditions are treated as
// valid results.
template<typename T>
struct Nonempty
{
  Nonempty(T const* p)
    : ptr(p)
  { }

  // Returns true iff the term is non-empty.
  explicit operator bool() const { return !is_empty_node(ptr); }

  // Returns the underlying term, even if it is a empty.
  T const* operator*() const { return ptr; }
  T const* operator->() const { return ptr; }

  bool is_error() const { return is_error_node(ptr); }
  bool is_empty() const { return is_empty_node(ptr); }

  T const* ptr;
};

} // namespace lingo

#endif
<|endoftext|>


<commit_before>// This file is part of the AliceVision project.
// Copyright (c) 2016 AliceVision contributors.
// Copyright (c) 2012 openMVG contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "aliceVision/numeric/numeric.hpp"
#include <aliceVision/config.hpp>

#include <aliceVision/multiview/projection.hpp>
#include "aliceVision/multiview/conditioning.hpp"
#include "aliceVision/multiview/triangulation/Triangulation.hpp"

// Linear programming solver(s)
#include "aliceVision/linearProgramming/ISolver.hpp"
#include "aliceVision/linearProgramming/OSIXSolver.hpp"
#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
#include "aliceVision/linearProgramming/MOSEKSolver.hpp"
#endif

#include "aliceVision/linearProgramming/bisectionLP.hpp"
#include "aliceVision/linearProgramming/lInfinityCV/tijsAndXis_From_xi_Ri.hpp"

namespace aliceVision {
namespace trifocal {
namespace kernel {

/// A trifocal tensor seen as 3 projective cameras
struct TrifocalTensorModel {
  Mat34 P1, P2, P3;

  static double Error(const TrifocalTensorModel & t, const Vec2 & pt1, const Vec2 & pt2, const Vec2 & pt3)
  {
    // Triangulate
    Triangulation triangulationObj;
    triangulationObj.add(t.P1, pt1);
    triangulationObj.add(t.P2, pt2);
    triangulationObj.add(t.P3, pt3);
    const Vec3 X = triangulationObj.compute();

    // Return the maximum observed reprojection error
    const double pt1ReProj = (Project(t.P1, X) - pt1).squaredNorm();
    const double pt2ReProj = (Project(t.P2, X) - pt2).squaredNorm();
    const double pt3ReProj = (Project(t.P3, X) - pt3).squaredNorm();

    return std::max(pt1ReProj, std::max(pt2ReProj,pt3ReProj));
  }
};

}  // namespace kernel
}  // namespace trifocal
}  // namespace aliceVision

namespace aliceVision{

using namespace aliceVision::trifocal::kernel;

/// Solve the translations and the structure of a view-triplet that have known rotations
struct translations_Triplet_Solver {
  enum { MINIMUM_SAMPLES = 4 };
  enum { MAX_MODELS = 1 };

  /// Solve the computation of the "tensor".
  static void Solve(
    const Mat &pt0, const Mat & pt1, const Mat & pt2,
    const std::vector<Mat3> & vec_KR, std::vector<TrifocalTensorModel> *P,
    const double ThresholdUpperBound)
  {
    //Build the megaMatMatrix
    const int n_obs = pt0.cols();
    Mat4X megaMat(4, n_obs*3);
    {
      size_t cpt = 0;
      for (size_t i = 0; i  < n_obs; ++i)
      {
        megaMat.col(cpt++) << pt0.col(i)(0), pt0.col(i)(1), (double)i, 0.0;
        megaMat.col(cpt++) << pt1.col(i)(0), pt1.col(i)(1), (double)i, 1.0;
        megaMat.col(cpt++) << pt2.col(i)(0), pt2.col(i)(1), (double)i, 2.0;
      }
    }
    //-- Solve the LInfinity translation and structure from Rotation and points data.
    std::vector<double> vec_solution((3 + MINIMUM_SAMPLES)*3);

    using namespace aliceVision::lInfinityCV;

#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
    MOSEKSolver LPsolver(static_cast<int>(vec_solution.size()));
#else
    OSI_CISolverWrapper LPsolver(static_cast<int>(vec_solution.size()));
#endif

    Translation_Structure_L1_ConstraintBuilder cstBuilder(vec_KR, megaMat);
    double gamma;
    if (BisectionLP<Translation_Structure_L1_ConstraintBuilder, LPConstraintsSparse>(
      LPsolver,
      cstBuilder,
      &vec_solution,
      ThresholdUpperBound,
      0.0, 1e-8, 2, &gamma, false))
    {
      const std::vector<Vec3> vec_tis = {
        Vec3(vec_solution[0], vec_solution[1], vec_solution[2]),
        Vec3(vec_solution[3], vec_solution[4], vec_solution[5]),
        Vec3(vec_solution[6], vec_solution[7], vec_solution[8])};

      TrifocalTensorModel PTemp;
      PTemp.P1 = HStack(vec_KR[0], vec_tis[0]);
      PTemp.P2 = HStack(vec_KR[1], vec_tis[1]);
      PTemp.P3 = HStack(vec_KR[2], vec_tis[2]);

      P->push_back(PTemp);
    }
  }

  // Compute the residual of reprojections
  static double Error(
    const TrifocalTensorModel & Tensor,
    const Vec2 & pt0, const Vec2 & pt1, const Vec2 & pt2)
  {
    return TrifocalTensorModel::Error(Tensor, pt0, pt1, pt2);
  }
};

} // namespace aliceVision

<commit_msg>Fix: change angle brackets <> to double quotes ""<commit_after>// This file is part of the AliceVision project.
// Copyright (c) 2016 AliceVision contributors.
// Copyright (c) 2012 openMVG contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "aliceVision/numeric/numeric.hpp"
#include "aliceVision/config.hpp"

#include "aliceVision/multiview/projection.hpp"
#include "aliceVision/multiview/conditioning.hpp"
#include "aliceVision/multiview/triangulation/Triangulation.hpp"

// Linear programming solver(s)
#include "aliceVision/linearProgramming/ISolver.hpp"
#include "aliceVision/linearProgramming/OSIXSolver.hpp"
#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
#include "aliceVision/linearProgramming/MOSEKSolver.hpp"
#endif

#include "aliceVision/linearProgramming/bisectionLP.hpp"
#include "aliceVision/linearProgramming/lInfinityCV/tijsAndXis_From_xi_Ri.hpp"

namespace aliceVision {
namespace trifocal {
namespace kernel {

/// A trifocal tensor seen as 3 projective cameras
struct TrifocalTensorModel {
  Mat34 P1, P2, P3;

  static double Error(const TrifocalTensorModel & t, const Vec2 & pt1, const Vec2 & pt2, const Vec2 & pt3)
  {
    // Triangulate
    Triangulation triangulationObj;
    triangulationObj.add(t.P1, pt1);
    triangulationObj.add(t.P2, pt2);
    triangulationObj.add(t.P3, pt3);
    const Vec3 X = triangulationObj.compute();

    // Return the maximum observed reprojection error
    const double pt1ReProj = (Project(t.P1, X) - pt1).squaredNorm();
    const double pt2ReProj = (Project(t.P2, X) - pt2).squaredNorm();
    const double pt3ReProj = (Project(t.P3, X) - pt3).squaredNorm();

    return std::max(pt1ReProj, std::max(pt2ReProj,pt3ReProj));
  }
};

}  // namespace kernel
}  // namespace trifocal
}  // namespace aliceVision

namespace aliceVision{

using namespace aliceVision::trifocal::kernel;

/// Solve the translations and the structure of a view-triplet that have known rotations
struct translations_Triplet_Solver {
  enum { MINIMUM_SAMPLES = 4 };
  enum { MAX_MODELS = 1 };

  /// Solve the computation of the "tensor".
  static void Solve(
    const Mat &pt0, const Mat & pt1, const Mat & pt2,
    const std::vector<Mat3> & vec_KR, std::vector<TrifocalTensorModel> *P,
    const double ThresholdUpperBound)
  {
    //Build the megaMatMatrix
    const int n_obs = pt0.cols();
    Mat4X megaMat(4, n_obs*3);
    {
      size_t cpt = 0;
      for (size_t i = 0; i  < n_obs; ++i)
      {
        megaMat.col(cpt++) << pt0.col(i)(0), pt0.col(i)(1), (double)i, 0.0;
        megaMat.col(cpt++) << pt1.col(i)(0), pt1.col(i)(1), (double)i, 1.0;
        megaMat.col(cpt++) << pt2.col(i)(0), pt2.col(i)(1), (double)i, 2.0;
      }
    }
    //-- Solve the LInfinity translation and structure from Rotation and points data.
    std::vector<double> vec_solution((3 + MINIMUM_SAMPLES)*3);

    using namespace aliceVision::lInfinityCV;

#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
    MOSEKSolver LPsolver(static_cast<int>(vec_solution.size()));
#else
    OSI_CISolverWrapper LPsolver(static_cast<int>(vec_solution.size()));
#endif

    Translation_Structure_L1_ConstraintBuilder cstBuilder(vec_KR, megaMat);
    double gamma;
    if (BisectionLP<Translation_Structure_L1_ConstraintBuilder, LPConstraintsSparse>(
      LPsolver,
      cstBuilder,
      &vec_solution,
      ThresholdUpperBound,
      0.0, 1e-8, 2, &gamma, false))
    {
      const std::vector<Vec3> vec_tis = {
        Vec3(vec_solution[0], vec_solution[1], vec_solution[2]),
        Vec3(vec_solution[3], vec_solution[4], vec_solution[5]),
        Vec3(vec_solution[6], vec_solution[7], vec_solution[8])};

      TrifocalTensorModel PTemp;
      PTemp.P1 = HStack(vec_KR[0], vec_tis[0]);
      PTemp.P2 = HStack(vec_KR[1], vec_tis[1]);
      PTemp.P3 = HStack(vec_KR[2], vec_tis[2]);

      P->push_back(PTemp);
    }
  }

  // Compute the residual of reprojections
  static double Error(
    const TrifocalTensorModel & Tensor,
    const Vec2 & pt0, const Vec2 & pt1, const Vec2 & pt2)
  {
    return TrifocalTensorModel::Error(Tensor, pt0, pt1, pt2);
  }
};

} // namespace aliceVision

<|endoftext|>


<commit_before>#include "StepEdgeModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Algorithms/ModelBasedSegmentation/Shape.hpp"

namespace fast {

StepEdgeModel::StepEdgeModel() {
	mLineLength = 0;
	mLineSampleSpacing = 0;
}

typedef struct DetectedEdge {
    int edgeIndex;
    float uncertainty;
} DetectedEdge;

inline DetectedEdge findEdge(
        std::vector<float> intensityProfile) {
    // Pre calculate partial sum
    float * sum_k = new float[intensityProfile.size()]();
    float totalSum = 0.0f;
    for(int k = 0; k < intensityProfile.size(); ++k) {
        if(k == 0) {
            sum_k[k] = intensityProfile[0];
        }else{
            sum_k[k] = sum_k[k-1] + intensityProfile[k];
        }
        totalSum += intensityProfile[k];
    }

    float bestScore = std::numeric_limits<float>::max();
    int bestK = -1;
    float bestHeightDifference = 0;
    for(int k = 0; k < intensityProfile.size()-1; ++k) {
        float score = 0.0f;
        if(intensityProfile[k] < 20)
            continue;
        for(int t = 0; t <= k; ++t) {
            score += fabs((1.0f/(k+1))*sum_k[k] - intensityProfile[t]);
        }
        for(int t = k+1; t < intensityProfile.size(); ++t) {
            score += fabs((1.0f/(intensityProfile.size()-k))*(totalSum-sum_k[k]) - intensityProfile[t]);
        }
        if(score < bestScore) {
            bestScore = score;
            bestK = k;
            bestHeightDifference = (((1.0/(k+1))*sum_k[bestK] - (1.0f/(intensityProfile.size()-k))*(totalSum-sum_k[bestK])));
        }
    }
    delete[] sum_k;

    DetectedEdge edge;

    // Should be dark inside and bright outside

    if(bestHeightDifference > 0) {
        bestK = -1;

    }

    edge.edgeIndex = bestK;
    edge.uncertainty = 1.0f / fabs(bestHeightDifference);

    return edge;
}

inline bool isInBounds(Image::pointer image, const Vector4f& position) {
    return position(0) >= 0 && position(1) >= 0 && position(2) >= 0 &&
        position(0) < image->getWidth() && position(1) < image->getHeight() && position(2) < image->getDepth();
}

inline float getValue(void* pixelPointer, Image::pointer image, const Vector4f& position) {

    uint index = (int)position(0)+(int)position(1)*image->getWidth()+(int)position(2)*image->getWidth()*image->getHeight();
    float value;
    switch(image->getDataType()) {
        // This macro creates a case statement for each data type and sets FAST_TYPE to the correct C++ data type
        fastSwitchTypeMacro(value = ((FAST_TYPE*)pixelPointer)[index]);
    }
    return value;
}

std::vector<Measurement> StepEdgeModel::getMeasurements(SharedPointer<Image> image, SharedPointer<Shape> shape) {
	if(mLineLength == 0 || mLineSampleSpacing == 0)
		throw Exception("Line length and sample spacing must be given to the StepEdgeModel");

	std::vector<Measurement> measurements;
	Mesh::pointer predictedMesh = shape->getMesh();
	MeshAccess::pointer predictedMeshAccess = predictedMesh->getMeshAccess(ACCESS_READ);
	std::vector<MeshVertex> points = predictedMeshAccess->getVertices();

	ImageAccess::pointer access = image->getImageAccess(ACCESS_READ);

	// For each point on the shape do a line search in the direction of the normal
	// Return set of displacements and uncertainties
	if(image->getDimensions() == 3) {
		AffineTransformation::pointer transformMatrix = SceneGraph::getAffineTransformationFromData(image);
		transformMatrix->scale(image->getSpacing());
		Matrix4f inverseTransformMatrix = transformMatrix->matrix().inverse();

		// Get model scene graph transform
		AffineTransformation::pointer modelTransformation = SceneGraph::getAffineTransformationFromData(shape->getMesh());
		MatrixXf modelTransformMatrix = modelTransformation->affine();

		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
				// Apply model transform
				// TODO the line search normal*d should propably be applied after this transform, so that we know that is correct units?
				position = modelTransformMatrix*position.homogeneous();
				const Vector4f longPosition(position(0), position(1), position(2), 1);
				// Apply image inverse transform to get image voxel position
				const Vector4f positionInt = inverseTransformMatrix*longPosition;
				try {
					const float value = access->getScalar(positionInt.cast<int>());
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector3f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	} else {
		Vector3f spacing = image->getSpacing();
		// For 2D images
		// For 2D, we probably want to ignore scene graph, and only use spacing.
		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
				const Vector2i pixelPosition(round(position.x() / spacing.x()), round(position.y()) / spacing.y());
				try {
					const float value = access->getScalar(pixelPosition);
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector2f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	}

	return measurements;
}

void StepEdgeModel::setLineLength(float length) {
	if(length <= 0)
		throw Exception("Length must be > 0");
	mLineLength = length;
}

void StepEdgeModel::setLineSampleSpacing(float spacing) {
	if(spacing <= 0)
		throw Exception("Sample spacing must be > 0");
	mLineSampleSpacing = spacing;
}

}
<commit_msg>fixed a bug in 2D step edge model<commit_after>#include "StepEdgeModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Algorithms/ModelBasedSegmentation/Shape.hpp"

namespace fast {

StepEdgeModel::StepEdgeModel() {
	mLineLength = 0;
	mLineSampleSpacing = 0;
}

typedef struct DetectedEdge {
    int edgeIndex;
    float uncertainty;
} DetectedEdge;

inline DetectedEdge findEdge(
        std::vector<float> intensityProfile) {
    // Pre calculate partial sum
    float * sum_k = new float[intensityProfile.size()]();
    float totalSum = 0.0f;
    for(int k = 0; k < intensityProfile.size(); ++k) {
        if(k == 0) {
            sum_k[k] = intensityProfile[0];
        }else{
            sum_k[k] = sum_k[k-1] + intensityProfile[k];
        }
        totalSum += intensityProfile[k];
    }

    float bestScore = std::numeric_limits<float>::max();
    int bestK = -1;
    float bestHeightDifference = 0;
    for(int k = 0; k < intensityProfile.size()-1; ++k) {
        float score = 0.0f;
        if(intensityProfile[k] < 20)
            continue;
        for(int t = 0; t <= k; ++t) {
            score += fabs((1.0f/(k+1))*sum_k[k] - intensityProfile[t]);
        }
        for(int t = k+1; t < intensityProfile.size(); ++t) {
            score += fabs((1.0f/(intensityProfile.size()-k))*(totalSum-sum_k[k]) - intensityProfile[t]);
        }
        if(score < bestScore) {
            bestScore = score;
            bestK = k;
            bestHeightDifference = (((1.0/(k+1))*sum_k[bestK] - (1.0f/(intensityProfile.size()-k))*(totalSum-sum_k[bestK])));
        }
    }
    delete[] sum_k;

    DetectedEdge edge;

    // Should be dark inside and bright outside

    if(bestHeightDifference > 0) {
        bestK = -1;

    }

    edge.edgeIndex = bestK;
    edge.uncertainty = 1.0f / fabs(bestHeightDifference);

    return edge;
}

inline bool isInBounds(Image::pointer image, const Vector4f& position) {
    return position(0) >= 0 && position(1) >= 0 && position(2) >= 0 &&
        position(0) < image->getWidth() && position(1) < image->getHeight() && position(2) < image->getDepth();
}

inline float getValue(void* pixelPointer, Image::pointer image, const Vector4f& position) {

    uint index = (int)position(0)+(int)position(1)*image->getWidth()+(int)position(2)*image->getWidth()*image->getHeight();
    float value;
    switch(image->getDataType()) {
        // This macro creates a case statement for each data type and sets FAST_TYPE to the correct C++ data type
        fastSwitchTypeMacro(value = ((FAST_TYPE*)pixelPointer)[index]);
    }
    return value;
}

std::vector<Measurement> StepEdgeModel::getMeasurements(SharedPointer<Image> image, SharedPointer<Shape> shape) {
	if(mLineLength == 0 || mLineSampleSpacing == 0)
		throw Exception("Line length and sample spacing must be given to the StepEdgeModel");

	std::vector<Measurement> measurements;
	Mesh::pointer predictedMesh = shape->getMesh();
	MeshAccess::pointer predictedMeshAccess = predictedMesh->getMeshAccess(ACCESS_READ);
	std::vector<MeshVertex> points = predictedMeshAccess->getVertices();

	ImageAccess::pointer access = image->getImageAccess(ACCESS_READ);

	// For each point on the shape do a line search in the direction of the normal
	// Return set of displacements and uncertainties
	if(image->getDimensions() == 3) {
		AffineTransformation::pointer transformMatrix = SceneGraph::getAffineTransformationFromData(image);
		transformMatrix->scale(image->getSpacing());
		Matrix4f inverseTransformMatrix = transformMatrix->matrix().inverse();

		// Get model scene graph transform
		AffineTransformation::pointer modelTransformation = SceneGraph::getAffineTransformationFromData(shape->getMesh());
		MatrixXf modelTransformMatrix = modelTransformation->affine();

		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
				// Apply model transform
				// TODO the line search normal*d should propably be applied after this transform, so that we know that is correct units?
				position = modelTransformMatrix*position.homogeneous();
				const Vector4f longPosition(position(0), position(1), position(2), 1);
				// Apply image inverse transform to get image voxel position
				const Vector4f positionInt = inverseTransformMatrix*longPosition;
				try {
					const float value = access->getScalar(positionInt.cast<int>());
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector3f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	} else {
		Vector3f spacing = image->getSpacing();
		// For 2D images
		// For 2D, we probably want to ignore scene graph, and only use spacing.
		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
				const Vector2i pixelPosition(round(position.x() / spacing.x()), round(position.y() / spacing.y()));
				try {
					const float value = access->getScalar(pixelPosition);
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector2f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	}

	return measurements;
}

void StepEdgeModel::setLineLength(float length) {
	if(length <= 0)
		throw Exception("Length must be > 0");
	mLineLength = length;
}

void StepEdgeModel::setLineSampleSpacing(float spacing) {
	if(spacing <= 0)
		throw Exception("Sample spacing must be > 0");
	mLineSampleSpacing = spacing;
}

}
<|endoftext|>