<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * Variable.tcc : implement long template functions
 *
 *  Created on: Jan 31, 2019
 *      Author: William F Godoy
 */

#ifndef ADIOS2_CORE_VARIABLE_TCC_
#define ADIOS2_CORE_VARIABLE_TCC_

#include "Variable.h"

#include "adios2/core/Engine.h"
#include "adios2/helper/adiosFunctions.h"

namespace adios2
{
namespace core
{

template <class T>
Dims Variable<T>::DoShape(const size_t step) const
{
    if (m_DebugMode)
    {
        if (!m_FirstStreamingStep && step != DefaultSizeT)
        {
            throw std::invalid_argument("ERROR: can't pass a step input in "
                                        "streaming (BeginStep/EndStep)"
                                        "mode for variable " +
                                        m_Name +
                                        ", in call to Variable<T>::Shape\n");
        }
    }

    if (m_FirstStreamingStep && step == DefaultSizeT)
    {
        return m_Shape;
    }

    if (m_Engine != nullptr && m_ShapeID == ShapeID::GlobalArray)
    {
        const size_t stepInput =
            !m_FirstStreamingStep ? m_Engine->CurrentStep() : step;

        const std::vector<typename Variable<T>::Info> blocksInfo =
            m_Engine->BlocksInfo<T>(*this, stepInput);

        if (blocksInfo.size() == 0)
        {
            return Dims();
        }

        if (blocksInfo.front().Shape.size() == 1 &&
            blocksInfo.front().Shape.front() == LocalValueDim)
        {
            return Dims{blocksInfo.size()};
        }

        return blocksInfo.front().Shape;
    }
    return m_Shape;
}

template <class T>
std::pair<T, T> Variable<T>::DoMinMax(const size_t step) const
{
    if (m_DebugMode && !m_FirstStreamingStep && step != DefaultSizeT)
    {
        throw std::invalid_argument(
            "ERROR: can't pass a step input in streaming (BeginStep/EndStep)"
            "mode for variable " +
            m_Name + ", in call to Variable<T>:: Min Max or MinMax\n");
    }

    std::pair<T, T> minMax;
    minMax.first = {};
    minMax.second = {};

    if (m_Engine != nullptr && !m_FirstStreamingStep)
    {
        const size_t stepInput =
            (step == DefaultSizeT) ? m_Engine->CurrentStep() : step;

        const std::vector<typename Variable<T>::Info> blocksInfo =
            m_Engine->BlocksInfo<T>(*this, stepInput);

        if (blocksInfo.size() == 0)
        {
            return minMax;
        }

        if (m_ShapeID == ShapeID::LocalArray)
        {
            if (m_DebugMode && m_BlockID >= blocksInfo.size())
            {
                throw std::invalid_argument(
                    "ERROR: BlockID " + std::to_string(m_BlockID) +
                    " does not exist for LocalArray variable " + m_Name +
                    ", in call to MinMax, Min or Maxn");
            }
            minMax.first = blocksInfo[m_BlockID].Min;
            minMax.second = blocksInfo[m_BlockID].Max;
            return minMax;
        }

        const bool isValue =
            ((blocksInfo.front().Shape.size() == 1 &&
              blocksInfo.front().Shape.front() == LocalValueDim) ||
             m_ShapeID == ShapeID::GlobalValue)
                ? true
                : false;

        minMax.first =
            isValue ? blocksInfo.front().Value : blocksInfo.front().Min;
        minMax.second =
            isValue ? blocksInfo.front().Value : blocksInfo.front().Max;

        for (const typename Variable<T>::Info &blockInfo : blocksInfo)
        {
            const T minValue = isValue ? blockInfo.Value : blockInfo.Min;

            if (helper::LessThan<T>(minValue, minMax.first))
            {
                minMax.first = minValue;
                continue;
            }

            const T maxValue = isValue ? blockInfo.Value : blockInfo.Max;

            if (helper::GreaterThan<T>(maxValue, minMax.second))
            {
                minMax.second = maxValue;
            }
        }
    }
    else
    {
        minMax.first = m_Min;
        minMax.second = m_Max;
    }
    return minMax;
}

} // end namespace core
} // end namespace adios2

#endif /* ADIOS2_CORE_VARIABLE_TCC_ */
<commit_msg>Calculate min/max of blocks at read time correctly<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * Variable.tcc : implement long template functions
 *
 *  Created on: Jan 31, 2019
 *      Author: William F Godoy
 */

#ifndef ADIOS2_CORE_VARIABLE_TCC_
#define ADIOS2_CORE_VARIABLE_TCC_

#include "Variable.h"

#include "adios2/core/Engine.h"
#include "adios2/helper/adiosFunctions.h"

namespace adios2
{
namespace core
{

template <class T>
Dims Variable<T>::DoShape(const size_t step) const
{
    if (m_DebugMode)
    {
        if (!m_FirstStreamingStep && step != DefaultSizeT)
        {
            throw std::invalid_argument("ERROR: can't pass a step input in "
                                        "streaming (BeginStep/EndStep)"
                                        "mode for variable " +
                                        m_Name +
                                        ", in call to Variable<T>::Shape\n");
        }
    }

    if (m_FirstStreamingStep && step == DefaultSizeT)
    {
        return m_Shape;
    }

    if (m_Engine != nullptr && m_ShapeID == ShapeID::GlobalArray)
    {
        const size_t stepInput =
            !m_FirstStreamingStep ? m_Engine->CurrentStep() : step;

        const std::vector<typename Variable<T>::Info> blocksInfo =
            m_Engine->BlocksInfo<T>(*this, stepInput);

        if (blocksInfo.size() == 0)
        {
            return Dims();
        }

        if (blocksInfo.front().Shape.size() == 1 &&
            blocksInfo.front().Shape.front() == LocalValueDim)
        {
            return Dims{blocksInfo.size()};
        }

        return blocksInfo.front().Shape;
    }
    return m_Shape;
}

template <class T>
std::pair<T, T> Variable<T>::DoMinMax(const size_t step) const
{
    if (m_DebugMode && !m_FirstStreamingStep && step != DefaultSizeT)
    {
        throw std::invalid_argument(
            "ERROR: can't pass a step input in streaming (BeginStep/EndStep)"
            "mode for variable " +
            m_Name + ", in call to Variable<T>:: Min Max or MinMax\n");
    }

    std::pair<T, T> minMax;
    minMax.first = {};
    minMax.second = {};

    if (m_Engine != nullptr && !m_FirstStreamingStep)
    {
        const size_t stepInput =
            (step == DefaultSizeT) ? m_Engine->CurrentStep() : step;

        const std::vector<typename Variable<T>::Info> blocksInfo =
            m_Engine->BlocksInfo<T>(*this, stepInput);

        if (blocksInfo.size() == 0)
        {
            return minMax;
        }

        if (m_ShapeID == ShapeID::LocalArray)
        {
            if (m_DebugMode && m_BlockID >= blocksInfo.size())
            {
                throw std::invalid_argument(
                    "ERROR: BlockID " + std::to_string(m_BlockID) +
                    " does not exist for LocalArray variable " + m_Name +
                    ", in call to MinMax, Min or Maxn");
            }
            minMax.first = blocksInfo[m_BlockID].Min;
            minMax.second = blocksInfo[m_BlockID].Max;
            return minMax;
        }

        const bool isValue =
            ((blocksInfo.front().Shape.size() == 1 &&
              blocksInfo.front().Shape.front() == LocalValueDim) ||
             m_ShapeID == ShapeID::GlobalValue)
                ? true
                : false;

        minMax.first =
            isValue ? blocksInfo.front().Value : blocksInfo.front().Min;
        minMax.second =
            isValue ? blocksInfo.front().Value : blocksInfo.front().Max;

        for (const typename Variable<T>::Info &blockInfo : blocksInfo)
        {
            const T minValue = isValue ? blockInfo.Value : blockInfo.Min;

            if (helper::LessThan<T>(minValue, minMax.first))
            {
                minMax.first = minValue;
            }

            const T maxValue = isValue ? blockInfo.Value : blockInfo.Max;

            if (helper::GreaterThan<T>(maxValue, minMax.second))
            {
                minMax.second = maxValue;
            }
        }
    }
    else
    {
        minMax.first = m_Min;
        minMax.second = m_Max;
    }
    return minMax;
}

} // end namespace core
} // end namespace adios2

#endif /* ADIOS2_CORE_VARIABLE_TCC_ */
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2008 Olivier Gueudelot <gueudelotolive@gmail.com>
 * Copyright (C) 2008 Charles Huet <packadal@gmail.com>
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "item.h"

#include <QtGui/QMatrix4x4>

#include <core/debughelper.h>

#include "mesh.h"
#include "camera.h"
#include "frustrum.h"
#include "engine.h"
#include "math.h"
#include "materialinstance.h"
#include "material.h"

using namespace GluonGraphics;

class Item::ItemPrivate
{
    public:
        ItemPrivate() { materialInstance = 0; }
        Mesh * mesh;
        QMatrix4x4 transform;
        MaterialInstance* materialInstance;
};

Item::Item(QObject * parent)
        : QObject(parent),
          d(new ItemPrivate)
{
    d->materialInstance = Engine::instance()->material("default")->instance("default");
}

Item::~Item()
{
    delete d;
}

Mesh*
Item::mesh()
{
    return d->mesh;
}

QMatrix4x4
Item::transform()
{
    return d->transform;
}

MaterialInstance*
Item::materialInstance()
{
    return d->materialInstance;
}

void
Item::render()
{
    Camera* activeCam = Engine::instance()->activeCamera();

    #ifdef __GNUC__
    #warning ToDo: Implement view frustum culling. After all, that is what that damn class is for... ;)
    #endif

    QMatrix4x4 modelViewProj = Math::calculateModelViewProj(d->transform, activeCam->viewMatrix(), activeCam->frustrum()->projectionMatrix());

    d->materialInstance->bind();
    d->materialInstance->setModelViewProjectionMatrix(modelViewProj);
    d->mesh->render(modelViewProj);
    d->materialInstance->release();

}

void
Item::setTransform( const QMatrix4x4 transform )
{
    d->transform = transform;
}

void
Item::setMesh( Mesh* mesh )
{
    d->mesh = mesh;
}

MaterialInstance*
Item::setMaterialInstance(MaterialInstance * instance)
{
    d->materialInstance = instance;
}

#include "item.moc"
<commit_msg>Why were you returning MaterialInstance*?<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2008 Olivier Gueudelot <gueudelotolive@gmail.com>
 * Copyright (C) 2008 Charles Huet <packadal@gmail.com>
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "item.h"

#include <QtGui/QMatrix4x4>

#include <core/debughelper.h>

#include "mesh.h"
#include "camera.h"
#include "frustrum.h"
#include "engine.h"
#include "math.h"
#include "materialinstance.h"
#include "material.h"

using namespace GluonGraphics;

class Item::ItemPrivate
{
    public:
        ItemPrivate() { materialInstance = 0; }
        Mesh * mesh;
        QMatrix4x4 transform;
        MaterialInstance* materialInstance;
};

Item::Item(QObject * parent)
        : QObject(parent),
          d(new ItemPrivate)
{
    d->materialInstance = Engine::instance()->material("default")->instance("default");
}

Item::~Item()
{
    delete d;
}

Mesh*
Item::mesh()
{
    return d->mesh;
}

QMatrix4x4
Item::transform()
{
    return d->transform;
}

MaterialInstance*
Item::materialInstance()
{
    return d->materialInstance;
}

