<commit_before>//
// WinAPI
//
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <SetupAPI.h>
#include <Shlwapi.h>
#include <initguid.h>
#include <winioctl.h>
#include "XUSB.h"

//
// STL
//
#include <string>
#include <codecvt>
#include <locale>
#include <map>
#include <iostream>
#include <fstream>

//
// JSON
//
#include <json/json.h>

//
// Hooking
//
#include <detours/detours.h>

//
// Logging
//
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/fmt/bin_to_hex.h>

using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;
std::once_flag g_init;
std::string g_dllDir;

static decltype(SetupDiEnumDeviceInterfaces) *real_SetupDiEnumDeviceInterfaces = SetupDiEnumDeviceInterfaces;
static decltype(DeviceIoControl) *real_DeviceIoControl = DeviceIoControl;
static decltype(CreateFileA) *real_CreateFileA = CreateFileA;
static decltype(CreateFileW) *real_CreateFileW = CreateFileW;
static decltype(WriteFile)* real_WriteFile = WriteFile;

static std::map<HANDLE, std::string> g_handleToPath;
static std::map<DWORD, std::string> g_ioctlMap;

//
// Hooks SetupDiEnumDeviceInterfaces() API
//
BOOL WINAPI DetourSetupDiEnumDeviceInterfaces(
	HDEVINFO DeviceInfoSet,
	PSP_DEVINFO_DATA DeviceInfoData,
	const GUID* InterfaceClassGuid,
	DWORD MemberIndex,
	PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("SetupDiEnumDeviceInterfaces");

	auto retval = real_SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex,
	                                               DeviceInterfaceData);

	_logger->info("InterfaceClassGuid = {{{0:X}-{1:X}-{2:X}-{3:X}{4:X}-{5:X}{6:X}{7:X}{8:X}{9:X}{10:X}}}, "
	              "return = 0x{11:X}, error = 0x{12:X}",
	              InterfaceClassGuid->Data1, InterfaceClassGuid->Data2, InterfaceClassGuid->Data3,
	              InterfaceClassGuid->Data4[0], InterfaceClassGuid->Data4[1], InterfaceClassGuid->Data4[2],
	              InterfaceClassGuid->Data4[3],
	              InterfaceClassGuid->Data4[4], InterfaceClassGuid->Data4[5], InterfaceClassGuid->Data4[6],
	              InterfaceClassGuid->Data4[7],
	              retval, GetLastError());

	return retval;
}

//
// Hooks CreateFileA() API
//
HANDLE WINAPI DetourCreateFileA(
	LPCSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("CreateFileA");
	std::string path(lpFileName);

	const bool isOfInterest = (path.rfind("\\\\", 0) == 0);

	if (isOfInterest)
		_logger->info("lpFileName = {}", path);

	const auto handle = real_CreateFileA(
		lpFileName,
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
	);

	if (handle != INVALID_HANDLE_VALUE)
	{
		g_handleToPath[handle] = path;
		if (isOfInterest)
			_logger->info("handle = {}, lpFileName = {}", handle, path);
	}

	return handle;
}

//
// Hooks CreateFileW() API
//
HANDLE WINAPI DetourCreateFileW(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("CreateFileW");
	std::string path(strconverter.to_bytes(lpFileName));

	const bool isOfInterest = (path.rfind("\\\\", 0) == 0);

	if (isOfInterest)
		_logger->info("lpFileName = {}", path);

	const auto handle = real_CreateFileW(
		lpFileName,
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
	);

	if (handle != INVALID_HANDLE_VALUE)
	{
		g_handleToPath[handle] = path;
		if (isOfInterest)
			_logger->info("handle = {}, lpFileName = {}", handle, path);
	}

	return handle;
}

//
// Hooks WriteFile() API
//
BOOL WINAPI DetourWriteFile(
	HANDLE       hFile,
	LPCVOID      lpBuffer,
	DWORD        nNumberOfBytesToWrite,
	LPDWORD      lpNumberOfBytesWritten,
	LPOVERLAPPED lpOverlapped
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("WriteFile");

	const PUCHAR charInBuf = PUCHAR(lpBuffer);
	const std::vector<char> inBuffer(charInBuf, charInBuf + nNumberOfBytesToWrite);

	const auto ret =  real_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
	const auto error = GetLastError();

	_logger->info("[I] ret={}, lastError={} ({:04d}) -> {:Xpn}",
		ret,
		error,
		nNumberOfBytesToWrite,
		spdlog::to_hex(inBuffer)
	);
}

//
// Hooks DeviceIoControl() API
//
BOOL WINAPI DetourDeviceIoControl(
	HANDLE hDevice,
	DWORD dwIoControlCode,
	LPVOID lpInBuffer,
	DWORD nInBufferSize,
	LPVOID lpOutBuffer,
	DWORD nOutBufferSize,
	LPDWORD lpBytesReturned,
	LPOVERLAPPED lpOverlapped
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("DeviceIoControl");

	const PUCHAR charInBuf = static_cast<PUCHAR>(lpInBuffer);
	const std::vector<char> inBuffer(charInBuf, charInBuf + nInBufferSize);

	if (g_ioctlMap.count(dwIoControlCode))
	{
		_logger->info("[I] [{}] ({:04d}) -> {:Xpn}",
		              g_ioctlMap[dwIoControlCode],
		              nInBufferSize,
		              spdlog::to_hex(inBuffer)
		);
	}

	DWORD tmpBytesReturned;

	const auto retval = real_DeviceIoControl(
		hDevice,
		dwIoControlCode,
		lpInBuffer,
		nInBufferSize,
		lpOutBuffer,
		nOutBufferSize,
		&tmpBytesReturned, // might be null, use our own variable
		lpOverlapped
	);

	if (lpBytesReturned)
		*lpBytesReturned = tmpBytesReturned;

	if (lpOutBuffer && nOutBufferSize > 0)
	{
		const PUCHAR charOutBuf = static_cast<PUCHAR>(lpOutBuffer);
		const auto bufSize = std::min(nOutBufferSize, tmpBytesReturned);
		const std::vector<char> outBuffer(charOutBuf, charOutBuf + bufSize);

		if (g_ioctlMap.count(dwIoControlCode))
		{
			_logger->info("[O] [{}] ({:04d}) -> {:Xpn}",
			              g_ioctlMap[dwIoControlCode],
			              bufSize,
			              spdlog::to_hex(outBuffer)
			);
		}
	}

	return retval;
}

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

BOOL WINAPI DllMain(HINSTANCE dll_handle, DWORD reason, LPVOID reserved)
{
	if (DetourIsHelperProcess())
	{
		return TRUE;
	}

	switch (reason)
	{
	case DLL_PROCESS_ATTACH:
		{
			CHAR dllPath[MAX_PATH];

			GetModuleFileNameA((HINSTANCE)&__ImageBase, dllPath, MAX_PATH);
			PathRemoveFileSpecA(dllPath);
			g_dllDir = std::string(dllPath);

			auto logger = spdlog::basic_logger_mt(
				"XInputHooker",
				g_dllDir + "\\XInputHooker.log"
			);

#if _DEBUG
			spdlog::set_level(spdlog::level::debug);
			logger->flush_on(spdlog::level::debug);
#else
		logger->flush_on(spdlog::level::info);
#endif

			set_default_logger(logger);

			//
			// Load known IOCTL code definitions
			//
			Json::Value root;
			std::ifstream ifs(g_dllDir + "\\ioctls.json");
			ifs >> root;

			for (auto& i : root)
			{
				g_ioctlMap[std::stoul(i["HexValue"].asString(), nullptr, 16)] = i["Ioctl"].asString();
			}
		}

		DisableThreadLibraryCalls(dll_handle);
		DetourRestoreAfterWith();

		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&static_cast<PVOID>(real_SetupDiEnumDeviceInterfaces), DetourSetupDiEnumDeviceInterfaces);
		DetourAttach(&static_cast<PVOID>(real_DeviceIoControl), DetourDeviceIoControl);
		DetourAttach(&static_cast<PVOID>(real_CreateFileA), DetourCreateFileA);
		DetourAttach(&static_cast<PVOID>(real_CreateFileW), DetourCreateFileW);
		DetourAttach(&static_cast<PVOID>(real_WriteFile), DetourWriteFile);
		DetourTransactionCommit();

		break;

	case DLL_PROCESS_DETACH:
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&static_cast<PVOID>(real_SetupDiEnumDeviceInterfaces), DetourSetupDiEnumDeviceInterfaces);
		DetourDetach(&static_cast<PVOID>(real_DeviceIoControl), DetourDeviceIoControl);
		DetourDetach(&static_cast<PVOID>(real_CreateFileA), DetourCreateFileA);
		DetourDetach(&static_cast<PVOID>(real_CreateFileW), DetourCreateFileW);
		DetourDetach(&static_cast<PVOID>(real_WriteFile), DetourWriteFile);
		DetourTransactionCommit();
		break;
	}
	return TRUE;
}
<commit_msg>Added DetourWriteFile and DetourGetOverlappedResult<commit_after>//
// WinAPI
//
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <SetupAPI.h>
#include <Shlwapi.h>
#include <initguid.h>
#include <winioctl.h>
#include "XUSB.h"

