<commit_before>#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#include <imgui.h>

#include "aten.h"
#include "atenscene.h"
#include "idaten.h"

#include "scenedefs.h"

#define MULTI_GPU_SVGF
#define GPU_NUM	(2)

static int WIDTH = 1280;
static int HEIGHT = 720;
static const char* TITLE = "multigpu";

#ifdef ENABLE_OMP
static uint32_t g_threadnum = 8;
#else
static uint32_t g_threadnum = 1;
#endif

static aten::PinholeCamera g_camera;
static bool g_isCameraDirty = false;

static aten::AcceleratedScene<aten::GPUBvh> g_scene;

#ifdef MULTI_GPU_SVGF
static idaten::GpuProxy<idaten::SVGFPathTracingMultiGPU> g_tracer[GPU_NUM];

static aten::TAA g_taa;

static aten::FBO g_fbo;

static aten::RasterizeRenderer g_rasterizer;

using GpuProxy = idaten::GpuProxy<idaten::SVGFPathTracingMultiGPU>;
#else
static idaten::GpuProxy<idaten::PathTracingMultiGPU> g_tracer[GPU_NUM];
using GpuProxy = idaten::GpuProxy<idaten::PathTracingMultiGPU>;
#endif

#if (GPU_NUM == 4)
static const idaten::TileDomain g_tileDomain[4] = {
	{ 0, 0 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 1 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 2 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 3 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
};
#else
static const idaten::TileDomain g_tileDomain[2] = {
	{ 0, 0 * HEIGHT / 2, WIDTH, HEIGHT / 2 },
	{ 0, 1 * HEIGHT / 2, WIDTH, HEIGHT / 2 },
};
#endif

static aten::visualizer* g_visualizer = nullptr;

static bool g_willShowGUI = true;
static bool g_willTakeScreenShot = false;
static int g_cntScreenShot = 0;

static int g_maxSamples = 1;
static int g_maxBounce = 5;

void onRun(aten::window* window)
{
	if (g_isCameraDirty) {
		g_camera.update();

		auto camparam = g_camera.param();
		camparam.znear = real(0.1);
		camparam.zfar = real(10000.0);

		for (int i = 0; i < AT_COUNTOF(g_tracer); i++) {
			g_tracer[i].getRenderer().updateCamera(camparam);
		}
		g_isCameraDirty = false;

		g_visualizer->clear();
	}

	aten::timer timer;
	timer.begin();

#ifdef MULTI_GPU_SVGF
	g_rasterizer.draw(
		g_tracer[0].getRenderer().frame(),
		&g_scene,
		&g_camera,
		&g_fbo);
#endif

	for (int i = 0; i < AT_COUNTOF(g_tracer); i++) {
		g_tracer[i].render(
			g_tileDomain[i],
			g_maxSamples,
			g_maxBounce);
	}

#if (GPU_NUM == 4)
	GpuProxy::swapCopy(g_tracer, AT_COUNTOF(g_tracer));
#else
	g_tracer[0].copyP2P(g_tracer[1]);
#endif

	g_tracer[0].postRender(WIDTH, HEIGHT);

	auto cudaelapsed = timer.end();

	g_visualizer->render(false);

	if (g_willTakeScreenShot) {
		static char buffer[1024];
		::sprintf(buffer, "sc_%d.png\0", g_cntScreenShot);

		g_visualizer->takeScreenshot(buffer);

		g_willTakeScreenShot = false;
		g_cntScreenShot++;

		AT_PRINTF("Take Screenshot[%s]\n", buffer);
	}

	if (g_willShowGUI)
	{
		ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		ImGui::Text("cuda : %.3f ms", cudaelapsed);
		ImGui::Text("%.3f Mrays/sec", (WIDTH * HEIGHT * g_maxSamples) / real(1000 * 1000) * (real(1000) / cudaelapsed));

		window->drawImGui();
	}
}

void onClose()
{

}

bool g_isMouseLBtnDown = false;
bool g_isMouseRBtnDown = false;
int g_prevX = 0;
int g_prevY = 0;

void onMouseBtn(bool left, bool press, int x, int y)
{
	g_isMouseLBtnDown = false;
	g_isMouseRBtnDown = false;

	if (press) {
		g_prevX = x;
		g_prevY = y;

		g_isMouseLBtnDown = left;
		g_isMouseRBtnDown = !left;
	}
}

void onMouseMove(int x, int y)
{
	if (g_isMouseLBtnDown) {
		aten::CameraOperator::rotate(
			g_camera,
			WIDTH, HEIGHT,
			g_prevX, g_prevY,
			x, y);
		g_isCameraDirty = true;
	}
	else if (g_isMouseRBtnDown) {
		aten::CameraOperator::move(
			g_camera,
			g_prevX, g_prevY,
			x, y,
			real(0.001));
		g_isCameraDirty = true;
	}

	g_prevX = x;
	g_prevY = y;
}

void onMouseWheel(int delta)
{
	aten::CameraOperator::dolly(g_camera, delta * real(0.1));
	g_isCameraDirty = true;
}

void onKey(bool press, aten::Key key)
{
	static const real offset = real(0.1);

	if (press) {
		if (key == aten::Key::Key_F1) {
			g_willShowGUI = !g_willShowGUI;
			return;
		}
		else if (key == aten::Key::Key_F2) {
			g_willTakeScreenShot = true;
			return;
		}
	}

	if (press) {
		switch (key) {
		case aten::Key::Key_W:
		case aten::Key::Key_UP:
			aten::CameraOperator::moveForward(g_camera, offset);
			break;
		case aten::Key::Key_S:
		case aten::Key::Key_DOWN:
			aten::CameraOperator::moveForward(g_camera, -offset);
			break;
		case aten::Key::Key_D:
		case aten::Key::Key_RIGHT:
			aten::CameraOperator::moveRight(g_camera, offset);
			break;
		case aten::Key::Key_A:
		case aten::Key::Key_LEFT:
			aten::CameraOperator::moveRight(g_camera, -offset);
			break;
		case aten::Key::Key_Z:
			aten::CameraOperator::moveUp(g_camera, offset);
			break;
		case aten::Key::Key_X:
			aten::CameraOperator::moveUp(g_camera, -offset);
			break;
		case aten::Key::Key_R:
		{
			aten::vec3 pos, at;
			real vfov;
			Scene::getCameraPosAndAt(pos, at, vfov);

			g_camera.init(
				pos,
				at,
				aten::vec3(0, 1, 0),
				vfov,
				WIDTH, HEIGHT);
		}
			break;
		default:
			break;
		}

		g_isCameraDirty = true;
	}
}

int main()
{
	idaten::initCuda();

	aten::timer::init();
	aten::OMPUtil::setThreadNum(g_threadnum);

	aten::initSampler(WIDTH, HEIGHT);

	auto window = aten::window::init(
		WIDTH, HEIGHT, TITLE,
		onRun,
		onClose,
		onMouseBtn,
		onMouseMove,
		onMouseWheel,
		onKey);
	window->enableVSync(false);

	g_visualizer = aten::visualizer::init(WIDTH, HEIGHT);

#ifdef MULTI_GPU_SVGF
	g_taa.init(
		WIDTH, HEIGHT,
		"../shader/fullscreen_vs.glsl", "../shader/taa_fs.glsl",
		"../shader/fullscreen_vs.glsl", "../shader/taa_final_fs.glsl");

	g_visualizer->addPostProc(&g_taa);

	g_rasterizer.init(
		WIDTH, HEIGHT,
		"../shader/ssrt_vs.glsl",
		"../shader/ssrt_gs.glsl",
		"../shader/ssrt_fs.glsl");

	g_fbo.asMulti(2);
	g_fbo.init(
		WIDTH, HEIGHT,
		aten::PixelFormat::rgba32f,
		true);

	g_taa.setMotionDepthBufferHandle(g_fbo.getTexHandle(1));
#endif

	aten::GammaCorrection gamma;
	gamma.init(
		WIDTH, HEIGHT,
		"../shader/fullscreen_vs.glsl",
		"../shader/gamma_fs.glsl");

	g_visualizer->addPostProc(&gamma);

	aten::vec3 pos, at;
	real vfov;
	Scene::getCameraPosAndAt(pos, at, vfov);

	g_camera.init(
		pos,
		at,
		aten::vec3(0, 1, 0),
		vfov,
		WIDTH, HEIGHT);

	Scene::makeScene(&g_scene);
	g_scene.build();

	auto envmap = aten::ImageLoader::load("../../asset/envmap/studio015.hdr");
	aten::envmap bg;
	bg.init(envmap);
	aten::ImageBasedLight ibl(&bg);

	g_scene.addImageBasedLight(&ibl);

	std::vector<aten::GeomParameter> shapeparams;
	std::vector<aten::PrimitiveParamter> primparams;
	std::vector<aten::LightParameter> lightparams;
	std::vector<aten::MaterialParameter> mtrlparms;
	std::vector<aten::vertex> vtxparams;

	aten::DataCollector::collect(
		shapeparams,
		primparams,
		lightparams,
		mtrlparms,
		vtxparams);

	const auto& nodes = g_scene.getAccel()->getNodes();
	const auto& mtxs = g_scene.getAccel()->getMatrices();

	std::vector<idaten::TextureResource> tex;
	{
		auto texs = aten::texture::getTextures();

		for (const auto t : texs) {
			tex.push_back(
				idaten::TextureResource(t->colors(), t->width(), t->height()));
		}
	}

	for (auto& l : lightparams) {
		if (l.type == aten::LightType::IBL) {
			l.envmap.idx = envmap->id();
		}
	}

	auto camparam = g_camera.param();
	camparam.znear = real(0.1);
	camparam.zfar = real(10000.0);

	g_tracer[0].init(0);
	g_tracer[1].init(1);

	// Set P2P access between GPUs.
	g_tracer[0].setPeerAccess(1);
	g_tracer[1].setPeerAccess(0);

#if (GPU_NUM == 4)
	g_tracer[2].init(2);
	g_tracer[3].init(3);

	g_tracer[2].setPeerAccess(3);
	g_tracer[3].setPeerAccess(2);
#endif

	for (int i = 0; i < AT_COUNTOF(g_tracer); i++)
	{
		const auto& tileDomain = g_tileDomain[i];

		g_tracer[i].setCurrent();

		g_tracer[i].getRenderer().getCompaction().init(
			tileDomain.w * tileDomain.h,
			1024);

		int w = i == 0 ? WIDTH : tileDomain.w;
		int h = i == 0 ? HEIGHT : tileDomain.h;

		h = i == 2 ? HEIGHT / 2 : h;

		g_tracer[i].getRenderer().update(
			aten::visualizer::getTexHandle(),
			w, h,
			camparam,
			shapeparams,
			mtrlparms,
			lightparams,
			nodes,
			primparams,
			vtxparams,
			mtxs,
			tex, idaten::EnvmapResource(envmap->id(), ibl.getAvgIlluminace(), real(4)));

#ifdef MULTI_GPU_SVGF
		g_tracer[i].getRenderer().setGBuffer(
			g_fbo.getTexHandle(0),
			g_fbo.getTexHandle(1));
#endif
	}

	aten::window::run();

	aten::window::terminate();
}
<commit_msg>Modify to try for single gpu.<commit_after>#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#include <imgui.h>

#include "aten.h"
#include "atenscene.h"
#include "idaten.h"

#include "scenedefs.h"

#define MULTI_GPU_SVGF
#define GPU_NUM	(2)

static int WIDTH = 1280;
static int HEIGHT = 720;
static const char* TITLE = "multigpu";

#ifdef ENABLE_OMP
static uint32_t g_threadnum = 8;
#else
static uint32_t g_threadnum = 1;
#endif

static aten::PinholeCamera g_camera;
static bool g_isCameraDirty = false;

static aten::AcceleratedScene<aten::GPUBvh> g_scene;

#ifdef MULTI_GPU_SVGF
static idaten::GpuProxy<idaten::SVGFPathTracingMultiGPU> g_tracer[GPU_NUM];

static aten::TAA g_taa;

static aten::FBO g_fbo;

static aten::RasterizeRenderer g_rasterizer;

using GpuProxy = idaten::GpuProxy<idaten::SVGFPathTracingMultiGPU>;
#else
static idaten::GpuProxy<idaten::PathTracingMultiGPU> g_tracer[GPU_NUM];
using GpuProxy = idaten::GpuProxy<idaten::PathTracingMultiGPU>;
#endif

#if (GPU_NUM == 4)
static const idaten::TileDomain g_tileDomain[4] = {
	{ 0, 0 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 1 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 2 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
	{ 0, 3 * HEIGHT / 4, WIDTH, HEIGHT / 4 },
};
#else
static const idaten::TileDomain g_tileDomain[2] = {
	{ 0, 0 * HEIGHT / 2, WIDTH, HEIGHT / 2 },
	{ 0, 1 * HEIGHT / 2, WIDTH, HEIGHT / 2 },
};
#endif

static aten::visualizer* g_visualizer = nullptr;

static bool g_willShowGUI = true;
static bool g_willTakeScreenShot = false;
static int g_cntScreenShot = 0;

static int g_maxSamples = 1;
static int g_maxBounce = 5;

void onRun(aten::window* window)
{
	if (g_isCameraDirty) {
		g_camera.update();

		auto camparam = g_camera.param();
		camparam.znear = real(0.1);
		camparam.zfar = real(10000.0);

		for (int i = 0; i < AT_COUNTOF(g_tracer); i++) {
			g_tracer[i].getRenderer().updateCamera(camparam);
		}
		g_isCameraDirty = false;

		g_visualizer->clear();
	}

	aten::timer timer;
	timer.begin();

#ifdef MULTI_GPU_SVGF
	g_rasterizer.draw(
		g_tracer[0].getRenderer().frame(),
		&g_scene,
		&g_camera,
		&g_fbo);
#endif

	for (int i = 0; i < AT_COUNTOF(g_tracer); i++) {
		g_tracer[i].render(
			g_tileDomain[i],
			g_maxSamples,
			g_maxBounce);
	}

#if (GPU_NUM == 4)
	GpuProxy::swapCopy(g_tracer, AT_COUNTOF(g_tracer));
#else
	for (int i = 1; i < AT_COUNTOF(g_tracer); i++) {
		g_tracer[0].copyP2P(g_tracer[1]);
	}
#endif

	g_tracer[0].postRender(WIDTH, HEIGHT);

	auto cudaelapsed = timer.end();

	g_visualizer->render(false);

	if (g_willTakeScreenShot) {
		static char buffer[1024];
		::sprintf(buffer, "sc_%d.png\0", g_cntScreenShot);

		g_visualizer->takeScreenshot(buffer);

		g_willTakeScreenShot = false;
		g_cntScreenShot++;

		AT_PRINTF("Take Screenshot[%s]\n", buffer);
	}

	if (g_willShowGUI)
	{
		ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		ImGui::Text("cuda : %.3f ms", cudaelapsed);
		ImGui::Text("%.3f Mrays/sec", (WIDTH * HEIGHT * g_maxSamples) / real(1000 * 1000) * (real(1000) / cudaelapsed));

		window->drawImGui();
	}
}

void onClose()
{

}

bool g_isMouseLBtnDown = false;
bool g_isMouseRBtnDown = false;
int g_prevX = 0;
int g_prevY = 0;

void onMouseBtn(bool left, bool press, int x, int y)
{
	g_isMouseLBtnDown = false;
	g_isMouseRBtnDown = false;

	if (press) {
		g_prevX = x;
		g_prevY = y;

		g_isMouseLBtnDown = left;
		g_isMouseRBtnDown = !left;
	}
}

void onMouseMove(int x, int y)
{
	if (g_isMouseLBtnDown) {
		aten::CameraOperator::rotate(
			g_camera,
			WIDTH, HEIGHT,
			g_prevX, g_prevY,
			x, y);
		g_isCameraDirty = true;
	}
	else if (g_isMouseRBtnDown) {
		aten::CameraOperator::move(
			g_camera,
			g_prevX, g_prevY,
			x, y,
			real(0.001));
		g_isCameraDirty = true;
	}

	g_prevX = x;
	g_prevY = y;
}

void onMouseWheel(int delta)
{
	aten::CameraOperator::dolly(g_camera, delta * real(0.1));
	g_isCameraDirty = true;
}

void onKey(bool press, aten::Key key)
{
	static const real offset = real(0.1);

	if (press) {
		if (key == aten::Key::Key_F1) {
			g_willShowGUI = !g_willShowGUI;
			return;
		}
		else if (key == aten::Key::Key_F2) {
			g_willTakeScreenShot = true;
			return;
		}
	}

	if (press) {
		switch (key) {
		case aten::Key::Key_W:
		case aten::Key::Key_UP:
			aten::CameraOperator::moveForward(g_camera, offset);
			break;
		case aten::Key::Key_S:
		case aten::Key::Key_DOWN:
			aten::CameraOperator::moveForward(g_camera, -offset);
			break;
		case aten::Key::Key_D:
		case aten::Key::Key_RIGHT:
			aten::CameraOperator::moveRight(g_camera, offset);
			break;
		case aten::Key::Key_A:
		case aten::Key::Key_LEFT:
			aten::CameraOperator::moveRight(g_camera, -offset);
			break;
		case aten::Key::Key_Z:
			aten::CameraOperator::moveUp(g_camera, offset);
			break;
		case aten::Key::Key_X:
			aten::CameraOperator::moveUp(g_camera, -offset);
			break;
		case aten::Key::Key_R:
		{
			aten::vec3 pos, at;
			real vfov;
			Scene::getCameraPosAndAt(pos, at, vfov);

			g_camera.init(
				pos,
				at,
				aten::vec3(0, 1, 0),
				vfov,
				WIDTH, HEIGHT);
		}
			break;
		default:
			break;
		}

		g_isCameraDirty = true;
	}
}

int main()
{
	idaten::initCuda();

	aten::timer::init();
	aten::OMPUtil::setThreadNum(g_threadnum);

	aten::initSampler(WIDTH, HEIGHT);

	auto window = aten::window::init(
		WIDTH, HEIGHT, TITLE,
		onRun,
		onClose,
		onMouseBtn,
		onMouseMove,
		onMouseWheel,
		onKey);
	window->enableVSync(false);

	g_visualizer = aten::visualizer::init(WIDTH, HEIGHT);

#ifdef MULTI_GPU_SVGF
	g_taa.init(
		WIDTH, HEIGHT,
		"../shader/fullscreen_vs.glsl", "../shader/taa_fs.glsl",
		"../shader/fullscreen_vs.glsl", "../shader/taa_final_fs.glsl");

	g_visualizer->addPostProc(&g_taa);

	g_rasterizer.init(
		WIDTH, HEIGHT,
		"../shader/ssrt_vs.glsl",
		"../shader/ssrt_gs.glsl",
		"../shader/ssrt_fs.glsl");

	g_fbo.asMulti(2);
	g_fbo.init(
		WIDTH, HEIGHT,
		aten::PixelFormat::rgba32f,
		true);

	g_taa.setMotionDepthBufferHandle(g_fbo.getTexHandle(1));
#endif

	aten::GammaCorrection gamma;
	gamma.init(
		WIDTH, HEIGHT,
		"../shader/fullscreen_vs.glsl",
		"../shader/gamma_fs.glsl");

	g_visualizer->addPostProc(&gamma);

	aten::vec3 pos, at;
	real vfov;
	Scene::getCameraPosAndAt(pos, at, vfov);

	g_camera.init(
		pos,
		at,
		aten::vec3(0, 1, 0),
		vfov,
		WIDTH, HEIGHT);

	Scene::makeScene(&g_scene);
	g_scene.build();

	auto envmap = aten::ImageLoader::load("../../asset/envmap/studio015.hdr");
	aten::envmap bg;
	bg.init(envmap);
	aten::ImageBasedLight ibl(&bg);

	g_scene.addImageBasedLight(&ibl);

	std::vector<aten::GeomParameter> shapeparams;
	std::vector<aten::PrimitiveParamter> primparams;
	std::vector<aten::LightParameter> lightparams;
	std::vector<aten::MaterialParameter> mtrlparms;
	std::vector<aten::vertex> vtxparams;

	aten::DataCollector::collect(
		shapeparams,
		primparams,
		lightparams,
		mtrlparms,
		vtxparams);

	const auto& nodes = g_scene.getAccel()->getNodes();
	const auto& mtxs = g_scene.getAccel()->getMatrices();

	std::vector<idaten::TextureResource> tex;
	{
		auto texs = aten::texture::getTextures();

		for (const auto t : texs) {
			tex.push_back(
				idaten::TextureResource(t->colors(), t->width(), t->height()));
		}
	}

	for (auto& l : lightparams) {
		if (l.type == aten::LightType::IBL) {
			l.envmap.idx = envmap->id();
		}
	}

	auto camparam = g_camera.param();
	camparam.znear = real(0.1);
	camparam.zfar = real(10000.0);

	g_tracer[0].init(0);
	g_tracer[1].init(1);

	// Set P2P access between GPUs.
	g_tracer[0].setPeerAccess(1);
	g_tracer[1].setPeerAccess(0);

#if (GPU_NUM == 4)
	g_tracer[2].init(2);
	g_tracer[3].init(3);

	g_tracer[2].setPeerAccess(3);
	g_tracer[3].setPeerAccess(2);
#endif

	for (int i = 0; i < AT_COUNTOF(g_tracer); i++)
	{
		const auto& tileDomain = g_tileDomain[i];

		g_tracer[i].setCurrent();

		g_tracer[i].getRenderer().getCompaction().init(
			tileDomain.w * tileDomain.h,
			1024);

		int w = i == 0 ? WIDTH : tileDomain.w;
		int h = i == 0 ? HEIGHT : tileDomain.h;

		h = i == 2 ? HEIGHT / 2 : h;

		g_tracer[i].getRenderer().update(
			aten::visualizer::getTexHandle(),
			w, h,
			camparam,
			shapeparams,
			mtrlparms,
			lightparams,
			nodes,
			primparams,
			vtxparams,
			mtxs,
			tex, idaten::EnvmapResource(envmap->id(), ibl.getAvgIlluminace(), real(4)));

#ifdef MULTI_GPU_SVGF
		g_tracer[i].getRenderer().setGBuffer(
			g_fbo.getTexHandle(0),
			g_fbo.getTexHandle(1));
#endif
	}

	aten::window::run();

	aten::window::terminate();
}
<|endoftext|>


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

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.commontk.org/LICENSE

  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.

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

// Qt includes
#include <QDebug>

// CTK includes
#include "ctkLogger.h"
#include "ctkVTKScalarsToColorsView.h"
#include "ctkVTKScalarsToColorsWidget.h"
#include "ui_ctkVTKScalarsToColorsWidget.h"

// VTK includes
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkColorTransferControlPointsItem.h>
#include <vtkColorTransferFunction.h>
#include <vtkColorTransferFunctionItem.h>
#include <vtkCompositeControlPointsItem.h>
#include <vtkCompositeTransferFunctionItem.h>
#include <vtkContextScene.h>
#include <vtkLookupTable.h>
#include <vtkLookupTableItem.h>
#include <vtkPiecewiseControlPointsItem.h>
#include <vtkPiecewiseFunction.h>
#include <vtkPiecewiseFunctionItem.h>

//----------------------------------------------------------------------------
static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKScalarsToColorsWidget");
//----------------------------------------------------------------------------

class ctkVTKScalarsToColorsWidgetPrivate:
  public Ui_ctkVTKScalarsToColorsWidget
{
   Q_DECLARE_PUBLIC(ctkVTKScalarsToColorsWidget);
protected:
  ctkVTKScalarsToColorsWidget* const q_ptr;
public:
  ctkVTKScalarsToColorsWidgetPrivate(ctkVTKScalarsToColorsWidget& object);
  void setupUi(QWidget* widget);

  bool blockSignals(bool);

  vtkControlPointsItem* CurrentControlPointsItem;
};

// ----------------------------------------------------------------------------
// ctkVTKScalarsToColorsWidgetPrivate methods

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsWidgetPrivate::ctkVTKScalarsToColorsWidgetPrivate(
  ctkVTKScalarsToColorsWidget& object)
  : q_ptr(&object)
{
  this->CurrentControlPointsItem = 0;
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidgetPrivate::setupUi(QWidget* widget)
{
  Q_Q(ctkVTKScalarsToColorsWidget);
  this->Ui_ctkVTKScalarsToColorsWidget::setupUi(widget);
  QObject::connect(this->View, SIGNAL(plotAdded(vtkPlot*)),
                   q, SLOT(onPlotAdded(vtkPlot*)));
  QObject::connect(this->View, SIGNAL(boundsChanged()),
                   q, SLOT(onBoundsChanged()));

  this->PointIdSpinBox->setSpecialValueText("None");
  QObject::connect(this->PointIdSpinBox, SIGNAL(valueChanged(int)),
                   q, SLOT(onCurrentPointChanged(int)));
  this->PointIdSpinBox->setValue(-1);
  QObject::connect(this->ColorPickerButton, SIGNAL(colorChanged(const QColor&)),
                   q, SLOT(onColorChanged(const QColor&)));
  QObject::connect(this->OpacitySpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onOpacityChanged(double)));
  QObject::connect(this->MidPointSpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onMidPointChanged(double)));
  QObject::connect(this->SharpnessSpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onSharpnessChanged(double)));
  this->ColorPickerButton->setVisible(false);
  this->OpacityLabel->setVisible(false);
  this->OpacitySpinBox->setVisible(false);
  QObject::connect(this->XRangeSlider, SIGNAL(valuesChanged(double, double)),
                   q, SLOT(onXRangeChanged(double, double)));
  QObject::connect(this->YRangeSlider, SIGNAL(valuesChanged(double, double)),
                   q, SLOT(onYRangeChanged(double, double)));
  q->qvtkConnect(this->View->chart()->GetAxis(0),vtkCommand::ModifiedEvent,
                    q, SLOT(onAxesModified()));
  q->qvtkConnect(this->View->chart()->GetAxis(1),vtkCommand::ModifiedEvent,
                    q, SLOT(onAxesModified()));

}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidget::blockSignals(bool block)
{
  d->ColorPickerButton->blockSignals(block);
  d->OpacitySpinBox->blockSignals(block);
  d->MidPointSpinBox->blockSignals(block);
  return d->SharpnessSpinBox->blockSignals(block);
}