void
Item::render()
{
    Camera* activeCam = Engine::instance()->activeCamera();

    #ifdef __GNUC__
    #warning ToDo: Implement view frustum culling. After all, that is what that damn class is for... ;)
    #endif

    QMatrix4x4 modelViewProj = Math::calculateModelViewProj(d->transform, activeCam->viewMatrix(), activeCam->frustrum()->projectionMatrix());

    d->materialInstance->bind();
    d->materialInstance->setModelViewProjectionMatrix(modelViewProj);
    d->mesh->render();
    d->materialInstance->release();
}

void
Item::setTransform( const QMatrix4x4 transform )
{
    d->transform = transform;
}

void
Item::setMesh( Mesh* mesh )
{
    d->mesh = mesh;
}

void
Item::setMaterialInstance(MaterialInstance * instance)
{
    d->materialInstance = instance;
}

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


<commit_before>#pragma once

// std
#include <vector>

// libraries
#include <nlohmann/json.hpp>

// project
#include "NeuralNetworkProperties.hpp"
#include "depthai-shared/common/DetectionNetworkType.hpp"
#include "depthai-shared/common/optional.hpp"

namespace dai {

/**
 * Properties for DetectionNetwork
 */
struct DetectionNetworkProperties : NeuralNetworkProperties {
    /// Generic Neural Network properties
    DetectionNetworkType nnFamily;
    float confidenceThreshold;

    /// YOLO specific network properties
    int classes;
    int coordinates;
    std::vector<float> anchors;
    std::map<std::string, std::vector<int>> anchorMasks;
    float iouThreshold;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
    DetectionNetworkProperties, nnFamily, blobSize, blobUri, numFrames, numThreads, confidenceThreshold, classes, coordinates, anchors, anchorMasks, iouThreshold)

}  // namespace dai
<commit_msg>Apply formatting<commit_after>#pragma once

// std
#include <vector>

// libraries
#include <nlohmann/json.hpp>

// project
#include "NeuralNetworkProperties.hpp"
#include "depthai-shared/common/DetectionNetworkType.hpp"
#include "depthai-shared/common/optional.hpp"

namespace dai {

/**
 * Properties for DetectionNetwork
 */
struct DetectionNetworkProperties : NeuralNetworkProperties {
    /// Generic Neural Network properties
    DetectionNetworkType nnFamily;
    float confidenceThreshold;

    /// YOLO specific network properties
    int classes;
    int coordinates;
    std::vector<float> anchors;
    std::map<std::string, std::vector<int>> anchorMasks;
    float iouThreshold;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(DetectionNetworkProperties,
                                   nnFamily,
                                   blobSize,
                                   blobUri,
                                   numFrames,
                                   numThreads,
                                   confidenceThreshold,
                                   classes,
                                   coordinates,
                                   anchors,
                                   anchorMasks,
                                   iouThreshold)

}  // namespace dai
<|endoftext|>


<commit_before>// this thing is somehow required to be able to initialise OLE
#define _WIN32_DCOM

#include "../common/common.h"
#include "../common/CException.h"
#include "../graysvr/graysvr.h"
#include "threads.h"
// #include "mutex.h"

// number of exceptions after which we restart thread and think that the thread have gone in exceptioning loops
#define EXCEPTIONS_ALLOWED	10

// Normal Buffer
// SimpleMutex g_tmpStringMutex;
volatile long g_tmpStringIndex = 0;
char g_tmpStrings[THREAD_TSTRING_STORAGE][THREAD_STRING_LENGTH];

// TemporaryString Buffer
// SimpleMutex g_tmpTemporaryStringMutex;
volatile long g_tmpTemporaryStringIndex = 0;
char g_tmpTemporaryStringUsed[THREAD_STRING_STORAGE];
char g_tmpTemporaryStrings[THREAD_STRING_STORAGE][THREAD_STRING_LENGTH];

/**
 * ThreadHolder
 * NOTE: due to it is difficult to create a good sync on this level, instead of storying a list of threads
 * we store an array and mark records being removed, which is absolutely thread-safe
**/
IThread *ThreadHolder::m_threads[MAX_THREADS];
int ThreadHolder::m_threadCount = 0;
bool ThreadHolder::m_inited = false;

IThread *ThreadHolder::current()
{
	init();
#ifdef _WIN32
	unsigned id = ::GetCurrentThreadId();
#else
	unsigned id = (unsigned)pthread_self();
#endif

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] != NULL )
		{
			if( m_threads[i]->getId() == id )
			{
				return m_threads[i];
			}
		}
	}

	return DummySphereThread::getInstance();
}

void ThreadHolder::push(IThread *thread)
{
	init();
	if( m_threadCount >= MAX_THREADS-1 )
	{
		throw new CException(LOGL_FATAL, 0, "Too many opened threads");
	}

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] == NULL )
		{
			m_threads[i] = thread;
			m_threadCount++;
			return;
		}
	}

	throw new CException(LOGL_FATAL, 0, "Unable to find an empty slot for thread");
}

void ThreadHolder::pop(IThread *thread)
{
	init();
	if( m_threadCount <= 0 )
	{
		throw new CException(LOGL_ERROR, 0, "Trying to dequeue thread while no threads are active");
	}

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] != NULL )
		{
			if( m_threads[i]->getId() == thread->getId() )
			{
				m_threads[i] = NULL;
				m_threadCount--;
				return;
			}
		}
	}

	throw new CException(LOGL_ERROR, 0, "Unable to dequeue a thread (not registered)");
}

int ThreadHolder::getActiveThreads()
{
	return m_threadCount;
}

void ThreadHolder::init()
{
	if( !m_inited )
	{
		for( int i = 0; i < MAX_THREADS; i++ )
		{
			m_threads[i] = NULL;
		}

		memset(g_tmpStrings, 0, sizeof(g_tmpStrings));
		memset(g_tmpTemporaryStringUsed, 0, sizeof(g_tmpTemporaryStringUsed));
		memset(g_tmpTemporaryStrings, 0, sizeof(g_tmpTemporaryStrings));

		m_inited = true;
	}
}

/*
 * AbstractThread
*/
int AbstractThread::m_threadsAvailable = 0;

AbstractThread::AbstractThread(const char *name, IThread::Priority priority)
{
	if( AbstractThread::m_threadsAvailable == 0 )
	{
		// no threads were started before - initialise thread subsystem
#ifdef _WIN32
		if( CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK )
		{
			throw new CException(LOGL_FATAL, 0, "OLE is not available, threading model unimplementable");
		}
#endif
		AbstractThread::m_threadsAvailable++;
	}
	m_id = 0;
	m_name = name;
	m_handle = NULL;
	m_hangCheck = 0;
	m_priority = priority;
}

AbstractThread::~AbstractThread()
{
	terminate();
	AbstractThread::m_threadsAvailable--;
	if( AbstractThread::m_threadsAvailable == 0 )
	{
		// all running threads have gone, the thread subsystem is no longer needed
#ifdef _WIN32
		CoUninitialize();
#else
		// No pthread equivalent
#endif
	}
}

unsigned AbstractThread::getId()
{
	return m_id;
}

const char *AbstractThread::getName()
{
	return m_name;
}

void AbstractThread::start()
{
#ifdef _WIN32
	m_handle = (spherethread_t) _beginthreadex(NULL, 0, &runner, this, 0, &m_id);
#else
	// pthread_create doesn't return the new thread id, so we set it in runner?
	if ( pthread_create( &m_handle, NULL, &runner, this ) )
	{
		m_handle = (spherethread_t) NULL;
		throw new CException(LOGL_FATAL, 0, "Unable to spawn a new thread");
	}
	else
		m_id = (unsigned) m_handle; //pthread_self() and m_handle should be the same
#endif
	push(this);
}

void AbstractThread::terminate()
{
	if( isActive() )
	{
#ifdef _WIN32
		if( getId() == ::GetCurrentThreadId() )
		{
			_endthreadex(0);
		}
		else
		{
			TerminateThread(m_handle, 0);
		}
		CloseHandle(m_handle);
#else
		if( pthread_equal(m_handle,pthread_self()) )
		{
			pthread_exit(0);
		}
		else
		{
			pthread_cancel(m_handle); // IBM say it so
		}
#endif
		// Common things
		pop(this);
		m_id = 0;
		m_handle = NULL;
	}
}

void AbstractThread::run()
{
	// is the very first since there is a possibility of something being altered there
	onStart();

	// detect a sleep period for thread depending on priority
	int tickPeriod;
	switch( m_priority )
	{
		case IThread::Idle:
			tickPeriod = 1000;
			break;
		case IThread::Low:
			tickPeriod = 200;
			break;
		case IThread::Normal:
			tickPeriod = 100;
			break;
		case IThread::High:
			tickPeriod = 50;
			break;
		case IThread::Highest:
			tickPeriod = 25;
			break;
		case IThread::RealTime:
			tickPeriod = 0;
			break;
		default:
			throw new CException(LOGL_FATAL, 0, "Unable to determine thread priority");
	}

	int exceptions = 0;
	bool lastWasException = false;
	while( true )
	{
		bool gotException = false;

		//	report me being alive if I am being checked for status
		if( m_hangCheck != 0 )
		{
			m_hangCheck = 0;
		}

		try
		{
			tick();
		}
		catch( CException e )
		{
			gotException = true;
			//	TODO: notify of exceptions
		}
		catch( ... )
		{
			gotException = true;
			//	TODO: notify of exceptions
		}

		if( gotException )
		{
			if( lastWasException )
			{
				exceptions++;
			}
			else
			{
				lastWasException = true;
				exceptions = 0;
			}
			if( exceptions >= EXCEPTIONS_ALLOWED )
			{
				// a bad thing really happened. ALL previous EXCEPTIONS_ALLOWED ticks resulted in exception
				// almost for sure we have looped somewhere and have no way to get out from this situation
				// probably a thread restart can fix the problems
				// but there is no real need to restart a thread, we will just simulate a thread restart,
				// notifying a subclass like we have been just restarted, so it will restart it's operations
				//	TODO: notify the logger
				onStart();
				lastWasException = false;
			}
		}
		else
		{
			lastWasException = false;
		}

		if( shouldExit() )
		{
			terminate();
		}
		Sleep(tickPeriod);
	}
}

SPHERE_THREADENTRY_RETNTYPE AbstractThread::runner(void *callerThread)
{
	AbstractThread *caller = (AbstractThread*)callerThread;

	caller->run();

#ifdef _WIN32
	_endthreadex(0);
#else
	pthread_exit(0);
#endif
	return 0;
}

bool AbstractThread::isActive()
{
	return m_handle != NULL;
}

void AbstractThread::waitForClose()
{
	int count = 150; // 15 seconds = 15000ms
	while( isActive() && count-- )
	{
		Sleep(100);
	}
	terminate();
}

void AbstractThread::checkStuck()
{
	if( isActive() )
	{
		if( m_hangCheck == 0 )
		{
			//	initiate hang check
			m_hangCheck = 0xDEAD;
		}
		else if( m_hangCheck == 0xDEAD )
		{
			//	one time period was not answered, wait a bit more
			m_hangCheck = 0xDEADDEADl;
			//	TODO:
			//g_Log.Event(LOGL_CRIT, "'%s' thread seems being hang (frozen) at '%s'?\n", m_name, m_action);
		}
		else if( m_hangCheck == 0xDEADDEADl )
		{
			//	TODO:
			//g_Log.Event(LOGL_CRIT, "'%s' thread hang, restarting...\n", m_name);
			terminate();
			start();
		}
	}
}

void AbstractThread::onStart()
{
	//	empty. override if need in subclass
}

bool AbstractThread::shouldExit()
{
	return false;
}

/*
 * AbstractSphereThread
*/
AbstractSphereThread::AbstractSphereThread(const char *name, Priority priority)
	: AbstractThread(name, priority)
{
}

// IMHO we need a lock on allocateBuffer and allocateStringBuffer