//
// STL
//
#include <string>
#include <codecvt>
#include <locale>
#include <map>
#include <iostream>
#include <fstream>

//
// JSON
//
#include <json/json.h>

//
// Hooking
//
#include <detours/detours.h>

//
// Logging
//
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/fmt/bin_to_hex.h>

using convert_t = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_t, wchar_t> strconverter;
std::once_flag g_init;
std::string g_dllDir;

static decltype(SetupDiEnumDeviceInterfaces) *real_SetupDiEnumDeviceInterfaces = SetupDiEnumDeviceInterfaces;
static decltype(DeviceIoControl) *real_DeviceIoControl = DeviceIoControl;
static decltype(CreateFileA) *real_CreateFileA = CreateFileA;
static decltype(CreateFileW) *real_CreateFileW = CreateFileW;
static decltype(WriteFile)* real_WriteFile = WriteFile;
static decltype(GetOverlappedResult)* real_GetOverlappedResult = GetOverlappedResult;

static std::map<HANDLE, std::string> g_handleToPath;
static std::map<DWORD, std::string> g_ioctlMap;

//
// Hooks SetupDiEnumDeviceInterfaces() API
//
BOOL WINAPI DetourSetupDiEnumDeviceInterfaces(
	HDEVINFO DeviceInfoSet,
	PSP_DEVINFO_DATA DeviceInfoData,
	const GUID* InterfaceClassGuid,
	DWORD MemberIndex,
	PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("SetupDiEnumDeviceInterfaces");

	auto retval = real_SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex,
	                                               DeviceInterfaceData);

	_logger->info("InterfaceClassGuid = {{{0:X}-{1:X}-{2:X}-{3:X}{4:X}-{5:X}{6:X}{7:X}{8:X}{9:X}{10:X}}}, "
	              "return = 0x{11:X}, error = 0x{12:X}",
	              InterfaceClassGuid->Data1, InterfaceClassGuid->Data2, InterfaceClassGuid->Data3,
	              InterfaceClassGuid->Data4[0], InterfaceClassGuid->Data4[1], InterfaceClassGuid->Data4[2],
	              InterfaceClassGuid->Data4[3],
	              InterfaceClassGuid->Data4[4], InterfaceClassGuid->Data4[5], InterfaceClassGuid->Data4[6],
	              InterfaceClassGuid->Data4[7],
	              retval, GetLastError());

	return retval;
}

//
// Hooks CreateFileA() API
//
HANDLE WINAPI DetourCreateFileA(
	LPCSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("CreateFileA");
	std::string path(lpFileName);

	const bool isOfInterest = (path.rfind("\\\\", 0) == 0);

	if (isOfInterest)
		_logger->info("lpFileName = {}", path);

	const auto handle = real_CreateFileA(
		lpFileName,
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
	);

	if (handle != INVALID_HANDLE_VALUE)
	{
		g_handleToPath[handle] = path;
		if (isOfInterest)
			_logger->info("handle = {}, lpFileName = {}", handle, path);
	}

	return handle;
}

//
// Hooks CreateFileW() API
//
HANDLE WINAPI DetourCreateFileW(
	LPCWSTR lpFileName,
	DWORD dwDesiredAccess,
	DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes,
	HANDLE hTemplateFile
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("CreateFileW");
	std::string path(strconverter.to_bytes(lpFileName));

	const bool isOfInterest = (path.rfind("\\\\", 0) == 0);

	if (isOfInterest)
		_logger->info("lpFileName = {}", path);

	const auto handle = real_CreateFileW(
		lpFileName,
		dwDesiredAccess,
		dwShareMode,
		lpSecurityAttributes,
		dwCreationDisposition,
		dwFlagsAndAttributes,
		hTemplateFile
	);

	if (handle != INVALID_HANDLE_VALUE)
	{
		g_handleToPath[handle] = path;
		if (isOfInterest)
			_logger->info("handle = {}, lpFileName = {}", handle, path);
	}

	return handle;
}

//
// Hooks WriteFile() API
//
BOOL WINAPI DetourWriteFile(
	HANDLE       hFile,
	LPCVOID      lpBuffer,
	DWORD        nNumberOfBytesToWrite,
	LPDWORD      lpNumberOfBytesWritten,
	LPOVERLAPPED lpOverlapped
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("WriteFile");

	const PUCHAR charInBuf = PUCHAR(lpBuffer);
	const std::vector<char> inBuffer(charInBuf, charInBuf + nNumberOfBytesToWrite);

	const auto ret =  real_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
	const auto error = GetLastError();

	_logger->info("ret={}, lastError={} ({:04d}) -> {:Xpn}",
		ret,
		error,
		nNumberOfBytesToWrite,
		spdlog::to_hex(inBuffer)
	);

	return ret;
}

BOOL WINAPI DetourGetOverlappedResult(
	HANDLE       hFile,
	LPOVERLAPPED lpOverlapped,
	LPDWORD      lpNumberOfBytesTransferred,
	BOOL         bWait
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("GetOverlappedResult");

	const auto ret = real_GetOverlappedResult(hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait);
	const auto error = GetLastError();

	_logger->info("ret={}, lastError={}, bytesWritten={}",
		ret,
		error,
		(lpNumberOfBytesTransferred) ? *lpNumberOfBytesTransferred : 0
	);

	return ret;
}

//
// Hooks DeviceIoControl() API
//
BOOL WINAPI DetourDeviceIoControl(
	HANDLE hDevice,
	DWORD dwIoControlCode,
	LPVOID lpInBuffer,
	DWORD nInBufferSize,
	LPVOID lpOutBuffer,
	DWORD nOutBufferSize,
	LPDWORD lpBytesReturned,
	LPOVERLAPPED lpOverlapped
)
{
	std::shared_ptr<spdlog::logger> _logger = spdlog::get("XInputHooker")->clone("DeviceIoControl");

	const PUCHAR charInBuf = static_cast<PUCHAR>(lpInBuffer);
	const std::vector<char> inBuffer(charInBuf, charInBuf + nInBufferSize);

	if (g_ioctlMap.count(dwIoControlCode))
	{
		_logger->info("[I] [{}] ({:04d}) -> {:Xpn}",
		              g_ioctlMap[dwIoControlCode],
		              nInBufferSize,
		              spdlog::to_hex(inBuffer)
		);
	}

	DWORD tmpBytesReturned;

	const auto retval = real_DeviceIoControl(
		hDevice,
		dwIoControlCode,
		lpInBuffer,
		nInBufferSize,
		lpOutBuffer,
		nOutBufferSize,
		&tmpBytesReturned, // might be null, use our own variable
		lpOverlapped
	);

	if (lpBytesReturned)
		*lpBytesReturned = tmpBytesReturned;

	if (lpOutBuffer && nOutBufferSize > 0)
	{
		const PUCHAR charOutBuf = static_cast<PUCHAR>(lpOutBuffer);
		const auto bufSize = std::min(nOutBufferSize, tmpBytesReturned);
		const std::vector<char> outBuffer(charOutBuf, charOutBuf + bufSize);

		if (g_ioctlMap.count(dwIoControlCode))
		{
			_logger->info("[O] [{}] ({:04d}) -> {:Xpn}",
			              g_ioctlMap[dwIoControlCode],
			              bufSize,
			              spdlog::to_hex(outBuffer)
			);
		}
	}

	return retval;
}

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

BOOL WINAPI DllMain(HINSTANCE dll_handle, DWORD reason, LPVOID reserved)
{
	if (DetourIsHelperProcess())
	{
		return TRUE;
	}

	switch (reason)
	{
	case DLL_PROCESS_ATTACH:
		{
			CHAR dllPath[MAX_PATH];

			GetModuleFileNameA((HINSTANCE)&__ImageBase, dllPath, MAX_PATH);
			PathRemoveFileSpecA(dllPath);
			g_dllDir = std::string(dllPath);

			auto logger = spdlog::basic_logger_mt(
				"XInputHooker",
				g_dllDir + "\\XInputHooker.log"
			);

#if _DEBUG
			spdlog::set_level(spdlog::level::debug);
			logger->flush_on(spdlog::level::debug);
#else
		logger->flush_on(spdlog::level::info);
#endif

			set_default_logger(logger);

			//
			// Load known IOCTL code definitions
			//
			Json::Value root;
			std::ifstream ifs(g_dllDir + "\\ioctls.json");
			ifs >> root;

			for (auto& i : root)
			{
				g_ioctlMap[std::stoul(i["HexValue"].asString(), nullptr, 16)] = i["Ioctl"].asString();
			}
		}

		DisableThreadLibraryCalls(dll_handle);
		DetourRestoreAfterWith();

		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&static_cast<PVOID>(real_SetupDiEnumDeviceInterfaces), DetourSetupDiEnumDeviceInterfaces);
		DetourAttach(&static_cast<PVOID>(real_DeviceIoControl), DetourDeviceIoControl);
		DetourAttach(&static_cast<PVOID>(real_CreateFileA), DetourCreateFileA);
		DetourAttach(&static_cast<PVOID>(real_CreateFileW), DetourCreateFileW);
		DetourAttach(&static_cast<PVOID>(real_WriteFile), DetourWriteFile);
		DetourAttach(&static_cast<PVOID>(real_GetOverlappedResult), DetourGetOverlappedResult);
		DetourTransactionCommit();

		break;

	case DLL_PROCESS_DETACH:
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&static_cast<PVOID>(real_SetupDiEnumDeviceInterfaces), DetourSetupDiEnumDeviceInterfaces);
		DetourDetach(&static_cast<PVOID>(real_DeviceIoControl), DetourDeviceIoControl);
		DetourDetach(&static_cast<PVOID>(real_CreateFileA), DetourCreateFileA);
		DetourDetach(&static_cast<PVOID>(real_CreateFileW), DetourCreateFileW);
		DetourDetach(&static_cast<PVOID>(real_WriteFile), DetourWriteFile);
		DetourDetach(&static_cast<PVOID>(real_GetOverlappedResult), DetourGetOverlappedResult);
		DetourTransactionCommit();
		break;
	}
	return TRUE;
}
<|endoftext|>


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