// ----------------------------------------------------------------------------
// ctkVTKScalarsToColorsWidget methods

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsWidget::ctkVTKScalarsToColorsWidget(QWidget* parentWidget)
  :QWidget(parentWidget)
   , d_ptr(new ctkVTKScalarsToColorsWidgetPrivate(*this))
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->setupUi(this);
}

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

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsView* ctkVTKScalarsToColorsWidget::view()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->View;
}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidget::isHorizontalSliderVisible()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->XRangeSlider->isVisibleTo(
    const_cast<ctkVTKScalarsToColorsWidget*>(this));
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setHorizontalSliderVisible(bool visible)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->XRangeSlider->setVisible(visible);
}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidget::isVerticalSliderVisible()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->YRangeSlider->isVisibleTo(
    const_cast<ctkVTKScalarsToColorsWidget*>(this));
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setVerticalSliderVisible(bool visible)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->YRangeSlider->setVisible(visible);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onPlotAdded(vtkPlot* plot)
{
  if (vtkControlPointsItem::SafeDownCast(plot))
    {
    this->qvtkConnect(plot, vtkControlPointsItem::CurrentPointChangedEvent,
                      this, SLOT(setCurrentPoint(vtkObject*, void*)));
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onBoundsChanged()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  double bounds[8];
  d->View->chartBounds(bounds);
  d->XRangeSlider->setMinimum(bounds[vtkAxis::BOTTOM * 2]);
  d->XRangeSlider->setMaximum(bounds[vtkAxis::BOTTOM * 2 + 1]);
  d->YRangeSlider->setMinimum(bounds[vtkAxis::LEFT * 2]);
  d->YRangeSlider->setMaximum(bounds[vtkAxis::LEFT * 2 + 1]);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentPoint(vtkObject* caller, void* callData)
{
  vtkControlPointsItem* controlPoints = reinterpret_cast<vtkControlPointsItem*>(caller);
  long newPoint = reinterpret_cast<long>(callData);
  if (!controlPoints || newPoint < -1)
    {
    return;
    }
  this->setCurrentControlPointsItem(controlPoints);
  this->setCurrentPoint(newPoint);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentPoint(int newPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->PointIdSpinBox->setValue(newPoint);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentControlPointsItem(vtkControlPointsItem* item)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (d->CurrentControlPointsItem == item)
    {
    return;
    }
  this->qvtkReconnect(d->CurrentControlPointsItem, item, vtkCommand::ModifiedEvent,
                      this, SLOT(updateCurrentPoint()));
  this->qvtkReconnect(d->CurrentControlPointsItem ?
                      d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(0),
                      item ? item->GetXAxis() : d->View->chart()->GetAxis(0),
                      vtkCommand::ModifiedEvent,
                      this, SLOT(onAxesModified()));
  this->qvtkReconnect(d->CurrentControlPointsItem ?
                      d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(1),
                      item ? item->GetYAxis() : d->View->chart()->GetAxis(1),
                      vtkCommand::ModifiedEvent,
                      this, SLOT(onAxesModified()));
  d->CurrentControlPointsItem = item;
  if (item)
    {
    d->ColorPickerButton->setVisible(
      vtkColorTransferControlPointsItem::SafeDownCast(item) != 0 ||
      vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    d->OpacityLabel->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
                                vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    d->OpacitySpinBox->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
                                  vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    this->onAxesModified();
    }
  d->PointIdSpinBox->setEnabled(item != 0);
  d->PointIdSpinBox->setMaximum((item ? item->GetNumberOfPoints() : 0) - 1);
  d->PointIdSpinBox->setValue(item ? item->GetCurrentPoint() : -1);
  this->updateCurrentPoint();
}

// ----------------------------------------------------------------------------
vtkControlPointsItem* ctkVTKScalarsToColorsWidget::currentControlPointsItem()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->CurrentControlPointsItem;
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onCurrentPointChanged(int currentPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (d->CurrentControlPointsItem)
    {
    d->CurrentControlPointsItem->SetCurrentPoint(currentPoint);
    }

  d->ColorPickerButton->setEnabled(currentPoint != -1);
  d->OpacitySpinBox->setEnabled(currentPoint != -1);
  d->MidPointSpinBox->setEnabled(currentPoint != -1);
  d->SharpnessSpinBox->setEnabled(currentPoint != -1);

  if (d->CurrentControlPointsItem)
    {
    this->updateCurrentPoint();
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::updateCurrentPoint()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);
  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());
  d->PointIdSpinBox->setMaximum((d->CurrentControlPointsItem ?
                                 d->CurrentControlPointsItem->GetNumberOfPoints() : 0) - 1);

  int pointId = d->PointIdSpinBox->value();
  if (pointId == -1)
    {
    return;
    }

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(pointId, point);

  bool oldBlock = d->blockSignals(true);
  d->OpacitySpinBox->setValue(point[1]);
  d->MidPointSpinBox->setValue(point[2]);
  d->SharpnessSpinBox->setValue(point[3]);

  vtkColorTransferControlPointsItem* colorControlPoints =
    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
  if (colorControlPoints)
    {
    vtkColorTransferFunction* colorTF =
      colorControlPoints->GetColorTransferFunction();
    double xrgbms[6];
    colorTF->GetNodeValue(d->PointIdSpinBox->value(), xrgbms);
    QColor color = QColor::fromRgbF(xrgbms[1], xrgbms[2], xrgbms[3]);
    d->ColorPickerButton->setColor(color);
    }
  d->blockSignals(oldBlock);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onColorChanged(const QColor& color)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (!color.isValid())
    {
    return;
    }
  Q_ASSERT(d->CurrentControlPointsItem);
  Q_ASSERT(d->PointIdSpinBox->value() != -1);
  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());

  vtkColorTransferControlPointsItem* colorControlPoints =
    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
  if (colorControlPoints)
    {
    vtkColorTransferFunction* colorTF =
      colorControlPoints->GetColorTransferFunction();
    double point[6];
    colorTF->GetNodeValue(d->PointIdSpinBox->value(), point);
    point[1] = color.redF();
    point[2] = color.greenF();
    point[3] = color.blueF();
    colorTF->SetNodeValue(d->PointIdSpinBox->value(), point);
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onOpacityChanged(double opacity)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[1] = opacity;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onMidPointChanged(double midPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[2] = midPoint;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onSharpnessChanged(double sharpness)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[3] = sharpness;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onXRangeChanged(double min, double max)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* xAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
  Q_ASSERT(xAxis);
  xAxis->SetRange(min, max);
  d->View->scene()->SetDirty(true);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onYRangeChanged(double min, double max)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* yAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
  Q_ASSERT(yAxis);
  yAxis->SetRange(min, max);
  d->View->scene()->SetDirty(true);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onAxesModified()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* xAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
  Q_ASSERT(xAxis);
  d->XRangeSlider->setValues(xAxis->GetMinimum(), xAxis->GetMaximum());
  vtkAxis* yAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
  Q_ASSERT(yAxis);
  d->YRangeSlider->setValues(yAxis->GetMinimum(), yAxis->GetMaximum());
}
<commit_msg>Fixup ctkVTKScalarsToColorsWidgetPrivate::blockSignals()<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.commontk.org/LICENSE

  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.

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

// Qt includes
#include <QDebug>

// CTK includes
#include "ctkLogger.h"
#include "ctkVTKScalarsToColorsView.h"
#include "ctkVTKScalarsToColorsWidget.h"
#include "ui_ctkVTKScalarsToColorsWidget.h"

// VTK includes
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkColorTransferControlPointsItem.h>
#include <vtkColorTransferFunction.h>
#include <vtkColorTransferFunctionItem.h>
#include <vtkCompositeControlPointsItem.h>
#include <vtkCompositeTransferFunctionItem.h>
#include <vtkContextScene.h>
#include <vtkLookupTable.h>
#include <vtkLookupTableItem.h>
#include <vtkPiecewiseControlPointsItem.h>
#include <vtkPiecewiseFunction.h>
#include <vtkPiecewiseFunctionItem.h>

//----------------------------------------------------------------------------
static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKScalarsToColorsWidget");
//----------------------------------------------------------------------------

class ctkVTKScalarsToColorsWidgetPrivate:
  public Ui_ctkVTKScalarsToColorsWidget
{
   Q_DECLARE_PUBLIC(ctkVTKScalarsToColorsWidget);
protected:
  ctkVTKScalarsToColorsWidget* const q_ptr;
public:
  ctkVTKScalarsToColorsWidgetPrivate(ctkVTKScalarsToColorsWidget& object);
  void setupUi(QWidget* widget);

  bool blockSignals(bool);

  vtkControlPointsItem* CurrentControlPointsItem;
};

// ----------------------------------------------------------------------------
// ctkVTKScalarsToColorsWidgetPrivate methods

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsWidgetPrivate::ctkVTKScalarsToColorsWidgetPrivate(
  ctkVTKScalarsToColorsWidget& object)
  : q_ptr(&object)
{
  this->CurrentControlPointsItem = 0;
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidgetPrivate::setupUi(QWidget* widget)
{
  Q_Q(ctkVTKScalarsToColorsWidget);
  this->Ui_ctkVTKScalarsToColorsWidget::setupUi(widget);
  QObject::connect(this->View, SIGNAL(plotAdded(vtkPlot*)),
                   q, SLOT(onPlotAdded(vtkPlot*)));
  QObject::connect(this->View, SIGNAL(boundsChanged()),
                   q, SLOT(onBoundsChanged()));

  this->PointIdSpinBox->setSpecialValueText("None");
  QObject::connect(this->PointIdSpinBox, SIGNAL(valueChanged(int)),
                   q, SLOT(onCurrentPointChanged(int)));
  this->PointIdSpinBox->setValue(-1);
  QObject::connect(this->ColorPickerButton, SIGNAL(colorChanged(const QColor&)),
                   q, SLOT(onColorChanged(const QColor&)));
  QObject::connect(this->OpacitySpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onOpacityChanged(double)));
  QObject::connect(this->MidPointSpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onMidPointChanged(double)));
  QObject::connect(this->SharpnessSpinBox, SIGNAL(valueChanged(double)),
                   q, SLOT(onSharpnessChanged(double)));
  this->ColorPickerButton->setVisible(false);
  this->OpacityLabel->setVisible(false);
  this->OpacitySpinBox->setVisible(false);
  QObject::connect(this->XRangeSlider, SIGNAL(valuesChanged(double, double)),
                   q, SLOT(onXRangeChanged(double, double)));
  QObject::connect(this->YRangeSlider, SIGNAL(valuesChanged(double, double)),
                   q, SLOT(onYRangeChanged(double, double)));
  q->qvtkConnect(this->View->chart()->GetAxis(0),vtkCommand::ModifiedEvent,
                    q, SLOT(onAxesModified()));
  q->qvtkConnect(this->View->chart()->GetAxis(1),vtkCommand::ModifiedEvent,
                    q, SLOT(onAxesModified()));

}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidgetPrivate::blockSignals(bool block)
{
  this->ColorPickerButton->blockSignals(block);
  this->OpacitySpinBox->blockSignals(block);
  this->MidPointSpinBox->blockSignals(block);
  return this->SharpnessSpinBox->blockSignals(block);
}

// ----------------------------------------------------------------------------
// ctkVTKScalarsToColorsWidget methods

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsWidget::ctkVTKScalarsToColorsWidget(QWidget* parentWidget)
  :QWidget(parentWidget)
   , d_ptr(new ctkVTKScalarsToColorsWidgetPrivate(*this))
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->setupUi(this);
}

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

// ----------------------------------------------------------------------------
ctkVTKScalarsToColorsView* ctkVTKScalarsToColorsWidget::view()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->View;
}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidget::isHorizontalSliderVisible()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->XRangeSlider->isVisibleTo(
    const_cast<ctkVTKScalarsToColorsWidget*>(this));
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setHorizontalSliderVisible(bool visible)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->XRangeSlider->setVisible(visible);
}