char *AbstractSphereThread::allocateBuffer()
{
//	SimpleThreadLock stlBuffer(g_tmpStringMutex);

	char * buffer = NULL;
	g_tmpStringIndex++;

	if( g_tmpStringIndex >= THREAD_TSTRING_STORAGE )
	{
		g_tmpStringIndex %= THREAD_TSTRING_STORAGE;
	}

	buffer = g_tmpStrings[g_tmpStringIndex];
	*buffer = '\0';

	return buffer;
}

char *AbstractSphereThread::allocateStringBuffer()
{
//	SimpleThreadLock stlBuffer(g_tmpTemporaryStringMutex);

	long initialPosition = g_tmpTemporaryStringIndex;
	while( true )
	{
		long index = ++g_tmpTemporaryStringIndex;
		if( g_tmpTemporaryStringIndex >= THREAD_STRING_STORAGE )
		{
			index = g_tmpTemporaryStringIndex %= THREAD_STRING_STORAGE;
		}

		if( g_tmpTemporaryStringUsed[index] == 0 )
		{
			char *buffer = g_tmpTemporaryStrings[index];
			*buffer = '\0';
			return buffer;
		}

		// a protection against deadlock. All string buffers are marked as being used somewhere, so we
		// have few possibilities (the case shows that we have a bug and temporary strings used not such):
		// a) return NULL and wait for exceptions in the program
		// b) allocate a string from a heap
		if( initialPosition == index )
		{
			// but the best is to throw an exception to give better formed information for end users
			// rather than access violations
			DEBUG_WARN(( "Thread temporary string buffer is full.\n" ));
			throw new CException(LOGL_FATAL, 0, "Thread temporary string buffer is full");
		}
	}
}

String AbstractSphereThread::allocateString()
{
	TemporaryString s(allocateStringBuffer(), &g_tmpTemporaryStringUsed[g_tmpTemporaryStringIndex]);

	return s;
}

void AbstractSphereThread::allocateString(TemporaryString &string)
{
	string.init(allocateStringBuffer(), &g_tmpTemporaryStringUsed[g_tmpTemporaryStringIndex]);
}

bool AbstractSphereThread::shouldExit()
{
	if( g_Serv.m_iModeCode == SERVMODE_Exiting )
	{
		return true;
	}
	return false;
}

/*
 * DummySphereThread
*/
DummySphereThread *DummySphereThread::instance = NULL;

DummySphereThread::DummySphereThread()
	: AbstractSphereThread("dummy", IThread::Normal)
{
}

DummySphereThread *DummySphereThread::getInstance()
{
	if( instance == NULL )
	{
		instance = new DummySphereThread();
	}
	return instance;
}

void DummySphereThread::tick()
{
}
<commit_msg>_USESTRINGMUTEX For string mutex<commit_after>// this thing is somehow required to be able to initialise OLE
#define _WIN32_DCOM

#include "../common/common.h"
#include "../common/CException.h"
#include "../graysvr/graysvr.h"
#include "threads.h"
// #include "mutex.h"

// number of exceptions after which we restart thread and think that the thread have gone in exceptioning loops
#define EXCEPTIONS_ALLOWED	10

// Normal Buffer
#ifdef _USESTRINGMUTEX
    SimpleMutex g_tmpStringMutex;
#endif
volatile long g_tmpStringIndex = 0;
char g_tmpStrings[THREAD_TSTRING_STORAGE][THREAD_STRING_LENGTH];

// TemporaryString Buffer
#ifdef _USESTRINGMUTEX
    SimpleMutex g_tmpTemporaryStringMutex;
#endif
volatile long g_tmpTemporaryStringIndex = 0;
char g_tmpTemporaryStringUsed[THREAD_STRING_STORAGE];
char g_tmpTemporaryStrings[THREAD_STRING_STORAGE][THREAD_STRING_LENGTH];

/**
 * ThreadHolder
 * NOTE: due to it is difficult to create a good sync on this level, instead of storying a list of threads
 * we store an array and mark records being removed, which is absolutely thread-safe
**/
IThread *ThreadHolder::m_threads[MAX_THREADS];
int ThreadHolder::m_threadCount = 0;
bool ThreadHolder::m_inited = false;

IThread *ThreadHolder::current()
{
	init();
#ifdef _WIN32
	unsigned id = ::GetCurrentThreadId();
#else
	unsigned id = (unsigned)pthread_self();
#endif

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] != NULL )
		{
			if( m_threads[i]->getId() == id )
			{
				return m_threads[i];
			}
		}
	}

	return DummySphereThread::getInstance();
}

void ThreadHolder::push(IThread *thread)
{
	init();
	if( m_threadCount >= MAX_THREADS-1 )
	{
		throw new CException(LOGL_FATAL, 0, "Too many opened threads");
	}

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] == NULL )
		{
			m_threads[i] = thread;
			m_threadCount++;
			return;
		}
	}

	throw new CException(LOGL_FATAL, 0, "Unable to find an empty slot for thread");
}

void ThreadHolder::pop(IThread *thread)
{
	init();
	if( m_threadCount <= 0 )
	{
		throw new CException(LOGL_ERROR, 0, "Trying to dequeue thread while no threads are active");
	}

	for( int i = 0; i < MAX_THREADS; i++ )
	{
		if( m_threads[i] != NULL )
		{
			if( m_threads[i]->getId() == thread->getId() )
			{
				m_threads[i] = NULL;
				m_threadCount--;
				return;
			}
		}
	}

	throw new CException(LOGL_ERROR, 0, "Unable to dequeue a thread (not registered)");
}

int ThreadHolder::getActiveThreads()
{
	return m_threadCount;
}

void ThreadHolder::init()
{
	if( !m_inited )
	{
		for( int i = 0; i < MAX_THREADS; i++ )
		{
			m_threads[i] = NULL;
		}

		memset(g_tmpStrings, 0, sizeof(g_tmpStrings));
		memset(g_tmpTemporaryStringUsed, 0, sizeof(g_tmpTemporaryStringUsed));
		memset(g_tmpTemporaryStrings, 0, sizeof(g_tmpTemporaryStrings));

		m_inited = true;
	}
}

/*
 * AbstractThread
*/
int AbstractThread::m_threadsAvailable = 0;

AbstractThread::AbstractThread(const char *name, IThread::Priority priority)
{
	if( AbstractThread::m_threadsAvailable == 0 )
	{
		// no threads were started before - initialise thread subsystem
#ifdef _WIN32
		if( CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK )
		{
			throw new CException(LOGL_FATAL, 0, "OLE is not available, threading model unimplementable");
		}
#endif
		AbstractThread::m_threadsAvailable++;
	}
	m_id = 0;
	m_name = name;
	m_handle = NULL;
	m_hangCheck = 0;
	m_priority = priority;
}

AbstractThread::~AbstractThread()
{
	terminate();
	AbstractThread::m_threadsAvailable--;
	if( AbstractThread::m_threadsAvailable == 0 )
	{
		// all running threads have gone, the thread subsystem is no longer needed
#ifdef _WIN32
		CoUninitialize();
#else
		// No pthread equivalent
#endif
	}
}

unsigned AbstractThread::getId()
{
	return m_id;
}

const char *AbstractThread::getName()
{
	return m_name;
}

void AbstractThread::start()
{
#ifdef _WIN32
	m_handle = (spherethread_t) _beginthreadex(NULL, 0, &runner, this, 0, &m_id);
#else
	// pthread_create doesn't return the new thread id, so we set it in runner?
	if ( pthread_create( &m_handle, NULL, &runner, this ) )
	{
		m_handle = (spherethread_t) NULL;
		throw new CException(LOGL_FATAL, 0, "Unable to spawn a new thread");
	}
	else
		m_id = (unsigned) m_handle; //pthread_self() and m_handle should be the same
#endif
	push(this);
}

void AbstractThread::terminate()
{
	if( isActive() )
	{
#ifdef _WIN32
		if( getId() == ::GetCurrentThreadId() )
		{
			_endthreadex(0);
		}
		else
		{
			TerminateThread(m_handle, 0);
		}
		CloseHandle(m_handle);
#else
		if( pthread_equal(m_handle,pthread_self()) )
		{
			pthread_exit(0);
		}
		else
		{
			pthread_cancel(m_handle); // IBM say it so
		}
#endif
		// Common things
		pop(this);
		m_id = 0;
		m_handle = NULL;
	}
}

void AbstractThread::run()
{
	// is the very first since there is a possibility of something being altered there
	onStart();

	// detect a sleep period for thread depending on priority
	int tickPeriod;
	switch( m_priority )
	{
		case IThread::Idle:
			tickPeriod = 1000;
			break;
		case IThread::Low:
			tickPeriod = 200;
			break;
		case IThread::Normal:
			tickPeriod = 100;
			break;
		case IThread::High:
			tickPeriod = 50;
			break;
		case IThread::Highest:
			tickPeriod = 25;
			break;
		case IThread::RealTime:
			tickPeriod = 0;
			break;
		default:
			throw new CException(LOGL_FATAL, 0, "Unable to determine thread priority");
	}

	int exceptions = 0;
	bool lastWasException = false;
	while( true )
	{
		bool gotException = false;

		//	report me being alive if I am being checked for status
		if( m_hangCheck != 0 )
		{
			m_hangCheck = 0;
		}

		try
		{
			tick();
		}
		catch( CException e )
		{
			gotException = true;
			//	TODO: notify of exceptions
		}
		catch( ... )
		{
			gotException = true;
			//	TODO: notify of exceptions
		}

		if( gotException )
		{
			if( lastWasException )
			{
				exceptions++;
			}
			else
			{
				lastWasException = true;
				exceptions = 0;
			}
			if( exceptions >= EXCEPTIONS_ALLOWED )
			{
				// a bad thing really happened. ALL previous EXCEPTIONS_ALLOWED ticks resulted in exception
				// almost for sure we have looped somewhere and have no way to get out from this situation
				// probably a thread restart can fix the problems
				// but there is no real need to restart a thread, we will just simulate a thread restart,
				// notifying a subclass like we have been just restarted, so it will restart it's operations
				//	TODO: notify the logger
				onStart();
				lastWasException = false;
			}
		}
		else
		{
			lastWasException = false;
		}

		if( shouldExit() )
		{
			terminate();
		}
		Sleep(tickPeriod);
	}
}

SPHERE_THREADENTRY_RETNTYPE AbstractThread::runner(void *callerThread)
{
	AbstractThread *caller = (AbstractThread*)callerThread;

	caller->run();

#ifdef _WIN32
	_endthreadex(0);
#else
	pthread_exit(0);
#endif
	return 0;
}

bool AbstractThread::isActive()
{
	return m_handle != NULL;
}

void AbstractThread::waitForClose()
{
	int count = 150; // 15 seconds = 15000ms
	while( isActive() && count-- )
	{
		Sleep(100);
	}
	terminate();
}

void AbstractThread::checkStuck()
{
	if( isActive() )
	{
		if( m_hangCheck == 0 )
		{
			//	initiate hang check
			m_hangCheck = 0xDEAD;
		}
		else if( m_hangCheck == 0xDEAD )
		{
			//	one time period was not answered, wait a bit more
			m_hangCheck = 0xDEADDEADl;
			//	TODO:
			//g_Log.Event(LOGL_CRIT, "'%s' thread seems being hang (frozen) at '%s'?\n", m_name, m_action);
		}
		else if( m_hangCheck == 0xDEADDEADl )
		{
			//	TODO:
			//g_Log.Event(LOGL_CRIT, "'%s' thread hang, restarting...\n", m_name);
			terminate();
			start();
		}
	}
}

void AbstractThread::onStart()
{
	//	empty. override if need in subclass
}