#include "chrome/browser/views/tab_contents/tab_contents_container.h"

#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/interstitial_page.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"

#if defined(TOUCH_UI)
#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h"
#include "views/border.h"
#include "views/fill_layout.h"
#endif

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, public:

TabContentsContainer::TabContentsContainer()
    : native_container_(NULL),
      tab_contents_(NULL),
      reserved_area_delegate_(NULL) {
  SetID(VIEW_ID_TAB_CONTAINER);
}

TabContentsContainer::~TabContentsContainer() {
  if (tab_contents_)
    RemoveObservers();
}

void TabContentsContainer::ChangeTabContents(TabContents* contents) {
  if (tab_contents_) {
#if !defined(TOUCH_UI)
    native_container_->DetachContents(tab_contents_);
#endif
    tab_contents_->WasHidden();
    RemoveObservers();
  }
#if !defined(TOUCH_UI)
  TabContents* old_contents = tab_contents_;
#endif
  tab_contents_ = contents;
  // When detaching the last tab of the browser ChangeTabContents is invoked
  // with NULL. Don't attempt to do anything in that case.
  if (tab_contents_) {
#if defined(TOUCH_UI)
    views::View *v = static_cast<TabContentsViewViews*>(contents->view());
    // Guard against re-adding ourselves, which happens because the NULL
    // value is ignored by the pre-existing if() above.
    if (v->GetParent() != this) {
      AddChildView(v);
      SetLayoutManager(new views::FillLayout());
      Layout();
    }
#else
    RenderWidgetHostViewChanged(
        old_contents ? old_contents->GetRenderWidgetHostView() : NULL,
        tab_contents_->GetRenderWidgetHostView());
    native_container_->AttachContents(tab_contents_);
#endif
    AddObservers();
  }
}

void TabContentsContainer::TabContentsFocused(TabContents* tab_contents) {
  if (native_container_)
    native_container_->TabContentsFocused(tab_contents);
}

void TabContentsContainer::SetFastResize(bool fast_resize) {
  if (native_container_)
    native_container_->SetFastResize(fast_resize);
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, NotificationObserver implementation:

void TabContentsContainer::Observe(NotificationType type,
                                   const NotificationSource& source,
                                   const NotificationDetails& details) {
  if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
    RenderViewHostSwitchedDetails* switched_details =
        Details<RenderViewHostSwitchedDetails>(details).ptr();
    RenderViewHostChanged(switched_details->old_host,
                          switched_details->new_host);
  } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    TabContentsDestroyed(Source<TabContents>(source).ptr());
  } else {
    NOTREACHED();
  }
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, View overrides:

void TabContentsContainer::Layout() {
#if defined(TOUCH_UI)
  views::View::Layout();
#else
  if (native_container_) {
    if (reserved_area_delegate_)
      reserved_area_delegate_->UpdateReservedContentsRect(this);
    native_container_->GetView()->SetBounds(0, 0, width(), height());
    native_container_->GetView()->Layout();
  }
#endif
}

AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() {
  return AccessibilityTypes::ROLE_WINDOW;
}

void TabContentsContainer::ViewHierarchyChanged(bool is_add,
                                                views::View* parent,
                                                views::View* child) {
#if defined(TOUCH_UI)
  views::View::ViewHierarchyChanged(is_add, parent, child);
#else
  if (is_add && child == this) {
    native_container_ = NativeTabContentsContainer::CreateNativeContainer(this);
    AddChildView(native_container_->GetView());
  }
#endif
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, private:

void TabContentsContainer::AddObservers() {
  // TabContents can change their RenderViewHost and hence the HWND that is
  // shown and getting focused.  We need to keep track of that so we install
  // the focus subclass on the shown HWND so we intercept focus change events.
  registrar_.Add(this,
                 NotificationType::RENDER_VIEW_HOST_CHANGED,
                 Source<NavigationController>(&tab_contents_->controller()));

  registrar_.Add(this,
                 NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab_contents_));
}

void TabContentsContainer::RemoveObservers() {
  registrar_.RemoveAll();
}

void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host,
                                                 RenderViewHost* new_host) {
#if defined(TOUCH_UI)
  NOTIMPLEMENTED();  // TODO(anicolao)
#else
  if (new_host) {
    RenderWidgetHostViewChanged(
        old_host ? old_host->view() : NULL, new_host->view());
  }
  native_container_->RenderViewHostChanged(old_host, new_host);
#endif
}

void TabContentsContainer::TabContentsDestroyed(TabContents* contents) {
  // Sometimes, a TabContents is destroyed before we know about it. This allows
  // us to clean up our state in case this happens.
  DCHECK(contents == tab_contents_);
  ChangeTabContents(NULL);
}

void TabContentsContainer::RenderWidgetHostViewChanged(
    RenderWidgetHostView* old_view, RenderWidgetHostView* new_view) {
  // Carry over the reserved rect, if possible.
  if (old_view && new_view) {
    new_view->set_reserved_contents_rect(old_view->reserved_contents_rect());
  } else {
    if (reserved_area_delegate_)
      reserved_area_delegate_->UpdateReservedContentsRect(this);
  }
}
<commit_msg>Remove undisplayed tabs from the views hierarchy because event delivery doesn't respect z-order.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/tab_contents/tab_contents_container.h"

#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/interstitial_page.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"

#if defined(TOUCH_UI)
#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h"
#include "views/border.h"
#include "views/fill_layout.h"
#endif

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, public:

TabContentsContainer::TabContentsContainer()
    : native_container_(NULL),
      tab_contents_(NULL),
      reserved_area_delegate_(NULL) {
  SetID(VIEW_ID_TAB_CONTAINER);
}

TabContentsContainer::~TabContentsContainer() {
  if (tab_contents_)
    RemoveObservers();
}

void TabContentsContainer::ChangeTabContents(TabContents* contents) {
  if (tab_contents_) {
#if !defined(TOUCH_UI)
    native_container_->DetachContents(tab_contents_);
#else
    views::View *v = static_cast<TabContentsViewViews*>(tab_contents_->view());
    RemoveChildView(v);
#endif
    tab_contents_->WasHidden();
    RemoveObservers();
  }
#if !defined(TOUCH_UI)
  TabContents* old_contents = tab_contents_;
#endif
  tab_contents_ = contents;
  // When detaching the last tab of the browser ChangeTabContents is invoked
  // with NULL. Don't attempt to do anything in that case.
  if (tab_contents_) {
#if defined(TOUCH_UI)
    views::View *v = static_cast<TabContentsViewViews*>(contents->view());
    // Guard against re-adding ourselves, which happens because the NULL
    // value is ignored by the pre-existing if() above.
    if (v->GetParent() != this) {
      AddChildView(v);
      SetLayoutManager(new views::FillLayout());
      Layout();
    }
#else
    RenderWidgetHostViewChanged(
        old_contents ? old_contents->GetRenderWidgetHostView() : NULL,
        tab_contents_->GetRenderWidgetHostView());
    native_container_->AttachContents(tab_contents_);
#endif
    AddObservers();
  }
}

void TabContentsContainer::TabContentsFocused(TabContents* tab_contents) {
  if (native_container_)
    native_container_->TabContentsFocused(tab_contents);
}

void TabContentsContainer::SetFastResize(bool fast_resize) {
  if (native_container_)
    native_container_->SetFastResize(fast_resize);
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, NotificationObserver implementation:

void TabContentsContainer::Observe(NotificationType type,
                                   const NotificationSource& source,
                                   const NotificationDetails& details) {
  if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
    RenderViewHostSwitchedDetails* switched_details =
        Details<RenderViewHostSwitchedDetails>(details).ptr();
    RenderViewHostChanged(switched_details->old_host,
                          switched_details->new_host);
  } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
    TabContentsDestroyed(Source<TabContents>(source).ptr());
  } else {
    NOTREACHED();
  }
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, View overrides:

void TabContentsContainer::Layout() {
#if defined(TOUCH_UI)
  views::View::Layout();
#else
  if (native_container_) {
    if (reserved_area_delegate_)
      reserved_area_delegate_->UpdateReservedContentsRect(this);
    native_container_->GetView()->SetBounds(0, 0, width(), height());
    native_container_->GetView()->Layout();
  }
#endif
}

AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() {
  return AccessibilityTypes::ROLE_WINDOW;
}

void TabContentsContainer::ViewHierarchyChanged(bool is_add,
                                                views::View* parent,
                                                views::View* child) {
#if defined(TOUCH_UI)
  views::View::ViewHierarchyChanged(is_add, parent, child);
#else
  if (is_add && child == this) {
    native_container_ = NativeTabContentsContainer::CreateNativeContainer(this);
    AddChildView(native_container_->GetView());
  }
#endif
}

////////////////////////////////////////////////////////////////////////////////
// TabContentsContainer, private:

void TabContentsContainer::AddObservers() {
  // TabContents can change their RenderViewHost and hence the HWND that is
  // shown and getting focused.  We need to keep track of that so we install
  // the focus subclass on the shown HWND so we intercept focus change events.
  registrar_.Add(this,
                 NotificationType::RENDER_VIEW_HOST_CHANGED,
                 Source<NavigationController>(&tab_contents_->controller()));

  registrar_.Add(this,
                 NotificationType::TAB_CONTENTS_DESTROYED,
                 Source<TabContents>(tab_contents_));
}

void TabContentsContainer::RemoveObservers() {
  registrar_.RemoveAll();
}

void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host,
                                                 RenderViewHost* new_host) {
#if defined(TOUCH_UI)
  NOTIMPLEMENTED();  // TODO(anicolao)
#else
  if (new_host) {
    RenderWidgetHostViewChanged(
        old_host ? old_host->view() : NULL, new_host->view());
  }
  native_container_->RenderViewHostChanged(old_host, new_host);
#endif
}

void TabContentsContainer::TabContentsDestroyed(TabContents* contents) {
  // Sometimes, a TabContents is destroyed before we know about it. This allows
  // us to clean up our state in case this happens.
  DCHECK(contents == tab_contents_);
  ChangeTabContents(NULL);
}

void TabContentsContainer::RenderWidgetHostViewChanged(
    RenderWidgetHostView* old_view, RenderWidgetHostView* new_view) {
  // Carry over the reserved rect, if possible.
  if (old_view && new_view) {
    new_view->set_reserved_contents_rect(old_view->reserved_contents_rect());
  } else {
    if (reserved_area_delegate_)
      reserved_area_delegate_->UpdateReservedContentsRect(this);
  }
}
<|endoftext|>


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

#ifndef PCL_KDTREE_KDTREE_IMPL_FLANN_H_
#define PCL_KDTREE_KDTREE_IMPL_FLANN_H_

#include "pcl/kdtree/kdtree_flann.h"
#include <pcl/console/print.h>
#include <flann/flann.hpp>

