<commit_before>/**
 * @file llmarketplacefunctions.cpp
 * @brief Implementation of assorted functions related to the marketplace
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llmarketplacefunctions.h"

#include "llagent.h"
#include "llhttpclient.h"
#include "lltimer.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewernetwork.h"

//
// Helpers
//

static std::string getMarketplaceDomain()
{
	std::string domain = "secondlife.com";

//	if (!LLGridManager::getInstance()->isInProductionGrid()) <FS:ND> For OpenSim
	if (!LLGridManager::getInstance()->isInSLMain())
	{
		const std::string& grid_label = LLGridManager::getInstance()->getGridLabel();
		const std::string& grid_label_lower = utf8str_tolower(grid_label);

		if (grid_label_lower == "damballah")
		{
			domain = "secondlife-staging.com";
		}
		else
		{
			domain = llformat("%s.lindenlab.com", grid_label_lower.c_str());
		}
	}

	return domain;
}

static std::string getMarketplaceURL(const std::string& urlStringName)
{
	LLStringUtil::format_map_t domain_arg;
	domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain();

	std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg);

	return marketplace_url;
}

LLSD getMarketplaceStringSubstitutions()
{
	std::string marketplace_url = getMarketplaceURL("MarketplaceURL");
	std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore");
	std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard");
	std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports");
	std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore");

	LLSD marketplace_sub_map;

	marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url;
	marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create;
	marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info;
	marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard;
	marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports;

	return marketplace_sub_map;
}

namespace LLMarketplaceImport
{
	// Basic interface for this namespace

	bool hasSessionCookie();
	bool inProgress();
	bool resultPending();
	U32 getResultStatus();
	const LLSD& getResults();

	bool establishMarketplaceSessionCookie();
	bool pollStatus();
	bool triggerImport();

	// Internal state variables

	static std::string sMarketplaceCookie = "";
	static LLSD sImportId = LLSD::emptyMap();
	static bool sImportInProgress = false;
	static bool sImportPostPending = false;
	static bool sImportGetPending = false;
	static U32 sImportResultStatus = 0;
	static LLSD sImportResults = LLSD::emptyMap();

	static LLTimer slmGetTimer;
	static LLTimer slmPostTimer;

	// Responders

	class LLImportPostResponder : public LLHTTPClient::Responder
	{
	public:
		LLImportPostResponder() : LLCurl::Responder() {}

		void completed(U32 status, const std::string& reason, const LLSD& content)
		{
			slmPostTimer.stop();

			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
			{
				llinfos << " SLM POST status: " << status << llendl;
				llinfos << " SLM POST reason: " << reason << llendl;
				llinfos << " SLM POST content: " << content.asString() << llendl;

				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
			}

			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
			{
				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
				{
					llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
				}

				sMarketplaceCookie.clear();
			}

			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE);
			sImportPostPending = false;
			sImportResultStatus = status;
			sImportId = content;
		}
	};

	class LLImportGetResponder : public LLHTTPClient::Responder
	{
	public:
		LLImportGetResponder() : LLCurl::Responder() {}

		void completedHeader(U32 status, const std::string& reason, const LLSD& content)
		{
			const std::string& set_cookie_string = content["set-cookie"].asString();

			if (!set_cookie_string.empty())
			{
				sMarketplaceCookie = set_cookie_string;
			}
		}

		void completed(U32 status, const std::string& reason, const LLSD& content)
		{
			slmGetTimer.stop();

			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
			{
				llinfos << " SLM GET status: " << status << llendl;
				llinfos << " SLM GET reason: " << reason << llendl;
				llinfos << " SLM GET content: " << content.asString() << llendl;

				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
			}

			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
			{
				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
				{
					llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
				}

				sMarketplaceCookie.clear();
			}

			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
			sImportGetPending = false;
			sImportResultStatus = status;
			sImportResults = content;
		}
	};

	// Basic API

	bool hasSessionCookie()
	{
		return !sMarketplaceCookie.empty();
	}

	bool inProgress()
	{
		return sImportInProgress;
	}

	bool resultPending()
	{
		return (sImportPostPending || sImportGetPending);
	}

	U32 getResultStatus()
	{
		return sImportResultStatus;
	}

	const LLSD& getResults()
	{
		return sImportResults;
	}

	static std::string getInventoryImportURL()
	{
		std::string url = getMarketplaceURL("MarketplaceURL");

		url += "api/1/";
		url += gAgent.getID().getString();
		url += "/inventory/import/";

		return url;
	}

	bool establishMarketplaceSessionCookie()
	{
		if (hasSessionCookie())
		{
			return false;
		}

		sImportInProgress = true;
		sImportGetPending = true;

		std::string url = getInventoryImportURL();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM GET: " << url << llendl;
		}

		slmGetTimer.start();
		LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());

		return true;
	}

	bool pollStatus()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportGetPending = true;

		std::string url = getInventoryImportURL();

		url += sImportId.asString();

		// Make the headers for the post
		LLSD headers = LLSD::emptyMap();
		headers["Accept"] = "*/*";
		headers["Cookie"] = sMarketplaceCookie;
		headers["Content-Type"] = "application/llsd+xml";
		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM GET: " << url << llendl;
		}

		slmGetTimer.start();
		LLHTTPClient::get(url, new LLImportGetResponder(), headers);

		return true;
	}

	bool triggerImport()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportId = LLSD::emptyMap();
		sImportInProgress = true;
		sImportPostPending = true;
		sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING;
		sImportResults = LLSD::emptyMap();

		std::string url = getInventoryImportURL();

		// Make the headers for the post
		LLSD headers = LLSD::emptyMap();
		headers["Accept"] = "*/*";
		headers["Connection"] = "Keep-Alive";
		headers["Cookie"] = sMarketplaceCookie;
		headers["Content-Type"] = "application/xml";
		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM POST: " << url << llendl;
		}

		slmPostTimer.start();
		LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);

		return true;
	}
}

//
// Interface class
//

//static
void LLMarketplaceInventoryImporter::update()
{
	if (instanceExists())
	{
		LLMarketplaceInventoryImporter::instance().updateImport();
	}
}

LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
	: mAutoTriggerImport(false)
	, mImportInProgress(false)
	, mInitialized(false)
	, mErrorInitSignal(NULL)
	, mStatusChangedSignal(NULL)
	, mStatusReportSignal(NULL)
{
}

boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb)
{
	if (mErrorInitSignal == NULL)
	{
		mErrorInitSignal = new status_report_signal_t();
	}

	return mErrorInitSignal->connect(cb);
}

boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
{
	if (mStatusChangedSignal == NULL)
	{
		mStatusChangedSignal = new status_changed_signal_t();
	}

	return mStatusChangedSignal->connect(cb);
}

boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
{
	if (mStatusReportSignal == NULL)
	{
		mStatusReportSignal = new status_report_signal_t();
	}

	return mStatusReportSignal->connect(cb);
}

void LLMarketplaceInventoryImporter::initialize()
{
	llassert(!mInitialized);

	if (!LLMarketplaceImport::hasSessionCookie())
	{
		LLMarketplaceImport::establishMarketplaceSessionCookie();
	}
}

void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
{
	mInitialized = false;

	initialize();

	mAutoTriggerImport = true;
}

bool LLMarketplaceInventoryImporter::triggerImport()
{
	const bool import_triggered = LLMarketplaceImport::triggerImport();

	if (!import_triggered)
	{
		reinitializeAndTriggerImport();
	}

	return import_triggered;
}