// ----------------------------------------------------------------------------
bool ctkVTKScalarsToColorsWidget::isVerticalSliderVisible()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->YRangeSlider->isVisibleTo(
    const_cast<ctkVTKScalarsToColorsWidget*>(this));
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setVerticalSliderVisible(bool visible)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->YRangeSlider->setVisible(visible);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onPlotAdded(vtkPlot* plot)
{
  if (vtkControlPointsItem::SafeDownCast(plot))
    {
    this->qvtkConnect(plot, vtkControlPointsItem::CurrentPointChangedEvent,
                      this, SLOT(setCurrentPoint(vtkObject*, void*)));
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onBoundsChanged()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  double bounds[8];
  d->View->chartBounds(bounds);
  d->XRangeSlider->setMinimum(bounds[vtkAxis::BOTTOM * 2]);
  d->XRangeSlider->setMaximum(bounds[vtkAxis::BOTTOM * 2 + 1]);
  d->YRangeSlider->setMinimum(bounds[vtkAxis::LEFT * 2]);
  d->YRangeSlider->setMaximum(bounds[vtkAxis::LEFT * 2 + 1]);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentPoint(vtkObject* caller, void* callData)
{
  vtkControlPointsItem* controlPoints = reinterpret_cast<vtkControlPointsItem*>(caller);
  long newPoint = reinterpret_cast<long>(callData);
  if (!controlPoints || newPoint < -1)
    {
    return;
    }
  this->setCurrentControlPointsItem(controlPoints);
  this->setCurrentPoint(newPoint);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentPoint(int newPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  d->PointIdSpinBox->setValue(newPoint);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::setCurrentControlPointsItem(vtkControlPointsItem* item)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (d->CurrentControlPointsItem == item)
    {
    return;
    }
  this->qvtkReconnect(d->CurrentControlPointsItem, item, vtkCommand::ModifiedEvent,
                      this, SLOT(updateCurrentPoint()));
  this->qvtkReconnect(d->CurrentControlPointsItem ?
                      d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(0),
                      item ? item->GetXAxis() : d->View->chart()->GetAxis(0),
                      vtkCommand::ModifiedEvent,
                      this, SLOT(onAxesModified()));
  this->qvtkReconnect(d->CurrentControlPointsItem ?
                      d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(1),
                      item ? item->GetYAxis() : d->View->chart()->GetAxis(1),
                      vtkCommand::ModifiedEvent,
                      this, SLOT(onAxesModified()));
  d->CurrentControlPointsItem = item;
  if (item)
    {
    d->ColorPickerButton->setVisible(
      vtkColorTransferControlPointsItem::SafeDownCast(item) != 0 ||
      vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    d->OpacityLabel->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
                                vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    d->OpacitySpinBox->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
                                  vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
    this->onAxesModified();
    }
  d->PointIdSpinBox->setEnabled(item != 0);
  d->PointIdSpinBox->setMaximum((item ? item->GetNumberOfPoints() : 0) - 1);
  d->PointIdSpinBox->setValue(item ? item->GetCurrentPoint() : -1);
  this->updateCurrentPoint();
}

// ----------------------------------------------------------------------------
vtkControlPointsItem* ctkVTKScalarsToColorsWidget::currentControlPointsItem()const
{
  Q_D(const ctkVTKScalarsToColorsWidget);
  return d->CurrentControlPointsItem;
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onCurrentPointChanged(int currentPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (d->CurrentControlPointsItem)
    {
    d->CurrentControlPointsItem->SetCurrentPoint(currentPoint);
    }

  d->ColorPickerButton->setEnabled(currentPoint != -1);
  d->OpacitySpinBox->setEnabled(currentPoint != -1);
  d->MidPointSpinBox->setEnabled(currentPoint != -1);
  d->SharpnessSpinBox->setEnabled(currentPoint != -1);

  if (d->CurrentControlPointsItem)
    {
    this->updateCurrentPoint();
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::updateCurrentPoint()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);
  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());
  d->PointIdSpinBox->setMaximum((d->CurrentControlPointsItem ?
                                 d->CurrentControlPointsItem->GetNumberOfPoints() : 0) - 1);

  int pointId = d->PointIdSpinBox->value();
  if (pointId == -1)
    {
    return;
    }

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(pointId, point);

  bool oldBlock = d->blockSignals(true);
  d->OpacitySpinBox->setValue(point[1]);
  d->MidPointSpinBox->setValue(point[2]);
  d->SharpnessSpinBox->setValue(point[3]);

  vtkColorTransferControlPointsItem* colorControlPoints =
    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
  if (colorControlPoints)
    {
    vtkColorTransferFunction* colorTF =
      colorControlPoints->GetColorTransferFunction();
    double xrgbms[6];
    colorTF->GetNodeValue(d->PointIdSpinBox->value(), xrgbms);
    QColor color = QColor::fromRgbF(xrgbms[1], xrgbms[2], xrgbms[3]);
    d->ColorPickerButton->setColor(color);
    }
  d->blockSignals(oldBlock);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onColorChanged(const QColor& color)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  if (!color.isValid())
    {
    return;
    }
  Q_ASSERT(d->CurrentControlPointsItem);
  Q_ASSERT(d->PointIdSpinBox->value() != -1);
  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());

  vtkColorTransferControlPointsItem* colorControlPoints =
    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
  if (colorControlPoints)
    {
    vtkColorTransferFunction* colorTF =
      colorControlPoints->GetColorTransferFunction();
    double point[6];
    colorTF->GetNodeValue(d->PointIdSpinBox->value(), point);
    point[1] = color.redF();
    point[2] = color.greenF();
    point[3] = color.blueF();
    colorTF->SetNodeValue(d->PointIdSpinBox->value(), point);
    }
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onOpacityChanged(double opacity)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[1] = opacity;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onMidPointChanged(double midPoint)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[2] = midPoint;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onSharpnessChanged(double sharpness)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  Q_ASSERT(d->CurrentControlPointsItem);

  double point[4];
  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
  point[3] = sharpness;
  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onXRangeChanged(double min, double max)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* xAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
  Q_ASSERT(xAxis);
  xAxis->SetRange(min, max);
  d->View->scene()->SetDirty(true);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onYRangeChanged(double min, double max)
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* yAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
  Q_ASSERT(yAxis);
  yAxis->SetRange(min, max);
  d->View->scene()->SetDirty(true);
}

// ----------------------------------------------------------------------------
void ctkVTKScalarsToColorsWidget::onAxesModified()
{
  Q_D(ctkVTKScalarsToColorsWidget);
  vtkAxis* xAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
  Q_ASSERT(xAxis);
  d->XRangeSlider->setValues(xAxis->GetMinimum(), xAxis->GetMaximum());
  vtkAxis* yAxis = d->CurrentControlPointsItem ?
    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
  Q_ASSERT(yAxis);
  d->YRangeSlider->setValues(yAxis->GetMinimum(), yAxis->GetMaximum());
}
<|endoftext|>


<commit_before>/** @file

  Record compatibility definitions

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "libts.h"
#include "P_RecFile.h"
#include "P_RecDefs.h"
#include "P_RecUtils.h"

//-------------------------------------------------------------------------
// RecFileOpenR
//-------------------------------------------------------------------------

RecHandle
RecFileOpenR(const char *file)
{
  RecHandle h_file;
  return ((h_file =::open(file, O_RDONLY)) < 0) ? REC_HANDLE_INVALID : h_file;
}

//-------------------------------------------------------------------------
// RecFileOpenW
//-------------------------------------------------------------------------

RecHandle
RecFileOpenW(const char *file)
{
  RecHandle h_file;

  if ((h_file =::open(file, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
    return REC_HANDLE_INVALID;
  }
  fcntl(h_file, F_SETFD, 1);
  return h_file;
}

//-------------------------------------------------------------------------
// RecFileSync
//-------------------------------------------------------------------------

int RecFileSync(RecHandle h_file)
{
  return (fsync(h_file) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}

//-------------------------------------------------------------------------
// RecFileClose
//-------------------------------------------------------------------------

int
RecFileClose(RecHandle h_file)
{
  return (close(h_file) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}

//-------------------------------------------------------------------------
// RecFileRead
//-------------------------------------------------------------------------

int
RecFileRead(RecHandle h_file, char *buf, int size, int *bytes_read)
{
  if ((*bytes_read =::read(h_file, buf, size)) <= 0) {
    *bytes_read = 0;
    return REC_ERR_FAIL;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecFileWrite
//-------------------------------------------------------------------------

int
RecFileWrite(RecHandle h_file, char *buf, int size, int *bytes_written)
{
  if ((*bytes_written =::write(h_file, buf, size)) < 0) {
    *bytes_written = 0;
    return REC_ERR_FAIL;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecFileGetSize
//-------------------------------------------------------------------------

int
RecFileGetSize(RecHandle h_file)
{
  struct stat fileStats;
  fstat(h_file, &fileStats);
  return (int) fileStats.st_size;
}

//-------------------------------------------------------------------------
// RecFileExists
//-------------------------------------------------------------------------

int
RecFileExists(const char *file)
{
  RecHandle h_file;
  if ((h_file = RecFileOpenR(file)) == REC_HANDLE_INVALID) {
    return REC_ERR_FAIL;
  }
  RecFileClose(h_file);
  return REC_ERR_OKAY;

}

//-------------------------------------------------------------------------
// RecPipeCreate
//-------------------------------------------------------------------------

RecHandle
RecPipeCreate(const char *base_path, const char *name)
{

  RecHandle listenfd;
  RecHandle acceptfd;
  struct sockaddr_un servaddr;
  struct sockaddr_un cliaddr;
  int servaddr_len;
  socklen_t cliaddr_len;

  // first, let's disable SIGPIPE (move out later!)
  struct sigaction act, oact;
  act.sa_handler = SIG_IGN;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  act.sa_flags |= SA_RESTART;
  sigaction(SIGPIPE, &act, &oact);

  // construct a path/filename for the pipe
#define SEPERATOR "/"
  char path[PATH_NAME_MAX];
  snprintf(path, sizeof(path), "%s%s%s", base_path, SEPERATOR, name);
#undef SEPERATOR
  if (strlen(path) > (sizeof(servaddr.sun_path) - 1)) {
    RecLog(DL_Warning, "[RecPipeCreate] Path name too long; exiting\n");
    return REC_HANDLE_INVALID;
  }

  unlink(path);

  if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] socket error\n");
    return REC_HANDLE_INVALID;
  }
  // set so that child process doesn't inherit our fd
  if (fcntl(listenfd, F_SETFD, 1) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] fcntl error\n");
    return REC_HANDLE_INVALID;
  }

  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sun_family = AF_UNIX;
  ink_strlcpy(servaddr.sun_path, path, sizeof(servaddr.sun_path));

  int optval = 1;
  if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(int)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] setsockopt error\n");
    return REC_HANDLE_INVALID;
  }

  servaddr_len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
  if ((bind(listenfd, (struct sockaddr *) &servaddr, servaddr_len)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] bind error\n");
    return REC_HANDLE_INVALID;
  }
  // listen, backlog of 1 (expecting only one client)
  if ((listen(listenfd, 1)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] listen error\n");
    return REC_HANDLE_INVALID;
  }
  // block until we get a connection from the other side
  cliaddr_len = sizeof(cliaddr);
  if ((acceptfd = accept(listenfd, (struct sockaddr *) &cliaddr,
                         &cliaddr_len)) < 0) {
    return REC_HANDLE_INVALID;
  }

  close(listenfd);

  return acceptfd;
}

//-------------------------------------------------------------------------
// RecPipeConnect
//-------------------------------------------------------------------------

RecHandle
RecPipeConnect(const char *base_path, const char *name)
{

  RecHandle sockfd;
  struct sockaddr_un servaddr;
  int servaddr_len;

  // construct a path/filename for the pipe
#define SEPERATOR "/"
  char path[PATH_NAME_MAX];
  snprintf(path, sizeof(path), "%s%s%s", base_path, SEPERATOR, name);
#undef SEPERATOR
  if (strlen(path) > (sizeof(servaddr.sun_path) - 1)) {
    RecLog(DL_Warning, "[RecPipeConnect] Path name too long\n");
    return REC_HANDLE_INVALID;
  }
  // Setup Connection to LocalManager */
  memset((char *) &servaddr, 0, sizeof(servaddr));
  servaddr.sun_family = AF_UNIX;
  ink_strlcpy(servaddr.sun_path, path, sizeof(servaddr.sun_path));
  servaddr_len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);

  if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] socket error\n");
    return REC_HANDLE_INVALID;
  }
  // set so that child process doesn't inherit our fd
  if (fcntl(sockfd, F_SETFD, 1) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] fcntl error\n");
    close(sockfd);
    return REC_HANDLE_INVALID;
  }
  // blocking connect
  if ((connect(sockfd, (struct sockaddr *) &servaddr, servaddr_len)) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] connect error\n");
    close(sockfd);
    return REC_HANDLE_INVALID;
  }

  return sockfd;
}