namespace pcl
{
  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::setInputCloud (const PointCloudConstPtr &cloud, const IndicesConstPtr &indices)
  {
    cleanup ();   // Perform an automatic cleanup of structures

    if (!initParameters())
      return;

    input_   = cloud;
    indices_ = indices;

    if (input_ == NULL)
      return;

    m_lock_.lock ();
    // Allocate enough data
    if (!input_)
    {
      PCL_ERROR ("[pcl::KdTreeANN::setInputCloud] Invalid input!\n");
      return;
    }
    if (indices != NULL)
      convertCloudToArray (*input_, *indices_);
    else
      convertCloudToArray (*input_);

    initData ();
    m_lock_.unlock ();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT> int
  KdTreeFLANN<PointT>::nearestKSearch (const PointT &point, int k,
                                       std::vector<int> &k_indices,
                                       std::vector<float> &k_distances)
  {
    if (!point_representation_->isValid (point))
    {
      //PCL_ERROR_STREAM ("[pcl::KdTreeFLANN::nearestKSearch] Invalid query point given!" << point);
      return (0);
    }

    if (k_indices.size() < (size_t)k) {
        k_indices.resize(k);
    }
    if (k_distances.size() < (size_t)k) {
        k_distances.resize(k);
    }

    std::vector<float> tmp (dim_);
    point_representation_->vectorize ((PointT)point, tmp);

    flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k);
    flann::Matrix<float> k_distances_mat (&k_distances[0], 1, k);
    flann_index_->knnSearch (flann::Matrix<float>(&tmp[0], 1, dim_), k_indices_mat, k_distances_mat, k, flann::SearchParams (-1 ,epsilon_));

    // Do mapping to original point cloud
    if (!identity_mapping_) {
      for (size_t i = 0; i < k_indices.size (); ++i)
      {
        int& neighbor_index = k_indices[i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }

    return (k);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  int KdTreeFLANN<PointT>::radiusSearch (const PointT &point, double radius, std::vector<int> &k_indices,
                                          std::vector<float> &k_squared_distances, int max_nn) const
  {
    static flann::Matrix<int> indices_empty;
    static flann::Matrix<float> dists_empty;

    if (!point_representation_->isValid (point))
    {
      //PCL_ERROR_STREAM ("[pcl::KdTreeFLANN::radiusSearch] Invalid query point given!" << point);
      return 0;
    }

    std::vector<float> tmp(dim_);
    point_representation_->vectorize ((PointT)point, tmp);
    radius *= radius; // flann uses squared radius

    size_t size;
    if (indices_ == NULL) // no indices set, use full size of point cloud:
      size = input_->points.size ();
    else
      size = indices_->size ();

    int neighbors_in_radius = 0;
    if (k_indices.size () == size && k_squared_distances.size () == size)  // preallocated vectors
    {
      // if using preallocated vectors we ignore max_nn as we are sure to have enought space
      // to store all neighbors found in radius
      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size());
      flann::Matrix<float> k_distances_mat (&k_squared_distances[0], 1, k_squared_distances.size());
      neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          k_indices_mat, k_distances_mat, radius, flann::SearchParams (-1, epsilon_, sorted_));
    }
    else // need to do search twice, first to find how many neighbors and allocate the vectors
    {
      neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          indices_empty, dists_empty, radius, flann::SearchParams (-1, epsilon_, sorted_));
      if (max_nn > 0)
      {
        neighbors_in_radius = std::min(neighbors_in_radius, max_nn);
      }
      k_indices.resize (neighbors_in_radius);
      k_squared_distances.resize (neighbors_in_radius);
      if (neighbors_in_radius == 0)
      {
        return (0);
      }

      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size());
      flann::Matrix<float> k_distances_mat (&k_squared_distances[0], 1, k_squared_distances.size());
      flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          k_indices_mat, k_distances_mat, radius, flann::SearchParams (-1, epsilon_, sorted_));

    }

    // Do mapping to original point cloud
    if (!identity_mapping_) {
      for (int i = 0; i < neighbors_in_radius; ++i)
      {
        int& neighbor_index = k_indices[i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }

    return (neighbors_in_radius);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::cleanup ()
  {
    delete flann_index_;

    m_lock_.lock ();
    // Data array cleanup
    free (cloud_);
    cloud_ = NULL;
    index_mapping_.clear();

    if (indices_)
      indices_.reset ();

    m_lock_.unlock ();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  bool KdTreeFLANN<PointT>::initParameters ()
  {
    epsilon_ = 0.0;   // default error bound value
    dim_ = point_representation_->getNumberOfDimensions (); // Number of dimensions - default is 3 = xyz
    // Create the kd_tree representation
    return (true);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::initData ()
  {
    flann_index_ = new FLANNIndex(flann::Matrix<float>(cloud_, index_mapping_.size(), dim_),
			  	  	  	  	  	  flann::KDTreeSingleIndexParams(15)); // max 15 points/leaf
    flann_index_->buildIndex();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::convertCloudToArray (const PointCloud &ros_cloud)
  {
    // No point in doing anything if the array is empty
    if (ros_cloud.points.empty ())
    {
      cloud_ = NULL;
      return;
    }

    int original_no_of_points = ros_cloud.points.size();

    cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof(float));
    float* cloud_ptr = cloud_;
    index_mapping_.reserve(original_no_of_points);
    identity_mapping_ = true;

    for (int cloud_index = 0; cloud_index < original_no_of_points; ++cloud_index)
    {
      const PointT point = ros_cloud.points[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid(point)) {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back(cloud_index);

      point_representation_->vectorize(point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::convertCloudToArray (const PointCloud &ros_cloud, const std::vector<int> &indices)
  {
    // No point in doing anything if the array is empty
    if (ros_cloud.points.empty ())
    {
      cloud_ = NULL;
      return;
    }

    int original_no_of_points = indices.size();

    cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
    float* cloud_ptr = cloud_;
    index_mapping_.reserve(original_no_of_points);
    identity_mapping_ = true;

    for (int indices_index = 0; indices_index < original_no_of_points; ++indices_index)
    {
      int cloud_index = indices[indices_index];
      const PointT point = ros_cloud.points[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid(point)) {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back(indices_index);  // If the returned index should be for the indices vector
      //index_mapping_.push_back(cloud_index);  // If the returned index should be for the ros cloud

      point_representation_->vectorize(point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }

}  // end namespace

#define PCL_INSTANTIATE_KdTreeFLANN(T) template class PCL_EXPORTS pcl::KdTreeFLANN<T>;

#endif  //#ifndef _PCL_KDTREE_KDTREE_IMPL_FLANN_H_

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

#ifndef PCL_KDTREE_KDTREE_IMPL_FLANN_H_
#define PCL_KDTREE_KDTREE_IMPL_FLANN_H_

#include "pcl/kdtree/kdtree_flann.h"
#include <pcl/console/print.h>
#include <flann/flann.hpp>

namespace pcl
{
  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::setInputCloud (const PointCloudConstPtr &cloud, const IndicesConstPtr &indices)
  {
    cleanup ();   // Perform an automatic cleanup of structures

    if (!initParameters())
      return;

    input_   = cloud;
    indices_ = indices;

    if (input_ == NULL)
      return;

    m_lock_.lock ();
    // Allocate enough data
    if (!input_)
    {
      PCL_ERROR ("[pcl::KdTreeANN::setInputCloud] Invalid input!\n");
      return;
    }
    if (indices != NULL)
      convertCloudToArray (*input_, *indices_);
    else
      convertCloudToArray (*input_);

    initData ();
    m_lock_.unlock ();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT> int
  KdTreeFLANN<PointT>::nearestKSearch (const PointT &point, int k,
                                       std::vector<int> &k_indices,
                                       std::vector<float> &k_distances)
  {
    if (!point_representation_->isValid (point))
    {
      //PCL_ERROR_STREAM ("[pcl::KdTreeFLANN::nearestKSearch] Invalid query point given!" << point);
      return (0);
    }

    if (k_indices.size() < (size_t)k)
    {
        k_indices.resize(k);
    }
    if (k_distances.size() < (size_t)k)
    {
        k_distances.resize(k);
    }

    std::vector<float> tmp (dim_);
    point_representation_->vectorize ((PointT)point, tmp);

    flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k);
    flann::Matrix<float> k_distances_mat (&k_distances[0], 1, k);
    flann_index_->knnSearch (flann::Matrix<float>(&tmp[0], 1, dim_), k_indices_mat, k_distances_mat, k, flann::SearchParams (-1 ,epsilon_));

    // Do mapping to original point cloud
    if (!identity_mapping_) {
      for (size_t i = 0; i < k_indices.size (); ++i)
      {
        int& neighbor_index = k_indices[i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }

    return (k);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  int KdTreeFLANN<PointT>::radiusSearch (const PointT &point, double radius, std::vector<int> &k_indices,
                                          std::vector<float> &k_squared_distances, int max_nn) const
  {
    static flann::Matrix<int> indices_empty;
    static flann::Matrix<float> dists_empty;

    if (!point_representation_->isValid (point))
    {
      //PCL_ERROR_STREAM ("[pcl::KdTreeFLANN::radiusSearch] Invalid query point given!" << point);
      return 0;
    }

    std::vector<float> tmp(dim_);
    point_representation_->vectorize ((PointT)point, tmp);
    radius *= radius; // flann uses squared radius

    size_t size;
    if (indices_ == NULL) // no indices set, use full size of point cloud:
      size = input_->points.size ();
    else
      size = indices_->size ();

    int neighbors_in_radius = 0;
    if (k_indices.size () == size && k_squared_distances.size () == size)  // preallocated vectors
    {
      // if using preallocated vectors we ignore max_nn as we are sure to have enought space
      // to store all neighbors found in radius
      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size());
      flann::Matrix<float> k_distances_mat (&k_squared_distances[0], 1, k_squared_distances.size());
      neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          k_indices_mat, k_distances_mat, radius, flann::SearchParams (-1, epsilon_, sorted_));
    }
    else // need to do search twice, first to find how many neighbors and allocate the vectors
    {
      neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          indices_empty, dists_empty, radius, flann::SearchParams (-1, epsilon_, sorted_));
      if (max_nn > 0)
      {
        neighbors_in_radius = std::min(neighbors_in_radius, max_nn);
      }
      k_indices.resize (neighbors_in_radius);
      k_squared_distances.resize (neighbors_in_radius);
      if (neighbors_in_radius == 0)
      {
        return (0);
      }

      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size());
      flann::Matrix<float> k_distances_mat (&k_squared_distances[0], 1, k_squared_distances.size());
      flann_index_->radiusSearch (flann::Matrix<float>(&tmp[0], 1, dim_),
          k_indices_mat, k_distances_mat, radius, flann::SearchParams (-1, epsilon_, sorted_));

    }

    // Do mapping to original point cloud
    if (!identity_mapping_) {
      for (int i = 0; i < neighbors_in_radius; ++i)
      {
        int& neighbor_index = k_indices[i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }

    return (neighbors_in_radius);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::cleanup ()
  {
    delete flann_index_;

    m_lock_.lock ();
    // Data array cleanup
    free (cloud_);
    cloud_ = NULL;
    index_mapping_.clear();

    if (indices_)
      indices_.reset ();

    m_lock_.unlock ();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  bool KdTreeFLANN<PointT>::initParameters ()
  {
    epsilon_ = 0.0;   // default error bound value
    dim_ = point_representation_->getNumberOfDimensions (); // Number of dimensions - default is 3 = xyz
    // Create the kd_tree representation
    return (true);
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::initData ()
  {
    flann_index_ = new FLANNIndex(flann::Matrix<float>(cloud_, index_mapping_.size(), dim_),
			  	  	  	  	  	  flann::KDTreeSingleIndexParams(15)); // max 15 points/leaf
    flann_index_->buildIndex();
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::convertCloudToArray (const PointCloud &ros_cloud)
  {
    // No point in doing anything if the array is empty
    if (ros_cloud.points.empty ())
    {
      cloud_ = NULL;
      return;
    }

    int original_no_of_points = ros_cloud.points.size();

    cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof(float));
    float* cloud_ptr = cloud_;
    index_mapping_.reserve(original_no_of_points);
    identity_mapping_ = true;

    for (int cloud_index = 0; cloud_index < original_no_of_points; ++cloud_index)
    {
      const PointT point = ros_cloud.points[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid(point)) {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back(cloud_index);

      point_representation_->vectorize(point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }

  ////////////////////////////////////////////////////////////////////////////////////////////
  template <typename PointT>
  void KdTreeFLANN<PointT>::convertCloudToArray (const PointCloud &ros_cloud, const std::vector<int> &indices)
  {
    // No point in doing anything if the array is empty
    if (ros_cloud.points.empty ())
    {
      cloud_ = NULL;
      return;
    }

    int original_no_of_points = indices.size();

    cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
    float* cloud_ptr = cloud_;
    index_mapping_.reserve(original_no_of_points);
    identity_mapping_ = true;

    for (int indices_index = 0; indices_index < original_no_of_points; ++indices_index)
    {
      int cloud_index = indices[indices_index];
      const PointT point = ros_cloud.points[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid(point)) {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back(indices_index);  // If the returned index should be for the indices vector
      //index_mapping_.push_back(cloud_index);  // If the returned index should be for the ros cloud

      point_representation_->vectorize(point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }

}  // end namespace

#define PCL_INSTANTIATE_KdTreeFLANN(T) template class PCL_EXPORTS pcl::KdTreeFLANN<T>;

#endif  //#ifndef _PCL_KDTREE_KDTREE_IMPL_FLANN_H_

<|endoftext|>


<commit_before>// Copyright 2009-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "curve_intersector_virtual.h"
#include "intersector_epilog.h"

#include "../subdiv/bezier_curve.h"
#include "../subdiv/bspline_curve.h"
#include "../subdiv/hermite_curve.h"
#include "../subdiv/catmullrom_curve.h"

#include "spherei_intersector.h"
#include "disci_intersector.h"

#include "linei_intersector.h"

#include "curveNi_intersector.h"
#include "curveNv_intersector.h"
#include "curveNi_mb_intersector.h"

#include "curve_intersector_distance.h"
#include "curve_intersector_ribbon.h"
#include "curve_intersector_oriented.h"
#include "curve_intersector_sweep.h"

namespace embree
{
  namespace isa
  {
#if defined (__AVX__)

    VirtualCurveIntersector* VirtualCurveIntersector8i()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNiIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNiIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

    VirtualCurveIntersector* VirtualCurveIntersector8v()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNvIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNvIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNvIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNvIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

    VirtualCurveIntersector* VirtualCurveIntersector8iMB()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNiMBIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNiMBIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiMBIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNiMBIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNiMBIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiMBIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiMBIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiMBIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiMBIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiMBIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiMBIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiMBIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

#endif
  }
}
<commit_msg>add intersectors for 8 wide<commit_after>// Copyright 2009-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "curve_intersector_virtual.h"
#include "intersector_epilog.h"

#include "../subdiv/bezier_curve.h"
#include "../subdiv/bspline_curve.h"
#include "../subdiv/hermite_curve.h"
#include "../subdiv/catmullrom_curve.h"

#include "spherei_intersector.h"
#include "disci_intersector.h"

#include "linei_intersector.h"

#include "curveNi_intersector.h"
#include "curveNv_intersector.h"
#include "curveNi_mb_intersector.h"

#include "curve_intersector_distance.h"
#include "curve_intersector_ribbon.h"
#include "curve_intersector_oriented.h"
#include "curve_intersector_sweep.h"

namespace embree
{
  namespace isa
  {
#if defined (__AVX__)

    VirtualCurveIntersector* VirtualCurveIntersector8i()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_CONE_LINEAR_CURVE ] = LinearConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNiIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNiIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

    VirtualCurveIntersector* VirtualCurveIntersector8v()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_CONE_LINEAR_CURVE ] = LinearConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNvIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNvIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNvIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNvIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

    VirtualCurveIntersector* VirtualCurveIntersector8iMB()
    {
      static VirtualCurveIntersector function_local_static_prim;
      function_local_static_prim.vtbl[Geometry::GTY_SPHERE_POINT] = SphereNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_DISC_POINT] = DiscNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_DISC_POINT] = OrientedDiscNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_CONE_LINEAR_CURVE ] = LinearConeNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_LINEAR_CURVE ] = LinearRoundConeNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_LINEAR_CURVE ] = LinearRibbonNiMBIntersectors<8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BEZIER_CURVE] = CurveNiMBIntersectors <BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BEZIER_CURVE ] = RibbonNiMBIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BEZIER_CURVE] = OrientedCurveNiMBIntersectors<BezierCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_BSPLINE_CURVE] = CurveNiMBIntersectors <BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_BSPLINE_CURVE ] = RibbonNiMBIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_BSPLINE_CURVE] = OrientedCurveNiMBIntersectors<BSplineCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_HERMITE_CURVE] = HermiteCurveNiMBIntersectors <HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_HERMITE_CURVE ] = HermiteRibbonNiMBIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_HERMITE_CURVE] = HermiteOrientedCurveNiMBIntersectors<HermiteCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ROUND_CATMULL_ROM_CURVE] = CurveNiMBIntersectors <CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_FLAT_CATMULL_ROM_CURVE ] = RibbonNiMBIntersectors<CatmullRomCurveT,8>();
      function_local_static_prim.vtbl[Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE] = OrientedCurveNiMBIntersectors<CatmullRomCurveT,8>();
      return &function_local_static_prim;
    }

#endif
  }
}
<|endoftext|>


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

/*
 * Simple ranger example, using VL53L0X Time-of-flight range sensor I2C device.
 * This program uses FastArduino VL53L0X support API.
 * It checks conditions of use of GPIO pin.
 *
 * Wiring:
 * - on ATmega328P based boards (including Arduino UNO):
 *   - A4 (PC4, SDA): connected to VL53L0X SDA pin
 *   - A5 (PC5, SCL): connected to VL53L0X SCL pin
 *   - D2 (EXT0): connected to VL53L0X GPIO pin
 */

#include <fastarduino/gpio.h>
#include <fastarduino/int.h>
#include <fastarduino/realtime_timer.h>
#include <fastarduino/time.h>
#include <fastarduino/uart.h>
#include <fastarduino/i2c_handler.h>
#include <fastarduino/devices/vl53l0x.h>

// #define FORCE_SYNC

static constexpr const i2c::I2CMode MODE = i2c::I2CMode::FAST;
static constexpr const board::ExternalInterruptPin GPIO = board::ExternalInterruptPin::D2_PD2_EXT0;

static constexpr const board::USART UART = board::USART::USART0;
static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

REGISTER_RTT_ISR(0)
REGISTER_UATX_ISR(0)

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using MANAGER = i2c::I2CAsyncManager<MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
REGISTER_I2C_ISR(MANAGER)
#else
using MANAGER = i2c::I2CSyncManager<MODE>;
#endif

using streams::dec;
using streams::hex;
using streams::fixed;
using streams::endl;
using streams::flush;

using namespace devices::vl53l0x;
using TOF = VL53L0X<MANAGER>;

#define CHECK_OK(STATEMENT) if (! STATEMENT) out << F(#STATEMENT) << F(" ERROR!") << endl

class ToFController
{
public:
	ToFController(TOF& tof) : tof_{tof}
	{
		interrupt::register_handler(*this);
		signal_.enable();
	}

	void await_gpio()
	{
		while (!gpio_)
		{
			time::yield();
		}
		gpio_ = false;
	}

private:
	void gpio_raised()
	{
		gpio_ = true;
	}

	TOF& tof_;
	gpio::FAST_EXT_PIN<GPIO> gpio_pin_{gpio::PinMode::INPUT};
	interrupt::INTSignal<GPIO> signal_{interrupt::InterruptTrigger::FALLING_EDGE};
	volatile bool gpio_ = false;

	DECL_INT_ISR_HANDLERS_FRIEND
};

REGISTER_INT_ISR_METHOD(0, GPIO, ToFController, &ToFController::gpio_raised)

static void loop_gpio(
	streams::ostream& out, timer::RTT<board::Timer::TIMER0>& rtt, ToFController& controller, TOF& tof)
{
	out << F("await GPIO") << endl;
	// Limit loop to 1'
	for (uint8_t i = 0; i < 60; ++i)
	{
		uint16_t range = 0;
		rtt.millis(0);
		controller.await_gpio();
		time::RTTTime time1 = rtt.time();

		rtt.millis(0);
		CHECK_OK(tof.get_direct_range(range));
		time::RTTTime time2 = rtt.time();
		// Clear interrupt
		CHECK_OK(tof.clear_interrupt());

		out << F("GPIO after ") << dec << time1.millis() << "ms " << time1.micros() << "us" << streams::endl;
		out << F("Range after ") << time2.millis() << "ms " << time2.micros() << "us" << streams::endl;
		out << F("range = ") << range << F("mm") << endl;
	}
}

int main() __attribute__((OS_main));
int main()
{
	board::init();
	sei();

	// open UART for traces
	serial::hard::UATX<UART> uart{output_buffer};
	streams::ostream out = uart.out();
	uart.begin(115200);
	out << streams::boolalpha;

	timer::RTT<board::Timer::TIMER0> rtt;
	rtt.begin();

	// Initialize I2C async handler
#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
	MANAGER manager{i2c_buffer};
#else
	MANAGER manager;
#endif

	TOF tof{manager};
	manager.begin();
	ToFController controller{tof};

	uint8_t value = 0;
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;

	CHECK_OK(tof.begin(Profile::STANDARD));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;

	out << F("GPIOSettings::sample_ready()") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::sample_ready()));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::low_threshold(200)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::low_threshold(200)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::high_threshold(400)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::high_threshold(400)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::out_of_window(200, 400)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::out_of_window(200, 400)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	tof.stop_continuous_ranging();
	manager.end();

	out << F("Finished!") << endl;
}
<commit_msg>Shorten timing of VL53L0X example<commit_after>//   Copyright 2016-2020 Jean-Francois Poilpret
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