void LLMarketplaceInventoryImporter::updateImport()
{
	const bool in_progress = LLMarketplaceImport::inProgress();

	if (in_progress && !LLMarketplaceImport::resultPending())
	{
		const bool polling_status = LLMarketplaceImport::pollStatus();

		if (!polling_status)
		{
			reinitializeAndTriggerImport();
		}
	}

	if (mImportInProgress != in_progress)
	{
		mImportInProgress = in_progress;

		// If we are no longer in progress
		if (!mImportInProgress)
		{
			if (mInitialized)
			{
				// Report results
				if (mStatusReportSignal)
				{
					(*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
				}
			}
			else
			{
				// Look for results success
				mInitialized = LLMarketplaceImport::hasSessionCookie();

				if (mInitialized)
				{
					// Follow up with auto trigger of import
					if (mAutoTriggerImport)
					{
						mAutoTriggerImport = false;

						mImportInProgress = triggerImport();
					}
				}
				else if (mErrorInitSignal)
				{
					(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
				}
			}
		}

		// Make sure we trigger the status change with the final state (in case of auto trigger after initialize)
		if (mStatusChangedSignal)
		{
			(*mStatusChangedSignal)(mImportInProgress);
		}
	}
}

<commit_msg>Increase timeout of merchant outbox fetching to 2 minutes; martketplace is often rather slow to respond.<commit_after>/**
 * @file llmarketplacefunctions.cpp
 * @brief Implementation of assorted functions related to the marketplace
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llmarketplacefunctions.h"

#include "llagent.h"
#include "llhttpclient.h"
#include "lltimer.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewernetwork.h"

//
// Helpers
//

static std::string getMarketplaceDomain()
{
	std::string domain = "secondlife.com";

//	if (!LLGridManager::getInstance()->isInProductionGrid()) <FS:ND> For OpenSim
	if (!LLGridManager::getInstance()->isInSLMain())
	{
		const std::string& grid_label = LLGridManager::getInstance()->getGridLabel();
		const std::string& grid_label_lower = utf8str_tolower(grid_label);

		if (grid_label_lower == "damballah")
		{
			domain = "secondlife-staging.com";
		}
		else
		{
			domain = llformat("%s.lindenlab.com", grid_label_lower.c_str());
		}
	}

	return domain;
}

static std::string getMarketplaceURL(const std::string& urlStringName)
{
	LLStringUtil::format_map_t domain_arg;
	domain_arg["[MARKETPLACE_DOMAIN_NAME]"] = getMarketplaceDomain();

	std::string marketplace_url = LLTrans::getString(urlStringName, domain_arg);

	return marketplace_url;
}

LLSD getMarketplaceStringSubstitutions()
{
	std::string marketplace_url = getMarketplaceURL("MarketplaceURL");
	std::string marketplace_url_create = getMarketplaceURL("MarketplaceURL_CreateStore");
	std::string marketplace_url_dashboard = getMarketplaceURL("MarketplaceURL_Dashboard");
	std::string marketplace_url_imports = getMarketplaceURL("MarketplaceURL_Imports");
	std::string marketplace_url_info = getMarketplaceURL("MarketplaceURL_LearnMore");

	LLSD marketplace_sub_map;

	marketplace_sub_map["[MARKETPLACE_URL]"] = marketplace_url;
	marketplace_sub_map["[MARKETPLACE_CREATE_STORE_URL]"] = marketplace_url_create;
	marketplace_sub_map["[MARKETPLACE_LEARN_MORE_URL]"] = marketplace_url_info;
	marketplace_sub_map["[MARKETPLACE_DASHBOARD_URL]"] = marketplace_url_dashboard;
	marketplace_sub_map["[MARKETPLACE_IMPORTS_URL]"] = marketplace_url_imports;

	return marketplace_sub_map;
}

namespace LLMarketplaceImport
{
	// Basic interface for this namespace

	bool hasSessionCookie();
	bool inProgress();
	bool resultPending();
	U32 getResultStatus();
	const LLSD& getResults();

	bool establishMarketplaceSessionCookie();
	bool pollStatus();
	bool triggerImport();

	// Internal state variables

	static std::string sMarketplaceCookie = "";
	static LLSD sImportId = LLSD::emptyMap();
	static bool sImportInProgress = false;
	static bool sImportPostPending = false;
	static bool sImportGetPending = false;
	static U32 sImportResultStatus = 0;
	static LLSD sImportResults = LLSD::emptyMap();

	static LLTimer slmGetTimer;
	static LLTimer slmPostTimer;

	// Responders

	class LLImportPostResponder : public LLHTTPClient::Responder
	{
	public:
		LLImportPostResponder() : LLCurl::Responder() {}

		void completed(U32 status, const std::string& reason, const LLSD& content)
		{
			slmPostTimer.stop();

			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
			{
				llinfos << " SLM POST status: " << status << llendl;
				llinfos << " SLM POST reason: " << reason << llendl;
				llinfos << " SLM POST content: " << content.asString() << llendl;

				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
			}

			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
			{
				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
				{
					llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
				}

				sMarketplaceCookie.clear();
			}

			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE);
			sImportPostPending = false;
			sImportResultStatus = status;
			sImportId = content;
		}
	};

	class LLImportGetResponder : public LLHTTPClient::Responder
	{
	public:
		LLImportGetResponder() : LLCurl::Responder() {}

		void completedHeader(U32 status, const std::string& reason, const LLSD& content)
		{
			const std::string& set_cookie_string = content["set-cookie"].asString();

			if (!set_cookie_string.empty())
			{
				sMarketplaceCookie = set_cookie_string;
			}
		}

		void completed(U32 status, const std::string& reason, const LLSD& content)
		{
			slmGetTimer.stop();

			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
			{
				llinfos << " SLM GET status: " << status << llendl;
				llinfos << " SLM GET reason: " << reason << llendl;
				llinfos << " SLM GET content: " << content.asString() << llendl;

				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
			}

			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
			{
				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
				{
					llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
				}

				sMarketplaceCookie.clear();
			}

			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
			sImportGetPending = false;
			sImportResultStatus = status;
			sImportResults = content;
		}
	};

	// Basic API

	bool hasSessionCookie()
	{
		return !sMarketplaceCookie.empty();
	}

	bool inProgress()
	{
		return sImportInProgress;
	}

	bool resultPending()
	{
		return (sImportPostPending || sImportGetPending);
	}

	U32 getResultStatus()
	{
		return sImportResultStatus;
	}

	const LLSD& getResults()
	{
		return sImportResults;
	}

	static std::string getInventoryImportURL()
	{
		std::string url = getMarketplaceURL("MarketplaceURL");

		url += "api/1/";
		url += gAgent.getID().getString();
		url += "/inventory/import/";

		return url;
	}

	bool establishMarketplaceSessionCookie()
	{
		if (hasSessionCookie())
		{
			return false;
		}

		sImportInProgress = true;
		sImportGetPending = true;

		std::string url = getInventoryImportURL();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM GET: " << url << llendl;
		}

		slmGetTimer.start();

		// <FS:ND> Bump timeout to 2 minutes. Marketplace can be really slow ...
		//		LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());
		LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders(), 2*60);
		// </FS:ND>

		return true;
	}

	bool pollStatus()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportGetPending = true;

		std::string url = getInventoryImportURL();

		url += sImportId.asString();

		// Make the headers for the post
		LLSD headers = LLSD::emptyMap();
		headers["Accept"] = "*/*";
		headers["Cookie"] = sMarketplaceCookie;
		headers["Content-Type"] = "application/llsd+xml";
		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM GET: " << url << llendl;
		}

		slmGetTimer.start();
		LLHTTPClient::get(url, new LLImportGetResponder(), headers);

		return true;
	}

	bool triggerImport()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportId = LLSD::emptyMap();
		sImportInProgress = true;
		sImportPostPending = true;
		sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING;
		sImportResults = LLSD::emptyMap();

		std::string url = getInventoryImportURL();

		// Make the headers for the post
		LLSD headers = LLSD::emptyMap();
		headers["Accept"] = "*/*";
		headers["Connection"] = "Keep-Alive";
		headers["Cookie"] = sMarketplaceCookie;
		headers["Content-Type"] = "application/xml";
		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM POST: " << url << llendl;
		}

		slmPostTimer.start();
		LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);

		return true;
	}
}

//
// Interface class
//

//static
void LLMarketplaceInventoryImporter::update()
{
	if (instanceExists())
	{
		LLMarketplaceInventoryImporter::instance().updateImport();
	}
}

LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
	: mAutoTriggerImport(false)
	, mImportInProgress(false)
	, mInitialized(false)
	, mErrorInitSignal(NULL)
	, mStatusChangedSignal(NULL)
	, mStatusReportSignal(NULL)
{
}

boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb)
{
	if (mErrorInitSignal == NULL)
	{
		mErrorInitSignal = new status_report_signal_t();
	}

	return mErrorInitSignal->connect(cb);
}

boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
{
	if (mStatusChangedSignal == NULL)
	{
		mStatusChangedSignal = new status_changed_signal_t();
	}

	return mStatusChangedSignal->connect(cb);
}

boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
{
	if (mStatusReportSignal == NULL)
	{
		mStatusReportSignal = new status_report_signal_t();
	}

	return mStatusReportSignal->connect(cb);
}

void LLMarketplaceInventoryImporter::initialize()
{
	llassert(!mInitialized);

	if (!LLMarketplaceImport::hasSessionCookie())
	{
		LLMarketplaceImport::establishMarketplaceSessionCookie();
	}
}

void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
{
	mInitialized = false;

	initialize();

	mAutoTriggerImport = true;
}

bool LLMarketplaceInventoryImporter::triggerImport()
{
	const bool import_triggered = LLMarketplaceImport::triggerImport();

	if (!import_triggered)
	{
		reinitializeAndTriggerImport();
	}

	return import_triggered;
}