//-------------------------------------------------------------------------
// RecPipeRead
//-------------------------------------------------------------------------

int
RecPipeRead(RecHandle h_pipe, char *buf, int size)
{
  int bytes_read = 0;
  int bytes_wanted = size;
  char *p = buf;
  while (bytes_wanted > 0) {
    bytes_read = read(h_pipe, p, bytes_wanted);
    if (bytes_read < 0) {
      // FIXME: something more intelligent please!
      return REC_ERR_FAIL;
    }
    bytes_wanted -= bytes_read;
    p += bytes_read;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecPipeWrite
//-------------------------------------------------------------------------

int
RecPipeWrite(RecHandle h_pipe, char *buf, int size)
{
  int bytes_written = 0;
  int bytes_to_write = size;
  char *p = buf;
  while (bytes_to_write > 0) {
    bytes_written = write(h_pipe, p, bytes_to_write);
    if (bytes_written < 0) {
      // FIXME: something more intelligent please!
      return REC_ERR_FAIL;
    }
    bytes_to_write -= bytes_written;
    p += bytes_written;
  }

  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecPipeClose
//-------------------------------------------------------------------------

int
RecPipeClose(RecHandle h_pipe)
{
  return (close(h_pipe) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}
<commit_msg>TS-1475: Coverity 1021829 Resource leak<commit_after>/** @file

  Record compatibility definitions

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "libts.h"
#include "P_RecFile.h"
#include "P_RecDefs.h"
#include "P_RecUtils.h"

//-------------------------------------------------------------------------
// RecFileOpenR
//-------------------------------------------------------------------------

RecHandle
RecFileOpenR(const char *file)
{
  RecHandle h_file;
  return ((h_file =::open(file, O_RDONLY)) < 0) ? REC_HANDLE_INVALID : h_file;
}

//-------------------------------------------------------------------------
// RecFileOpenW
//-------------------------------------------------------------------------

RecHandle
RecFileOpenW(const char *file)
{
  RecHandle h_file;

  if ((h_file =::open(file, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
    return REC_HANDLE_INVALID;
  }
  fcntl(h_file, F_SETFD, 1);
  return h_file;
}

//-------------------------------------------------------------------------
// RecFileSync
//-------------------------------------------------------------------------

int RecFileSync(RecHandle h_file)
{
  return (fsync(h_file) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}

//-------------------------------------------------------------------------
// RecFileClose
//-------------------------------------------------------------------------

int
RecFileClose(RecHandle h_file)
{
  return (close(h_file) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}

//-------------------------------------------------------------------------
// RecFileRead
//-------------------------------------------------------------------------

int
RecFileRead(RecHandle h_file, char *buf, int size, int *bytes_read)
{
  if ((*bytes_read =::read(h_file, buf, size)) <= 0) {
    *bytes_read = 0;
    return REC_ERR_FAIL;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecFileWrite
//-------------------------------------------------------------------------

int
RecFileWrite(RecHandle h_file, char *buf, int size, int *bytes_written)
{
  if ((*bytes_written =::write(h_file, buf, size)) < 0) {
    *bytes_written = 0;
    return REC_ERR_FAIL;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecFileGetSize
//-------------------------------------------------------------------------

int
RecFileGetSize(RecHandle h_file)
{
  struct stat fileStats;
  fstat(h_file, &fileStats);
  return (int) fileStats.st_size;
}

//-------------------------------------------------------------------------
// RecFileExists
//-------------------------------------------------------------------------

int
RecFileExists(const char *file)
{
  RecHandle h_file;
  if ((h_file = RecFileOpenR(file)) == REC_HANDLE_INVALID) {
    return REC_ERR_FAIL;
  }
  RecFileClose(h_file);
  return REC_ERR_OKAY;

}

//-------------------------------------------------------------------------
// RecPipeCreate
//-------------------------------------------------------------------------

RecHandle
RecPipeCreate(const char *base_path, const char *name)
{

  RecHandle listenfd;
  RecHandle acceptfd;
  struct sockaddr_un servaddr;
  struct sockaddr_un cliaddr;
  int servaddr_len;
  socklen_t cliaddr_len;

  // first, let's disable SIGPIPE (move out later!)
  struct sigaction act, oact;
  act.sa_handler = SIG_IGN;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  act.sa_flags |= SA_RESTART;
  sigaction(SIGPIPE, &act, &oact);

  // construct a path/filename for the pipe
#define SEPERATOR "/"
  char path[PATH_NAME_MAX];
  snprintf(path, sizeof(path), "%s%s%s", base_path, SEPERATOR, name);
#undef SEPERATOR
  if (strlen(path) > (sizeof(servaddr.sun_path) - 1)) {
    RecLog(DL_Warning, "[RecPipeCreate] Path name too long; exiting\n");
    return REC_HANDLE_INVALID;
  }

  unlink(path);

  if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] socket error\n");
    return REC_HANDLE_INVALID;
  }
  // set so that child process doesn't inherit our fd
  if (fcntl(listenfd, F_SETFD, 1) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] fcntl error\n");
    return REC_HANDLE_INVALID;
  }

  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sun_family = AF_UNIX;
  ink_strlcpy(servaddr.sun_path, path, sizeof(servaddr.sun_path));

  int optval = 1;
  if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(int)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] setsockopt error\n");
    return REC_HANDLE_INVALID;
  }

  servaddr_len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
  if ((bind(listenfd, (struct sockaddr *) &servaddr, servaddr_len)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] bind error\n");
    close(listenfd);
    return REC_HANDLE_INVALID;
  }
  // listen, backlog of 1 (expecting only one client)
  if ((listen(listenfd, 1)) < 0) {
    RecLog(DL_Warning, "[RecPipeCreate] listen error\n");
    close(listenfd);
    return REC_HANDLE_INVALID;
  }
  // block until we get a connection from the other side
  cliaddr_len = sizeof(cliaddr);
  if ((acceptfd = accept(listenfd, (struct sockaddr *) &cliaddr,
                         &cliaddr_len)) < 0) {
    close(listenfd);
    return REC_HANDLE_INVALID;
  }

  close(listenfd);

  return acceptfd;
}

//-------------------------------------------------------------------------
// RecPipeConnect
//-------------------------------------------------------------------------

RecHandle
RecPipeConnect(const char *base_path, const char *name)
{

  RecHandle sockfd;
  struct sockaddr_un servaddr;
  int servaddr_len;

  // construct a path/filename for the pipe
#define SEPERATOR "/"
  char path[PATH_NAME_MAX];
  snprintf(path, sizeof(path), "%s%s%s", base_path, SEPERATOR, name);
#undef SEPERATOR
  if (strlen(path) > (sizeof(servaddr.sun_path) - 1)) {
    RecLog(DL_Warning, "[RecPipeConnect] Path name too long\n");
    return REC_HANDLE_INVALID;
  }
  // Setup Connection to LocalManager */
  memset((char *) &servaddr, 0, sizeof(servaddr));
  servaddr.sun_family = AF_UNIX;
  ink_strlcpy(servaddr.sun_path, path, sizeof(servaddr.sun_path));
  servaddr_len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);

  if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] socket error\n");
    return REC_HANDLE_INVALID;
  }
  // set so that child process doesn't inherit our fd
  if (fcntl(sockfd, F_SETFD, 1) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] fcntl error\n");
    close(sockfd);
    return REC_HANDLE_INVALID;
  }
  // blocking connect
  if ((connect(sockfd, (struct sockaddr *) &servaddr, servaddr_len)) < 0) {
    RecLog(DL_Warning, "[RecPipeConnect] connect error\n");
    close(sockfd);
    return REC_HANDLE_INVALID;
  }

  return sockfd;
}