/*
 * Simple ranger example, using VL53L0X Time-of-flight range sensor I2C device.
 * This program uses FastArduino VL53L0X support API.
 * It checks conditions of use of GPIO pin.
 *
 * Wiring:
 * - on ATmega328P based boards (including Arduino UNO):
 *   - A4 (PC4, SDA): connected to VL53L0X SDA pin
 *   - A5 (PC5, SCL): connected to VL53L0X SCL pin
 *   - D2 (EXT0): connected to VL53L0X GPIO pin
 */

#include <fastarduino/gpio.h>
#include <fastarduino/int.h>
#include <fastarduino/realtime_timer.h>
#include <fastarduino/time.h>
#include <fastarduino/uart.h>
#include <fastarduino/i2c_handler.h>
#include <fastarduino/devices/vl53l0x.h>

// #define FORCE_SYNC

static constexpr const i2c::I2CMode MODE = i2c::I2CMode::FAST;
static constexpr const board::ExternalInterruptPin GPIO = board::ExternalInterruptPin::D2_PD2_EXT0;

static constexpr const board::USART UART = board::USART::USART0;
static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

REGISTER_RTT_ISR(0)
REGISTER_UATX_ISR(0)

#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
using MANAGER = i2c::I2CAsyncManager<MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS>;
static constexpr const uint8_t I2C_BUFFER_SIZE = 32;
static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE];
REGISTER_I2C_ISR(MANAGER)
#else
using MANAGER = i2c::I2CSyncManager<MODE>;
#endif

using streams::dec;
using streams::hex;
using streams::fixed;
using streams::endl;
using streams::flush;

using namespace devices::vl53l0x;
using TOF = VL53L0X<MANAGER>;

#define CHECK_OK(STATEMENT) if (! STATEMENT) out << F(#STATEMENT) << F(" ERROR!") << endl

class ToFController
{
public:
	ToFController(TOF& tof) : tof_{tof}
	{
		interrupt::register_handler(*this);
		signal_.enable();
	}

	void await_gpio()
	{
		while (!gpio_)
		{
			time::yield();
		}
		gpio_ = false;
	}

private:
	void gpio_raised()
	{
		gpio_ = true;
	}