void LLMarketplaceInventoryImporter::updateImport()
{
	const bool in_progress = LLMarketplaceImport::inProgress();

	if (in_progress && !LLMarketplaceImport::resultPending())
	{
		const bool polling_status = LLMarketplaceImport::pollStatus();

		if (!polling_status)
		{
			reinitializeAndTriggerImport();
		}
	}

	if (mImportInProgress != in_progress)
	{
		mImportInProgress = in_progress;

		// If we are no longer in progress
		if (!mImportInProgress)
		{
			if (mInitialized)
			{
				// Report results
				if (mStatusReportSignal)
				{
					(*mStatusReportSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
				}
			}
			else
			{
				// Look for results success
				mInitialized = LLMarketplaceImport::hasSessionCookie();

				if (mInitialized)
				{
					// Follow up with auto trigger of import
					if (mAutoTriggerImport)
					{
						mAutoTriggerImport = false;

						mImportInProgress = triggerImport();
					}
				}
				else if (mErrorInitSignal)
				{
					(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
				}
			}
		}

		// Make sure we trigger the status change with the final state (in case of auto trigger after initialize)
		if (mStatusChangedSignal)
		{
			(*mStatusChangedSignal)(mImportInProgress);
		}
	}
}

<|endoftext|>


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

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMeanShiftSmoothingImageFilter.h"

namespace otb
{
namespace Wrapper
{

class MeanShiftSmoothing : public Application
{
public:
  /** Standard class typedefs. */
  typedef MeanShiftSmoothing         Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  typedef otb::MeanShiftSmoothingImageFilter<FloatVectorImageType, FloatVectorImageType> MSFilterType;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(MeanShiftSmoothing, otb::Application);

private:
  void DoInit()
  {
    SetName("MeanShiftSmoothing");
    SetDescription("Perform mean shift filtering");

    // Documentation
    SetDocName("Exact Large-Scale Mean-Shift segmentation, step 1 (smoothing)");
    SetDocLongDescription("This application performs mean shift fitlering (multi-threaded).");
    SetDocLimitations("With mode search option, the result will slightly depend on thread number.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Filter);
    AddDocTag("LSMS");

    AddParameter(ParameterType_InputImage,   "in",     "Input Image");
    SetParameterDescription( "in", "The input image." );

    AddParameter(ParameterType_OutputImage,  "fout",    "Filtered output");
    SetParameterDescription( "fout", "The filtered output image." );

    AddParameter(ParameterType_OutputImage,  "foutpos",    "Spatial image");
    SetParameterDescription( "foutpos", " The spatial image output. Spatial image output is a displacement map (pixel position after convergence).");
    MandatoryOff("foutpos");

    AddRAMParameter();

    AddParameter(ParameterType_Int, "spatialr", "Spatial radius");
    SetParameterDescription("spatialr", "Spatial radius of the neighborhood.");
    SetDefaultParameterInt("spatialr", 5);
    MandatoryOff("spatialr");

    AddParameter(ParameterType_Float, "ranger", "Range radius");
    SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
    SetDefaultParameterFloat("ranger", 15.0);
    MandatoryOff("ranger");

    AddParameter(ParameterType_Float, "thres", "Mode convergence threshold");
    SetParameterDescription("thres", "Algorithm iterative scheme will stop if mean-shift "
                               "vector is below this threshold or if iteration number reached maximum number of iterations.");
    SetMinimumParameterFloatValue("thres", 0.0);
    SetDefaultParameterFloat("thres", 0.1);
    MandatoryOff("thres");

    AddParameter(ParameterType_Int, "maxiter", "Maximum number of iterations");
    SetParameterDescription("maxiter", "Algorithm iterative scheme will stop if convergence hasn't been reached after the maximum number of iterations.");
    SetDefaultParameterInt("maxiter", 100);
    SetMinimumParameterIntValue("maxiter", 1);
    MandatoryOff("maxiter");

    AddParameter(ParameterType_Float, "rangeramp", "Range radius coefficient");
    SetParameterDescription("rangeramp", "This coefficient makes dependent the ranger of the colorimetry of the filtered pixel : y = rangeramp*x+ranger.");
    SetDefaultParameterFloat("rangeramp", 0.);
    SetMinimumParameterFloatValue("rangeramp", 0);
    MandatoryOff("rangeramp");

    AddParameter(ParameterType_Empty, "modesearch", "Mode search.");
    SetParameterDescription("modesearch", "If activated pixel iterative convergence is stopped if the path . Be careful, with this option, the result will slightly depend on thread number");
    EnableParameter("modesearch");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "maur_rgb.png");
    SetDocExampleParameterValue("fout", "MeanShift_FilterOutput.tif");
    SetDocExampleParameterValue("foutpos", "MeanShift_SpatialOutput.tif");
    SetDocExampleParameterValue("spatialr", "16");
    SetDocExampleParameterValue("ranger", "16");
    SetDocExampleParameterValue("thres", "0.1");
    SetDocExampleParameterValue("maxiter", "100");

  }

  void DoUpdateParameters()
  {
    if(IsParameterEnabled("modesearch"))
      {
      MandatoryOn("foutpos");
      EnableParameter("foutpos");
      }
    else
      {
      MandatoryOff("foutpos");
      DisableParameter("foutpos");
      }
  }

  void DoExecute()
  {
    FloatVectorImageType* input = GetParameterImage("in");

    m_Filter = MSFilterType::New();

    m_Filter->SetInput(input);

    m_Filter->SetSpatialBandwidth(GetParameterInt("spatialr"));
    m_Filter->SetRangeBandwidth(GetParameterFloat("ranger"));
    m_Filter->SetThreshold(GetParameterFloat("thres"));
    m_Filter->SetMaxIterationNumber(GetParameterInt("maxiter"));
    m_Filter->SetRangeBandwidthRamp(GetParameterFloat("rangeramp"));

    //Compute the margin used to ensure exact results (tile wise smoothing)
    //This margin is valid for the default uniform kernel used by the
    //MeanShiftSmoothing filter (bandwidth equal to radius in this case)
    const unsigned int margin = (m_Filter->GetMaxIterationNumber() * m_Filter->GetSpatialBandwidth()) + 1;

    otbAppLogINFO(<<"Margin of " << margin << " pixels applied to each tile to stabilized mean shift filtering." << std::endl);

    if ( margin > std::min(input->GetLargestPossibleRegion().GetSize()[0],input->GetLargestPossibleRegion().GetSize()[1]) )
      {
      otbAppLogWARNING(<<"Margin value exceed the input image size." << std::endl);
      }

    SetParameterOutputImage("fout", m_Filter->GetOutput());
    SetParameterOutputImage("foutpos", m_Filter->GetSpatialOutput());
    if(!IsParameterEnabled("modesearch"))
      {
        otbAppLogINFO(<<"Mode Search is disabled." << std::endl);
        m_Filter->SetModeSearch(false);
      }
   }

  MSFilterType::Pointer m_Filter;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::MeanShiftSmoothing)
<commit_msg>BUG: Mantis-1166: fix modesearch interaction with foutpos<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbMeanShiftSmoothingImageFilter.h"

namespace otb
{
namespace Wrapper
{

class MeanShiftSmoothing : public Application
{
public:
  /** Standard class typedefs. */
  typedef MeanShiftSmoothing         Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  typedef otb::MeanShiftSmoothingImageFilter<FloatVectorImageType, FloatVectorImageType> MSFilterType;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(MeanShiftSmoothing, otb::Application);

private:
  void DoInit()
  {
    SetName("MeanShiftSmoothing");
    SetDescription("Perform mean shift filtering");

    // Documentation
    SetDocName("Exact Large-Scale Mean-Shift segmentation, step 1 (smoothing)");
    SetDocLongDescription("This application performs mean shift fitlering (multi-threaded).");
    SetDocLimitations("With mode search option, the result will slightly depend on thread number.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Filter);
    AddDocTag("LSMS");

    AddParameter(ParameterType_InputImage,   "in",     "Input Image");
    SetParameterDescription( "in", "The input image." );

    AddParameter(ParameterType_OutputImage,  "fout",    "Filtered output");
    SetParameterDescription( "fout", "The filtered output image." );

    AddParameter(ParameterType_OutputImage,  "foutpos",    "Spatial image");
    SetParameterDescription( "foutpos", " The spatial image output. Spatial image output is a displacement map (pixel position after convergence).");
    MandatoryOff("foutpos");

    AddRAMParameter();

    AddParameter(ParameterType_Int, "spatialr", "Spatial radius");
    SetParameterDescription("spatialr", "Spatial radius of the neighborhood.");
    SetDefaultParameterInt("spatialr", 5);
    MandatoryOff("spatialr");

    AddParameter(ParameterType_Float, "ranger", "Range radius");
    SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
    SetDefaultParameterFloat("ranger", 15.0);
    MandatoryOff("ranger");

    AddParameter(ParameterType_Float, "thres", "Mode convergence threshold");
    SetParameterDescription("thres", "Algorithm iterative scheme will stop if mean-shift "
                               "vector is below this threshold or if iteration number reached maximum number of iterations.");
    SetMinimumParameterFloatValue("thres", 0.0);
    SetDefaultParameterFloat("thres", 0.1);
    MandatoryOff("thres");

    AddParameter(ParameterType_Int, "maxiter", "Maximum number of iterations");
    SetParameterDescription("maxiter", "Algorithm iterative scheme will stop if convergence hasn't been reached after the maximum number of iterations.");
    SetDefaultParameterInt("maxiter", 100);
    SetMinimumParameterIntValue("maxiter", 1);
    MandatoryOff("maxiter");

    AddParameter(ParameterType_Float, "rangeramp", "Range radius coefficient");
    SetParameterDescription("rangeramp", "This coefficient makes dependent the ranger of the colorimetry of the filtered pixel : y = rangeramp*x+ranger.");
    SetDefaultParameterFloat("rangeramp", 0.);
    SetMinimumParameterFloatValue("rangeramp", 0);
    MandatoryOff("rangeramp");

    AddParameter(ParameterType_Empty, "modesearch", "Mode search.");
    SetParameterDescription("modesearch", "If activated pixel iterative convergence is stopped if the path . Be careful, with this option, the result will slightly depend on thread number");
    EnableParameter("modesearch");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "maur_rgb.png");
    SetDocExampleParameterValue("fout", "MeanShift_FilterOutput.tif");
    SetDocExampleParameterValue("foutpos", "MeanShift_SpatialOutput.tif");
    SetDocExampleParameterValue("spatialr", "16");
    SetDocExampleParameterValue("ranger", "16");
    SetDocExampleParameterValue("thres", "0.1");
    SetDocExampleParameterValue("maxiter", "100");

  }

  void DoUpdateParameters()
  {
    if(IsParameterEnabled("modesearch"))
      {
      MandatoryOn("foutpos");
      EnableParameter("foutpos");
      }
    else
      {
      MandatoryOff("foutpos");
      }
  }

  void DoExecute()
  {
    FloatVectorImageType* input = GetParameterImage("in");

    m_Filter = MSFilterType::New();

    m_Filter->SetInput(input);

    m_Filter->SetSpatialBandwidth(GetParameterInt("spatialr"));
    m_Filter->SetRangeBandwidth(GetParameterFloat("ranger"));
    m_Filter->SetThreshold(GetParameterFloat("thres"));
    m_Filter->SetMaxIterationNumber(GetParameterInt("maxiter"));
    m_Filter->SetRangeBandwidthRamp(GetParameterFloat("rangeramp"));
    m_Filter->SetModeSearch(IsParameterEnabled("modesearch"));

    //Compute the margin used to ensure exact results (tile wise smoothing)
    //This margin is valid for the default uniform kernel used by the
    //MeanShiftSmoothing filter (bandwidth equal to radius in this case)
    const unsigned int margin = (m_Filter->GetMaxIterationNumber() * m_Filter->GetSpatialBandwidth()) + 1;

    otbAppLogINFO(<<"Margin of " << margin << " pixels applied to each tile to stabilized mean shift filtering." << std::endl);

    if ( margin > std::min(input->GetLargestPossibleRegion().GetSize()[0],input->GetLargestPossibleRegion().GetSize()[1]) )
      {
      otbAppLogWARNING(<<"Margin value exceed the input image size." << std::endl);
      }

    SetParameterOutputImage("fout", m_Filter->GetOutput());
    if (IsParameterEnabled("foutpos") && HasValue("foutpos"))
      {
      SetParameterOutputImage("foutpos", m_Filter->GetSpatialOutput());
      }
    if(!IsParameterEnabled("modesearch"))
      {
      otbAppLogINFO(<<"Mode Search is disabled." << std::endl);
      }
   }

  MSFilterType::Pointer m_Filter;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::MeanShiftSmoothing)
<|endoftext|>


<commit_before>// CCharacterController.cpp

#include <Core/Reflection/ReflectionBuilder.h>
#include "../../../include/Engine/Components/Gameplay/CCharacterController.h"
#include "../../../include/Engine/Scene.h"
#include "../../../include/Engine/Util/BasicComponentContainer.h"

SGE_REFLECT_TYPE(sge::CCharacterController)
.property("step_height", &CCharacterController::step_height, &CCharacterController::step_height)
.property("max_slope", &CCharacterController::max_slope, &CCharacterController::max_slope)
.property("jump_speed", &CCharacterController::jump_speed, &CCharacterController::jump_speed)
.property("fall_speed", &CCharacterController::fall_speed, &CCharacterController::fall_speed)
.property("on_ground", &CCharacterController::on_ground, nullptr, PF_EDITOR_HIDDEN);

SGE_REFLECT_TYPE(sge::CCharacterController::FJumpEvent);

SGE_REFLECT_TYPE(sge::CCharacterController::FWalkEvent)
.field_property("direction", &FWalkEvent::direction);

namespace sge
{
    struct CCharacterController::Data
    {
        ///////////////////
        ///   Methods   ///
    public:

        void to_archive(ArchiveWriter& writer) const
        {
            writer.object_member("stpht", step_height);
            writer.object_member("mxslp", max_slope);
            writer.object_member("jspd", jump_speed);
            writer.object_member("fspd", fall_speed);
            writer.object_member("grd", on_ground);
        }

        void from_archive(ArchiveReader& reader)
        {
            reader.object_member("stpht", step_height);
            reader.object_member("mxslp", max_slope);
            reader.object_member("jspd", jump_speed);
            reader.object_member("fsdp", fall_speed);
            reader.object_member("grd", on_ground);
        }

        //////////////////
        ///   Fields   ///
    public:

        float step_height = 0.1f;
        Angle max_slope;
        float jump_speed = 10.f;
        float fall_speed = 55.f;
        bool on_ground = true;
    };

    CCharacterController::CCharacterController(ProcessingFrame& pframe, EntityId entity, Data& data)
        : TComponentInterface<sge::CCharacterController>(pframe, entity),
        _data(&data)
    {
    }

    void CCharacterController::register_type(Scene& scene)
    {
        scene.register_component_type(type_info, std::make_unique<BasicComponentContainer<CCharacterController, Data>>());
    }

    bool CCharacterController::on_ground() const
    {
        return _data->on_ground;
    }

    void CCharacterController::set_on_ground(bool value)
    {
        // Should a tag be created for this?
        _data->on_ground = true;
    }

    float CCharacterController::step_height() const
    {
        return _data->step_height;
    }

    void CCharacterController::step_height(float value)
    {
        checked_setter(value, _data->step_height);
    }

    Angle CCharacterController::max_slope() const
    {
        return _data->max_slope;
    }

    void CCharacterController::max_slope(Angle value)
    {
        checked_setter(value, _data->max_slope);
    }

    float CCharacterController::jump_speed() const
    {
        return _data->jump_speed;
    }

    void CCharacterController::jump_speed(float value)
    {
        checked_setter(value, _data->jump_speed);
    }

    float CCharacterController::fall_speed() const
    {
        return _data->fall_speed;
    }

    void CCharacterController::fall_speed(float value)
    {
        checked_setter(value, _data->fall_speed);
    }

    void CCharacterController::jump() const
    {
        if (on_ground())
        {
            create_tag(FJumpEvent{});
        }
    }

    void CCharacterController::walk(const Vec2& direction) const
    {
        create_tag(FWalkEvent{ direction });
    }
}
<commit_msg>Fixed wonky character controller behavior<commit_after>// CCharacterController.cpp

#include <Core/Reflection/ReflectionBuilder.h>
#include "../../../include/Engine/Components/Gameplay/CCharacterController.h"
#include "../../../include/Engine/Scene.h"
#include "../../../include/Engine/Util/BasicComponentContainer.h"

SGE_REFLECT_TYPE(sge::CCharacterController)
.property("step_height", &CCharacterController::step_height, &CCharacterController::step_height)
.property("max_slope", &CCharacterController::max_slope, &CCharacterController::max_slope)
.property("jump_speed", &CCharacterController::jump_speed, &CCharacterController::jump_speed)
.property("fall_speed", &CCharacterController::fall_speed, &CCharacterController::fall_speed)
.property("on_ground", &CCharacterController::on_ground, nullptr, PF_EDITOR_HIDDEN);

SGE_REFLECT_TYPE(sge::CCharacterController::FJumpEvent);

SGE_REFLECT_TYPE(sge::CCharacterController::FWalkEvent)
.field_property("direction", &FWalkEvent::direction);

namespace sge
{
    struct CCharacterController::Data
    {
        ///////////////////
        ///   Methods   ///
    public:

        void to_archive(ArchiveWriter& writer) const
        {
            writer.object_member("stpht", step_height);
            writer.object_member("mxslp", max_slope);
            writer.object_member("jspd", jump_speed);
            writer.object_member("fspd", fall_speed);
            writer.object_member("grd", on_ground);
        }

        void from_archive(ArchiveReader& reader)
        {
            reader.object_member("stpht", step_height);
            reader.object_member("mxslp", max_slope);
            reader.object_member("jspd", jump_speed);
            reader.object_member("fsdp", fall_speed);
            reader.object_member("grd", on_ground);
        }

        //////////////////
        ///   Fields   ///
    public:

        float step_height = 0.1f;
        Angle max_slope = degrees(30);
        float jump_speed = 10.f;
        float fall_speed = 55.f;
        bool on_ground = true;
    };

    CCharacterController::CCharacterController(ProcessingFrame& pframe, EntityId entity, Data& data)
        : TComponentInterface<sge::CCharacterController>(pframe, entity),
        _data(&data)
    {
    }

    void CCharacterController::register_type(Scene& scene)
    {
        scene.register_component_type(type_info, std::make_unique<BasicComponentContainer<CCharacterController, Data>>());
    }

    bool CCharacterController::on_ground() const
    {
        return _data->on_ground;
    }

    void CCharacterController::set_on_ground(bool value)
    {
        // Should a tag be created for this?
        _data->on_ground = true;
    }

    float CCharacterController::step_height() const
    {
        return _data->step_height;
    }

    void CCharacterController::step_height(float value)
    {
        checked_setter(value, _data->step_height);
    }

    Angle CCharacterController::max_slope() const
    {
        return _data->max_slope;
    }

    void CCharacterController::max_slope(Angle value)
    {
        checked_setter(value, _data->max_slope);
    }

    float CCharacterController::jump_speed() const
    {
        return _data->jump_speed;
    }

    void CCharacterController::jump_speed(float value)
    {
        checked_setter(value, _data->jump_speed);
    }

    float CCharacterController::fall_speed() const
    {
        return _data->fall_speed;
    }

    void CCharacterController::fall_speed(float value)
    {
        checked_setter(value, _data->fall_speed);
    }

    void CCharacterController::jump() const
    {
        if (on_ground())
        {
            create_tag(FJumpEvent{});
        }
    }

    void CCharacterController::walk(const Vec2& direction) const
    {
        create_tag(FWalkEvent{ direction });
    }
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

// Testing
#include <mitkTestingMacros.h>
#include <mitkTestFixture.h>

// other
#include <mitkImage.h>
#include <mitkIOUtil.h>
#include <mitkSegmentationInterpolationController.h>

class mitkSegmentationInterpolationTestSuite : public mitk::TestFixture
{
    CPPUNIT_TEST_SUITE(mitkSegmentationInterpolationTestSuite);
    MITK_TEST(Equal_TestFeedbackAndReferenceFeedback_ReturnsTrue);
    CPPUNIT_TEST_SUITE_END();

private:

    // Load data into these
    mitk::Image::Pointer m_ReferenceImage;
    mitk::Image::Pointer m_AxialBase;
    mitk::Surface::Pointer m_AxialFeedback;
    mitk::Image::Pointer m_AxialInterpolated;

    mitk::SegmentationInterpolationController::Pointer m_InterpolationController;

public:

    void setUp() override
    {
        m_ReferenceImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd"));
        CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [Pic3D.nrrd]", m_ReferenceImage.IsNotNull());
        m_AxialBase = mitk::IOUtil::LoadImage(GetTestDataFilePath("SegmentationInterpolation/AxialBase.nrrd"));
        CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialBase.nrrd]", m_AxialBase.IsNotNull());
        m_AxialFeedback = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SegmentationInterpolation/AxialFeedback.vtp"));
        CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialFeedback.nrrd]", m_AxialFeedback.IsNotNull());
        m_AxialInterpolated = mitk::IOUtil::LoadImage(GetTestDataFilePath("SegmentationInterpolation/AxialInterpolated.nrrd"));
        CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialInterpolated.nrrd]", m_AxialInterpolated.IsNotNull());

        m_InterpolationController = mitk::SegmentationInterpolationController::GetInstance();
        m_InterpolationController->SetReferenceVolume(m_ReferenceImage);
    }

    void tearDown() override
    {
        m_ReferenceImage = nullptr;
        m_AxialBase = nullptr;
        m_AxialFeedback = nullptr;
        m_AxialInterpolated = nullptr;
    }

    void Equal_Axial_TestFeedbackAndReferenceFeedback_ReturnsTrue()
    {
        // Create Feedback from base segmentation
        m_InterpolationController->SetSegmentationVolume(m_AxialBase);
        m_InterpolationController->Interpolate(); // HIER GEHTS WEITER
    }
};

MITK_TEST_SUITE_REGISTRATION(mitkSegmentationInterpolation);

//#include "mitkSegmentationInterpolationController.h"
//#include "mitkCoreObjectFactory.h"
//#include "mitkStandardFileLocations.h"
////#include "mitkDataNodeFactory.h"
//#include "ipSegmentation.h"
//#include "mitkCompareImageSliceTestHelper.h"

//class mitkSegmentationInterpolationTestClass
//{
//  public:
//    mitkSegmentationInterpolationTestClass() {}
//    ~mitkSegmentationInterpolationTestClass() {}

//    bool Test(std::string filename1, std::string filename2)
//    {
//      return CreateNewInterpolator()
//          && CreateSegmentation()
//          && ClearSegmentation()
//          && CreateTwoSlices(2)
//          && TestInterpolation(2)
//          && ClearSegmentation()
//          && CreateTwoSlices(1)
//          && TestInterpolation(1)
//          && ClearSegmentation()
//          && CreateTwoSlices(0)
//          && TestInterpolation(0)
//          && DeleteInterpolator()
//          && CreateNewInterpolator()
//          && LoadTestImages(filename1, filename2)
//          && CompareInterpolationsToDefinedReference();
//    }

//  protected:

//    bool CreateNewInterpolator();
//    bool CreateSegmentation();
//    bool ClearSegmentation();
//    bool CreateTwoSlices(int);
//    bool TestInterpolation(int);
//    bool DeleteInterpolator();
//    bool LoadTestImages(std::string filename1, std::string filename2);
//    bool CompareInterpolationsToDefinedReference();

//    mitk::Image::Pointer LoadImage(const std::string& filename);

//    mitk::SegmentationInterpolationController::Pointer m_Interpolator;
//    mitk::Image::Pointer m_Image;

//    mitk::Image::Pointer m_ManualSlices;
//    mitk::Image::Pointer m_InterpolatedSlices;

//    unsigned int dim[3];
//    int pad[3];
//};

//bool mitkSegmentationInterpolationTestClass::CreateNewInterpolator()
//{
//  std::cout << "Instantiation" << std::endl;

//// instantiation
//  m_Interpolator = mitk::SegmentationInterpolationController::New();
//  if (m_Interpolator.IsNotNull())
//  {
//    std::cout << "  (II) Instantiation works." << std::endl;
//  }
//  else
//  {
//    std::cout << " Instantiation test failed!" << std::endl;
//    return false;
//  }

//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::CreateSegmentation()
//{
//  m_Image = mitk::Image::New();
//  dim[0]=15;
//  dim[1]=20;
//  dim[2]=25;
//  pad[0]=2;
//  pad[1]=3;
//  pad[2]=4;

//  m_Image->Initialize( mitk::MakeScalarPixelType<int>(), 3, dim);

//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::ClearSegmentation()
//{
//  int* p = (int*)m_Image->GetData(); // pointer to pixel data
//  int size = dim[0]*dim[1]*dim[2];
//  for(int i=0; i<size; ++i, ++p) *p=0; // fill image with zeros

//  return true;
//}

///**
// * Creates a square segmentation in slices 0 and 2.
//*/
//bool mitkSegmentationInterpolationTestClass::CreateTwoSlices(int slicedim)
//{
//  int* p = (int*)m_Image->GetData(); // pointer to pixel data

//  int size = dim[0]*dim[1]*dim[2];
//  for(int i=0; i<size; ++i, ++p)
//  {
//    int x,y,z;
//    int xdim,ydim;
//    switch (slicedim)
//    {
//      case 0:
//        z = i % dim[0];
//        y = i / dim[0] %  dim[1];
//        x = i / (dim[1]*dim[0]);
//        xdim = 2;
//        ydim = 1;
//        break;
//      case 1:
//        x = i % dim[0];
//        z = i / dim[0] %  dim[1];
//        y = i / (dim[1]*dim[0]);
//        xdim = 0;
//        ydim = 2;
//        break;
//      case 2:
//      default:
//        x = i % dim[0];
//        y = i / dim[0] %  dim[1];
//        z = i / (dim[1]*dim[0]);
//        xdim = 0;
//        ydim = 1;
//        break;
//    }

//    if ( ((z == 0) || (z == 2)) && (x >= pad[xdim]) && (x < ( (signed) dim[xdim]-pad[xdim])) && (y >= pad[ydim]) && (y < ( (signed) dim[ydim]-pad[ydim])) )
//    {
//      *p = 1;
//    }
//    else
//    {
//      *p = 0;
//    }
//  }

//  m_Interpolator->SetSegmentationVolume( m_Image );
//  std::cout << "  (II) SetSegmentationVolume works (slicedim " << slicedim << ")" << std::endl;

//  return true;
//}

///**
// * Checks if interpolation would create a square in slice 1
//*/
//bool mitkSegmentationInterpolationTestClass::TestInterpolation(int slicedim)
//{
//  int slice = 1;
//  mitk::Image::Pointer interpolated = m_Interpolator->Interpolate( slicedim, slice, 0 ); // interpolate second slice axial
//  if (interpolated.IsNull())
//  {
//    std::cerr << "  (EE) Interpolation did not return anything for slicedim == " << slicedim << " (although it should)." << std::endl;
//    return false;
//  }

//  int xdim,ydim;
//  switch (slicedim)
//  {
//    case 0:
//      xdim = 1;
//      ydim = 2; // different than above!
//      break;
//    case 1:
//      xdim = 0;
//      ydim = 2;
//      break;
//    case 2:
//    default:
//      xdim = 0;
//      ydim = 1;
//      break;
//  }

//  ipMITKSegmentationTYPE* p = (ipMITKSegmentationTYPE*)interpolated->GetData(); // pointer to pixel data

//  int size = dim[xdim]*dim[ydim];
//  if ( (signed) interpolated->GetDimension(0) * (signed) interpolated->GetDimension(1) != size )
//  {
//    std::cout << "  (EE) Size of interpolated image differs from original segmentation..." << std::endl;
//    return false;
//  }

//  for(int i=0; i<size; ++i, ++p)
//  {
//    int x,y;
//    x = i % dim[xdim];
//    y = i / dim[xdim];

//    //if (x == 0) std::cout << std::endl;

//    ipMITKSegmentationTYPE value = *p;

//    //if (value == 1) std::cout << "O"; else std::cout << ".";

//    if ( (x >= pad[xdim]) && (x < ((signed) dim[xdim]-pad[xdim])) && (y >= pad[ydim]) && (y < ((signed) dim[ydim]-pad[ydim])) && (value != 1) )
//    {
//      std::cout << "  (EE) Interpolation of a square figure failed" << std::endl;
//      std::cout << "  Value at " << x << " " << y << ": " << (int)value << std::endl;
//      return false;
//    }
//  }

//  std::cout << "  (II) Interpolation of a square figure works like expected (slicedim " << slicedim << ")" << std::endl;
//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::DeleteInterpolator()
//{
//  std::cout << "Object destruction" << std::endl;

//// freeing
//  m_Interpolator = NULL;

//  std::cout << "  (II) Freeing works." << std::endl;
//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::LoadTestImages(std::string filename1, std::string filename2)
//{
//  m_ManualSlices = LoadImage( filename1 );
//  m_InterpolatedSlices = LoadImage( filename2 );

//  return ( m_ManualSlices.IsNotNull() && m_InterpolatedSlices.IsNotNull() );
//}

//mitk::Image::Pointer mitkSegmentationInterpolationTestClass::LoadImage(const std::string& filename)
//{
//  mitk::Image::Pointer image = NULL;
//  mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
//  try
//  {
//    factory->SetFileName( filename );
//    factory->Update();

//    if(factory->GetNumberOfOutputs()<1)
//    {
//      std::cerr<<"File " << filename << " could not be loaded [FAILED]"<<std::endl;
//      return NULL;
//    }
//    mitk::DataNode::Pointer node = factory->GetOutput( 0 );
//    image = dynamic_cast<mitk::Image*>(node->GetData());
//    if(image.IsNull())
//    {
//      std::cout<<"File " << filename << " is not an image! [FAILED]"<<std::endl;
//      return NULL;
//    }
//  }
//  catch ( itk::ExceptionObject & ex )
//  {
//    std::cerr << "Exception: " << ex << "[FAILED]" << std::endl;
//    return NULL;
//  }

//  return image;
//}

//bool mitkSegmentationInterpolationTestClass::CompareInterpolationsToDefinedReference()
//{
//  std::cout << "  (II) Setting segmentation volume... " << std::flush;

//  m_Interpolator->SetSegmentationVolume( m_ManualSlices );

//  std::cout << "OK" << std::endl;

//  std::cout << "  (II) Testing interpolation result for slice " << std::flush;

//  for (unsigned int slice = 1; slice < 98; ++slice)
//  {
//    if (slice % 2 == 0) continue; // these were manually drawn, no interpolation possible

//    std::cout << slice << " " << std::flush;

//    mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( 2, slice, 0 );

//    if ( interpolation.IsNull() )
//    {
//      std::cerr << "  (EE) Interpolated image is NULL." << std::endl;
//      return false;
//    }

//    if ( !CompareImageSliceTestHelper::CompareSlice( m_InterpolatedSlices, 2, slice, interpolation ) )
//    {
//      std::cerr << "  (EE) interpolated image is not identical to reference in slice " << slice << std::endl;
//      return false;
//    }
//  }

//  std::cout << std::endl;
//  std::cout << "  (II) Interpolations are the same as the saved references." << std::endl;

//  return true;
//}

///// ctest entry point
//int mitkSegmentationInterpolationTest(int argc, char* argv[])
//{
//// one big variable to tell if anything went wrong
////  std::cout << "Creating CoreObjectFactory" << std::endl;
////  itk::ObjectFactoryBase::RegisterFactory(mitk::CoreObjectFactory::New());
//  if (argc < 3)
//  {
//    std::cerr << " (EE) Missing arguments for testing" << std::endl;
//  }
//  mitkSegmentationInterpolationTestClass test;
//  if ( test.Test(argv[1], argv[2]) )
//  {
//    std::cout << "[PASSED]" << std::endl;
//    return EXIT_SUCCESS;
//  }
//  else
//  {
//    std::cout << "[FAILED]" << std::endl;
//    return EXIT_FAILURE;
//  }
//}

<commit_msg>Manage to get desired slice<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

// Testing
#include <mitkTestingMacros.h>
#include <mitkTestFixture.h>

// other
#include <mitkExtractSliceFilter.h>
#include <mitkImage.h>
#include <mitkIOUtil.h>
#include <mitkSegmentationInterpolationController.h>

class mitkSegmentationInterpolationTestSuite : public mitk::TestFixture
{
  CPPUNIT_TEST_SUITE(mitkSegmentationInterpolationTestSuite);
  MITK_TEST(Equal_Axial_TestInterpolationAndReferenceInterpolation_ReturnsTrue);
  CPPUNIT_TEST_SUITE_END();

private:

  // Load data into these
  mitk::Image::Pointer m_ReferenceImage;
  mitk::Image::Pointer m_AxialBase;
  mitk::Surface::Pointer m_AxialFeedback;
  mitk::Image::Pointer m_AxialInterpolated;

  // Plane indices
  int m_AxialPlaneIndex;

  mitk::SegmentationInterpolationController::Pointer m_InterpolationController;

public:

  void setUp() override
  {
    m_AxialPlaneIndex = 22;

    m_ReferenceImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd"));
    CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [Pic3D.nrrd]", m_ReferenceImage.IsNotNull());
    m_AxialBase = mitk::IOUtil::LoadImage(GetTestDataFilePath("SegmentationInterpolation/AxialBase.nrrd"));
    CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialBase.nrrd]", m_AxialBase.IsNotNull());
    m_AxialFeedback = mitk::IOUtil::LoadSurface(GetTestDataFilePath("SegmentationInterpolation/AxialFeedback.vtp"));
    CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialFeedback.nrrd]", m_AxialFeedback.IsNotNull());
    m_AxialInterpolated = mitk::IOUtil::LoadImage(GetTestDataFilePath("SegmentationInterpolation/AxialInterpolated.nrrd"));
    CPPUNIT_ASSERT_MESSAGE("Failed to load image for test: [AxialInterpolated.nrrd]", m_AxialInterpolated.IsNotNull());

    m_InterpolationController = mitk::SegmentationInterpolationController::GetInstance();
    m_InterpolationController->SetReferenceVolume(m_ReferenceImage);
  }

  void tearDown() override
  {
    m_ReferenceImage = nullptr;
    m_AxialBase = nullptr;
    m_AxialFeedback = nullptr;
    m_AxialInterpolated = nullptr;
  }

  void Equal_Axial_TestInterpolationAndReferenceInterpolation_ReturnsTrue()
  {
    // Create Interpolation from base segmentation
    m_InterpolationController->SetSegmentationVolume(m_AxialBase);
    mitk::PlaneGeometry* plane = dynamic_cast<mitk::PlaneGeometry*>(m_ReferenceImage->GetSlicedGeometry()->GetPlaneGeometry(m_AxialPlaneIndex));
    mitk::Image::Pointer resultTestInterpolation = m_InterpolationController->Interpolate(0, m_AxialPlaneIndex, plane, 0);
    MITK_ASSERT_EQUAL(resultTestInterpolation, m_AxialInterpolated, "The created interpolation should fit the reference interpolation.");
  }

};

MITK_TEST_SUITE_REGISTRATION(mitkSegmentationInterpolation);

//#include "mitkSegmentationInterpolationController.h"
//#include "mitkCoreObjectFactory.h"
//#include "mitkStandardFileLocations.h"
////#include "mitkDataNodeFactory.h"
//#include "ipSegmentation.h"
//#include "mitkCompareImageSliceTestHelper.h"

//class mitkSegmentationInterpolationTestClass
//{
//  public:
//    mitkSegmentationInterpolationTestClass() {}
//    ~mitkSegmentationInterpolationTestClass() {}

//    bool Test(std::string filename1, std::string filename2)
//    {
//      return CreateNewInterpolator()
//          && CreateSegmentation()
//          && ClearSegmentation()
//          && CreateTwoSlices(2)
//          && TestInterpolation(2)
//          && ClearSegmentation()
//          && CreateTwoSlices(1)
//          && TestInterpolation(1)
//          && ClearSegmentation()
//          && CreateTwoSlices(0)
//          && TestInterpolation(0)
//          && DeleteInterpolator()
//          && CreateNewInterpolator()
//          && LoadTestImages(filename1, filename2)
//          && CompareInterpolationsToDefinedReference();
//    }

//  protected:

//    bool CreateNewInterpolator();
//    bool CreateSegmentation();
//    bool ClearSegmentation();
//    bool CreateTwoSlices(int);
//    bool TestInterpolation(int);
//    bool DeleteInterpolator();
//    bool LoadTestImages(std::string filename1, std::string filename2);
//    bool CompareInterpolationsToDefinedReference();

//    mitk::Image::Pointer LoadImage(const std::string& filename);

//    mitk::SegmentationInterpolationController::Pointer m_Interpolator;
//    mitk::Image::Pointer m_Image;

//    mitk::Image::Pointer m_ManualSlices;
//    mitk::Image::Pointer m_InterpolatedSlices;

//    unsigned int dim[3];
//    int pad[3];
//};

//bool mitkSegmentationInterpolationTestClass::CreateNewInterpolator()
//{
//  std::cout << "Instantiation" << std::endl;

//// instantiation
//  m_Interpolator = mitk::SegmentationInterpolationController::New();
//  if (m_Interpolator.IsNotNull())
//  {
//    std::cout << "  (II) Instantiation works." << std::endl;
//  }
//  else
//  {
//    std::cout << " Instantiation test failed!" << std::endl;
//    return false;
//  }

//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::CreateSegmentation()
//{
//  m_Image = mitk::Image::New();
//  dim[0]=15;
//  dim[1]=20;
//  dim[2]=25;
//  pad[0]=2;
//  pad[1]=3;
//  pad[2]=4;

//  m_Image->Initialize( mitk::MakeScalarPixelType<int>(), 3, dim);

//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::ClearSegmentation()
//{
//  int* p = (int*)m_Image->GetData(); // pointer to pixel data
//  int size = dim[0]*dim[1]*dim[2];
//  for(int i=0; i<size; ++i, ++p) *p=0; // fill image with zeros

//  return true;
//}

///**
// * Creates a square segmentation in slices 0 and 2.
//*/
//bool mitkSegmentationInterpolationTestClass::CreateTwoSlices(int slicedim)
//{
//  int* p = (int*)m_Image->GetData(); // pointer to pixel data

//  int size = dim[0]*dim[1]*dim[2];
//  for(int i=0; i<size; ++i, ++p)
//  {
//    int x,y,z;
//    int xdim,ydim;
//    switch (slicedim)
//    {
//      case 0:
//        z = i % dim[0];
//        y = i / dim[0] %  dim[1];
//        x = i / (dim[1]*dim[0]);
//        xdim = 2;
//        ydim = 1;
//        break;
//      case 1:
//        x = i % dim[0];
//        z = i / dim[0] %  dim[1];
//        y = i / (dim[1]*dim[0]);
//        xdim = 0;
//        ydim = 2;
//        break;
//      case 2:
//      default:
//        x = i % dim[0];
//        y = i / dim[0] %  dim[1];
//        z = i / (dim[1]*dim[0]);
//        xdim = 0;
//        ydim = 1;
//        break;
//    }

//    if ( ((z == 0) || (z == 2)) && (x >= pad[xdim]) && (x < ( (signed) dim[xdim]-pad[xdim])) && (y >= pad[ydim]) && (y < ( (signed) dim[ydim]-pad[ydim])) )
//    {
//      *p = 1;
//    }
//    else
//    {
//      *p = 0;
//    }
//  }

//  m_Interpolator->SetSegmentationVolume( m_Image );
//  std::cout << "  (II) SetSegmentationVolume works (slicedim " << slicedim << ")" << std::endl;

//  return true;
//}

///**
// * Checks if interpolation would create a square in slice 1
//*/
//bool mitkSegmentationInterpolationTestClass::TestInterpolation(int slicedim)
//{
//  int slice = 1;
//  mitk::Image::Pointer interpolated = m_Interpolator->Interpolate( slicedim, slice, 0 ); // interpolate second slice axial
//  if (interpolated.IsNull())
//  {
//    std::cerr << "  (EE) Interpolation did not return anything for slicedim == " << slicedim << " (although it should)." << std::endl;
//    return false;
//  }

//  int xdim,ydim;
//  switch (slicedim)
//  {
//    case 0:
//      xdim = 1;
//      ydim = 2; // different than above!
//      break;
//    case 1:
//      xdim = 0;
//      ydim = 2;
//      break;
//    case 2:
//    default:
//      xdim = 0;
//      ydim = 1;
//      break;
//  }

//  ipMITKSegmentationTYPE* p = (ipMITKSegmentationTYPE*)interpolated->GetData(); // pointer to pixel data

//  int size = dim[xdim]*dim[ydim];
//  if ( (signed) interpolated->GetDimension(0) * (signed) interpolated->GetDimension(1) != size )
//  {
//    std::cout << "  (EE) Size of interpolated image differs from original segmentation..." << std::endl;
//    return false;
//  }

//  for(int i=0; i<size; ++i, ++p)
//  {
//    int x,y;
//    x = i % dim[xdim];
//    y = i / dim[xdim];

//    //if (x == 0) std::cout << std::endl;

//    ipMITKSegmentationTYPE value = *p;

//    //if (value == 1) std::cout << "O"; else std::cout << ".";

//    if ( (x >= pad[xdim]) && (x < ((signed) dim[xdim]-pad[xdim])) && (y >= pad[ydim]) && (y < ((signed) dim[ydim]-pad[ydim])) && (value != 1) )
//    {
//      std::cout << "  (EE) Interpolation of a square figure failed" << std::endl;
//      std::cout << "  Value at " << x << " " << y << ": " << (int)value << std::endl;
//      return false;
//    }
//  }

//  std::cout << "  (II) Interpolation of a square figure works like expected (slicedim " << slicedim << ")" << std::endl;
//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::DeleteInterpolator()
//{
//  std::cout << "Object destruction" << std::endl;

//// freeing
//  m_Interpolator = NULL;

//  std::cout << "  (II) Freeing works." << std::endl;
//  return true;
//}

//bool mitkSegmentationInterpolationTestClass::LoadTestImages(std::string filename1, std::string filename2)
//{
//  m_ManualSlices = LoadImage( filename1 );
//  m_InterpolatedSlices = LoadImage( filename2 );

//  return ( m_ManualSlices.IsNotNull() && m_InterpolatedSlices.IsNotNull() );
//}

//mitk::Image::Pointer mitkSegmentationInterpolationTestClass::LoadImage(const std::string& filename)
//{
//  mitk::Image::Pointer image = NULL;
//  mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
//  try
//  {
//    factory->SetFileName( filename );
//    factory->Update();

//    if(factory->GetNumberOfOutputs()<1)
//    {
//      std::cerr<<"File " << filename << " could not be loaded [FAILED]"<<std::endl;
//      return NULL;
//    }
//    mitk::DataNode::Pointer node = factory->GetOutput( 0 );
//    image = dynamic_cast<mitk::Image*>(node->GetData());
//    if(image.IsNull())
//    {
//      std::cout<<"File " << filename << " is not an image! [FAILED]"<<std::endl;
//      return NULL;
//    }
//  }
//  catch ( itk::ExceptionObject & ex )
//  {
//    std::cerr << "Exception: " << ex << "[FAILED]" << std::endl;
//    return NULL;
//  }

//  return image;
//}

//bool mitkSegmentationInterpolationTestClass::CompareInterpolationsToDefinedReference()
//{
//  std::cout << "  (II) Setting segmentation volume... " << std::flush;

//  m_Interpolator->SetSegmentationVolume( m_ManualSlices );

//  std::cout << "OK" << std::endl;

//  std::cout << "  (II) Testing interpolation result for slice " << std::flush;

//  for (unsigned int slice = 1; slice < 98; ++slice)
//  {
//    if (slice % 2 == 0) continue; // these were manually drawn, no interpolation possible

//    std::cout << slice << " " << std::flush;

//    mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( 2, slice, 0 );

//    if ( interpolation.IsNull() )
//    {
//      std::cerr << "  (EE) Interpolated image is NULL." << std::endl;
//      return false;
//    }

//    if ( !CompareImageSliceTestHelper::CompareSlice( m_InterpolatedSlices, 2, slice, interpolation ) )
//    {
//      std::cerr << "  (EE) interpolated image is not identical to reference in slice " << slice << std::endl;
//      return false;
//    }
//  }

//  std::cout << std::endl;
//  std::cout << "  (II) Interpolations are the same as the saved references." << std::endl;

//  return true;
//}

///// ctest entry point
//int mitkSegmentationInterpolationTest(int argc, char* argv[])
//{
//// one big variable to tell if anything went wrong
////  std::cout << "Creating CoreObjectFactory" << std::endl;
////  itk::ObjectFactoryBase::RegisterFactory(mitk::CoreObjectFactory::New());
//  if (argc < 3)
//  {
//    std::cerr << " (EE) Missing arguments for testing" << std::endl;
//  }
//  mitkSegmentationInterpolationTestClass test;
//  if ( test.Test(argv[1], argv[2]) )
//  {
//    std::cout << "[PASSED]" << std::endl;
//    return EXIT_SUCCESS;
//  }
//  else
//  {
//    std::cout << "[FAILED]" << std::endl;
//    return EXIT_FAILURE;
//  }
//}

<|endoftext|>


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

rima_solver_tools.cpp

Copyright (c) 2009-2011 Incremental IP Limited
see LICENSE for license information

*******************************************************************************/

#include "rima_solver_tools.h"
extern "C"
{
#include "lauxlib.h"
}
#include <vector>

/*============================================================================*/

int error(lua_State *L, const char *s)
{
  lua_settop(L, 0);
  lua_pushnil(L);
  lua_pushstring(L, s);
  return 2;
}

/*============================================================================*/

const char *check_constraints(lua_State *L, unsigned constraint_count, unsigned column_count, unsigned &max_non_zeroes)
{
  for (unsigned i = 0; i != constraint_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The elements of the constraints table must be tables of constraints";

    lua_pushstring(L, "lower");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The lower bound on a constraint (lower) must be a number";
    lua_pop(L, 1);

    lua_pushstring(L, "upper");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The upper bound on a constraint (upper) must be a number";
    lua_pop(L, 1);

    lua_pushstring(L, "elements");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The constraint elements array must be a table";

    unsigned nz = lua_objlen(L, -1);
    for (unsigned j = 0; j != nz; ++j)
    {
      lua_rawgeti(L, -1, j+1);
      if (lua_type(L, -1) != LUA_TTABLE)
        return "The elements of a table of non-zeroes must be a table";
      lua_pushstring(L, "index");
      lua_rawget(L, -2);
      lua_pushstring(L, "coeff");
      lua_rawget(L, -3);
      if (lua_type(L, -1) != LUA_TNUMBER || lua_type(L, -2) != LUA_TNUMBER)
        return "The elements of a table of non-zeroes must be a table with index and coeff fields";
      unsigned column = lua_tointeger(L, -2) - 1;
      if (column > column_count)
        return "An index in the column vector exceeded the number of columns";
      lua_pop(L, 3);
    }
    if (nz > max_non_zeroes)
      max_non_zeroes = nz;
    lua_pop(L, 2);
  }
  return 0;
}

const char *build_constraints(lua_State *L, unsigned max_non_zeroes, unsigned constraint_count, int column_offset, constraint_builder_function *bf, void *bfd)
{
  std::vector<int> columns(max_non_zeroes);
  std::vector<double> coefficients(max_non_zeroes);

  for (unsigned i = 0; i != constraint_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);

    lua_pushstring(L, "lower");
    lua_rawget(L, -2);
    double lower = lua_tonumber(L, -1);
    lua_pop(L, 1);

    lua_pushstring(L, "upper");
    lua_rawget(L, -2);
    double upper = lua_tonumber(L, -1);
    lua_pop(L, 1);

    lua_pushstring(L, "elements");
    lua_rawget(L, -2);

    unsigned nz = lua_objlen(L, -1);
    for (unsigned j = 0; j != nz; ++j)
    {
      lua_rawgeti(L, -1, j+1);
      lua_pushstring(L, "index");
      lua_rawget(L, -2);
      lua_pushstring(L, "coeff");
      lua_rawget(L, -3);
      unsigned column = lua_tointeger(L, -2) + column_offset;
      double coefficient = lua_tonumber(L, -1);
      columns[j] = column;
      coefficients[j] = coefficient;
      lua_pop(L, 3);
    }

    const char *err = bf(bfd, nz, &columns[0], &coefficients[0], lower, upper);
    if (err) return err;

    lua_pop(L, 2);
  }
  return 0;
}

/*============================================================================*/

const char *check_variables(lua_State *L, unsigned variable_count)
{
  for (unsigned i = 0; i != variable_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The elements of the constraints table must be tables of constraints";

    lua_pushstring(L, "type");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The constraint description must contain a table named type";
    {
      lua_pushstring(L, "lower");
      lua_rawget(L, -2);
      if (lua_type(L, -1) != LUA_TNUMBER)
        return "The lower bound on a variable (type.lower) must be a number";
      lua_pop(L, 1);

      lua_pushstring(L, "upper");
      lua_rawget(L, -2);
      if (lua_type(L, -1) != LUA_TNUMBER)
        return "The upper bound on a variable (type.upper) must be a number";
      lua_pop(L, 1);

      lua_pushstring(L, "integer");
      lua_rawget(L, -2);
      if (!lua_isboolean(L, -1) && !lua_isnil(L, -1))
        return "The integer flag for a variable (type.integer) must be true, false or nil";
      lua_pop(L, 1);
    }
    lua_pop(L, 1);

    lua_pushstring(L, "cost");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The cost of a variable (cost) must be a number";
    lua_pop(L, 1);

    lua_pop(L, 1);
  }
  return 0;
}

const char *build_variables(lua_State *L, unsigned variable_count, variable_builder_function *bf, void *bfd)
{
  for (unsigned i = 0; i != variable_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);

    double lower, upper;
    bool integer;

    lua_pushstring(L, "type");
    lua_rawget(L, -2);
    {
      lua_pushstring(L, "lower");
      lua_rawget(L, -2);
      lower = lua_tonumber(L, -1);
      lua_pop(L, 1);

      lua_pushstring(L, "upper");
      lua_rawget(L, -2);
      upper = lua_tonumber(L, -1);
      lua_pop(L, 1);

      lua_pushstring(L, "integer");
      lua_rawget(L, -2);
      integer = lua_toboolean(L, -1);
      lua_pop(L, 1);
    }
    lua_pop(L, 1);

    lua_pushstring(L, "cost");
    lua_rawget(L, -2);
    double cost = lua_tonumber(L, -1);
    lua_pop(L, 1);

    const char *err = bf(bfd, i, cost, lower, upper, integer);
    if (err) return err;

    lua_pop(L, 1);
  }
  return 0;
}