bool AbstractThread::shouldExit()
{
	return false;
}

/*
 * AbstractSphereThread
*/
AbstractSphereThread::AbstractSphereThread(const char *name, Priority priority)
	: AbstractThread(name, priority)
{
}

// IMHO we need a lock on allocateBuffer and allocateStringBuffer

char *AbstractSphereThread::allocateBuffer()
{
#ifdef _USESTRINGMUTEX
	SimpleThreadLock stlBuffer(g_tmpStringMutex);
#endif

	char * buffer = NULL;
	g_tmpStringIndex++;

	if( g_tmpStringIndex >= THREAD_TSTRING_STORAGE )
	{
		g_tmpStringIndex %= THREAD_TSTRING_STORAGE;
	}

	buffer = g_tmpStrings[g_tmpStringIndex];
	*buffer = '\0';

	return buffer;
}

char *AbstractSphereThread::allocateStringBuffer()
{
	long initialPosition = g_tmpTemporaryStringIndex;
	while( true )
	{
		long index = ++g_tmpTemporaryStringIndex;
		if( g_tmpTemporaryStringIndex >= THREAD_STRING_STORAGE )
		{
			index = g_tmpTemporaryStringIndex %= THREAD_STRING_STORAGE;
		}

		if( g_tmpTemporaryStringUsed[index] == 0 )
		{
			char *buffer = g_tmpTemporaryStrings[index];
			*buffer = '\0';
			return buffer;
		}

		// a protection against deadlock. All string buffers are marked as being used somewhere, so we
		// have few possibilities (the case shows that we have a bug and temporary strings used not such):
		// a) return NULL and wait for exceptions in the program
		// b) allocate a string from a heap
		if( initialPosition == index )
		{
			// but the best is to throw an exception to give better formed information for end users
			// rather than access violations
			DEBUG_WARN(( "Thread temporary string buffer is full.\n" ));
			throw new CException(LOGL_FATAL, 0, "Thread temporary string buffer is full");
		}
	}
}

String AbstractSphereThread::allocateString()
{
#ifdef _USESTRINGMUTEX
	SimpleThreadLock stlBuffer(g_tmpTemporaryStringMutex);
#endif

	TemporaryString s(allocateStringBuffer(), &g_tmpTemporaryStringUsed[g_tmpTemporaryStringIndex]);
	return s;
}

void AbstractSphereThread::allocateString(TemporaryString &string)
{
#ifdef _USESTRINGMUTEX
	SimpleThreadLock stlBuffer(g_tmpTemporaryStringMutex);
#endif

	string.init(allocateStringBuffer(), &g_tmpTemporaryStringUsed[g_tmpTemporaryStringIndex]);
}

bool AbstractSphereThread::shouldExit()
{
	if( g_Serv.m_iModeCode == SERVMODE_Exiting )
	{
		return true;
	}
	return false;
}

/*
 * DummySphereThread
*/
DummySphereThread *DummySphereThread::instance = NULL;

DummySphereThread::DummySphereThread()
	: AbstractSphereThread("dummy", IThread::Normal)
{
}

DummySphereThread *DummySphereThread::getInstance()
{
	if( instance == NULL )
	{
		instance = new DummySphereThread();
	}
	return instance;
}

void DummySphereThread::tick()
{
}
<|endoftext|>


<commit_before>/*
 * converts meshalyzer mesh files to vtk unstructured data
 */
#include <cmath>
#include <fstream>
#include <ios>
#include <iostream>
#include <sstream>

#include <boost/program_options.hpp>
#include <boost/tokenizer.hpp>
#include <boost/tuple/tuple.hpp>

#include "vtkXMLUnstructuredGridReader.h"
#include "vtkXMLUnstructuredGridWriter.h"
#include "vtkXMLPUnstructuredGridWriter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkGenericGeometryFilter.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkConfigure.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"

using namespace boost;

namespace po = boost::program_options;

/**
 * Reads a .pts file and adds the points to the given grid
 */