	TOF& tof_;
	gpio::FAST_EXT_PIN<GPIO> gpio_pin_{gpio::PinMode::INPUT};
	interrupt::INTSignal<GPIO> signal_{interrupt::InterruptTrigger::FALLING_EDGE};
	volatile bool gpio_ = false;

	DECL_INT_ISR_HANDLERS_FRIEND
};

REGISTER_INT_ISR_METHOD(0, GPIO, ToFController, &ToFController::gpio_raised)

static void loop_gpio(
	streams::ostream& out, timer::RTT<board::Timer::TIMER0>& rtt, ToFController& controller, TOF& tof)
{
	out << F("await GPIO") << endl;
	// Limit loop to 1'
	for (uint8_t i = 0; i < 30; ++i)
	{
		uint16_t range = 0;
		rtt.millis(0);
		controller.await_gpio();
		time::RTTTime time1 = rtt.time();

		rtt.millis(0);
		CHECK_OK(tof.get_direct_range(range));
		time::RTTTime time2 = rtt.time();
		// Clear interrupt
		CHECK_OK(tof.clear_interrupt());

		out << F("GPIO after ") << dec << time1.millis() << "ms " << time1.micros() << "us" << streams::endl;
		out << F("Range after ") << time2.millis() << "ms " << time2.micros() << "us" << streams::endl;
		out << F("range = ") << range << F("mm") << endl;
	}
}

int main() __attribute__((OS_main));
int main()
{
	board::init();
	sei();

	// open UART for traces
	serial::hard::UATX<UART> uart{output_buffer};
	streams::ostream out = uart.out();
	uart.begin(115200);
	out << streams::boolalpha;

	timer::RTT<board::Timer::TIMER0> rtt;
	rtt.begin();

	// Initialize I2C async handler
#if I2C_TRUE_ASYNC and not defined(FORCE_SYNC)
	MANAGER manager{i2c_buffer};
#else
	MANAGER manager;
#endif

	TOF tof{manager};
	manager.begin();
	ToFController controller{tof};

	uint8_t value = 0;
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;

	CHECK_OK(tof.begin(Profile::STANDARD));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;

	out << F("GPIOSettings::sample_ready()") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::sample_ready()));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::low_threshold(200)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::low_threshold(200)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::high_threshold(400)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::high_threshold(400)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	out << F("GPIOSettings::out_of_window(200, 400)") << endl;
	CHECK_OK(tof.set_GPIO_settings(GPIOSettings::out_of_window(200, 400)));
	CHECK_OK(tof.get_register<Register::GPIO_HV_MUX_ACTIVE_HIGH>(value));
	out << F("Register::GPIO_HV_MUX_ACTIVE_HIGH = ") << hex << value << endl;
	CHECK_OK(tof.start_continuous_ranging(1000));
	loop_gpio(out, rtt, controller, tof);

	tof.stop_continuous_ranging();
	manager.end();

	out << F("Finished!") << endl;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageChangeInformation.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

=========================================================================*/
#include "vtkImageChangeInformation.h"

#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

vtkCxxRevisionMacro(vtkImageChangeInformation, "1.17");
vtkStandardNewMacro(vtkImageChangeInformation);

//----------------------------------------------------------------------------
vtkImageChangeInformation::vtkImageChangeInformation()
{
  this->CenterImage = 0;

  for (int i = 0; i < 3; i++)
    {
    this->OutputExtentStart[i] = VTK_INT_MAX;
    this->ExtentTranslation[i] = 0;
    this->FinalExtentTranslation[i] = VTK_INT_MAX;

    this->OutputSpacing[i] = VTK_DOUBLE_MAX;
    this->SpacingScale[i] = 1.0;

    this->OutputOrigin[i] = VTK_DOUBLE_MAX;
    this->OriginScale[i] = 1.0;
    this->OriginTranslation[i] = 0.0;
    }

  // There is an optional second input.
  this->SetNumberOfInputPorts(2);
}

// Specify a source object at a specified table location.
void vtkImageChangeInformation::SetInformationInput(vtkImageData *pd)
{
  this->SetInput(1, pd);
}

// Get a pointer to a source object at a specified table location.
vtkImageData *vtkImageChangeInformation::GetInformationInput()
{
  if (this->GetNumberOfInputConnections(1) < 1)
    {
    return 0;
    }
  return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
}

//----------------------------------------------------------------------------
vtkImageChangeInformation::~vtkImageChangeInformation()
{
}

//----------------------------------------------------------------------------
void vtkImageChangeInformation::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "CenterImage : "
     << (this->CenterImage ? "On":"Off") << endl;

  os << indent << "OutputExtentStart: ("
     << this->OutputExtentStart[0] << ","
     << this->OutputExtentStart[1] << ","
     << this->OutputExtentStart[2] << ")" << endl;

  os << indent << "ExtentTranslation: ("
     << this->ExtentTranslation[0] << ","
     << this->ExtentTranslation[1] << ","
     << this->ExtentTranslation[2] << ")" << endl;

  os << indent << "OutputSpacing: ("
     << this->OutputSpacing[0] << ","
     << this->OutputSpacing[1] << ","
     << this->OutputSpacing[2] << ")" << endl;

  os << indent << "SpacingScale: ("
     << this->SpacingScale[0] << ","
     << this->SpacingScale[1] << ","
     << this->SpacingScale[2] << ")" << endl;

  os << indent << "OutputOrigin: ("
     << this->OutputOrigin[0] << ","
     << this->OutputOrigin[1] << ","
     << this->OutputOrigin[2] << ")" << endl;

  os << indent << "OriginScale: ("
     << this->OriginScale[0] << ","
     << this->OriginScale[1] << ","
     << this->OriginScale[2] << ")" << endl;

  os << indent << "OriginTranslation: ("
     << this->OriginTranslation[0] << ","
     << this->OriginTranslation[1] << ","
     << this->OriginTranslation[2] << ")" << endl;
}

//----------------------------------------------------------------------------
// Change the information
void vtkImageChangeInformation::ExecuteInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  int i;
  int extent[6], inExtent[6];
  double spacing[3], origin[3];

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),inExtent);

  if (this->GetInformationInput())
    {
    // If there is an InformationInput, it is set as a second input
    vtkInformation *in2Info = inputVector[1]->GetInformationObject(0);
    in2Info->Get(vtkDataObject::ORIGIN(),origin);
    in2Info->Get(vtkDataObject::SPACING(),spacing);
    in2Info->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
    for (i = 0; i < 3; i++)
      {
      extent[2*i+1] = extent[2*i] - inExtent[2*i] + inExtent[2*i+1];
      }
    }
  else
    {
    inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
    inInfo->Get(vtkDataObject::ORIGIN(),origin);
    inInfo->Get(vtkDataObject::SPACING(),spacing);
    }

  for (i = 0; i < 3; i++)
    {
    if (this->OutputSpacing[i] != VTK_DOUBLE_MAX)
      {
      spacing[i] = this->OutputSpacing[i];
      }

    if (this->OutputOrigin[i] != VTK_DOUBLE_MAX)
      {
      origin[i] = this->OutputOrigin[i];
      }

    if (this->OutputExtentStart[i] != VTK_INT_MAX)
      {
      extent[2*i+1] += this->OutputExtentStart[i] - extent[2*i];
      extent[2*i] = this->OutputExtentStart[i];
      }
    }

  if (this->CenterImage)
    {
    for (i = 0; i < 3; i++)
      {
      origin[i] = -(extent[2*i] + extent[2*i+1])*spacing[i]/2;
      }
    }

  for (i = 0; i < 3; i++)
    {
    spacing[i] = spacing[i]*this->SpacingScale[i];
    origin[i] = origin[i]*this->OriginScale[i] + this->OriginTranslation[i];
    extent[2*i] = extent[2*i] + this->ExtentTranslation[i];
    extent[2*i+1] = extent[2*i+1] + this->ExtentTranslation[i];
    this->FinalExtentTranslation[i] = extent[2*i] - inExtent[2*i];
    }

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
  outInfo->Set(vtkDataObject::SPACING(),spacing,3);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
}

//----------------------------------------------------------------------------
// This method simply copies by reference the input data to the output.
void vtkImageChangeInformation::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
    {
    vtkErrorMacro("Bug in code, ExecuteInformation was not called");
    return;
    }

  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  int extent[6];

  vtkImageData *inData = vtkImageData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *outData = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // since inData can be larger than update extent.
//  inInfo->Get(vtkDataObject::DATA_EXTENT(),extent);
  inData->GetExtent(extent);
  for (int i = 0; i < 3; ++i)
    {
    extent[i*2] += this->FinalExtentTranslation[i];
    extent[i*2+1] += this->FinalExtentTranslation[i];
    }
//  outInfo->Set(vtkDataObject::DATA_EXTENT(),extent,6);
  outData->SetExtent(extent);
  outData->GetPointData()->PassData(inData->GetPointData());
}

//----------------------------------------------------------------------------
void vtkImageChangeInformation::RequestUpdateExtent (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
    {
    vtkErrorMacro("Bug in code.");
    return;
    }

  int inExt[6];
  outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExt);

  inExt[0] -= this->FinalExtentTranslation[0];
  inExt[1] -= this->FinalExtentTranslation[0];
  inExt[2] -= this->FinalExtentTranslation[1];
  inExt[3] -= this->FinalExtentTranslation[1];
  inExt[4] -= this->FinalExtentTranslation[2];
  inExt[5] -= this->FinalExtentTranslation[2];

  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
}