/*============================================================================*/

<commit_msg>fixed a typo in rima_solver_tools.cpp<commit_after>/*******************************************************************************

rima_solver_tools.cpp

Copyright (c) 2009-2011 Incremental IP Limited
see LICENSE for license information

*******************************************************************************/

#include "rima_solver_tools.h"
extern "C"
{
#include "lauxlib.h"
}
#include <vector>

/*============================================================================*/

int error(lua_State *L, const char *s)
{
  lua_settop(L, 0);
  lua_pushnil(L);
  lua_pushstring(L, s);
  return 2;
}

/*============================================================================*/

const char *check_constraints(lua_State *L, unsigned constraint_count, unsigned column_count, unsigned &max_non_zeroes)
{
  for (unsigned i = 0; i != constraint_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The elements of the constraints table must be tables of constraints";

    lua_pushstring(L, "lower");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The lower bound on a constraint (lower) must be a number";
    lua_pop(L, 1);

    lua_pushstring(L, "upper");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The upper bound on a constraint (upper) must be a number";
    lua_pop(L, 1);

    lua_pushstring(L, "elements");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The constraint elements array must be a table";

    unsigned nz = lua_objlen(L, -1);
    for (unsigned j = 0; j != nz; ++j)
    {
      lua_rawgeti(L, -1, j+1);
      if (lua_type(L, -1) != LUA_TTABLE)
        return "The elements of a table of non-zeroes must be a table";
      lua_pushstring(L, "index");
      lua_rawget(L, -2);
      lua_pushstring(L, "coeff");
      lua_rawget(L, -3);
      if (lua_type(L, -1) != LUA_TNUMBER || lua_type(L, -2) != LUA_TNUMBER)
        return "The elements of a table of non-zeroes must be a table with index and coeff fields";
      unsigned column = lua_tointeger(L, -2) - 1;
      if (column > column_count)
        return "An index in the column vector exceeded the number of columns";
      lua_pop(L, 3);
    }
    if (nz > max_non_zeroes)
      max_non_zeroes = nz;
    lua_pop(L, 2);
  }
  return 0;
}