void create_points(const std::string& file_name,
                   vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .tris file and adds the triangles to the given grid
 */
void create_tris(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .elem file and adds the triangles to the given grid
 */
void create_elem(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .cnnx file and adds the lines to the given grid;
 */
void create_lines(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .lon file and adds the vectors to the given elements;
 */

void create_vectors(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid);

int main(int argc, char *argv[])
{
  //Process command line
  //set up possible options
  po::options_description desc("Command line arguments");
  desc.add_options()
    ("help", "produce help message")
    ("pts", po::value<std::string>(), "name of input pts file")
    ("tris", po::value<std::string>(), "name of input tris file")
    ("elem", po::value<std::string>(), "name of input elem file")
    ("cnnx", po::value<std::string>(), "name of input cnnx file")
    ("lon", po::value<std::string>(), "name of input lon file")
    ("output", po::value<std::string>(), "name of output file")
    ;

  //Parse command line
  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help"))
  {
    std::cout << desc << "\n";
    return EXIT_FAILURE;
  }

  if (!vm.count("pts"))
  {
    std::cout << "Input was not set.\n";
    return EXIT_FAILURE;
  }

  if (!vm.count("output"))
  {
    std::cout << "Output was not set.\n";
    return EXIT_FAILURE;
  }

  //Create vtk data structure and writer
  vtkSmartPointer<vtkUnstructuredGrid> grid = vtkSmartPointer<vtkUnstructuredGrid>::New();

  create_points(vm["pts"].as<std::string>(),
                grid);

  if(vm.count("tris"))
  {
    create_tris(vm["tris"].as<std::string>(),
                grid);
  }

  if(vm.count("elem"))
  {
    create_elem(vm["elem"].as<std::string>(),
                grid);
  }

  if(vm.count("cnnx"))
  {
    create_lines(vm["cnnx"].as<std::string>(),
                 grid);
  }

  if(vm.count("cnnx"))
  {
    create_vectors(vm["lon"].as<std::string>(),
                   grid);
  }

  vtkXMLUnstructuredGridWriter* writer= vtkXMLUnstructuredGridWriter::New();
  writer->SetInput(grid);
  //writer->SetDataModeToAscii();
  writer->SetFileName(vm["output"].as<std::string>().c_str());
  writer->Write();
  writer->Delete();

}

//
//
//
void create_points(const std::string& file_name,
                   vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //parse file and simultaneously output to vtk
  std::ifstream pts_file(file_name.c_str());
  if (!pts_file)
  {
    std::cerr << "Failed to read pts file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(pts_file, line); //Skip over the first line

  //Create Vertices
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  unsigned vertex_index = 0;
  while(std::getline(pts_file, line))
  {
    double coords[3];

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> coords[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> coords[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> coords[2];

    points->InsertPoint(vertex_index, coords);
    ++vertex_index;
  }

  grid->SetPoints(points);
}

//
//
//
void create_tris(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream tris_file(file_name.c_str());
  if (!tris_file)
  {
    std::cerr << "Failed to read tris file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(tris_file, line); //Skip over the first line

  //Create Vertices
  unsigned tri_index = 0;
  while(std::getline(tris_file, line))
  {
    std::vector<unsigned int> conn(3);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> conn[2];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(3);

    for(unsigned int i=0;i<conn.size();++i)
    {
	  pts->SetId(i,conn[i]);
    }

    grid->InsertNextCell(VTK_TRIANGLE,pts);
    pts->Delete();

    ++tri_index;
  }
}

//
//
//
void create_elem(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create elem
  std::ifstream elem_file(file_name.c_str());
  if (!elem_file)
  {
    std::cerr << "Failed to read elem file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(elem_file, line); //Skip over the first line

  //Create Vertices
  unsigned elem_index = 0;
  while(std::getline(elem_file, line))
  {
    std::vector<unsigned int> conn(4);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    ++beg; //Throw away Tt first entry
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> conn[2];
    ++beg;

    std::istringstream iss4(*beg);
    iss4 >> conn[3];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(4);

    for(unsigned int i=0;i<conn.size();++i)
    {
      //std::cout << i << " " << conn[i] << std::endl;
	  pts->SetId(i,conn[i]);
    //std::cout << pts->GetId(i) << std::endl;
    }

    grid->InsertNextCell(VTK_TETRA,pts);
    pts->Delete();

    ++elem_index;
  }
}

/**
 * Reads a .cnnx file and adds the lines to the given grid;
 */
void create_lines(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream cnnx_file(file_name.c_str());
  if (!cnnx_file)
  {
    std::cerr << "Failed to read cnnx file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(cnnx_file, line); //Skip over the first line

  //Create Vertices
  unsigned cnnx_index = 0;
  while(std::getline(cnnx_file, line))
  {
    std::vector<unsigned int> conn(2);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(2);

    for(unsigned int i=0;i<conn.size();++i)
    {
	  pts->SetId(i,conn[i]);
    }

    grid->InsertNextCell(VTK_LINE,pts);
    pts->Delete();

    ++cnnx_index;
  }
}

/**
 * Reads a .lon file and adds the vectors to the given elements;
 * Code assumes that the file has a first line to ignore.
 */
void create_vectors(const std::string& file_name,
                    vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream lon_file(file_name.c_str());
  if (!lon_file)
  {
    std::cerr << "Failed to read lon file" << std::endl;
    abort();
  }

  //

  //Read the pts file
  std::string line;
  std::getline(lon_file, line); //Skip over the first line

  // quick and dirty way to check if there is a one-line header
  // if there is, ignore it
  // if (found!=string::npos)
  //
  vtkCellData* cellData = grid->GetCellData();
  vtkSmartPointer< vtkFloatArray > vectors = vtkSmartPointer< vtkFloatArray >::New();
  vectors->SetName("lon");
  cellData->AddArray(vectors);

  //Create Vertices
  while(std::getline(lon_file, line))
  {
    double lon[3];

     // >> lon[0] >> lon[1] >> lon[2];

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> lon[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> lon[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> lon[2];
    ++beg;

    vectors->InsertNextTuple(lon);

    //
    //     vtkIdList *pts = vtkIdList::New();
    //     pts->SetNumberOfIds(2);
    //
    //     for(unsigned int i=0;i<lon.size();++i)
    //     {
    // pts->SetId(i,lon[i]);
    //     }
    //
    //     grid->InsertNextCell(VTK_LINE,pts);
    //     pts->Delete();
  }
}
<commit_msg>Fixed bugs in convert_carp_to_vtk.cpp<commit_after>/*
 * converts meshalyzer mesh files to vtk unstructured data
 */
#include <cmath>
#include <fstream>
#include <ios>
#include <iostream>
#include <sstream>

#include <boost/program_options.hpp>
#include <boost/tokenizer.hpp>
#include <boost/tuple/tuple.hpp>

#include "vtkXMLUnstructuredGridReader.h"
#include "vtkXMLUnstructuredGridWriter.h"
#include "vtkXMLPUnstructuredGridWriter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkGenericGeometryFilter.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkConfigure.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"

using namespace boost;

namespace po = boost::program_options;

/**
 * Reads a .pts file and adds the points to the given grid
 */
void create_points(const std::string& file_name,
                   vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .tris file and adds the triangles to the given grid
 */
void create_tris(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .elem file and adds the triangles to the given grid
 */
void create_elem(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .cnnx file and adds the lines to the given grid;
 */
void create_lines(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid);

/**
 * Reads a .lon file and adds the vectors to the given elements;
 */

void create_vectors(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid);

int main(int argc, char *argv[])
{
  //Process command line
  //set up possible options
  po::options_description desc("Command line arguments");
  desc.add_options()
    ("help", "produce help message")
    ("pts", po::value<std::string>(), "name of input pts file")
    ("tris", po::value<std::string>(), "name of input tris file")
    ("elem", po::value<std::string>(), "name of input elem file")
    ("cnnx", po::value<std::string>(), "name of input cnnx file")
    ("lon", po::value<std::string>(), "name of input lon file")
    ("output", po::value<std::string>(), "name of output file")
    ;

  //Parse command line
  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help"))
  {
    std::cout << desc << "\n";
    return EXIT_FAILURE;
  }

  if (!vm.count("pts"))
  {
    std::cout << "Input was not set.\n";
    return EXIT_FAILURE;
  }

  if (!vm.count("output"))
  {
    std::cout << "Output was not set.\n";
    return EXIT_FAILURE;
  }

  //Create vtk data structure and writer
  vtkSmartPointer<vtkUnstructuredGrid> grid = vtkSmartPointer<vtkUnstructuredGrid>::New();

  create_points(vm["pts"].as<std::string>(),
                grid);

  if(vm.count("tris"))
  {
    create_tris(vm["tris"].as<std::string>(),
                grid);
  }

  if(vm.count("elem"))
  {
    create_elem(vm["elem"].as<std::string>(),
                grid);
  }

  if(vm.count("cnnx"))
  {
    create_lines(vm["cnnx"].as<std::string>(),
                 grid);
  }

  if(vm.count("lon"))
  {
    create_vectors(vm["lon"].as<std::string>(),
                   grid);
  }

  vtkXMLUnstructuredGridWriter* writer= vtkXMLUnstructuredGridWriter::New();
  writer->SetInput(grid);
  //writer->SetDataModeToAscii();
  writer->SetFileName(vm["output"].as<std::string>().c_str());
  writer->Write();
  writer->Delete();

}

//
//
//
void create_points(const std::string& file_name,
                   vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //parse file and simultaneously output to vtk
  std::ifstream pts_file(file_name.c_str());
  if (!pts_file)
  {
    std::cerr << "Failed to read pts file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(pts_file, line); //Skip over the first line

  //Create Vertices
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  unsigned vertex_index = 0;
  while(std::getline(pts_file, line))
  {
    double coords[3];

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> coords[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> coords[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> coords[2];

    points->InsertPoint(vertex_index, coords);
    ++vertex_index;
  }

  grid->SetPoints(points);
}

//
//
//
void create_tris(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream tris_file(file_name.c_str());
  if (!tris_file)
  {
    std::cerr << "Failed to read tris file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(tris_file, line); //Skip over the first line

  //Create Vertices
  unsigned tri_index = 0;
  while(std::getline(tris_file, line))
  {
    std::vector<unsigned int> conn(3);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> conn[2];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(3);

    for(unsigned int i=0;i<conn.size();++i)
    {
	  pts->SetId(i,conn[i]);
    }

    grid->InsertNextCell(VTK_TRIANGLE,pts);
    pts->Delete();

    ++tri_index;
  }
}

//
//
//
void create_elem(const std::string& file_name,
                 vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create elem
  std::ifstream elem_file(file_name.c_str());
  if (!elem_file)
  {
    std::cerr << "Failed to read elem file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(elem_file, line); //Skip over the first line

  //Create Vertices
  unsigned elem_index = 0;
  while(std::getline(elem_file, line))
  {
    std::vector<unsigned int> conn(4);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    ++beg; //Throw away Tt first entry
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> conn[2];
    ++beg;

    std::istringstream iss4(*beg);
    iss4 >> conn[3];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(4);

    for(unsigned int i=0;i<conn.size();++i)
    {
      //std::cout << i << " " << conn[i] << std::endl;
	  pts->SetId(i,conn[i]);
    //std::cout << pts->GetId(i) << std::endl;
    }

    grid->InsertNextCell(VTK_TETRA,pts);
    pts->Delete();

    ++elem_index;
  }
}

/**
 * Reads a .cnnx file and adds the lines to the given grid;
 */
void create_lines(const std::string& file_name,
                  vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream cnnx_file(file_name.c_str());
  if (!cnnx_file)
  {
    std::cerr << "Failed to read cnnx file" << std::endl;
    abort();
  }

  //Read the pts file
  std::string line;
  std::getline(cnnx_file, line); //Skip over the first line

  //Create Vertices
  unsigned cnnx_index = 0;
  while(std::getline(cnnx_file, line))
  {
    std::vector<unsigned int> conn(2);

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> conn[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> conn[1];
    ++beg;

    vtkIdList *pts = vtkIdList::New();
    pts->SetNumberOfIds(2);

    for(unsigned int i=0;i<conn.size();++i)
    {
	  pts->SetId(i,conn[i]);
    }

    grid->InsertNextCell(VTK_LINE,pts);
    pts->Delete();

    ++cnnx_index;
  }
}

/**
 * Reads a .lon file and adds the vectors to the given elements;
 * Code assumes that the file has a first line to ignore.
 */
void create_vectors(const std::string& file_name,
                    vtkSmartPointer<vtkUnstructuredGrid> grid)
{
  //Create tris
  std::ifstream lon_file(file_name.c_str());
  if (!lon_file)
  {
    std::cerr << "Failed to read lon file" << std::endl;
    abort();
  }

  //

  //Read the pts file
  std::string line;
  // std::getline(lon_file, line); //Skip over the first line

  // quick and dirty way to check if there is a one-line header
  // if there is, ignore it
  // if (found!=string::npos)
  //
  vtkCellData* cellData = grid->GetCellData();
  vtkSmartPointer< vtkFloatArray > vectors = vtkSmartPointer< vtkFloatArray >::New();
  vectors->SetName("lon");
  cellData->AddArray(vectors);

  //Create Vertices
  while(std::getline(lon_file, line))
  {
    double lon[3];

     // >> lon[0] >> lon[1] >> lon[2];

    char_delimiters_separator<char> sep(false, "", " ");
    tokenizer<> line_toks(line, sep);

    std::stringstream vertex_coords;

    tokenizer<>::iterator beg=line_toks.begin();
    std::istringstream iss(*beg);
    iss >> lon[0];
    ++beg;

    std::istringstream iss2(*beg);
    iss2 >> lon[1];
    ++beg;

    std::istringstream iss3(*beg);
    iss3 >> lon[2];
    ++beg;

    vectors->SetNumberOfComponents(3);
    vectors->InsertNextTuple3(lon[0],lon[1],lon[2]);

    // vectors->InsertNextTuple(lon[0]);

    //
    //     vtkIdList *pts = vtkIdList::New();
    //     pts->SetNumberOfIds(2);
    //
    //     for(unsigned int i=0;i<lon.size();++i)
    //     {
    // pts->SetId(i,lon[i]);
    //     }
    //
    //     grid->InsertNextCell(VTK_LINE,pts);
    //     pts->Delete();
  }
}
<|endoftext|>


<commit_before>//
// Created by vincent on 13/06/17.
//

#include "Game.hpp"
#include "Bomb.hpp"

unsigned int			is::Bomb::ID = 0;

is::Bomb::Bomb(is::map &map, irr::video::ITexture *texture, irr::scene::IAnimatedMesh *bombMesh, const irr::core::vector3df &posMap, int power,
	       irr::video::IVideoDriver &videoDriver, irr::scene::ISceneManager &sceneManager) :
	_id(ID++),
	_posMap(posMap),
	_posSpace(posMap.Y * SCALE - SCALE / 2, 0.55 * SCALE, posMap.X * SCALE + SCALE / 2),
	_power(power),
	_map(map),
	_videoDriver(videoDriver),
	_sceneManager(sceneManager),
	_alreadyBlowUp(false),
	_start_clock(std::clock()),
	_state(BOMB_PLANTED),
	_fires()
{
  if (!(this->_node = this->_sceneManager.addAnimatedMeshSceneNode(bombMesh)))
    throw is::IndieStudioException("Error on loading bomb.");
  this->_node->setPosition(this->_posSpace);
  this->_node->setScale({0.5f * SCALE, 0.5f * SCALE, 0.5f * SCALE});
  this->_map.addObject(Type::BOMB, {(int)posMap.X, (int)posMap.Y, (int)posMap.Z});
  std::cerr << "Bomb() id = " << this->_id << std::endl;
  std::cout << "Bomb pos.x = " << posMap.X << " pos.y = " << posMap.Y << " pos.Z = " << posMap.Z << std::endl;
}

is::Bomb::~Bomb()
{
  this->_map.delObject({(int)this->_posMap.X, (int)this->_posMap.Y, (int)this->_posMap.Z});
  std::cerr << "~Bomb() id = " << this->_id << std::endl;
}

void is::Bomb::draw()
{
  this->_node->render();
}

void is::Bomb::remove()
{
  this->_node->remove();
}

bool is::Bomb::blowUp(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  std::clock_t 		end_clock = std::clock();
  int 			duration = static_cast<int>((std::clock() - _start_clock) / CLOCKS_PER_SEC);

  if (this->_state == BOMB_PLANTED && duration == ((_id == 0) ? (2) : (5)))
    {
      this->_explosion(bombs);
    }
  else if (this->_state == FIRE && duration == 2)
      {
	this->_stopFires();
	return (true);
      }
  return (false);
}

int 			is::Bomb::_reducePower(std::list<std::shared_ptr<is::Bomb>> bombs,
						  irr::core::vector3df pos,
						  int power,
						  const std::function<void(irr::core::vector3df &)> &callback)
{
  int			ret = 0;
  const 		Block *b;

  //std::cerr << "_reducPower" << std::endl;
  callback(pos);
  //std::cout << "pos.x = " << pos.X << " pos.y = " << pos.Y << " pos.z = " << pos.Z<< std::endl;
  while (this->_map.canIMoove(is::Vector3d(pos.X, pos.Y, pos.Z)) && ret < power)
    {
      callback(pos);
      ret += 1;
    }

  if ((b = this->_map.findBlock({(int)pos.X, (int)pos.Y, (int)pos.Z}))->getType() == is::Type::BREAK)
    {
      this->_blocksToDelete.emplace_back(pos.X, pos.Y, pos.Z);
      ret += 1;
    }
  else if (b->getType() == Type::BOMB)
      {
	auto it = std::find_if(bombs.begin(), bombs.end(), [pos](auto bomb) { return pos == bomb->getPos(); });

	std::cout << std::boolalpha << _alreadyBlowUp << std::endl;
	if ((*it)->_alreadyBlowUp == false)
	  (*it)->_explosion(bombs);
	ret += 1;
	//std::cout << "DESTRUIT UNE AUTRE BOMBE" << std::endl;
      }
  //std::cout << "ret = " << ret << std::endl;
  //std::cerr << "_reducPower" << std::endl;
  return (ret);
}

is::Bomb		&is::Bomb::operator=(const Bomb &o)
{
  this->_posMap = o._posMap;
  this->_posSpace = o._posSpace;
  this->_power = o._power;
  this->_node = o._node;
}

bool is::Bomb::operator==(const is::Bomb &other) const
{
  return (this == &other);
}

bool is::Bomb::operator!=(const is::Bomb &rhs) const
{
  return !(rhs == *this);
}

void is::Bomb::_startFires(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::FORWARD,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.X += 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::BACKWARD,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.X -= 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::RIGHT,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.Y += 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::LEFT,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.Y -= 1; }));
  std::for_each(this->_fires.begin(), this->_fires.end(), [](Fire &fire) {
    fire.startFire();
  });
  std::for_each(this->_blocksToDelete.begin(), this->_blocksToDelete.end(), [&](auto pos) {
    this->_map.delObject(pos);
  });
}

void is::Bomb::_stopFires()
{
  std::for_each(this->_fires.begin(), this->_fires.end(), [](Fire &fire) {
    fire.stopFire();
  });
}

const irr::core::vector3df &is::Bomb::getPos() const
{
  return (this->_posMap);
}

void is::Bomb::_explosion(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  this->_alreadyBlowUp = true;
  this->_state = FIRE;
  this->_startFires(bombs);
  this->_node->remove();
  this->_start_clock = std::clock();
}
<commit_msg>MAJ Bomb<commit_after>//
// Created by vincent on 13/06/17.
//

#include "Game.hpp"
#include "Bomb.hpp"

unsigned int			is::Bomb::ID = 0;

is::Bomb::Bomb(is::map &map, irr::video::ITexture *texture, irr::scene::IAnimatedMesh *bombMesh, const irr::core::vector3df &posMap, int power,
	       irr::video::IVideoDriver &videoDriver, irr::scene::ISceneManager &sceneManager) :
	_id(ID++),
	_posMap(posMap),
	_posSpace(posMap.Y * SCALE - SCALE / 2, 0.55 * SCALE, posMap.X * SCALE + SCALE / 2),
	_power(power),
	_map(map),
	_videoDriver(videoDriver),
	_sceneManager(sceneManager),
	_alreadyBlowUp(false),
	_start_clock(std::clock()),
	_state(BOMB_PLANTED),
	_fires()
{
  if (!(this->_node = this->_sceneManager.addAnimatedMeshSceneNode(bombMesh)))
    throw is::IndieStudioException("Error on loading bomb.");
  this->_node->setPosition(this->_posSpace);
  this->_node->setScale({0.5f * SCALE, 0.5f * SCALE, 0.5f * SCALE});
  this->_map.addObject(Type::BOMB, {(int)posMap.X, (int)posMap.Y, (int)posMap.Z});
  std::cerr << "Bomb() id = " << this->_id << std::endl;
  std::cout << "Bomb pos.x = " << posMap.X << " pos.y = " << posMap.Y << " pos.Z = " << posMap.Z << std::endl;
}

is::Bomb::~Bomb()
{
  this->_map.delObject({(int)this->_posMap.X, (int)this->_posMap.Y, (int)this->_posMap.Z});
  std::cerr << "~Bomb() id = " << this->_id << std::endl;
}

void is::Bomb::draw()
{
  this->_node->render();
}

void is::Bomb::remove()
{
  this->_node->remove();
}

bool is::Bomb::blowUp(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  std::clock_t 		end_clock = std::clock();
  int 			duration = static_cast<int>((std::clock() - _start_clock) / CLOCKS_PER_SEC);

  if (this->_state == BOMB_PLANTED && duration == ((_id == 0) ? (2) : (5)))
    {
      this->_explosion(bombs);
    }
  else if (this->_state == FIRE && duration == 2)
      {
	this->_stopFires();
	return (true);
      }
  return (false);
}

int 			is::Bomb::_reducePower(std::list<std::shared_ptr<is::Bomb>> bombs,
						  irr::core::vector3df pos,
						  int power,
						  const std::function<void(irr::core::vector3df &)> &callback)
{
  int			ret = 0;
  const 		Block *b;

  //std::cerr << "_reducPower" << std::endl;
  callback(pos);
  //std::cout << "pos.x = " << pos.X << " pos.y = " << pos.Y << " pos.z = " << pos.Z<< std::endl;
  while (this->_map.canIMoove(is::Vector3d(pos.X, pos.Y, pos.Z)) && ret < power)
    {
      callback(pos);
      ret += 1;
    }

  if ((b = this->_map.findBlock({(int)pos.X, (int)pos.Y, (int)pos.Z}))->getType() == is::Type::BREAK)
    {
      this->_blocksToDelete.emplace_back(pos.X, pos.Y, pos.Z);
      ret += 1;
    }
  else if (b->getType() == Type::BOMB)
      {
	ret += 1;
	auto it = std::find_if(bombs.begin(),
			       bombs.end(),
			       [pos](auto bomb) { return pos.X == bomb->getPos().X && pos.Y == bomb->getPos().Y && pos.Z == bomb->getPos().Z; });
	if (it == bombs.end())
	  return (ret);

	std::cout << std::boolalpha << _alreadyBlowUp << std::endl;
	if ((*it)->_alreadyBlowUp == false)
	  (*it)->_explosion(bombs);
	//std::cout << "DESTRUIT UNE AUTRE BOMBE" << std::endl;
      }
  //std::cout << "ret = " << ret << std::endl;
  //std::cerr << "_reducPower" << std::endl;
  return (ret);
}

is::Bomb		&is::Bomb::operator=(const Bomb &o)
{
  this->_posMap = o._posMap;
  this->_posSpace = o._posSpace;
  this->_power = o._power;
  this->_node = o._node;
}

bool is::Bomb::operator==(const is::Bomb &other) const
{
  return (this == &other);
}

bool is::Bomb::operator!=(const is::Bomb &rhs) const
{
  return !(rhs == *this);
}

void is::Bomb::_startFires(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::FORWARD,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.X += 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::BACKWARD,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.X -= 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::RIGHT,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.Y += 1; }));
  this->_fires.emplace_back(&this->_sceneManager, &this->_videoDriver, this->_posSpace, FireDirection::LEFT,
			    this->_reducePower(bombs, this->_posMap, this->_power, [&](irr::core::vector3df &pos) { pos.Y -= 1; }));
  std::for_each(this->_fires.begin(), this->_fires.end(), [](Fire &fire) {
    fire.startFire();
  });
  std::for_each(this->_blocksToDelete.begin(), this->_blocksToDelete.end(), [&](auto pos) {
    this->_map.delObject(pos);
  });
}

void is::Bomb::_stopFires()
{
  std::for_each(this->_fires.begin(), this->_fires.end(), [](Fire &fire) {
    fire.stopFire();
  });
}

const irr::core::vector3df &is::Bomb::getPos() const
{
  return (this->_posMap);
}

void is::Bomb::_explosion(std::list<std::shared_ptr<is::Bomb>> bombs)
{
  this->_alreadyBlowUp = true;
  this->_state = FIRE;
  this->_startFires(bombs);
  this->_node->remove();
  this->_start_clock = std::clock();
}
<|endoftext|>


<commit_before>#include "medToolBoxDiffusionTensorView.h"

class medToolBoxDiffusionTensorViewPrivate
{
public:
    QComboBox*    glyphShape;
    QSlider*      sampleRate;
    QCheckBox*    flipX;
    QCheckBox*    flipY;
    QCheckBox*    flipZ;
    QRadioButton* eigenVectorV1;
    QRadioButton* eigenVectorV2;
    QRadioButton* eigenVectorV3;
    QCheckBox*    reverseBackgroundColor;
    QSlider*      glyphResolution;

    // labels for showing the slider's actual value
    QLabel* sampleRateLabel;
};

medToolBoxDiffusionTensorView::medToolBoxDiffusionTensorView(QWidget *parent) : medToolBox(parent), d(new medToolBoxDiffusionTensorViewPrivate)
{
    QWidget* displayWidget = new QWidget(this);

    // combobox to control the glyph shape
    d->glyphShape = new QComboBox(displayWidget);
    d->glyphShape->addItem("Lines");
    d->glyphShape->addItem("Arrows");
    d->glyphShape->addItem("Disks");
    d->glyphShape->addItem("Cylinders");
    d->glyphShape->addItem("Cubes");
    d->glyphShape->addItem("Ellipsoids");
    d->glyphShape->addItem("Superquadrics");

    QHBoxLayout* glyphShapeLayout = new QHBoxLayout;
    glyphShapeLayout->addWidget(new QLabel("Shape: "));
    glyphShapeLayout->addWidget(d->glyphShape);

    // slider to control sample rate
    d->sampleRate =  new QSlider(Qt::Horizontal, displayWidget);
    d->sampleRate->setMinimum(1);
    d->sampleRate->setMaximum(10);
    d->sampleRate->setSingleStep(1);
    d->sampleRate->setValue(1);

    d->sampleRateLabel = new QLabel("1", displayWidget);

    QHBoxLayout* sampleRateLayout = new QHBoxLayout;
    sampleRateLayout->addWidget(new QLabel("Sample rate: "));
    sampleRateLayout->addWidget(d->sampleRate);
    sampleRateLayout->addWidget(d->sampleRateLabel);

    connect(d->sampleRate, SIGNAL(valueChanged(int)), d->sampleRateLabel, SLOT(setNum(int)));

    // flipX, flipY and flipZ checkboxes
    d->flipX = new QCheckBox("Flip X", displayWidget);
    d->flipY = new QCheckBox("Flip Y", displayWidget);
    d->flipZ = new QCheckBox("Flip Z", displayWidget);

    QHBoxLayout* flipAxesLayout = new QHBoxLayout;
    flipAxesLayout->addWidget(d->flipX);
    flipAxesLayout->addWidget(d->flipY);
    flipAxesLayout->addWidget(d->flipZ);

    // eigen vectors
    d->eigenVectorV1 = new QRadioButton("v1", displayWidget);
    d->eigenVectorV2 = new QRadioButton("v2", displayWidget);
    d->eigenVectorV3 = new QRadioButton("v3", displayWidget);

    QButtonGroup *eigenVectorRadioGroup = new QButtonGroup(displayWidget);
    eigenVectorRadioGroup->addButton(d->eigenVectorV1);
    eigenVectorRadioGroup->addButton(d->eigenVectorV2);
    eigenVectorRadioGroup->addButton(d->eigenVectorV3);
    eigenVectorRadioGroup->setExclusive(true);

    QHBoxLayout *eigenVectorGroupLayout = new QHBoxLayout;
    eigenVectorGroupLayout->addWidget(d->eigenVectorV1);
    eigenVectorGroupLayout->addWidget(d->eigenVectorV2);
    eigenVectorGroupLayout->addWidget(d->eigenVectorV3);
    //eigenVectorGroupLayout->addStretch(1);

    QVBoxLayout* eigenLayout = new QVBoxLayout;
    eigenLayout->addWidget(new QLabel("Eigen Vector for color-coding:"));
    eigenLayout->addLayout(eigenVectorGroupLayout);

    d->eigenVectorV1->setChecked(true);

    // reverse background color
    d->reverseBackgroundColor = new QCheckBox("Reverse Background Color", displayWidget);

    // slider to control glyph resolution
    d->glyphResolution =  new QSlider(Qt::Horizontal, displayWidget);
    d->glyphResolution->setMinimum(2);
    d->glyphResolution->setMaximum(20);
    d->glyphResolution->setSingleStep(1);
    d->glyphResolution->setValue(6);
    //d->glyphResolution->setTickPosition(QSlider::TicksAbove);

    QHBoxLayout* glyphResolutionLayout = new QHBoxLayout;
    glyphResolutionLayout->addWidget(new QLabel("Glyph resolution: "));
    glyphResolutionLayout->addWidget(d->glyphResolution);

    // layout all the controls in the toolbox
    QVBoxLayout* layout = new QVBoxLayout(displayWidget);
    layout->addLayout(glyphShapeLayout);
    layout->addLayout(sampleRateLayout);
    layout->addLayout(flipAxesLayout);
    layout->addLayout(eigenLayout);
    layout->addWidget(d->reverseBackgroundColor);
    layout->addLayout(glyphResolutionLayout);

    // connect all the signals
    connect(d->glyphShape,              SIGNAL(currentIndexChanged(const QString&)), this, SIGNAL(glyphShapeChanged(const QString&)));
    connect(d->sampleRate,              SIGNAL(valueChanged(int)),                   this, SIGNAL(sampleRateChanged(int)));
    connect(d->reverseBackgroundColor,  SIGNAL(stateChanged(int)),                   this, SIGNAL(reverseBackgroundColor(bool)));
    connect(d->glyphResolution,         SIGNAL(valueChanged(int)),                   this, SIGNAL(glyphResolutionChanged(int)));

    // the axes signals require one more step to translate from Qt::CheckState to bool
    connect(d->flipX,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipXCheckBoxStateChanged(int)));
    connect(d->flipY,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipYCheckBoxStateChanged(int)));
    connect(d->flipZ,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipZCheckBoxStateChanged(int)));

    // we also need to translate radio buttons boolean states to an eigen vector
    connect(d->eigenVectorV1,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV1Toggled(bool)));
    connect(d->eigenVectorV2,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV2Toggled(bool)));
    connect(d->eigenVectorV3,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV3Toggled(bool)));

    this->setTitle("Tensor View");
    this->addWidget(displayWidget);
}

medToolBoxDiffusionTensorView::~medToolBoxDiffusionTensorView()
{
    delete d;
    d = NULL;
}

void medToolBoxDiffusionTensorView::update (dtkAbstractView *view)
{
}

void medToolBoxDiffusionTensorView::onFlipXCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipX(false);
    else if (checkBoxState == Qt::Checked)
        emit flipX(true);
}

void medToolBoxDiffusionTensorView::onFlipYCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipY(false);
    else if (checkBoxState == Qt::Checked)
        emit flipY(true);
}

void medToolBoxDiffusionTensorView::onFlipZCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipZ(false);
    else if (checkBoxState == Qt::Checked)
        emit flipZ(true);
}

void medToolBoxDiffusionTensorView::onEigenVectorV1Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(1);
}

void medToolBoxDiffusionTensorView::onEigenVectorV2Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(2);
}

void medToolBoxDiffusionTensorView::onEigenVectorV3Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(3);
}
<commit_msg>Added label next to the glyph resolution slider in the tensor toolbox to show the actual value.<commit_after>#include "medToolBoxDiffusionTensorView.h"

class medToolBoxDiffusionTensorViewPrivate
{
public:
    QComboBox*    glyphShape;
    QSlider*      sampleRate;
    QCheckBox*    flipX;
    QCheckBox*    flipY;
    QCheckBox*    flipZ;
    QRadioButton* eigenVectorV1;
    QRadioButton* eigenVectorV2;
    QRadioButton* eigenVectorV3;
    QCheckBox*    reverseBackgroundColor;
    QSlider*      glyphResolution;

    // labels for showing the slider's actual value
    QLabel* sampleRateLabel;
    QLabel* glyphResolutionLabel;
};

medToolBoxDiffusionTensorView::medToolBoxDiffusionTensorView(QWidget *parent) : medToolBox(parent), d(new medToolBoxDiffusionTensorViewPrivate)
{
    QWidget* displayWidget = new QWidget(this);

    // combobox to control the glyph shape
    d->glyphShape = new QComboBox(displayWidget);
    d->glyphShape->addItem("Lines");
    d->glyphShape->addItem("Arrows");
    d->glyphShape->addItem("Disks");
    d->glyphShape->addItem("Cylinders");
    d->glyphShape->addItem("Cubes");
    d->glyphShape->addItem("Ellipsoids");
    d->glyphShape->addItem("Superquadrics");

    QHBoxLayout* glyphShapeLayout = new QHBoxLayout;
    glyphShapeLayout->addWidget(new QLabel("Shape: "));
    glyphShapeLayout->addWidget(d->glyphShape);

    // slider to control sample rate
    d->sampleRate =  new QSlider(Qt::Horizontal, displayWidget);
    d->sampleRate->setMinimum(1);
    d->sampleRate->setMaximum(10);
    d->sampleRate->setSingleStep(1);
    d->sampleRate->setValue(1);

    d->sampleRateLabel = new QLabel("1", displayWidget);

    QHBoxLayout* sampleRateLayout = new QHBoxLayout;
    sampleRateLayout->addWidget(new QLabel("Sample rate: "));
    sampleRateLayout->addWidget(d->sampleRate);
    sampleRateLayout->addWidget(d->sampleRateLabel);

    connect(d->sampleRate, SIGNAL(valueChanged(int)), d->sampleRateLabel, SLOT(setNum(int)));

    // flipX, flipY and flipZ checkboxes
    d->flipX = new QCheckBox("Flip X", displayWidget);
    d->flipY = new QCheckBox("Flip Y", displayWidget);
    d->flipZ = new QCheckBox("Flip Z", displayWidget);

    QHBoxLayout* flipAxesLayout = new QHBoxLayout;
    flipAxesLayout->addWidget(d->flipX);
    flipAxesLayout->addWidget(d->flipY);
    flipAxesLayout->addWidget(d->flipZ);

    // eigen vectors
    d->eigenVectorV1 = new QRadioButton("v1", displayWidget);
    d->eigenVectorV2 = new QRadioButton("v2", displayWidget);
    d->eigenVectorV3 = new QRadioButton("v3", displayWidget);

    QButtonGroup *eigenVectorRadioGroup = new QButtonGroup(displayWidget);
    eigenVectorRadioGroup->addButton(d->eigenVectorV1);
    eigenVectorRadioGroup->addButton(d->eigenVectorV2);
    eigenVectorRadioGroup->addButton(d->eigenVectorV3);
    eigenVectorRadioGroup->setExclusive(true);

    QHBoxLayout *eigenVectorGroupLayout = new QHBoxLayout;
    eigenVectorGroupLayout->addWidget(d->eigenVectorV1);
    eigenVectorGroupLayout->addWidget(d->eigenVectorV2);
    eigenVectorGroupLayout->addWidget(d->eigenVectorV3);
    //eigenVectorGroupLayout->addStretch(1);

    QVBoxLayout* eigenLayout = new QVBoxLayout;
    eigenLayout->addWidget(new QLabel("Eigen Vector for color-coding:"));
    eigenLayout->addLayout(eigenVectorGroupLayout);

    d->eigenVectorV1->setChecked(true);

    // reverse background color
    d->reverseBackgroundColor = new QCheckBox("Reverse Background Color", displayWidget);

    // slider to control glyph resolution
    d->glyphResolution =  new QSlider(Qt::Horizontal, displayWidget);
    d->glyphResolution->setMinimum(2);
    d->glyphResolution->setMaximum(20);
    d->glyphResolution->setSingleStep(1);
    d->glyphResolution->setValue(6);

    d->glyphResolutionLabel = new QLabel("6", displayWidget);

    QHBoxLayout* glyphResolutionLayout = new QHBoxLayout;
    glyphResolutionLayout->addWidget(new QLabel("Glyph resolution: "));
    glyphResolutionLayout->addWidget(d->glyphResolution);
    glyphResolutionLayout->addWidget(d->glyphResolutionLabel);

    connect(d->glyphResolution, SIGNAL(valueChanged(int)), d->glyphResolutionLabel, SLOT(setNum(int)));

    // layout all the controls in the toolbox
    QVBoxLayout* layout = new QVBoxLayout(displayWidget);
    layout->addLayout(glyphShapeLayout);
    layout->addLayout(sampleRateLayout);
    layout->addLayout(flipAxesLayout);
    layout->addLayout(eigenLayout);
    layout->addWidget(d->reverseBackgroundColor);
    layout->addLayout(glyphResolutionLayout);

    // connect all the signals
    connect(d->glyphShape,              SIGNAL(currentIndexChanged(const QString&)), this, SIGNAL(glyphShapeChanged(const QString&)));
    connect(d->sampleRate,              SIGNAL(valueChanged(int)),                   this, SIGNAL(sampleRateChanged(int)));
    connect(d->reverseBackgroundColor,  SIGNAL(stateChanged(int)),                   this, SIGNAL(reverseBackgroundColor(bool)));
    connect(d->glyphResolution,         SIGNAL(valueChanged(int)),                   this, SIGNAL(glyphResolutionChanged(int)));

    // the axes signals require one more step to translate from Qt::CheckState to bool
    connect(d->flipX,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipXCheckBoxStateChanged(int)));
    connect(d->flipY,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipYCheckBoxStateChanged(int)));
    connect(d->flipZ,           SIGNAL(stateChanged(int)),                   this, SLOT(onFlipZCheckBoxStateChanged(int)));

    // we also need to translate radio buttons boolean states to an eigen vector
    connect(d->eigenVectorV1,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV1Toggled(bool)));
    connect(d->eigenVectorV2,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV2Toggled(bool)));
    connect(d->eigenVectorV3,   SIGNAL(toggled(bool)),                       this, SLOT(onEigenVectorV3Toggled(bool)));

    this->setTitle("Tensor View");
    this->addWidget(displayWidget);
}