int vtkImageChangeInformation::FillInputPortInformation(
  int port, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
  if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
    }

  return 1;
}
<commit_msg>removing commented-out lines<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageChangeInformation.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

=========================================================================*/
#include "vtkImageChangeInformation.h"

#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkPointData.h"

vtkCxxRevisionMacro(vtkImageChangeInformation, "1.18");
vtkStandardNewMacro(vtkImageChangeInformation);

//----------------------------------------------------------------------------
vtkImageChangeInformation::vtkImageChangeInformation()
{
  this->CenterImage = 0;

  for (int i = 0; i < 3; i++)
    {
    this->OutputExtentStart[i] = VTK_INT_MAX;
    this->ExtentTranslation[i] = 0;
    this->FinalExtentTranslation[i] = VTK_INT_MAX;

    this->OutputSpacing[i] = VTK_DOUBLE_MAX;
    this->SpacingScale[i] = 1.0;

    this->OutputOrigin[i] = VTK_DOUBLE_MAX;
    this->OriginScale[i] = 1.0;
    this->OriginTranslation[i] = 0.0;
    }

  // There is an optional second input.
  this->SetNumberOfInputPorts(2);
}

// Specify a source object at a specified table location.
void vtkImageChangeInformation::SetInformationInput(vtkImageData *pd)
{
  this->SetInput(1, pd);
}

// Get a pointer to a source object at a specified table location.
vtkImageData *vtkImageChangeInformation::GetInformationInput()
{
  if (this->GetNumberOfInputConnections(1) < 1)
    {
    return 0;
    }
  return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(1, 0));
}

//----------------------------------------------------------------------------
vtkImageChangeInformation::~vtkImageChangeInformation()
{
}

//----------------------------------------------------------------------------
void vtkImageChangeInformation::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "CenterImage : "
     << (this->CenterImage ? "On":"Off") << endl;

  os << indent << "OutputExtentStart: ("
     << this->OutputExtentStart[0] << ","
     << this->OutputExtentStart[1] << ","
     << this->OutputExtentStart[2] << ")" << endl;

  os << indent << "ExtentTranslation: ("
     << this->ExtentTranslation[0] << ","
     << this->ExtentTranslation[1] << ","
     << this->ExtentTranslation[2] << ")" << endl;

  os << indent << "OutputSpacing: ("
     << this->OutputSpacing[0] << ","
     << this->OutputSpacing[1] << ","
     << this->OutputSpacing[2] << ")" << endl;

  os << indent << "SpacingScale: ("
     << this->SpacingScale[0] << ","
     << this->SpacingScale[1] << ","
     << this->SpacingScale[2] << ")" << endl;

  os << indent << "OutputOrigin: ("
     << this->OutputOrigin[0] << ","
     << this->OutputOrigin[1] << ","
     << this->OutputOrigin[2] << ")" << endl;

  os << indent << "OriginScale: ("
     << this->OriginScale[0] << ","
     << this->OriginScale[1] << ","
     << this->OriginScale[2] << ")" << endl;

  os << indent << "OriginTranslation: ("
     << this->OriginTranslation[0] << ","
     << this->OriginTranslation[1] << ","
     << this->OriginTranslation[2] << ")" << endl;
}

//----------------------------------------------------------------------------
// Change the information
void vtkImageChangeInformation::ExecuteInformation (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  int i;
  int extent[6], inExtent[6];
  double spacing[3], origin[3];

  inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),inExtent);

  if (this->GetInformationInput())
    {
    // If there is an InformationInput, it is set as a second input
    vtkInformation *in2Info = inputVector[1]->GetInformationObject(0);
    in2Info->Get(vtkDataObject::ORIGIN(),origin);
    in2Info->Get(vtkDataObject::SPACING(),spacing);
    in2Info->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
    for (i = 0; i < 3; i++)
      {
      extent[2*i+1] = extent[2*i] - inExtent[2*i] + inExtent[2*i+1];
      }
    }
  else
    {
    inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent);
    inInfo->Get(vtkDataObject::ORIGIN(),origin);
    inInfo->Get(vtkDataObject::SPACING(),spacing);
    }

  for (i = 0; i < 3; i++)
    {
    if (this->OutputSpacing[i] != VTK_DOUBLE_MAX)
      {
      spacing[i] = this->OutputSpacing[i];
      }

    if (this->OutputOrigin[i] != VTK_DOUBLE_MAX)
      {
      origin[i] = this->OutputOrigin[i];
      }

    if (this->OutputExtentStart[i] != VTK_INT_MAX)
      {
      extent[2*i+1] += this->OutputExtentStart[i] - extent[2*i];
      extent[2*i] = this->OutputExtentStart[i];
      }
    }

  if (this->CenterImage)
    {
    for (i = 0; i < 3; i++)
      {
      origin[i] = -(extent[2*i] + extent[2*i+1])*spacing[i]/2;
      }
    }

  for (i = 0; i < 3; i++)
    {
    spacing[i] = spacing[i]*this->SpacingScale[i];
    origin[i] = origin[i]*this->OriginScale[i] + this->OriginTranslation[i];
    extent[2*i] = extent[2*i] + this->ExtentTranslation[i];
    extent[2*i+1] = extent[2*i+1] + this->ExtentTranslation[i];
    this->FinalExtentTranslation[i] = extent[2*i] - inExtent[2*i];
    }

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
  outInfo->Set(vtkDataObject::SPACING(),spacing,3);
  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
}

//----------------------------------------------------------------------------
// This method simply copies by reference the input data to the output.
void vtkImageChangeInformation::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
    {
    vtkErrorMacro("Bug in code, ExecuteInformation was not called");
    return;
    }

  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  int extent[6];

  vtkImageData *inData = vtkImageData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkImageData *outData = vtkImageData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // since inData can be larger than update extent.
  inData->GetExtent(extent);
  for (int i = 0; i < 3; ++i)
    {
    extent[i*2] += this->FinalExtentTranslation[i];
    extent[i*2+1] += this->FinalExtentTranslation[i];
    }
  outData->SetExtent(extent);
  outData->GetPointData()->PassData(inData->GetPointData());
}

//----------------------------------------------------------------------------
void vtkImageChangeInformation::RequestUpdateExtent (
  vtkInformation * vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  if (this->FinalExtentTranslation[0] == VTK_INT_MAX)
    {
    vtkErrorMacro("Bug in code.");
    return;
    }

  int inExt[6];
  outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExt);

  inExt[0] -= this->FinalExtentTranslation[0];
  inExt[1] -= this->FinalExtentTranslation[0];
  inExt[2] -= this->FinalExtentTranslation[1];
  inExt[3] -= this->FinalExtentTranslation[1];
  inExt[4] -= this->FinalExtentTranslation[2];
  inExt[5] -= this->FinalExtentTranslation[2];

  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
}

int vtkImageChangeInformation::FillInputPortInformation(
  int port, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
  if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
    }

  return 1;
}
<|endoftext|>


<commit_before><commit_msg>Fix file extension when renaming<commit_after><|endoftext|>


<commit_before>/**
 * \file SimpleWorkerStealer.cpp
 * \date Jun 23, 2010
 * \author samael
 */

#include <ctime>
#include <cstdlib>
#include "WaitCondition.h"
#include "SimpleWorkerStealer.h"

using namespace std;
using namespace cml;

namespace wfe
{

SimpleWorkerStealer::SimpleWorkerStealer(int n):
		_runner(NULL), _mx(), _stealing(false), _num(n)
{
	srand(time(NULL));
}

void SimpleWorkerStealer::workerMissed()
{
	if (!isStealing()) {
		setStealing(true);
		if (!_runner) {
			PERR("No runner has been set.");
		} else {
			if (!_runner->runnerSocks().empty()) {
				int index = rand() % _runner->runnerSocks().size();
				_runner->sendWorkerSteal(_runner->runnerSocks()[index], 1);
			}
		}
		setStealing(false);
	}
}

}
<commit_msg><commit_after>/**
 * \file SimpleWorkerStealer.cpp
 * \date Jun 23, 2010
 * \author samael
 */

#include <ctime>
#include <cstdlib>
#include "WaitCondition.h"
#include "SimpleWorkerStealer.h"

using namespace std;
using namespace cml;

namespace wfe
{

SimpleWorkerStealer::SimpleWorkerStealer(int n):
		_runner(NULL), _mx(), _stealing(false), _num(n)
{
	srand(time(NULL));
}

void SimpleWorkerStealer::workerMissed()
{
	if (!isStealing()) {
		setStealing(true);
		if (!_runner) {
			PERR("No runner has been set.");
		} else {
			if (!_runner->runnerSocks().empty()) {
				int index = rand() % _runner->runnerSocks().size();
				_runner->sendWorkerSteal(_runner->runnerSocks()[index], _num);
			}
		}
		setStealing(false);
	}
}

}
<|endoftext|>