const char *build_constraints(lua_State *L, unsigned max_non_zeroes, unsigned constraint_count, int column_offset, constraint_builder_function *bf, void *bfd)
{
  std::vector<int> columns(max_non_zeroes);
  std::vector<double> coefficients(max_non_zeroes);

  for (unsigned i = 0; i != constraint_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);

    lua_pushstring(L, "lower");
    lua_rawget(L, -2);
    double lower = lua_tonumber(L, -1);
    lua_pop(L, 1);

    lua_pushstring(L, "upper");
    lua_rawget(L, -2);
    double upper = lua_tonumber(L, -1);
    lua_pop(L, 1);

    lua_pushstring(L, "elements");
    lua_rawget(L, -2);

    unsigned nz = lua_objlen(L, -1);
    for (unsigned j = 0; j != nz; ++j)
    {
      lua_rawgeti(L, -1, j+1);
      lua_pushstring(L, "index");
      lua_rawget(L, -2);
      lua_pushstring(L, "coeff");
      lua_rawget(L, -3);
      unsigned column = lua_tointeger(L, -2) + column_offset;
      double coefficient = lua_tonumber(L, -1);
      columns[j] = column;
      coefficients[j] = coefficient;
      lua_pop(L, 3);
    }

    const char *err = bf(bfd, nz, &columns[0], &coefficients[0], lower, upper);
    if (err) return err;

    lua_pop(L, 2);
  }
  return 0;
}