medToolBoxDiffusionTensorView::~medToolBoxDiffusionTensorView()
{
    delete d;
    d = NULL;
}

void medToolBoxDiffusionTensorView::update (dtkAbstractView *view)
{
}

void medToolBoxDiffusionTensorView::onFlipXCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipX(false);
    else if (checkBoxState == Qt::Checked)
        emit flipX(true);
}

void medToolBoxDiffusionTensorView::onFlipYCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipY(false);
    else if (checkBoxState == Qt::Checked)
        emit flipY(true);
}

void medToolBoxDiffusionTensorView::onFlipZCheckBoxStateChanged(int checkBoxState)
{
    if (checkBoxState == Qt::Unchecked)
        emit flipZ(false);
    else if (checkBoxState == Qt::Checked)
        emit flipZ(true);
}

void medToolBoxDiffusionTensorView::onEigenVectorV1Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(1);
}

void medToolBoxDiffusionTensorView::onEigenVectorV2Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(2);
}

void medToolBoxDiffusionTensorView::onEigenVectorV3Toggled(bool isSelected)
{
    if (isSelected)
        emit eigenVectorChanged(3);
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal2lkit authors
//
//    This file is part of the deal2lkit library.
//
//    The deal2lkit library is free software; you can use it, redistribute
//    it, and/or modify it under the terms of the GNU Lesser General
//    Public License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal2lkit distribution.
//
//-----------------------------------------------------------

#include <deal2lkit/parsed_finite_element.h>
#include <deal2lkit/utilities.h>
#include <deal.II/fe/fe_tools.h>

#include <algorithm> // std::find

D2K_NAMESPACE_OPEN

template <int dim, int spacedim>
ParsedFiniteElement<dim, spacedim>::ParsedFiniteElement(const std::string &name,
                                                        const std::string &default_name,
                                                        const std::string &default_component_names,
                                                        const unsigned int n_components) :
  ParameterAcceptor(name),
  _n_components(n_components),
  fe_name(default_name),
  default_component_names(default_component_names)
{
  component_names = Utilities::split_string_list(default_component_names);
  parse_parameters_call_back();
}

template <int dim, int spacedim>
void ParsedFiniteElement<dim, spacedim>::declare_parameters(ParameterHandler &prm)
{
  add_parameter(prm, &fe_name,
                "Finite element space", fe_name,
                Patterns::Anything(),
                "The finite element space to use. For vector "
                "finite elements use the notation "
                "FESystem[FE_Q(2)^2-FE_DGP(1)] (e.g. Navier-Stokes). ");

  add_parameter(prm, &component_names,
                "Blocking of the finite element", default_component_names,
                // This ensures that an assert is thrown if you try to
                // read something with the wrong number of components
                Patterns::List(Patterns::Anything(),
                               (_n_components ? _n_components: 1),
                               (_n_components ? _n_components: numbers::invalid_unsigned_int)),
                "How to partition the finite element. This information can be used "
                "to construct block matrices and vectors, as well as to create "
                "names for solution vectors, or error tables. A repeated component "
                "is interpreted as a vector field, with dimension equal to the "
                "number of repetitions (up to 3). This is used in conjunction "
                "with a ParsedFiniteElement class, to generate arbitrary "
                "finite dimensional spaces.");
}

template <int dim, int spacedim>
FiniteElement<dim,spacedim> *
ParsedFiniteElement<dim, spacedim>::operator()() const
{
  return FETools::get_fe_by_name<dim,spacedim>(fe_name);
}

template<int dim, int spacedim>
void ParsedFiniteElement<dim,spacedim>::parse_parameters_call_back()
{
  component_blocks.resize(component_names.size());
  block_names.resize(component_names.size());
  unsigned int j=0;
  for (unsigned int i=0; i<component_names.size(); ++i)
    {
      if ( (i>0) && (component_names[i-1] != component_names[i]) )
        j++;
      component_blocks[i] = j;
      block_names[j] = component_names[i];
    }
  block_names.resize(j+1);
  FiniteElement<dim,spacedim> *fe = (*this)();
  const unsigned int nc = fe->n_components();
  delete fe;
  AssertThrow(component_names.size() == nc,
              ExcInternalError("Generated FE has the wrong number of components."));
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::n_components() const
{
  return component_names.size();
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::n_blocks() const
{
  return block_names.size();
}

template<int dim, int spacedim>
std::string ParsedFiniteElement<dim,spacedim>::get_component_names() const
{
  return print(component_names);
}

template<int dim, int spacedim>
std::string ParsedFiniteElement<dim,spacedim>::get_block_names() const
{
  return print(block_names);
}

template<int dim, int spacedim>
std::vector<unsigned int> ParsedFiniteElement<dim,spacedim>::get_component_blocks() const
{
  return component_blocks;
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::get_first_occurence(const std::string &var) const
{
  unsigned int pos_counter = 0;
  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
  Assert(pos_it != component_names.end(),
         ExcInternalError("Component not found!"));
  return pos_it - component_names.begin();
}

template<int dim, int spacedim>
bool ParsedFiniteElement<dim,spacedim>::is_vector(const std::string &var) const
{
  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
  Assert(pos_it != component_names.end(),
         ExcInternalError("Component not found!"));
  pos_it++;
  if (pos_it == component_names.end())
    return false;
  return (*pos_it == var);
}

D2K_NAMESPACE_CLOSE

template class deal2lkit::ParsedFiniteElement<1,1>;
template class deal2lkit::ParsedFiniteElement<1,2>;
template class deal2lkit::ParsedFiniteElement<1,3>;
template class deal2lkit::ParsedFiniteElement<2,2>;
template class deal2lkit::ParsedFiniteElement<2,3>;
template class deal2lkit::ParsedFiniteElement<3,3>;

<commit_msg>silence<commit_after>//-----------------------------------------------------------
//
//    Copyright (C) 2015 by the deal2lkit authors
//
//    This file is part of the deal2lkit library.
//
//    The deal2lkit library is free software; you can use it, redistribute
//    it, and/or modify it under the terms of the GNU Lesser General
//    Public License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//    The full text of the license can be found in the file LICENSE at
//    the top level of the deal2lkit distribution.
//
//-----------------------------------------------------------

#include <deal2lkit/parsed_finite_element.h>
#include <deal2lkit/utilities.h>
#include <deal.II/fe/fe_tools.h>

#include <algorithm> // std::find

D2K_NAMESPACE_OPEN

template <int dim, int spacedim>
ParsedFiniteElement<dim, spacedim>::ParsedFiniteElement(const std::string &name,
                                                        const std::string &default_name,
                                                        const std::string &default_component_names,
                                                        const unsigned int n_components) :
  ParameterAcceptor(name),
  _n_components(n_components),
  fe_name(default_name),
  default_component_names(default_component_names)
{
  component_names = Utilities::split_string_list(default_component_names);
  parse_parameters_call_back();
}

template <int dim, int spacedim>
void ParsedFiniteElement<dim, spacedim>::declare_parameters(ParameterHandler &prm)
{
  add_parameter(prm, &fe_name,
                "Finite element space", fe_name,
                Patterns::Anything(),
                "The finite element space to use. For vector "
                "finite elements use the notation "
                "FESystem[FE_Q(2)^2-FE_DGP(1)] (e.g. Navier-Stokes). ");

  add_parameter(prm, &component_names,
                "Blocking of the finite element", default_component_names,
                // This ensures that an assert is thrown if you try to
                // read something with the wrong number of components
                Patterns::List(Patterns::Anything(),
                               (_n_components ? _n_components: 1),
                               (_n_components ? _n_components: numbers::invalid_unsigned_int)),
                "How to partition the finite element. This information can be used "
                "to construct block matrices and vectors, as well as to create "
                "names for solution vectors, or error tables. A repeated component "
                "is interpreted as a vector field, with dimension equal to the "
                "number of repetitions (up to 3). This is used in conjunction "
                "with a ParsedFiniteElement class, to generate arbitrary "
                "finite dimensional spaces.");
}

template <int dim, int spacedim>
FiniteElement<dim,spacedim> *
ParsedFiniteElement<dim, spacedim>::operator()() const
{
  return FETools::get_fe_by_name<dim,spacedim>(fe_name);
}

template<int dim, int spacedim>
void ParsedFiniteElement<dim,spacedim>::parse_parameters_call_back()
{
  component_blocks.resize(component_names.size());
  block_names.resize(component_names.size());
  unsigned int j=0;
  for (unsigned int i=0; i<component_names.size(); ++i)
    {
      if ( (i>0) && (component_names[i-1] != component_names[i]) )
        j++;
      component_blocks[i] = j;
      block_names[j] = component_names[i];
    }
  block_names.resize(j+1);
  FiniteElement<dim,spacedim> *fe = (*this)();
  const unsigned int nc = fe->n_components();
  delete fe;
  AssertThrow(component_names.size() == nc,
              ExcInternalError("Generated FE has the wrong number of components."));
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::n_components() const
{
  return component_names.size();
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::n_blocks() const
{
  return block_names.size();
}

template<int dim, int spacedim>
std::string ParsedFiniteElement<dim,spacedim>::get_component_names() const
{
  return print(component_names);
}

template<int dim, int spacedim>
std::string ParsedFiniteElement<dim,spacedim>::get_block_names() const
{
  return print(block_names);
}

template<int dim, int spacedim>
std::vector<unsigned int> ParsedFiniteElement<dim,spacedim>::get_component_blocks() const
{
  return component_blocks;
}

template<int dim, int spacedim>
unsigned int ParsedFiniteElement<dim,spacedim>::get_first_occurence(const std::string &var) const
{
  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
  Assert(pos_it != component_names.end(),
         ExcInternalError("Component not found!"));
  return pos_it - component_names.begin();
}

template<int dim, int spacedim>
bool ParsedFiniteElement<dim,spacedim>::is_vector(const std::string &var) const
{
  auto pos_it = std::find (component_names.begin(), component_names.end(), var);
  Assert(pos_it != component_names.end(),
         ExcInternalError("Component not found!"));
  pos_it++;
  if (pos_it == component_names.end())
    return false;
  return (*pos_it == var);
}

D2K_NAMESPACE_CLOSE

template class deal2lkit::ParsedFiniteElement<1,1>;
template class deal2lkit::ParsedFiniteElement<1,2>;
template class deal2lkit::ParsedFiniteElement<1,3>;
template class deal2lkit::ParsedFiniteElement<2,2>;
template class deal2lkit::ParsedFiniteElement<2,3>;
template class deal2lkit::ParsedFiniteElement<3,3>;

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int H, W;
ll A, B;
bool f[210][210];

ll solve() {
  bool x[110][110][4];
  for (auto i = 1; i < H/2+1; ++i) {
    for (auto j = 1; j < W/2+1; ++j) {
      x[i][j][0] = f[i-1][j-1];
      x[i][j][1] = f[H-1-i+1][j-1];
      x[i][j][2] = f[i-1][W-1-j+1];
      x[i][j][3] = f[H-1-i+1][W-1-j+1];
    }
  }
  for (auto k = 0; k < 4; ++k) {
    cerr << "k = " << k << endl;
    for (auto i = 1; i < H/2+1; ++i) {
      for (auto j = 1; j < W/2+1; ++j) {
        cerr << (x[i][j][k] ? 'S' : '.');
      }
      cerr << endl;
    }
  }
  ll ryoho = 0;
  ll yobi = 0;
  ll tate = 0;
  ll yoko = 0;
  for (auto i = 1; i < H/2+1; ++i) {
    for (auto j = 1; j < W/2+1; ++j) {
      int cnt = 0;
      for (auto k = 0; k < 4; ++k) {
        if (x[i][j][k]) cnt++;
      }
      if (cnt == 4) ryoho++;
      if (cnt == 3) yobi++;
      if (cnt == 2) {
        if (x[i][j][0] == x[i][j][1] && x[i][j][2] == x[i][j][3]) {
          tate++;
        } else if (x[i][j][0] == x[i][j][2] && x[i][j][1] == x[i][j][3]) {
          yoko++;
        }
      }
    }
  }
  ll ans = 0;
  ans = max(ans, ryoho * (A + B + A) + (yobi + tate) * A);
  ans = max(ans, ryoho * (A + B + B) + (yobi + yoko) * B);
  return ans;
}

int main () {
  cin >> H >> W >> A >> B;
  string m[210];
  for (auto i = 0; i < H; ++i) {
    cin >> m[i];
  }
  fill(&f[0][0], &f[0][0]+210*210, false);
  for (auto i = 0; i < H; ++i) {
    for (auto j = 0; j < W; ++j) {
      f[i][j] = (m[i][j] == 'S');
    }
  }
  ll ans = solve();
  cout << ans << endl;
}
<commit_msg>tried D3.cpp to 'D'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int H, W;
ll A, B;
bool f[210][210];

ll solve() {
  bool x[110][110][4];
  for (auto i = 1; i < H/2+1; ++i) {
    for (auto j = 1; j < W/2+1; ++j) {
      x[i][j][0] = f[i-1][j-1];
      x[i][j][1] = f[H-1-i+1][j-1];
      x[i][j][2] = f[i-1][W-1-j+1];
      x[i][j][3] = f[H-1-i+1][W-1-j+1];
    }
  }
  for (auto k = 0; k < 4; ++k) {
    cerr << "k = " << k << endl;
    for (auto i = 1; i < H/2+1; ++i) {
      for (auto j = 1; j < W/2+1; ++j) {
        cerr << (x[i][j][k] ? 'S' : '.');
      }
      cerr << endl;
    }
  }
  ll ryoho = 0;
  ll yobi = 0;
  ll tate = 0;
  ll yoko = 0;
  for (auto i = 1; i < H/2+1; ++i) {
    for (auto j = 1; j < W/2+1; ++j) {
      int cnt = 0;
      for (auto k = 0; k < 4; ++k) {
        if (x[i][j][k]) cnt++;
      }
      if (cnt == 4) ryoho++;
      if (cnt == 3) yobi++;
      if (cnt == 2) {
        if (x[i][j][0] == x[i][j][1] && x[i][j][2] == x[i][j][3]) {
          tate++;
        } else if (x[i][j][0] == x[i][j][2] && x[i][j][1] == x[i][j][3]) {
          yoko++;
        }
      }
    }
  }
  ll ans = 0;
  ans = max(ans, ryoho * (A + B + A) + (yobi + tate) * A);
  ans = max(ans, ryoho * (A + B + B) + (yobi + yoko) * B);
  return ans + A + B;
}

int main () {
  cin >> H >> W >> A >> B;
  string m[210];
  for (auto i = 0; i < H; ++i) {
    cin >> m[i];
  }
  fill(&f[0][0], &f[0][0]+210*210, false);
  for (auto i = 0; i < H; ++i) {
    for (auto j = 0; j < W; ++j) {
      f[i][j] = (m[i][j] == 'S');
    }
  }
  ll ans = solve();
  cout << ans << endl;
}
<|endoftext|>