//-------------------------------------------------------------------------
// RecPipeRead
//-------------------------------------------------------------------------

int
RecPipeRead(RecHandle h_pipe, char *buf, int size)
{
  int bytes_read = 0;
  int bytes_wanted = size;
  char *p = buf;
  while (bytes_wanted > 0) {
    bytes_read = read(h_pipe, p, bytes_wanted);
    if (bytes_read < 0) {
      // FIXME: something more intelligent please!
      return REC_ERR_FAIL;
    }
    bytes_wanted -= bytes_read;
    p += bytes_read;
  }
  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecPipeWrite
//-------------------------------------------------------------------------

int
RecPipeWrite(RecHandle h_pipe, char *buf, int size)
{
  int bytes_written = 0;
  int bytes_to_write = size;
  char *p = buf;
  while (bytes_to_write > 0) {
    bytes_written = write(h_pipe, p, bytes_to_write);
    if (bytes_written < 0) {
      // FIXME: something more intelligent please!
      return REC_ERR_FAIL;
    }
    bytes_to_write -= bytes_written;
    p += bytes_written;
  }

  return REC_ERR_OKAY;
}

//-------------------------------------------------------------------------
// RecPipeClose
//-------------------------------------------------------------------------

int
RecPipeClose(RecHandle h_pipe)
{
  return (close(h_pipe) == 0) ? REC_ERR_OKAY : REC_ERR_FAIL;
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MAIN

#include <lightex/workspace.h>

#include <boost/test/unit_test.hpp>

namespace {
  class Tester {
    public:
      Tester()
        : workspace_(lightex::MakeHtmlWorkspace()) {}

      void check(const std::string& tex_input, const std::string& expected_output) const {
        std::string error_message;
        std::string output;
        const bool result = workspace_->ParseProgram(tex_input, &error_message, &output);
        BOOST_CHECK(result);
        if (result) {
          BOOST_CHECK_EQUAL(output, expected_output);
        }
      }

      void fail(const std::string& tex_input) const {
        std::string error_message;
        std::string output;
        const bool result = workspace_->ParseProgram(tex_input, &error_message, &output);
        BOOST_CHECK(!result);
      }

    private:
      std::shared_ptr<lightex::Workspace> workspace_;
  };
}

BOOST_AUTO_TEST_CASE(TestSimple) {
  Tester t;
  t.check("", "");
  t.check(" ", "

");
  t.check("hello", "
hello
");
  t.check("hello\n\n", "
hello
");
  t.check("hello world", "
hello world
");
  t.check("hello  world", "
hello world
");
  t.check("hello\n\nworld", "
hello

world
");
  t.check("hello\n\n\nworld", "
hello

world
");
  t.check("hello\n\n\n\nworld", "
hello

world
");
}

BOOST_AUTO_TEST_CASE(TestComments) {
  Tester t;
  t.check("% this is a comment", "

");
  t.check("\\% this is a percent sign", "
% this is a percent sign
");

  t.check("a%\nb", "
ab
");
  t.check("a %\nb", "
a b
");
  t.check("a  %\nb", "
a b
");
  t.check("a %\n b", "
a  b
");
  t.check("a     %\n       b", "
a  b
");
  t.check("a%     \nb", "
ab
");
  t.check("a%     \nb%cd", "
ab
");
  t.check("a%%%%%\\%%%%%%%%\\%", "
a
");

  t.check("a%%\\%\\\\%%b\nc", "
ac
");

  t.check("Lorem ipsum% comment starts\ndolor sit amet", "
Lorem ipsumdolor sit amet
");

  t.check(
    "Lorem ipsum dolor sit amet, % some comment\n"
    "% more comment\n"
    "% and more\n"
    "quis impetus adolescens ei vim, eu quo summo percipit scribentur.",
    "
Lorem ipsum dolor sit amet, quis impetus adolescens ei vim, eu quo summo percipit scribentur.
"
  );
}

BOOST_AUTO_TEST_CASE(TestEscaping) {
  Tester t;
  t.check("<", "
<
");
  t.check(">", "
>
");
  t.check("'", "
'
");
  t.check("\"", "
"
");
  t.check("\\&", "
&
");
  t.fail("&");
  t.fail("\\");
  t.fail("\\a");
  t.check("\\\\", "
\\
");
}
<commit_msg>Fix tests.<commit_after>#define BOOST_TEST_MAIN

#include <lightex/workspace.h>

#include <boost/test/unit_test.hpp>

namespace {
  class Tester {
    public:
      Tester()
        : workspace_(lightex::MakeHtmlWorkspace()) {}

      void check(const std::string& tex_input, const std::string& expected_output) const {
        std::string error_message;
        std::string output;
        const bool result = workspace_->ParseProgram(tex_input, &error_message, &output);
        BOOST_CHECK(result);
        if (result) {
          BOOST_CHECK_EQUAL(output, expected_output);
        }
      }

      void fail(const std::string& tex_input) const {
        std::string error_message;
        std::string output;
        const bool result = workspace_->ParseProgram(tex_input, &error_message, &output);
        BOOST_CHECK(!result);
      }

    private:
      std::shared_ptr<lightex::Workspace> workspace_;
  };
}

BOOST_AUTO_TEST_CASE(TestSimple) {
  Tester t;
  t.check("", "");
  t.check(" ", " ");
  t.check("hello", "
hello
");
  t.check("hello\n\n", "
hello
");
  t.check("hello world", "
hello world
");
  t.check("hello  world", "
hello world
");
  t.check("hello\n\nworld", "
hello

world
");
  t.check("hello\n\n\nworld", "
hello

world
");
  t.check("hello\n\n\n\nworld", "
hello

world
");
}

BOOST_AUTO_TEST_CASE(TestComments) {
  Tester t;
  t.check("% this is a comment", "");
  t.check("\\% this is a percent sign", "
% this is a percent sign
");

  t.check("a%\nb", "
ab
");
  t.check("a %\nb", "
a b
");
  t.check("a  %\nb", "
a b
");
  t.check("a %\n b", "
a  b
");
  t.check("a     %\n       b", "
a  b
");
  t.check("a%     \nb", "
ab
");
  t.check("a%     \nb%cd", "
ab
");
  t.check("a%%%%%\\%%%%%%%%\\%", "
a
");

  t.check("a%%\\%\\\\%%b\nc", "
ac
");

  t.check("Lorem ipsum% comment starts\ndolor sit amet", "
Lorem ipsumdolor sit amet
");

  t.check(
    "Lorem ipsum dolor sit amet, % some comment\n"
    "% more comment\n"
    "% and more\n"
    "quis impetus adolescens ei vim, eu quo summo percipit scribentur.",
    "
Lorem ipsum dolor sit amet, quis impetus adolescens ei vim, eu quo summo percipit scribentur.
"
  );
}

BOOST_AUTO_TEST_CASE(TestEscaping) {
  Tester t;
  t.check("<", "
<
");
  t.check(">", "
>
");
  t.check("'", "
'
");
  t.check("\"", "
"
");
  t.check("\\&", "
&
");
  t.fail("&");
  t.fail("\\");
  t.fail("\\a");
  t.check("\\\\", "
\\
");
}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH

#include <memory>
#include <type_traits>

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/io/file/vtk.hh>

#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/space/interface.hh>

#include "local.hh"

namespace Dune {
namespace GDT {

template <class SpaceImp, class VectorImp>
class ConstDiscreteFunction
    : public Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                                 SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                                 SpaceImp::dimRange, SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                              SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                              SpaceImp::dimRange, SpaceImp::dimRangeCols> BaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainFieldType DomainFieldType;
  typedef typename BaseType::DomainType DomainType;

  static const unsigned int dimRange     = BaseType::dimRange;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeFieldType RangeFieldType;
  typedef typename BaseType::RangeType RangeType;
  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  typedef ConstLocalDiscreteFunction<SpaceType, VectorType> ConstLocalDiscreteFunctionType;

  ConstDiscreteFunction(const SpaceType& sp, const VectorType& vec,
                        const std::string nm = "dune.gdt.constdiscretefunction")
    : space_(sp)
    , vector_(vec)
    , name_(nm)
  {
    assert(vector_.size() == space_.mapper().size() && "Given vector has wrong size!");
  }

  ConstDiscreteFunction(const ThisType& other)
    : space_(other.space_)
    , vector_(other.vector_)
    , name_(other.name_)
  {
  }

  ConstDiscreteFunction(ThisType&& source)
    : space_(source.space_)
    , vector_(source.vector_)
    , name_(std::move(source.name_))
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  ~ConstDiscreteFunction()
  {
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  virtual std::string name() const DS_OVERRIDE
  {
    return name_;
  }

  const SpaceType& space() const
  {
    return space_;
  }

  const VectorType& vector() const
  {
    return vector_;
  }

  ConstLocalDiscreteFunctionType local_discrete_function(const EntityType& entity) const
  {
    assert(space_.grid_view()->indexSet().contains(entity));
    return ConstLocalDiscreteFunctionType(space_, vector_, entity);
  }

  virtual std::unique_ptr<LocalfunctionType> local_function(const EntityType& entity) const DS_OVERRIDE
  {
    return std::unique_ptr<ConstLocalDiscreteFunctionType>(
        new ConstLocalDiscreteFunctionType(local_discrete_function(entity)));
  }

  void visualize(const std::string filename, const bool subsampling = true,
                 VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    BaseType::template visualize<typename SpaceType::GridViewType>(
        *(space().grid_view()), filename, subsampling, vtk_output_type);
  }

protected:
  const SpaceType& space_;

private:
  const VectorType& vector_;
  const std::string name_;
}; // class ConstDiscreteFunction

template <class SpaceImp, class VectorImp>
class DiscreteFunction : public ConstDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef DiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef LocalDiscreteFunction<SpaceType, VectorType> LocalDiscreteFunctionType;

  DiscreteFunction(const SpaceType& sp, VectorType& vec, const std::string nm = "dune.gdt.discretefunction")
    : BaseType(sp, vec, nm)
    , vector_(vec)
  {
  }

  DiscreteFunction(const ThisType& other)
    : BaseType(other)
    , vector_(other.vector_)
  {
  }

  DiscreteFunction(ThisType&& source)
    : BaseType(std::move(source))
    , vector_(source.vector_)
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  ~DiscreteFunction()
  {
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  VectorType& vector()
  {
    return vector_;
  }

  LocalDiscreteFunctionType local_discrete_function(const EntityType& entity)
  {
    assert(space_.grid_view()->indexSet().contains(entity));
    return LocalDiscreteFunctionType(space_, vector_, entity);
  }

private:
  using BaseType::space_;
  VectorType& vector_;
}; // class DiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
<commit_msg>[discretefunction.default] * allow to get a const local discrete function from a non const function<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH

#include <memory>
#include <type_traits>

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/io/file/vtk.hh>

#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/space/interface.hh>

#include "local.hh"

namespace Dune {
namespace GDT {

template <class SpaceImp, class VectorImp>
class ConstDiscreteFunction
    : public Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                                 SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                                 SpaceImp::dimRange, SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                              SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                              SpaceImp::dimRange, SpaceImp::dimRangeCols> BaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainFieldType DomainFieldType;
  typedef typename BaseType::DomainType DomainType;

  static const unsigned int dimRange     = BaseType::dimRange;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeFieldType RangeFieldType;
  typedef typename BaseType::RangeType RangeType;
  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  typedef ConstLocalDiscreteFunction<SpaceType, VectorType> ConstLocalDiscreteFunctionType;

  ConstDiscreteFunction(const SpaceType& sp, const VectorType& vec,
                        const std::string nm = "dune.gdt.constdiscretefunction")
    : space_(sp)
    , vector_(vec)
    , name_(nm)
  {
    assert(vector_.size() == space_.mapper().size() && "Given vector has wrong size!");
  }

  ConstDiscreteFunction(const ThisType& other)
    : space_(other.space_)
    , vector_(other.vector_)
    , name_(other.name_)
  {
  }

  ConstDiscreteFunction(ThisType&& source)
    : space_(source.space_)
    , vector_(source.vector_)
    , name_(std::move(source.name_))
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  ~ConstDiscreteFunction()
  {
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  virtual std::string name() const DS_OVERRIDE
  {
    return name_;
  }

  const SpaceType& space() const
  {
    return space_;
  }

  const VectorType& vector() const
  {
    return vector_;
  }

  ConstLocalDiscreteFunctionType local_discrete_function(const EntityType& entity) const
  {
    assert(space_.grid_view()->indexSet().contains(entity));
    return ConstLocalDiscreteFunctionType(space_, vector_, entity);
  }

  virtual std::unique_ptr<LocalfunctionType> local_function(const EntityType& entity) const DS_OVERRIDE
  {
    return std::unique_ptr<ConstLocalDiscreteFunctionType>(
        new ConstLocalDiscreteFunctionType(local_discrete_function(entity)));
  }

  void visualize(const std::string filename, const bool subsampling = true,
                 VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    BaseType::template visualize<typename SpaceType::GridViewType>(
        *(space().grid_view()), filename, subsampling, vtk_output_type);
  }

protected:
  const SpaceType& space_;

private:
  const VectorType& vector_;
  const std::string name_;
}; // class ConstDiscreteFunction

template <class SpaceImp, class VectorImp>
class DiscreteFunction : public ConstDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef DiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef LocalDiscreteFunction<SpaceType, VectorType> LocalDiscreteFunctionType;

  DiscreteFunction(const SpaceType& sp, VectorType& vec, const std::string nm = "dune.gdt.discretefunction")
    : BaseType(sp, vec, nm)
    , vector_(vec)
  {
  }

  DiscreteFunction(const ThisType& other)
    : BaseType(other)
    , vector_(other.vector_)
  {
  }

  DiscreteFunction(ThisType&& source)
    : BaseType(std::move(source))
    , vector_(source.vector_)
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  ~DiscreteFunction()
  {
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  VectorType& vector()
  {
    return vector_;
  }

  using BaseType::local_discrete_function;

  LocalDiscreteFunctionType local_discrete_function(const EntityType& entity)
  {
    assert(space_.grid_view()->indexSet().contains(entity));
    return LocalDiscreteFunctionType(space_, vector_, entity);
  }

private:
  using BaseType::space_;
  VectorType& vector_;
}; // class DiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
<|endoftext|>