/*============================================================================*/

const char *check_variables(lua_State *L, unsigned variable_count)
{
  for (unsigned i = 0; i != variable_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The elements of the variables table must be tables of variables";

    lua_pushstring(L, "type");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TTABLE)
      return "The variable description must contain a table named type";
    {
      lua_pushstring(L, "lower");
      lua_rawget(L, -2);
      if (lua_type(L, -1) != LUA_TNUMBER)
        return "The lower bound on a variable (type.lower) must be a number";
      lua_pop(L, 1);

      lua_pushstring(L, "upper");
      lua_rawget(L, -2);
      if (lua_type(L, -1) != LUA_TNUMBER)
        return "The upper bound on a variable (type.upper) must be a number";
      lua_pop(L, 1);

      lua_pushstring(L, "integer");
      lua_rawget(L, -2);
      if (!lua_isboolean(L, -1) && !lua_isnil(L, -1))
        return "The integer flag for a variable (type.integer) must be true, false or nil";
      lua_pop(L, 1);
    }
    lua_pop(L, 1);

    lua_pushstring(L, "cost");
    lua_rawget(L, -2);
    if (lua_type(L, -1) != LUA_TNUMBER)
      return "The cost of a variable (cost) must be a number";
    lua_pop(L, 1);

    lua_pop(L, 1);
  }
  return 0;
}

const char *build_variables(lua_State *L, unsigned variable_count, variable_builder_function *bf, void *bfd)
{
  for (unsigned i = 0; i != variable_count; ++i)
  {
    lua_rawgeti(L, 2, i+1);

    double lower, upper;
    bool integer;

    lua_pushstring(L, "type");
    lua_rawget(L, -2);
    {
      lua_pushstring(L, "lower");
      lua_rawget(L, -2);
      lower = lua_tonumber(L, -1);
      lua_pop(L, 1);

      lua_pushstring(L, "upper");
      lua_rawget(L, -2);
      upper = lua_tonumber(L, -1);
      lua_pop(L, 1);

      lua_pushstring(L, "integer");
      lua_rawget(L, -2);
      integer = lua_toboolean(L, -1);
      lua_pop(L, 1);
    }
    lua_pop(L, 1);

    lua_pushstring(L, "cost");
    lua_rawget(L, -2);
    double cost = lua_tonumber(L, -1);
    lua_pop(L, 1);

    const char *err = bf(bfd, i, cost, lower, upper, integer);
    if (err) return err;

    lua_pop(L, 1);
  }
  return 0;
}

/*============================================================================*/

<|endoftext|>


<commit_before>/*
    crlview.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2001,2002,2004 Klarlvdalens Datakonsult AB

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

    Kleopatra 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
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qlayout.h>
#include <qlabel.h>
#include <qtextview.h>

#include <klocale.h>
#include <kprocess.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>

#include "crlview.h"
#include "crlview.moc"

CRLView::CRLView( QWidget* parent, const char* name, bool modal )
  : QDialog( parent, name, modal ), _process(0)
{
  QVBoxLayout* topLayout = new QVBoxLayout( this, 10, 4 );

  topLayout->addWidget( new QLabel( i18n("CRL cache dump:"), this ) );

  _textView = new QTextView( this );
  _textView->setWordWrap( QTextEdit::NoWrap );
  topLayout->addWidget( _textView );

  QHBoxLayout* hbLayout = new QHBoxLayout( topLayout );

  _updateButton = new KPushButton( i18n("&Update"), this );
  _closeButton = new KPushButton( KStdGuiItem::close(), this );

  hbLayout->addWidget( _updateButton );
  hbLayout->addStretch();
  hbLayout->addWidget( _closeButton );

  // connections:
  connect( _updateButton, SIGNAL( clicked() ),
	   this, SLOT( slotUpdateView() ) );
  connect( _closeButton, SIGNAL( clicked() ),
	   this, SLOT( close() ) );
}

CRLView::~CRLView()
{
  delete _process;
}

void CRLView::slotUpdateView()
{
  _updateButton->setEnabled( false );
  _textView->clear();
  if( _process == 0 ) {
    _process = new KProcess();
    *_process << "gpgsm" << "--call-dirmngr" << "listcrls";
    connect( _process, SIGNAL( receivedStdout( KProcess*, char*, int) ),
	     this, SLOT( slotReadStdout( KProcess*, char*, int ) ) );
    connect( _process, SIGNAL( processExited( KProcess* ) ),
	     this, SLOT( slotProcessExited() ) );
  }
  if( _process->isRunning() ) _process->kill();
  if( !_process->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) {
    KMessageBox::error( this, i18n( "Unable to start gpgsm process. Please check your installation." ), i18n( "Certificate Manager Error" ) );
    slotProcessExited();
  }
}

void CRLView::slotReadStdout( KProcess*, char* buf, int len)
{
  _textView->append( QString::fromUtf8( buf, len ) );
}

void CRLView::slotProcessExited()
{
  _updateButton->setEnabled( true );

  if( !_process->normalExit() ) {
    KMessageBox::error( this, i18n( "The GpgSM process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
  }
}
<commit_msg>Make the window larger (approx. 80x25 chars).<commit_after>/*
    crlview.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2001,2002,2004 Klarlvdalens Datakonsult AB

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

    Kleopatra 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
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "crlview.h"

#include <klocale.h>
#include <kprocess.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>

#include <qlayout.h>
#include <qlabel.h>
#include <qtextview.h>
#include <qfontmetrics.h>

CRLView::CRLView( QWidget* parent, const char* name, bool modal )
  : QDialog( parent, name, modal ), _process(0)
{
  QVBoxLayout* topLayout = new QVBoxLayout( this, 10, 4 );

  topLayout->addWidget( new QLabel( i18n("CRL cache dump:"), this ) );

  _textView = new QTextView( this );
  _textView->setWordWrap( QTextEdit::NoWrap );
  topLayout->addWidget( _textView );

  QHBoxLayout* hbLayout = new QHBoxLayout( topLayout );

  _updateButton = new KPushButton( i18n("&Update"), this );
  _closeButton = new KPushButton( KStdGuiItem::close(), this );

  hbLayout->addWidget( _updateButton );
  hbLayout->addStretch();
  hbLayout->addWidget( _closeButton );

  // connections:
  connect( _updateButton, SIGNAL( clicked() ),
	   this, SLOT( slotUpdateView() ) );
  connect( _closeButton, SIGNAL( clicked() ),
	   this, SLOT( close() ) );

  resize( _textView->fontMetrics().width( 'M' ) * 80,
	  _textView->fontMetrics().lineSpacing() * 25 );
}

CRLView::~CRLView()
{
  delete _process;
}

void CRLView::slotUpdateView()
{
  _updateButton->setEnabled( false );
  _textView->clear();
  if( _process == 0 ) {
    _process = new KProcess();
    *_process << "gpgsm" << "--call-dirmngr" << "listcrls";
    connect( _process, SIGNAL( receivedStdout( KProcess*, char*, int) ),
	     this, SLOT( slotReadStdout( KProcess*, char*, int ) ) );
    connect( _process, SIGNAL( processExited( KProcess* ) ),
	     this, SLOT( slotProcessExited() ) );
  }
  if( _process->isRunning() ) _process->kill();
  if( !_process->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) {
    KMessageBox::error( this, i18n( "Unable to start gpgsm process. Please check your installation." ), i18n( "Certificate Manager Error" ) );
    slotProcessExited();
  }
}

void CRLView::slotReadStdout( KProcess*, char* buf, int len)
{
  _textView->append( QString::fromUtf8( buf, len ) );
}

void CRLView::slotProcessExited()
{
  _updateButton->setEnabled( true );

  if( !_process->normalExit() ) {
    KMessageBox::error( this, i18n( "The GpgSM process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
  }
}

#include "crlview.moc"
<|endoftext|>