<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include <android/window.h>
#include "EngineAndroid.hpp"
#include "WindowResourceAndroid.hpp"
#include "events/EventDispatcher.hpp"
#include "graphics/opengl/android/RenderDeviceOGLAndroid.hpp"
#include "thread/Lock.hpp"
#include "utils/Errors.hpp"

static int looperCallback(int fd, int events, void* data)
{
    if (events & ALOOPER_EVENT_INPUT)
    {
        char message;
        if (read(fd, &message, sizeof(message)) == -1)
            throw ouzel::SystemError("Failed to read from pipe");

        ouzel::EngineAndroid* engineAndroid = static_cast<ouzel::EngineAndroid*>(data);
        engineAndroid->executeAll();
    }

    return 1;
}

namespace ouzel
{
    EngineAndroid::EngineAndroid(JavaVM* initJavaVM):
        javaVM(initJavaVM)
    {
        std::fill(std::begin(fd), std::end(fd), 0);

        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        uriClass = jniEnv->FindClass("android/net/Uri");
        uriClass = static_cast<jclass>(jniEnv->NewGlobalRef(uriClass));
        parseMethod = jniEnv->GetStaticMethodID(uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
        intentClass = jniEnv->FindClass("android/content/Intent");
        intentClass = static_cast<jclass>(jniEnv->NewGlobalRef(intentClass));
        intentConstructor = jniEnv->GetMethodID(intentClass, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V");
    }

    EngineAndroid::~EngineAndroid()
    {
        if (updateThread.isJoinable()) updateThread.join();

        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) == JNI_OK)
        {
            if (mainActivity) jniEnv->DeleteGlobalRef(mainActivity);
            if (androidWindow) jniEnv->DeleteGlobalRef(androidWindow);
            if (surface) jniEnv->DeleteGlobalRef(surface);
            if (intentClass) jniEnv->DeleteGlobalRef(intentClass);
            if (uriClass) jniEnv->DeleteGlobalRef(uriClass);
        }

        if (looper) ALooper_release(looper);
        if (fd[0]) close(fd[0]);
        if (fd[1]) close(fd[1]);
    }

    void EngineAndroid::onCreate(jobject initMainActivity)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        mainActivity = jniEnv->NewGlobalRef(initMainActivity);

        jclass mainActivityClass = jniEnv->GetObjectClass(mainActivity);
        startActivityMethod = jniEnv->GetMethodID(mainActivityClass, "startActivity", "(Landroid/content/Intent;)V");

        // get resources
        jclass resourcesClass = jniEnv->FindClass("android/content/res/Resources");
        jmethodID getResourcesMethod = jniEnv->GetMethodID(mainActivityClass, "getResources", "()Landroid/content/res/Resources;");
        jobject resourcesObject = jniEnv->CallObjectMethod(mainActivity, getResourcesMethod);
        jmethodID getConfigurationMethod = jniEnv->GetMethodID(resourcesClass, "getConfiguration", "()Landroid/content/res/Configuration;");

        // get configuration
        configurationClass = jniEnv->FindClass("android/content/res/Configuration");
        jobject configurationObject = jniEnv->CallObjectMethod(resourcesObject, getConfigurationMethod);

        orientationField = jniEnv->GetFieldID(configurationClass, "orientation", "I");
        orientation = jniEnv->GetIntField(configurationObject, orientationField);

        // get asset manager
        jmethodID getAssetsMethod = jniEnv->GetMethodID(mainActivityClass, "getAssets", "()Landroid/content/res/AssetManager;");
        jobject assetManagerObject = jniEnv->CallObjectMethod(mainActivity, getAssetsMethod);
        assetManager = AAssetManager_fromJava(jniEnv, assetManagerObject);

        // get window
        jmethodID getWindowMethod = jniEnv->GetMethodID(mainActivityClass, "getWindow", "()Landroid/view/Window;");
        androidWindow = jniEnv->CallObjectMethod(mainActivity, getWindowMethod);
        androidWindow = jniEnv->NewGlobalRef(androidWindow);

        jclass windowClass = jniEnv->FindClass("android/view/Window");
        addFlagsMethod = jniEnv->GetMethodID(windowClass, "addFlags", "(I)V");
        clearFlagsMethod = jniEnv->GetMethodID(windowClass, "clearFlags", "(I)V");

        // File class
        jclass fileClass = jniEnv->FindClass("java/io/File");
        jmethodID getAbsolutePathMethod = jniEnv->GetMethodID(fileClass, "getAbsolutePath", "()Ljava/lang/String;");

        // dataDir
        jmethodID getFilesDirMethod = jniEnv->GetMethodID(mainActivityClass, "getFilesDir", "()Ljava/io/File;");
        jobject filesDirFile = jniEnv->CallObjectMethod(mainActivity, getFilesDirMethod);

        jstring filesDirString = static_cast<jstring>(jniEnv->CallObjectMethod(filesDirFile, getAbsolutePathMethod));
        const char* filesDirCString = jniEnv->GetStringUTFChars(filesDirString, 0);
        filesDirectory = filesDirCString;
        jniEnv->ReleaseStringUTFChars(filesDirString, filesDirCString);

        // cacheDir
        jmethodID getCacheDirMethod = jniEnv->GetMethodID(mainActivityClass, "getCacheDir", "()Ljava/io/File;");
        jobject cacheDirFile = jniEnv->CallObjectMethod(mainActivity, getCacheDirMethod);

        jstring cacheDirString = static_cast<jstring>(jniEnv->CallObjectMethod(cacheDirFile, getAbsolutePathMethod));
        const char* cacheDirCString = jniEnv->GetStringUTFChars(cacheDirString, 0);
        cacheDirectory = cacheDirCString;
        jniEnv->ReleaseStringUTFChars(cacheDirString, cacheDirCString);

        // looper
        looper = ALooper_forThread(); // this is called on main thread, so it is safe to get the looper here
        ALooper_acquire(looper);
        pipe(fd);
        if (ALooper_addFd(looper, fd[0], ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT, looperCallback, this) != 1)
            throw SystemError("Failed to add looper file descriptor");
    }

    void EngineAndroid::onSurfaceCreated(jobject newSurface)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        if (surface) jniEnv->DeleteGlobalRef(surface);
        surface = jniEnv->NewGlobalRef(newSurface);

        if (active)
        {
            WindowResourceAndroid* windowAndroid = static_cast<WindowResourceAndroid*>(window.getResource());
            windowAndroid->handleSurfaceChange(surface);

            if (renderer)
            {
                graphics::RenderDevice* renderDevice = renderer->getDevice();
                if (renderDevice->getDriver() == graphics::Renderer::Driver::OPENGL)
                {
                    graphics::RenderDeviceOGLAndroid* renderDeviceOGLAndroid = static_cast<graphics::RenderDeviceOGLAndroid*>(renderDevice);
                    renderDeviceOGLAndroid->reload();
                }
            }
        }
    }

    void EngineAndroid::onConfigurationChanged(jobject newConfig)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        jint newOrientation = jniEnv->GetIntField(newConfig, orientationField);

        if (orientation != newOrientation)
        {
            orientation = newOrientation;

            ouzel::Event event;
            event.type = ouzel::Event::Type::ORIENTATION_CHANGE;

            switch (orientation)
            {
                case ORIENTATION_PORTRAIT:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::PORTRAIT;
                    break;
                case ORIENTATION_LANDSCAPE:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::LANDSCAPE;
                    break;
                default:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::UNKNOWN;
                    break;
            }

            eventDispatcher.postEvent(event);
        }
    }

    void EngineAndroid::onSurfaceDestroyed()
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        if (surface)
        {
            jniEnv->DeleteGlobalRef(surface);
            surface = nullptr;
        }

        if (active)
        {
            WindowResourceAndroid* windowAndroid = static_cast<WindowResourceAndroid*>(window.getResource());
            windowAndroid->handleSurfaceDestroy();

            if (renderer)
            {
                graphics::RenderDevice* renderDevice = renderer->getDevice();
                if (renderDevice->getDriver() == graphics::Renderer::Driver::OPENGL)
                {
                    graphics::RenderDeviceOGLAndroid* renderDeviceOGLAndroid = static_cast<graphics::RenderDeviceOGLAndroid*>(renderDevice);
                    renderDeviceOGLAndroid->destroy();
                }
            }
        }
    }

    void EngineAndroid::run()
    {
        init();
        start();
    }

    void EngineAndroid::executeOnMainThread(const std::function<void(void)>& func)
    {
        {
            Lock lock(executeMutex);
            executeQueue.push(func);
        }

        char message = 1;
        if (write(fd[1], &message, sizeof(message)) == -1)
            throw SystemError("Failed to write to pipe");
    }

    void EngineAndroid::openURL(const std::string& url)
    {
        executeOnMainThread([url, this]() {
            JNIEnv* jniEnv;

            if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
                throw SystemError("Failed to get JNI environment");

            jstring actionString = jniEnv->NewStringUTF("android.intent.action.VIEW");
            jstring urlString = jniEnv->NewStringUTF(url.c_str());
            jobject uri = jniEnv->CallStaticObjectMethod(uriClass, parseMethod, urlString);
            jobject intentObject = jniEnv->NewObject(intentClass, intentConstructor, actionString, uri);

            jniEnv->CallVoidMethod(mainActivity, startActivityMethod, intentObject);

            jniEnv->DeleteLocalRef(intentObject);
            jniEnv->DeleteLocalRef(uri);
            jniEnv->DeleteLocalRef(urlString);
            jniEnv->DeleteLocalRef(actionString);

            if (jniEnv->ExceptionCheck())
            {
                jniEnv->ExceptionClear();
                throw SystemError("Failed to open URL");
            }
        });
    }

    void EngineAndroid::setScreenSaverEnabled(bool newScreenSaverEnabled)
    {
        Engine::setScreenSaverEnabled(newScreenSaverEnabled);

        executeOnMainThread([newScreenSaverEnabled, this]() {
            JNIEnv* jniEnv;

            if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
                throw SystemError("Failed to get JNI environment");

            if (newScreenSaverEnabled)
                jniEnv->CallVoidMethod(androidWindow, clearFlagsMethod, AWINDOW_FLAG_KEEP_SCREEN_ON);
            else
                jniEnv->CallVoidMethod(androidWindow, addFlagsMethod, AWINDOW_FLAG_KEEP_SCREEN_ON);
        });
    }

    void EngineAndroid::executeAll()
    {
        std::function<void(void)> func;

        {
           Lock lock(executeMutex);

            if (!executeQueue.empty())
            {
                func = std::move(executeQueue.front());
                executeQueue.pop();
            }
        }

        if (func) func();
    }

    void EngineAndroid::main()
    {
        JNIEnv* jniEnv;
        JavaVMAttachArgs attachArgs;
        attachArgs.version = JNI_VERSION_1_6;
        attachArgs.name = nullptr; // thread name
        attachArgs.group = nullptr; // thread group
        if (javaVM->AttachCurrentThread(&jniEnv, &attachArgs) != JNI_OK)
            throw SystemError("Failed to attach current thread to Java VM");

        Engine::main();

        if (javaVM->DetachCurrentThread() != JNI_OK)
            throw SystemError("Failed to detach current thread from Java VM");
    }
}
<commit_msg>Remove unused pthread include<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include <cstdlib>
#include <unistd.h>
#include <android/window.h>
#include "EngineAndroid.hpp"
#include "WindowResourceAndroid.hpp"
#include "events/EventDispatcher.hpp"
#include "graphics/opengl/android/RenderDeviceOGLAndroid.hpp"
#include "thread/Lock.hpp"
#include "utils/Errors.hpp"

static int looperCallback(int fd, int events, void* data)
{
    if (events & ALOOPER_EVENT_INPUT)
    {
        char message;
        if (read(fd, &message, sizeof(message)) == -1)
            throw ouzel::SystemError("Failed to read from pipe");

        ouzel::EngineAndroid* engineAndroid = static_cast<ouzel::EngineAndroid*>(data);
        engineAndroid->executeAll();
    }

    return 1;
}

namespace ouzel
{
    EngineAndroid::EngineAndroid(JavaVM* initJavaVM):
        javaVM(initJavaVM)
    {
        std::fill(std::begin(fd), std::end(fd), 0);

        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        uriClass = jniEnv->FindClass("android/net/Uri");
        uriClass = static_cast<jclass>(jniEnv->NewGlobalRef(uriClass));
        parseMethod = jniEnv->GetStaticMethodID(uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
        intentClass = jniEnv->FindClass("android/content/Intent");
        intentClass = static_cast<jclass>(jniEnv->NewGlobalRef(intentClass));
        intentConstructor = jniEnv->GetMethodID(intentClass, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V");
    }

    EngineAndroid::~EngineAndroid()
    {
        if (updateThread.isJoinable()) updateThread.join();

        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) == JNI_OK)
        {
            if (mainActivity) jniEnv->DeleteGlobalRef(mainActivity);
            if (androidWindow) jniEnv->DeleteGlobalRef(androidWindow);
            if (surface) jniEnv->DeleteGlobalRef(surface);
            if (intentClass) jniEnv->DeleteGlobalRef(intentClass);
            if (uriClass) jniEnv->DeleteGlobalRef(uriClass);
        }

        if (looper) ALooper_release(looper);
        if (fd[0]) close(fd[0]);
        if (fd[1]) close(fd[1]);
    }

    void EngineAndroid::onCreate(jobject initMainActivity)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        mainActivity = jniEnv->NewGlobalRef(initMainActivity);

        jclass mainActivityClass = jniEnv->GetObjectClass(mainActivity);
        startActivityMethod = jniEnv->GetMethodID(mainActivityClass, "startActivity", "(Landroid/content/Intent;)V");

        // get resources
        jclass resourcesClass = jniEnv->FindClass("android/content/res/Resources");
        jmethodID getResourcesMethod = jniEnv->GetMethodID(mainActivityClass, "getResources", "()Landroid/content/res/Resources;");
        jobject resourcesObject = jniEnv->CallObjectMethod(mainActivity, getResourcesMethod);
        jmethodID getConfigurationMethod = jniEnv->GetMethodID(resourcesClass, "getConfiguration", "()Landroid/content/res/Configuration;");

        // get configuration
        configurationClass = jniEnv->FindClass("android/content/res/Configuration");
        jobject configurationObject = jniEnv->CallObjectMethod(resourcesObject, getConfigurationMethod);

        orientationField = jniEnv->GetFieldID(configurationClass, "orientation", "I");
        orientation = jniEnv->GetIntField(configurationObject, orientationField);

        // get asset manager
        jmethodID getAssetsMethod = jniEnv->GetMethodID(mainActivityClass, "getAssets", "()Landroid/content/res/AssetManager;");
        jobject assetManagerObject = jniEnv->CallObjectMethod(mainActivity, getAssetsMethod);
        assetManager = AAssetManager_fromJava(jniEnv, assetManagerObject);

        // get window
        jmethodID getWindowMethod = jniEnv->GetMethodID(mainActivityClass, "getWindow", "()Landroid/view/Window;");
        androidWindow = jniEnv->CallObjectMethod(mainActivity, getWindowMethod);
        androidWindow = jniEnv->NewGlobalRef(androidWindow);

        jclass windowClass = jniEnv->FindClass("android/view/Window");
        addFlagsMethod = jniEnv->GetMethodID(windowClass, "addFlags", "(I)V");
        clearFlagsMethod = jniEnv->GetMethodID(windowClass, "clearFlags", "(I)V");

        // File class
        jclass fileClass = jniEnv->FindClass("java/io/File");
        jmethodID getAbsolutePathMethod = jniEnv->GetMethodID(fileClass, "getAbsolutePath", "()Ljava/lang/String;");

        // dataDir
        jmethodID getFilesDirMethod = jniEnv->GetMethodID(mainActivityClass, "getFilesDir", "()Ljava/io/File;");
        jobject filesDirFile = jniEnv->CallObjectMethod(mainActivity, getFilesDirMethod);

        jstring filesDirString = static_cast<jstring>(jniEnv->CallObjectMethod(filesDirFile, getAbsolutePathMethod));
        const char* filesDirCString = jniEnv->GetStringUTFChars(filesDirString, 0);
        filesDirectory = filesDirCString;
        jniEnv->ReleaseStringUTFChars(filesDirString, filesDirCString);

        // cacheDir
        jmethodID getCacheDirMethod = jniEnv->GetMethodID(mainActivityClass, "getCacheDir", "()Ljava/io/File;");
        jobject cacheDirFile = jniEnv->CallObjectMethod(mainActivity, getCacheDirMethod);

        jstring cacheDirString = static_cast<jstring>(jniEnv->CallObjectMethod(cacheDirFile, getAbsolutePathMethod));
        const char* cacheDirCString = jniEnv->GetStringUTFChars(cacheDirString, 0);
        cacheDirectory = cacheDirCString;
        jniEnv->ReleaseStringUTFChars(cacheDirString, cacheDirCString);

        // looper
        looper = ALooper_forThread(); // this is called on main thread, so it is safe to get the looper here
        ALooper_acquire(looper);
        pipe(fd);
        if (ALooper_addFd(looper, fd[0], ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT, looperCallback, this) != 1)
            throw SystemError("Failed to add looper file descriptor");
    }

    void EngineAndroid::onSurfaceCreated(jobject newSurface)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        if (surface) jniEnv->DeleteGlobalRef(surface);
        surface = jniEnv->NewGlobalRef(newSurface);

        if (active)
        {
            WindowResourceAndroid* windowAndroid = static_cast<WindowResourceAndroid*>(window.getResource());
            windowAndroid->handleSurfaceChange(surface);

            if (renderer)
            {
                graphics::RenderDevice* renderDevice = renderer->getDevice();
                if (renderDevice->getDriver() == graphics::Renderer::Driver::OPENGL)
                {
                    graphics::RenderDeviceOGLAndroid* renderDeviceOGLAndroid = static_cast<graphics::RenderDeviceOGLAndroid*>(renderDevice);
                    renderDeviceOGLAndroid->reload();
                }
            }
        }
    }

    void EngineAndroid::onConfigurationChanged(jobject newConfig)
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        jint newOrientation = jniEnv->GetIntField(newConfig, orientationField);

        if (orientation != newOrientation)
        {
            orientation = newOrientation;

            ouzel::Event event;
            event.type = ouzel::Event::Type::ORIENTATION_CHANGE;

            switch (orientation)
            {
                case ORIENTATION_PORTRAIT:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::PORTRAIT;
                    break;
                case ORIENTATION_LANDSCAPE:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::LANDSCAPE;
                    break;
                default:
                    event.systemEvent.orientation = ouzel::SystemEvent::Orientation::UNKNOWN;
                    break;
            }

            eventDispatcher.postEvent(event);
        }
    }

    void EngineAndroid::onSurfaceDestroyed()
    {
        JNIEnv* jniEnv;

        if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
            throw SystemError("Failed to get JNI environment");

        if (surface)
        {
            jniEnv->DeleteGlobalRef(surface);
            surface = nullptr;
        }

        if (active)
        {
            WindowResourceAndroid* windowAndroid = static_cast<WindowResourceAndroid*>(window.getResource());
            windowAndroid->handleSurfaceDestroy();

            if (renderer)
            {
                graphics::RenderDevice* renderDevice = renderer->getDevice();
                if (renderDevice->getDriver() == graphics::Renderer::Driver::OPENGL)
                {
                    graphics::RenderDeviceOGLAndroid* renderDeviceOGLAndroid = static_cast<graphics::RenderDeviceOGLAndroid*>(renderDevice);
                    renderDeviceOGLAndroid->destroy();
                }
            }
        }
    }

    void EngineAndroid::run()
    {
        init();
        start();
    }

    void EngineAndroid::executeOnMainThread(const std::function<void(void)>& func)
    {
        {
            Lock lock(executeMutex);
            executeQueue.push(func);
        }

        char message = 1;
        if (write(fd[1], &message, sizeof(message)) == -1)
            throw SystemError("Failed to write to pipe");
    }

    void EngineAndroid::openURL(const std::string& url)
    {
        executeOnMainThread([url, this]() {
            JNIEnv* jniEnv;

            if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
                throw SystemError("Failed to get JNI environment");

            jstring actionString = jniEnv->NewStringUTF("android.intent.action.VIEW");
            jstring urlString = jniEnv->NewStringUTF(url.c_str());
            jobject uri = jniEnv->CallStaticObjectMethod(uriClass, parseMethod, urlString);
            jobject intentObject = jniEnv->NewObject(intentClass, intentConstructor, actionString, uri);

            jniEnv->CallVoidMethod(mainActivity, startActivityMethod, intentObject);

            jniEnv->DeleteLocalRef(intentObject);
            jniEnv->DeleteLocalRef(uri);
            jniEnv->DeleteLocalRef(urlString);
            jniEnv->DeleteLocalRef(actionString);

            if (jniEnv->ExceptionCheck())
            {
                jniEnv->ExceptionClear();
                throw SystemError("Failed to open URL");
            }
        });
    }

    void EngineAndroid::setScreenSaverEnabled(bool newScreenSaverEnabled)
    {
        Engine::setScreenSaverEnabled(newScreenSaverEnabled);

        executeOnMainThread([newScreenSaverEnabled, this]() {
            JNIEnv* jniEnv;

            if (javaVM->GetEnv(reinterpret_cast<void**>(&jniEnv), JNI_VERSION_1_6) != JNI_OK)
                throw SystemError("Failed to get JNI environment");

            if (newScreenSaverEnabled)
                jniEnv->CallVoidMethod(androidWindow, clearFlagsMethod, AWINDOW_FLAG_KEEP_SCREEN_ON);
            else
                jniEnv->CallVoidMethod(androidWindow, addFlagsMethod, AWINDOW_FLAG_KEEP_SCREEN_ON);
        });
    }

    void EngineAndroid::executeAll()
    {
        std::function<void(void)> func;

        {
           Lock lock(executeMutex);

            if (!executeQueue.empty())
            {
                func = std::move(executeQueue.front());
                executeQueue.pop();
            }
        }

        if (func) func();
    }

    void EngineAndroid::main()
    {
        JNIEnv* jniEnv;
        JavaVMAttachArgs attachArgs;
        attachArgs.version = JNI_VERSION_1_6;
        attachArgs.name = nullptr; // thread name
        attachArgs.group = nullptr; // thread group
        if (javaVM->AttachCurrentThread(&jniEnv, &attachArgs) != JNI_OK)
            throw SystemError("Failed to attach current thread to Java VM");

        Engine::main();

        if (javaVM->DetachCurrentThread() != JNI_OK)
            throw SystemError("Failed to detach current thread from Java VM");
    }
}
<|endoftext|>


<commit_before>#include "Flax/Fiber.h"
#include "Flax/RoundRobinScheduler.h"

#include <algorithm>
#include <cassert>

namespace flax {

#if FLAX_USE_SCHEDULER
// static
thread_local Fiber::SchedulerContainer Fiber::scheduler(std::make_unique<RoundRobinScheduler>());

// static
thread_local std::vector<Fiber*> Fiber::fibers;
#endif // FLAX_USE_SCHEDULER

// static
thread_local Fiber* Fiber::activeFiber = nullptr;

// static
Fiber& Fiber::getMainFiber() {
   static thread_local Fiber mainFiber(nullptr, "Main Fiber", true);
   assert(mainFiber.isValid() && !mainFiber.isFinished() && mainFiber.isMainFiber());

   return mainFiber;
}

// static
std::unique_ptr<Fiber> Fiber::create(const std::function<void()>& func, const std::string& name) {
   // Make sure the main fiber is initialized
   getMainFiber();

   std::unique_ptr<Fiber> newFiber(new Fiber(func, name, false));
   if (!newFiber->isValid()) {
      return nullptr;
   }

   return newFiber;
}

// static
void Fiber::yieldTo(Fiber& fiber) {
   assert(fiber.isValid() && !fiber.isActive() && !fiber.isFinished());
   assert(activeFiber && activeFiber->isValid() && activeFiber->isActive());
   assert(&fiber != activeFiber);

#if FLAX_USE_SCHEDULER
   scheduler->onFiberYieldedTo(&fiber);
#endif // FLAX_USE_SCHEDULER

   FiberImpl& from = activeFiber->impl;
   FiberImpl& to = fiber.impl;
   activeFiber = &fiber;
   FiberImpl::swap(from, to);
}

#if FLAX_USE_SCHEDULER
// static
void Fiber::yield() {
   Fiber* nextFiber = scheduler->next();
   if (!nextFiber) {
      return;
   }

   assert(nextFiber->isValid() && !nextFiber->isActive() && !nextFiber->isFinished());
   assert(nextFiber != activeFiber);

   yieldTo(*nextFiber);
}

// static
void Fiber::setScheduler(std::unique_ptr<Scheduler> newScheduler) {
   if (newScheduler) {
      scheduler = std::move(newScheduler);

      for (Fiber* fiber : fibers) {
         assert(fiber->isValid());
         scheduler->onFiberCreated(fiber);
      }
   }
}
#endif // FLAX_USE_SCHEDULER

// static
void Fiber::fiberMain(Fiber* fiber) {
   assert(fiber && fiber->isValid() && fiber->isActive() && !fiber->isFinished() && !fiber->isMainFiber() && fiber->function != nullptr);

   fiber->function();

   fiber->finish();
#if FLAX_USE_SCHEDULER
   fiber->yield();
#else
   fiber->yieldTo(getMainFiber());
#endif // FLAX_USE_SCHEDULER

   assert(false); // Should never get here
}

Fiber::Fiber(const std::function<void()>& func, const std::string& name, bool isMainFiber)
   : function(func), fiberName(name), mainFiber(isMainFiber), finished(false), impl(this, &Fiber::fiberMain, isMainFiber) {
   if (isMainFiber) {
      assert(isValid() && function == nullptr);
      activeFiber = this;
   }

#if FLAX_USE_SCHEDULER
   if (isValid()) {
      fibers.push_back(this);
      scheduler->onFiberCreated(this);

      if (isMainFiber) {
         scheduler->onFiberYieldedTo(this);
      }
   }
#endif // FLAX_USE_SCHEDULER
}

Fiber::~Fiber() {
   assert(isActive() == isMainFiber());

   if (isValid() && !isFinished()) {
      finish();
   }
}

void Fiber::finish() {
   assert(isValid() && !isFinished());

   finished = true;

#if FLAX_USE_SCHEDULER
   scheduler->onFiberFinished(this);
   fibers.erase(std::remove_if(fibers.begin(), fibers.end(), [this](const Fiber* fiber) { return fiber == this; }), fibers.end());
#endif // FLAX_USE_SCHEDULER
}

} // namespace flax
<commit_msg>When a new scheduler is set, let it know about the currently active fiber<commit_after>#include "Flax/Fiber.h"
#include "Flax/RoundRobinScheduler.h"

#include <algorithm>
#include <cassert>

namespace flax {

#if FLAX_USE_SCHEDULER
// static
thread_local Fiber::SchedulerContainer Fiber::scheduler(std::make_unique<RoundRobinScheduler>());

// static
thread_local std::vector<Fiber*> Fiber::fibers;
#endif // FLAX_USE_SCHEDULER

// static
thread_local Fiber* Fiber::activeFiber = nullptr;

// static
Fiber& Fiber::getMainFiber() {
   static thread_local Fiber mainFiber(nullptr, "Main Fiber", true);
   assert(mainFiber.isValid() && !mainFiber.isFinished() && mainFiber.isMainFiber());

   return mainFiber;
}

// static
std::unique_ptr<Fiber> Fiber::create(const std::function<void()>& func, const std::string& name) {
   // Make sure the main fiber is initialized
   getMainFiber();

   std::unique_ptr<Fiber> newFiber(new Fiber(func, name, false));
   if (!newFiber->isValid()) {
      return nullptr;
   }

   return newFiber;
}

// static
void Fiber::yieldTo(Fiber& fiber) {
   assert(fiber.isValid() && !fiber.isActive() && !fiber.isFinished());
   assert(activeFiber && activeFiber->isValid() && activeFiber->isActive());
   assert(&fiber != activeFiber);

#if FLAX_USE_SCHEDULER
   scheduler->onFiberYieldedTo(&fiber);
#endif // FLAX_USE_SCHEDULER

   FiberImpl& from = activeFiber->impl;
   FiberImpl& to = fiber.impl;
   activeFiber = &fiber;
   FiberImpl::swap(from, to);
}

#if FLAX_USE_SCHEDULER
// static
void Fiber::yield() {
   Fiber* nextFiber = scheduler->next();
   if (!nextFiber) {
      return;
   }

   assert(nextFiber->isValid() && !nextFiber->isActive() && !nextFiber->isFinished());
   assert(nextFiber != activeFiber);

   yieldTo(*nextFiber);
}

// static
void Fiber::setScheduler(std::unique_ptr<Scheduler> newScheduler) {
   if (newScheduler) {
      scheduler = std::move(newScheduler);

      for (Fiber* fiber : fibers) {
         assert(fiber->isValid());
         scheduler->onFiberCreated(fiber);
      }

      if (activeFiber) {
         scheduler->onFiberYieldedTo(activeFiber);
      }
   }
}
#endif // FLAX_USE_SCHEDULER

// static
void Fiber::fiberMain(Fiber* fiber) {
   assert(fiber && fiber->isValid() && fiber->isActive() && !fiber->isFinished() && !fiber->isMainFiber() && fiber->function != nullptr);

   fiber->function();

   fiber->finish();
#if FLAX_USE_SCHEDULER
   fiber->yield();
#else
   fiber->yieldTo(getMainFiber());
#endif // FLAX_USE_SCHEDULER

   assert(false); // Should never get here
}

Fiber::Fiber(const std::function<void()>& func, const std::string& name, bool isMainFiber)
   : function(func), fiberName(name), mainFiber(isMainFiber), finished(false), impl(this, &Fiber::fiberMain, isMainFiber) {
   if (isMainFiber) {
      assert(isValid() && function == nullptr);
      activeFiber = this;
   }

#if FLAX_USE_SCHEDULER
   if (isValid()) {
      fibers.push_back(this);
      scheduler->onFiberCreated(this);

      if (isMainFiber) {
         scheduler->onFiberYieldedTo(this);
      }
   }
#endif // FLAX_USE_SCHEDULER
}

Fiber::~Fiber() {
   assert(isActive() == isMainFiber());

   if (isValid() && !isFinished()) {
      finish();
   }
}

void Fiber::finish() {
   assert(isValid() && !isFinished());

   finished = true;

#if FLAX_USE_SCHEDULER
   scheduler->onFiberFinished(this);
   fibers.erase(std::remove_if(fibers.begin(), fibers.end(), [this](const Fiber* fiber) { return fiber == this; }), fibers.end());
#endif // FLAX_USE_SCHEDULER
}

} // namespace flax
<|endoftext|>


<commit_before>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include "detection.h"
#include "people_detector.h"
#include "vehicle_detector.h"

using namespace std;
using namespace cv;

void Detection::ProcessFrame(Image image) {

  PeopleDetector peopleDetector;
  VehicleDetector vehicleDetector;

  Mat resizedFrame = ResizeFrame(image.GetRGBImage());

  std::vector<Rect> detectedPeople = peopleDetector.Detect(&resizedFrame);
  std::vector<Rect> detectedVehicles = vehicleDetector.Detect(&resizedFrame);

  DisplayDetectedObjects(detectedPeople, detectedVehicles, &resizedFrame);
}

Mat Detection::ResizeFrame(Mat *frame) {
  //resize the image to width of 400px to reduce detection time and improve detection accuracy
  //0.3125 is used because the test video is 1280 x 720, so the width resized images is 400px this has to be changed to our image size (best would be no hard coded scaling so other images sizes work too!)
  // TODO: dynamic risizeing depending on input (min width 400px)

  Mat resizedFrame;
  resize(*frame, resizedFrame, Size(0, 0), 0.3125, 0.3125, CV_INTER_AREA);
  return resizedFrame;
}

void Detection::DisplayDetectedObjects(std::vector<Rect> firstDetection, std::vector<Rect> secondDetection, Mat *frame) {
  //add retangle for each Object in firstDetection
  for (int i=0; i<firstDetection.size(); i++) {
      Rect r = firstDetection[i];
      rectangle(*frame, r.tl(), r.br(), Scalar(0,255,0), 2);
  }

  //add rectangle for each Object in secondDetection
  for (int i=0; i<secondDetection.size(); i++) {
      Rect r = secondDetection[i];
      rectangle(*frame, r.tl(), r.br(), Scalar(255,150,0), 2);
  }

  imshow("Camera stream", *frame); // TODO: Use image_view class
}
<commit_msg>the wrong argument was given to ResizeFrame<commit_after>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include "detection.h"
#include "people_detector.h"
#include "vehicle_detector.h"

using namespace std;
using namespace cv;

void Detection::ProcessFrame(Image image) {

  PeopleDetector peopleDetector;
  VehicleDetector vehicleDetector;

  Mat frame = image.GetRGBImage();
  Mat resizedFrame = ResizeFrame(&frame);

  std::vector<Rect> detectedPeople = peopleDetector.Detect(&resizedFrame);
  std::vector<Rect> detectedVehicles = vehicleDetector.Detect(&resizedFrame);

  DisplayDetectedObjects(detectedPeople, detectedVehicles, &resizedFrame);
}

Mat Detection::ResizeFrame(Mat *frame) {
  //resize the image to width of 400px to reduce detection time and improve detection accuracy
  //0.3125 is used because the test video is 1280 x 720, so the width resized images is 400px this has to be changed to our image size (best would be no hard coded scaling so other images sizes work too!)
  // TODO: dynamic risizeing depending on input (min width 400px)

  Mat resizedFrame;
  resize(*frame, resizedFrame, Size(0, 0), 0.3125, 0.3125, CV_INTER_AREA);
  return resizedFrame;
}

void Detection::DisplayDetectedObjects(std::vector<Rect> firstDetection, std::vector<Rect> secondDetection, Mat *frame) {
  //add retangle for each Object in firstDetection
  for (int i=0; i<firstDetection.size(); i++) {
      Rect r = firstDetection[i];
      rectangle(*frame, r.tl(), r.br(), Scalar(0,255,0), 2);
  }

  //add rectangle for each Object in secondDetection
  for (int i=0; i<secondDetection.size(); i++) {
      Rect r = secondDetection[i];
      rectangle(*frame, r.tl(), r.br(), Scalar(255,150,0), 2);
  }

  imshow("Camera stream", *frame); // TODO: Use image_view class
}
<|endoftext|>


<commit_before>#include "breakout.h"
#include <QDesktopWidget>
#include <QApplication>

void center(QWidget& widget){
    int x,y;
    int screenWidth;
    int screenHeight;

    int WIDTH = 300;
    int HEIGHT = 400;

    QDesktopWidget *desktop = QApplication::desktop();

    screenWidth = desktop->width();
    screenHeight = desktop->height();

    x = (screenWidth - WIDTH)/2;
    y = (screenHeight - HEIGHT)/2;

    widget.setGeometry(x, y, WIDTH, HEIGHT);
    widget.setFixedSize(WIDTH, HEIGHT);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Breakout window;

    window.setWindowTitle("Breakout");
    window.show();
    center(window);

    return a.exec();
}
<commit_msg>Add comments<commit_after>#include "breakout.h"
#include <QDesktopWidget>
#include <QApplication>

//Function to center a QWidget relative to the users display and give the QWidget a fixed size
void setup(QWidget& widget){
    int WIDTH = 300;
    int HEIGHT = 400;

    //Create a QDesktopWidget object to get inforamtion about the userss desktop
    QDesktopWidget* desktop = QApplication::desktop();

    //Reposition the QWidget in the middle of the user's desktop
    widget.setGeometry((desktop->width() - WIDTH)/2, (desktop->height() - HEIGHT)/2, WIDTH, HEIGHT);
    widget.setFixedSize(WIDTH, HEIGHT);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Breakout window;

    window.setWindowTitle("Breakout");
    window.show();
    setup(window);

    return a.exec();
}
<|endoftext|>


<commit_before>#include "Genes/Piece_Strength_Gene.h"

#include <array>
#include <memory>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Board.h"
#include "Utility.h"

Piece_Strength_Gene::Piece_Strength_Gene() : piece_strength{}
{
}

void Piece_Strength_Gene::reset_properties() const
{
    for(auto piece_type : {PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING})
    {
        auto piece = Board::piece_instance(piece_type, WHITE);
        properties[std::string(1, piece->fen_symbol())] = piece_value(piece);
    }
}

void Piece_Strength_Gene::load_properties()
{
    for(const auto& piece_score : properties)
    {
        Piece_Type piece;
        switch(piece_score.first[0])
        {
            case 'P':
                piece = PAWN;
                break;
            case 'R':
                piece = ROOK;
                break;
            case 'N':
                piece = KNIGHT;
                break;
            case 'B':
                piece = BISHOP;
                break;
            case 'Q':
                piece = QUEEN;
                break;
            case 'K':
                piece = KING;
                break;
            default:
                throw std::runtime_error("Unrecognized piece type: " + piece_score.first);
        }
        piece_value(piece) = piece_score.second;
    }
}

void Piece_Strength_Gene::gene_specific_mutation()
{
    for(auto& piece_score : piece_strength)
    {
        const double mean_number_of_mutations = 2.0;
        if(Random::success_probability(mean_number_of_mutations/piece_strength.size()))
        {
            piece_score += Random::random_laplace(1.0);
        }
    }
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const
{
    return piece_strength[type];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type)
{
    return piece_strength[type];
}

double Piece_Strength_Gene::piece_value(const Piece* piece) const
{
    if( ! piece)
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece->type());
    }
}

std::unique_ptr<Gene> Piece_Strength_Gene::duplicate() const
{
    return std::make_unique<Piece_Strength_Gene>(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, const Board&, size_t) const
{
    return 0.0;
}
<commit_msg>Only mutate one piece strength per mutation<commit_after>#include "Genes/Piece_Strength_Gene.h"

#include <array>
#include <memory>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Board.h"
#include "Utility.h"

Piece_Strength_Gene::Piece_Strength_Gene() : piece_strength{}
{
}

void Piece_Strength_Gene::reset_properties() const
{
    for(auto piece_type : {PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING})
    {
        auto piece = Board::piece_instance(piece_type, WHITE);
        properties[std::string(1, piece->fen_symbol())] = piece_value(piece);
    }
}

void Piece_Strength_Gene::load_properties()
{
    for(const auto& piece_score : properties)
    {
        Piece_Type piece;
        switch(piece_score.first[0])
        {
            case 'P':
                piece = PAWN;
                break;
            case 'R':
                piece = ROOK;
                break;
            case 'N':
                piece = KNIGHT;
                break;
            case 'B':
                piece = BISHOP;
                break;
            case 'Q':
                piece = QUEEN;
                break;
            case 'K':
                piece = KING;
                break;
            default:
                throw std::runtime_error("Unrecognized piece type: " + piece_score.first);
        }
        piece_value(piece) = piece_score.second;
    }
}

void Piece_Strength_Gene::gene_specific_mutation()
{
    auto index = Random::random_integer(0, piece_strength.size() - 1);
    piece_strength[index] += Random::random_laplace(1.0);
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const
{
    return piece_strength[type];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type)
{
    return piece_strength[type];
}

double Piece_Strength_Gene::piece_value(const Piece* piece) const
{
    if( ! piece)
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece->type());
    }
}

std::unique_ptr<Gene> Piece_Strength_Gene::duplicate() const
{
    return std::make_unique<Piece_Strength_Gene>(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, const Board&, size_t) const
{
    return 0.0;
}
<|endoftext|>


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

#include "boost/format.hpp"

#include "IECore/MPlayDisplayDriver.h"
#include "IECore/Exception.h"
#include "IECore/SimpleTypedData.h"

using namespace std;
using namespace IECore;
using namespace Imath;

//////////////////////////////////////////////////////////////////////////
// Header definitions required by imdisplay
//////////////////////////////////////////////////////////////////////////

struct MPlayDisplayDriver::ImageHeader
{
	ImageHeader( const V2i &resolution, size_t numPlanes )
	{
		magicNumber = (('h'<<24)+('M'<<16)+('P'<<8)+'0');
		xRes = resolution.x;
		yRes = resolution.y;
		dataType = 0; // floating point data
		numChannels = 0; // multiplane
		multiPlaneCount = numPlanes;
		reserved[0] = 0;
		reserved[1] = 0;
	}

	int	magicNumber;
	int	xRes;
	int	yRes;
	int	dataType;
	int	numChannels;
	int	multiPlaneCount;
	int	reserved[2];
};

struct MPlayDisplayDriver::TileHeader
{
	// this weird invalid tile header is used to signify that
	// we're about to send a plane.
	TileHeader( size_t planeIndex )
	{
		x0 = -1;
		x1 = planeIndex;
		y0 = 0;
		y1 = 0;
	}

	TileHeader( const Box2i &box )
	{
		x0 = box.min.x;
		x1 = box.max.x;
		y0 = box.min.y;
		y1 = box.max.y;
	}

	int	x0, x1;
	int	y0, y1;
};

struct MPlayDisplayDriver::PlaneHeader
{
	PlaneHeader( const Plane &plane, size_t index )
	{
		planeIndex = index;
		nameLength = plane.name.size();
		dataType = 0; // floating point data
		numChannels = plane.channelIndices.size();
		reserved[0] = 0;
		reserved[1] = 0;
		reserved[2] = 0;
		reserved[3] = 0;
	}

	int	planeIndex;
	int	nameLength;
	int	dataType;
	int	numChannels;
	int	reserved[4];
};

//////////////////////////////////////////////////////////////////////////
// MPlayDisplayDriver implementation
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( MPlayDisplayDriver );

const DisplayDriver::DisplayDriverDescription<MPlayDisplayDriver> MPlayDisplayDriver::g_description;

MPlayDisplayDriver::MPlayDisplayDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const std::vector<std::string> &channelNames, IECore::ConstCompoundDataPtr parameters )
	:	DisplayDriver( displayWindow, dataWindow, channelNames, parameters )
{
	// Sort out our flat list of channels into planes, based on common prefixes
	Plane *currentPlane = 0;
	for( vector<string>::const_iterator cIt = channelNames.begin(); cIt != channelNames.end(); cIt++ )
	{
		size_t separatorIndex = cIt->find( '.' );
		string planeName;
		string channelName = *cIt;
		if( separatorIndex != string::npos )
		{
			planeName = string( *cIt, 0, separatorIndex );
			channelName = string( *cIt, separatorIndex );
		}
		else
		{
			planeName = "C";
		}

		if( !m_planes.size() || m_planes.rbegin()->name != planeName )
		{
			m_planes.push_back( Plane( planeName ) );
			currentPlane = &(*m_planes.rbegin());
		}
		currentPlane->channelNames.push_back( channelName );
		currentPlane->channelIndices.push_back( cIt - channelNames.begin() );
	}

	// Validate that our planes match mplay requirements
	for( vector<Plane>::const_iterator pIt = m_planes.begin(); pIt != m_planes.end(); pIt++ )
	{
		if(
			pIt->channelNames.size() != 1 &&
			pIt->channelNames.size() != 3 &&
			pIt->channelNames.size() != 4
		)
		{
			throw Exception( "MPlayDisplayDriver only supports 1, 3, and 4 channel images" );
		}
	}

	// Construct a command line calling imdisplay, and open it as a pipe
	std::string commandLine = "imdisplay -f -p";

	V2i origin = dataWindow.min - displayWindow.min;
	commandLine += boost::str( boost::format( " -o %d %d" ) % origin.x % origin.y );

	V2i originalSize = displayWindow.size() + V2i( 1 );
	commandLine += boost::str( boost::format( " -Z %d %d" ) % originalSize.x % originalSize.y );

	const StringData *extraArguments = parameters->member<StringData>( "imdisplayExtraArguments" );
	if( extraArguments && extraArguments->readable().size() )
	{
		commandLine += " " + extraArguments->readable();
	}

	m_imDisplayStdIn = popen( commandLine.c_str(), "w" );

	// Pipe out our image header
	ImageHeader header( dataWindow.size() + V2i( 1 ), m_planes.size() );
	fwrite( &header, sizeof( ImageHeader ), 1, m_imDisplayStdIn );

	// Pipe out a header for each of our planes
	for( vector<Plane>::const_iterator pIt = m_planes.begin(); pIt != m_planes.end(); pIt++ )
	{
		PlaneHeader planeHeader( *pIt, pIt - m_planes.begin() );
		fwrite( &planeHeader, sizeof( PlaneHeader ), 1, m_imDisplayStdIn );
		fwrite( &(pIt->name[0]), pIt->name.size(), 1, m_imDisplayStdIn );
	}

}

MPlayDisplayDriver::~MPlayDisplayDriver()
{
	// in case imageClose() wasn't called for any reason.
	if( m_imDisplayStdIn )
	{
		pclose( m_imDisplayStdIn );
	}
}

bool MPlayDisplayDriver::scanLineOrderOnly() const
{
	return false;
}

void MPlayDisplayDriver::imageData( const Imath::Box2i &box, const float *data, size_t dataSize )
{
	for( size_t planeIndex = 0; planeIndex < m_planes.size(); planeIndex++ )
	{
		const Plane &plane = m_planes[planeIndex];

		TileHeader planeHeader( planeIndex );
		fwrite( &planeHeader, sizeof( planeHeader ), 1, m_imDisplayStdIn );

		TileHeader tileHeader( box );
		fwrite( &tileHeader, sizeof( tileHeader ), 1, m_imDisplayStdIn );

		const size_t numPixels = ( box.size().x + 1 ) * ( box.size().y + 1 );
		if( false && m_planes.size() == 1 )
		{
			// the data is already just as we need it, so we can just write it as-is
			fwrite( data, sizeof( float ), plane.channelIndices.size() * numPixels, m_imDisplayStdIn );
		}
		else
		{
			// need to create interleaved data for the channels in the current plane
			std::vector<float> planeData( plane.channelIndices.size() * numPixels );
			const float *in = data;
			float *out = &planeData[0];
			const size_t numInChannels = channelNames().size();
			const size_t numOutChannels = plane.channelIndices.size();

			for( size_t i=0; i<numPixels; ++i )
			{
				for( size_t c=0; c<numOutChannels; ++c )
				{
					*out++ = in[plane.channelIndices[c]];

				}
				in += numInChannels;
			}

			fwrite( &planeData[0], sizeof( float ), planeData.size(), m_imDisplayStdIn );
		}
	}
}

void MPlayDisplayDriver::imageClose()
{
	pclose( m_imDisplayStdIn );
	m_imDisplayStdIn = 0;
}

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

#include "boost/format.hpp"

#include "IECore/MPlayDisplayDriver.h"
#include "IECore/Exception.h"
#include "IECore/SimpleTypedData.h"

using namespace std;
using namespace IECore;
using namespace Imath;

//////////////////////////////////////////////////////////////////////////
// Header definitions required by imdisplay
//////////////////////////////////////////////////////////////////////////

struct MPlayDisplayDriver::ImageHeader
{
	ImageHeader( const V2i &resolution, size_t numPlanes )
	{
		magicNumber = (('h'<<24)+('M'<<16)+('P'<<8)+'0');
		xRes = resolution.x;
		yRes = resolution.y;
		dataType = 0; // floating point data
		numChannels = 0; // multiplane
		multiPlaneCount = numPlanes;
		reserved[0] = 0;
		reserved[1] = 0;
	}

	int	magicNumber;
	int	xRes;
	int	yRes;
	int	dataType;
	int	numChannels;
	int	multiPlaneCount;
	int	reserved[2];
};

struct MPlayDisplayDriver::TileHeader
{
	// this weird invalid tile header is used to signify that
	// we're about to send a plane.
	TileHeader( size_t planeIndex )
	{
		x0 = -1;
		x1 = planeIndex;
		y0 = 0;
		y1 = 0;
	}

	TileHeader( const Box2i &box )
	{
		x0 = box.min.x;
		x1 = box.max.x;
		y0 = box.min.y;
		y1 = box.max.y;
	}

	int	x0, x1;
	int	y0, y1;
};

struct MPlayDisplayDriver::PlaneHeader
{
	PlaneHeader( const Plane &plane, size_t index )
	{
		planeIndex = index;
		nameLength = plane.name.size();
		dataType = 0; // floating point data
		numChannels = plane.channelIndices.size();
		reserved[0] = 0;
		reserved[1] = 0;
		reserved[2] = 0;
		reserved[3] = 0;
	}

	int	planeIndex;
	int	nameLength;
	int	dataType;
	int	numChannels;
	int	reserved[4];
};

//////////////////////////////////////////////////////////////////////////
// MPlayDisplayDriver implementation
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( MPlayDisplayDriver );

const DisplayDriver::DisplayDriverDescription<MPlayDisplayDriver> MPlayDisplayDriver::g_description;

MPlayDisplayDriver::MPlayDisplayDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const std::vector<std::string> &channelNames, IECore::ConstCompoundDataPtr parameters )
	:	DisplayDriver( displayWindow, dataWindow, channelNames, parameters )
{
	// Sort out our flat list of channels into planes, based on common prefixes
	Plane *currentPlane = 0;
	for( vector<string>::const_iterator cIt = channelNames.begin(); cIt != channelNames.end(); cIt++ )
	{
		size_t separatorIndex = cIt->find( '.' );
		string planeName;
		string channelName = *cIt;
		if( separatorIndex != string::npos )
		{
			planeName = string( *cIt, 0, separatorIndex );
			channelName = string( *cIt, separatorIndex );
		}
		else
		{
			planeName = "C";
		}

		if( !m_planes.size() || m_planes.rbegin()->name != planeName )
		{
			m_planes.push_back( Plane( planeName ) );
			currentPlane = &(*m_planes.rbegin());
		}
		currentPlane->channelNames.push_back( channelName );
		currentPlane->channelIndices.push_back( cIt - channelNames.begin() );
	}

	// Validate that our planes match mplay requirements
	for( vector<Plane>::const_iterator pIt = m_planes.begin(); pIt != m_planes.end(); pIt++ )
	{
		if(
			pIt->channelNames.size() != 1 &&
			pIt->channelNames.size() != 3 &&
			pIt->channelNames.size() != 4
		)
		{
			throw Exception( "MPlayDisplayDriver only supports 1, 3, and 4 channel images" );
		}
	}

	// Construct a command line calling imdisplay, and open it as a pipe
	std::string commandLine = "imdisplay -f -p";

	commandLine += boost::str( boost::format( " -o %d %d" ) % displayWindow.min.x % displayWindow.min.y );

	V2i originalSize = displayWindow.size() + V2i( 1 );
	commandLine += boost::str( boost::format( " -Z %d %d" ) % originalSize.x % originalSize.y );

	const StringData *extraArguments = parameters->member<StringData>( "imdisplayExtraArguments" );
	if( extraArguments && extraArguments->readable().size() )
	{
		commandLine += " " + extraArguments->readable();
	}

	m_imDisplayStdIn = popen( commandLine.c_str(), "w" );

	// Pipe out our image header
	ImageHeader header( dataWindow.size() + V2i( 1 ), m_planes.size() );
	fwrite( &header, sizeof( ImageHeader ), 1, m_imDisplayStdIn );

	// Pipe out a header for each of our planes
	for( vector<Plane>::const_iterator pIt = m_planes.begin(); pIt != m_planes.end(); pIt++ )
	{
		PlaneHeader planeHeader( *pIt, pIt - m_planes.begin() );
		fwrite( &planeHeader, sizeof( PlaneHeader ), 1, m_imDisplayStdIn );
		fwrite( &(pIt->name[0]), pIt->name.size(), 1, m_imDisplayStdIn );
	}

}

MPlayDisplayDriver::~MPlayDisplayDriver()
{
	// in case imageClose() wasn't called for any reason.
	if( m_imDisplayStdIn )
	{
		pclose( m_imDisplayStdIn );
	}
}

bool MPlayDisplayDriver::scanLineOrderOnly() const
{
	return false;
}

void MPlayDisplayDriver::imageData( const Imath::Box2i &box, const float *data, size_t dataSize )
{
	for( size_t planeIndex = 0; planeIndex < m_planes.size(); planeIndex++ )
	{
		const Plane &plane = m_planes[planeIndex];

		TileHeader planeHeader( planeIndex );
		fwrite( &planeHeader, sizeof( planeHeader ), 1, m_imDisplayStdIn );

		TileHeader tileHeader( box );
		fwrite( &tileHeader, sizeof( tileHeader ), 1, m_imDisplayStdIn );

		const size_t numPixels = ( box.size().x + 1 ) * ( box.size().y + 1 );
		if( false && m_planes.size() == 1 )
		{
			// the data is already just as we need it, so we can just write it as-is
			fwrite( data, sizeof( float ), plane.channelIndices.size() * numPixels, m_imDisplayStdIn );
		}
		else
		{
			// need to create interleaved data for the channels in the current plane
			std::vector<float> planeData( plane.channelIndices.size() * numPixels );
			const float *in = data;
			float *out = &planeData[0];
			const size_t numInChannels = channelNames().size();
			const size_t numOutChannels = plane.channelIndices.size();

			for( size_t i=0; i<numPixels; ++i )
			{
				for( size_t c=0; c<numOutChannels; ++c )
				{
					*out++ = in[plane.channelIndices[c]];

				}
				in += numInChannels;
			}

			fwrite( &planeData[0], sizeof( float ), planeData.size(), m_imDisplayStdIn );
		}
	}
}

void MPlayDisplayDriver::imageClose()
{
	pclose( m_imDisplayStdIn );
	m_imDisplayStdIn = 0;
}

<|endoftext|>


<commit_before>/****************************************************************************
 *           Origin: I.Belikov, CERN, Jouri.Belikov@cern.ch                 *
 ****************************************************************************/

Int_t AliTPCtest() {
   Int_t rc=0;

//Test TPC simulation
   gROOT->LoadMacro("$(ALICE_ROOT)/macros/grun.C");
   grun();

AliKalmanTrack::SetConvConst(1000/0.299792458/gAlice->Field()->SolenoidField());

   Int_t ver=gAlice->GetDetector("TPC")->IsVersion();
   delete gAlice; gAlice=0;

   if ((ver!=1)&&(ver!=2)) {
      cerr<<"Invalid TPC version: "<<ver<<" ! (must be 1 or 2)\n";
      return 12345;
   }

   if (ver==2) {
     gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCHits2Digits.C");
     if (rc=AliTPCHits2Digits()) return rc;

     //gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCDisplayDigits.C");
     //if (rc=AliTPCDisplayDigits(1,1)) return rc;
   }

//Test TPC reconstruction
   gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCFindClusters.C");
   if (rc=AliTPCFindClusters()) return rc;

   //gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCDisplayClusters.C");
   //if (rc=AliTPCDisplayClusters()) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCFindTracks.C");
   if (rc=AliTPCFindTracks()) return rc;

   gSystem->SetIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS");
   gROOT->ProcessLine(".L $(ALICE_ROOT)/TPC/AliTPCComparison.C+");
   if (rc=AliTPCComparison()) return rc;

   return rc;
}

<commit_msg>Recompilation of AliTPCComparison.C to avoid clashes between platforms<commit_after>/****************************************************************************
 *           Origin: I.Belikov, CERN, Jouri.Belikov@cern.ch                 *
 ****************************************************************************/

Int_t AliTPCtest() {
   Int_t rc=0;

//Test TPC simulation
   gROOT->LoadMacro("$(ALICE_ROOT)/macros/grun.C");
   grun();

AliKalmanTrack::SetConvConst(1000/0.299792458/gAlice->Field()->SolenoidField());

   Int_t ver=gAlice->GetDetector("TPC")->IsVersion();
   delete gAlice; gAlice=0;

   if ((ver!=1)&&(ver!=2)) {
      cerr<<"Invalid TPC version: "<<ver<<" ! (must be 1 or 2)\n";
      return 12345;
   }

   if (ver==2) {
     gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCHits2Digits.C");
     if (rc=AliTPCHits2Digits()) return rc;

     //gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCDisplayDigits.C");
     //if (rc=AliTPCDisplayDigits(1,1)) return rc;
   }

//Test TPC reconstruction
   gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCFindClusters.C");
   if (rc=AliTPCFindClusters()) return rc;

   //gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCDisplayClusters.C");
   //if (rc=AliTPCDisplayClusters()) return rc;

   gROOT->LoadMacro("$(ALICE_ROOT)/TPC/AliTPCFindTracks.C");
   if (rc=AliTPCFindTracks()) return rc;

   gSystem->SetIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include -I$ALICE_ROOT/TPC -I$ALICE_ROOT/CONTAINERS");
   gROOT->ProcessLine(".L $(ALICE_ROOT)/TPC/AliTPCComparison.C++");
   if (rc=AliTPCComparison()) return rc;

   return rc;
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in
 *	  the documentation and/or other materials provided with the
 *	  distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.	IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "TraceListenerDefault.hpp"

#include <PlatformSupport/PrintWriter.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/NodeRefListBase.hpp>
#include <XPath/XPath.hpp>

#include "Constants.hpp"
#include "ElemTextLiteral.hpp"
#include "ElemTemplate.hpp"
#include "GenerateEvent.hpp"
#include "SelectionEvent.hpp"
#include "StylesheetRoot.hpp"
#include "TracerEvent.hpp"

TraceListenerDefault::TraceListenerDefault(
			PrintWriter&	thePrintWriter,
			bool			traceTemplates,
			bool			traceElements,
			bool			traceGeneration,
			bool			traceSelection) :
	m_printWriter(thePrintWriter),
	m_traceTemplates(traceTemplates),
	m_traceElements(traceElements),
	m_traceGeneration(traceGeneration),
	m_traceSelection(traceSelection)
{
}

TraceListenerDefault::~TraceListenerDefault()
{
}

void
TraceListenerDefault::trace(const TracerEvent&	ev)
{
	switch(ev.m_styleNode.getXSLToken())
	{
	case Constants::ELEMNAME_TEXTLITERALRESULT:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("    "));

			const ElemTextLiteral&	etl = static_cast<const ElemTextLiteral&>(ev.m_styleNode);

			m_printWriter.println(c_wstr(etl.getText()), etl.getText().size());
		}
		break;

	case Constants::ELEMNAME_TEMPLATE:
		if(m_traceTemplates == true || m_traceElements == true)
		{
			const ElemTemplate&		et = static_cast<const ElemTemplate&>(ev.m_styleNode);

			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());

			const XPath* const	theMatchPattern =
				et.getMatchPattern();

			if(0 != theMatchPattern)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING(" match=\""));
				m_printWriter.print(theMatchPattern->getExpression().getCurrentPattern());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			const QName&	theName = et.getName();

			if(theName.isEmpty() == false)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("name=\""));

				const XalanDOMString&	theNamespace =
					theName.getNamespace();

				if (isEmpty(theNamespace) == false)
				{
					m_printWriter.print(theNamespace);
					m_printWriter.print(':');
				}

				m_printWriter.print(theName.getLocalPart());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			m_printWriter.println();
		}
		break;

	default:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.println(ev.m_styleNode.getElementName());
		}
		break;
	}
}

void
TraceListenerDefault::selected(const SelectionEvent&	ev)
{
    if(m_traceSelection == true)
    {
		const ElemTemplateElement&	ete = ev.m_styleNode;

		if(ev.m_styleNode.getLineNumber() == 0)
		{
			// You may not have line numbers if the selection is occuring from a
			// default template.

			ElemTemplateElement* const	parent = ete.getParentNodeElem();

			if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRootRule())
			{
				m_printWriter.print("(default root rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultTextRule())
			{
				m_printWriter.print("(default text rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRule())
			{
				m_printWriter.print("(default rule) ");
			}
		}
		else
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(", ");
		}

		m_printWriter.print(ete.getElementName());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
		m_printWriter.print(ev.m_attributeName);
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("=\""));
		m_printWriter.print(ev.m_xpath.getExpression().getCurrentPattern());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("\": "));

		if(ev.m_selection->getType() == XObject::eTypeNodeSet)
		{
			m_printWriter.println();

			const NodeRefListBase&	nl = ev.m_selection->nodeset();

			const unsigned int	n = nl.getLength();

			if(n == 0)
			{
				m_printWriter.println(XALAN_STATIC_UCODE_STRING("     [empty node list]"));
			}
			else
			{
				for(unsigned int i = 0; i < n; i++)
				{
					m_printWriter.print(XALAN_STATIC_UCODE_STRING("     "));
					m_printWriter.println(DOMServices::getNodeData(*nl.item(i)));
				}
			}
		}
		else
		{
			m_printWriter.println(ev.m_selection->str());
		}
    }
}

void
TraceListenerDefault::generated(const GenerateEvent&	ev)
{
	if(m_traceGeneration == true)
	{
		switch(ev.m_eventType)
		{
		case GenerateEvent::EVENTTYPE_STARTDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("STARTDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_ENDDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENDDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_STARTELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("STARTELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_ENDELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("ENDELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_CHARACTERS:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CHARACTERS: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_CDATA:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CDATA: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_COMMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("COMMENT: "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_PI:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("PI: "));
			m_printWriter.print(ev.m_name);
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_ENTITYREF:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENTITYREF: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_IGNORABLEWHITESPACE:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("IGNORABLEWHITESPACE"));
			break;
		}
	}
}
<commit_msg>Fixed minor formatting glitch.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in
 *	  the documentation and/or other materials provided with the
 *	  distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.	IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "TraceListenerDefault.hpp"

#include <PlatformSupport/PrintWriter.hpp>

#include <DOMSupport/DOMServices.hpp>

#include <XPath/NodeRefListBase.hpp>
#include <XPath/XPath.hpp>

#include "Constants.hpp"
#include "ElemTextLiteral.hpp"
#include "ElemTemplate.hpp"
#include "GenerateEvent.hpp"
#include "SelectionEvent.hpp"
#include "StylesheetRoot.hpp"
#include "TracerEvent.hpp"

TraceListenerDefault::TraceListenerDefault(
			PrintWriter&	thePrintWriter,
			bool			traceTemplates,
			bool			traceElements,
			bool			traceGeneration,
			bool			traceSelection) :
	m_printWriter(thePrintWriter),
	m_traceTemplates(traceTemplates),
	m_traceElements(traceElements),
	m_traceGeneration(traceGeneration),
	m_traceSelection(traceSelection)
{
}

TraceListenerDefault::~TraceListenerDefault()
{
}

void
TraceListenerDefault::trace(const TracerEvent&	ev)
{
	switch(ev.m_styleNode.getXSLToken())
	{
	case Constants::ELEMNAME_TEXTLITERALRESULT:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("    "));

			const ElemTextLiteral&	etl = static_cast<const ElemTextLiteral&>(ev.m_styleNode);

			m_printWriter.println(c_wstr(etl.getText()), etl.getText().size());
		}
		break;

	case Constants::ELEMNAME_TEMPLATE:
		if(m_traceTemplates == true || m_traceElements == true)
		{
			const ElemTemplate&		et = static_cast<const ElemTemplate&>(ev.m_styleNode);

			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.print(ev.m_styleNode.getElementName());

			const XPath* const	theMatchPattern =
				et.getMatchPattern();

			if(0 != theMatchPattern)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING(" match=\""));
				m_printWriter.print(theMatchPattern->getExpression().getCurrentPattern());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			const QName&	theName = et.getName();

			if(theName.isEmpty() == false)
			{
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("name=\""));

				const XalanDOMString&	theNamespace =
					theName.getNamespace();

				if (isEmpty(theNamespace) == false)
				{
					m_printWriter.print(theNamespace);
					m_printWriter.print(':');
				}

				m_printWriter.print(theName.getLocalPart());
				m_printWriter.print(XALAN_STATIC_UCODE_STRING("\" "));
			}

			m_printWriter.println();
		}
		break;

	default:
		if(m_traceElements == true)
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(": "));
			m_printWriter.println(ev.m_styleNode.getElementName());
		}
		break;
	}
}

void
TraceListenerDefault::selected(const SelectionEvent&	ev)
{
    if(m_traceSelection == true)
    {
		const ElemTemplateElement&	ete = ev.m_styleNode;

		if(ev.m_styleNode.getLineNumber() == 0)
		{
			// You may not have line numbers if the selection is occuring from a
			// default template.

			ElemTemplateElement* const	parent = ete.getParentNodeElem();

			if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRootRule())
			{
				m_printWriter.print("(default root rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultTextRule())
			{
				m_printWriter.print("(default text rule) ");
			}
			else if(parent == ete.getStylesheet().getStylesheetRoot().getDefaultRule())
			{
				m_printWriter.print("(default rule) ");
			}
		}
		else
		{
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Line #"));
			m_printWriter.print(ev.m_styleNode.getLineNumber());
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("Column #"));
			m_printWriter.print(ev.m_styleNode.getColumnNumber());
			m_printWriter.print(", ");
		}

		m_printWriter.print(ete.getElementName());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
		m_printWriter.print(ev.m_attributeName);
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("=\""));
		m_printWriter.print(ev.m_xpath.getExpression().getCurrentPattern());
		m_printWriter.print(XALAN_STATIC_UCODE_STRING("\": "));

		if(ev.m_selection->getType() == XObject::eTypeNodeSet)
		{
			m_printWriter.println();

			const NodeRefListBase&	nl = ev.m_selection->nodeset();

			const unsigned int	n = nl.getLength();

			if(n == 0)
			{
				m_printWriter.println(XALAN_STATIC_UCODE_STRING("     [empty node list]"));
			}
			else
			{
				for(unsigned int i = 0; i < n; i++)
				{
					m_printWriter.print(XALAN_STATIC_UCODE_STRING("     "));
					m_printWriter.println(DOMServices::getNodeData(*nl.item(i)));
				}
			}
		}
		else
		{
			m_printWriter.println(ev.m_selection->str());
		}
    }
}

void
TraceListenerDefault::generated(const GenerateEvent&	ev)
{
	if(m_traceGeneration == true)
	{
		switch(ev.m_eventType)
		{
		case GenerateEvent::EVENTTYPE_STARTDOCUMENT:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("STARTDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_ENDDOCUMENT:
			m_printWriter.println();
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENDDOCUMENT"));
			break;

		case GenerateEvent::EVENTTYPE_STARTELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("STARTELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_ENDELEMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("ENDELEMENT: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_CHARACTERS:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CHARACTERS: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_CDATA:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("CDATA: "));
			m_printWriter.println(ev.m_characters);
			break;

		case GenerateEvent::EVENTTYPE_COMMENT:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("COMMENT: "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_PI:
			m_printWriter.print(XALAN_STATIC_UCODE_STRING("PI: "));
			m_printWriter.print(ev.m_name);
			m_printWriter.print(XALAN_STATIC_UCODE_STRING(", "));
			m_printWriter.println(ev.m_data);
			break;

		case GenerateEvent::EVENTTYPE_ENTITYREF:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("ENTITYREF: "));
			m_printWriter.println(ev.m_name);
			break;

		case GenerateEvent::EVENTTYPE_IGNORABLEWHITESPACE:
			m_printWriter.println(XALAN_STATIC_UCODE_STRING("IGNORABLEWHITESPACE"));
			break;
		}
	}
}
<|endoftext|>


<commit_before>/*
 * MeshGeneratorMarchingcube.cpp
 *
 *  Created on: Jun 6, 2016
 *      Author: hanyinbo
 */

#include "MeshGeneratorMarchingcube.h"
#include "utils/mesh/MeshIO.h"
#include "AppParams.h"
#include "cuda/CudaWrappers.h"
#include "cuda/CudaDeviceDataMan.h"
#include"keyframeMan.h"
MeshGeneratorMarchingcube::MeshGeneratorMarchingcube() {
	// TODO Auto-generated constructor stub

}

MeshGeneratorMarchingcube::~MeshGeneratorMarchingcube() {
	// TODO Auto-generated destructor stub
}

void MeshGeneratorMarchingcube::generateMesh()
{

	cudaMarchingcube(AppParams::instance()->_switch_params.useRGBData ,
			300*AppParams::instance()->_volume_params.fVolumeMeterSize/AppParams::instance()->_volume_params.nResolution);
}
bool MeshGeneratorMarchingcube::copyTrianglesToCPU()
{
	MarchingcubeData marchingcube_data =CudaDeviceDataMan::instance()->_marchingcube_data;
	MarchingcubeData marchingcube_data_cpu;
	marchingcube_data_cpu.init(CPU);
	marchingcube_data_cpu.copyFrom(marchingcube_data);
	int triangle_num=marchingcube_data_cpu.triangleNums();
	cout << "Marching Cubes triangles = " <<triangle_num  << std::endl;
	if (triangle_num == 0)
	{
		return false;
	}
	_meshes.m_Vertices.resize( 3 * triangle_num);
	if (AppParams::instance()->_switch_params.useRGBData == true)
	{
		_meshes.m_Colors.resize(3* triangle_num);
	}

	//float3*  vc = (float3*) triangle;
	for (unsigned int i = 0; i <  triangle_num; i++) {
		Triangle* ptriangle=marchingcube_data_cpu.triangleData()+i;
		_meshes.m_Vertices[3*i] = ptriangle->v0.pos;
		_meshes.m_Vertices[3 * i + 1] = ptriangle->v1.pos;
		_meshes.m_Vertices[3 * i + 2] = ptriangle->v2.pos;
		if (AppParams::instance()->_switch_params.useRGBData == true)
		{
			_meshes.m_Colors[3 * i] = make_float4(ptriangle->v0.color.x,ptriangle->v0.color.y,ptriangle->v0.color.z, 1.0);
			_meshes.m_Colors[3 * i + 1] = make_float4(ptriangle->v1.color.x,ptriangle->v1.color.y,ptriangle->v1.color.z, 1.0);
			_meshes.m_Colors[3 * i + 2] = make_float4(ptriangle->v2.color.x,ptriangle->v2.color.y,ptriangle->v2.color.z, 1.0);
		}
	}

	marchingcube_data_cpu.destroy();
	return true;
}
bool MeshGeneratorMarchingcube::saveMesh(const string& filename)
{
	if(false==copyTrianglesToCPU())
	{
		cout<<"copy triangles to cpu failed"<<endl;
		return false;

	}
	//create index buffer (required for merging the triangle soup)
	_meshes.m_FaceIndicesVertices.resize(_meshes.m_Vertices.size());
	for (unsigned int i = 0; i < (unsigned int)_meshes.m_Vertices.size() / 3; i++) {
		_meshes.m_FaceIndicesVertices[i][0] = 3 * i + 0;
		_meshes.m_FaceIndicesVertices[i][1] = 3 * i + 1;
		_meshes.m_FaceIndicesVertices[i][2] = 3 * i + 2;
	}
	std::cout << "vertices:\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;
	std::cout << "merging close vertices... ";
	_meshes.mergeCloseVertices(0.0001f, true);
	std::cout << "done!" << std::endl;
	std::cout << "vertices e:\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;
	std::cout << "removing duplicate faces... ";
	_meshes.removeDuplicateFaces();
	std::cout << "done!" << std::endl;
	_meshes.computeVertexNormals();
	std::cout << "vertices :\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;

//	m_meshData.applyTransform(transform);

	std::cout << "saving mesh (" << filename << ") ...";
	ml::MeshIOf::saveToFile(filename, _meshes);
	std::cout << "done!" << std::endl;
	return 0;//textureMesh(filename);
}
<commit_msg>Update MeshGeneratorMarchingcube.cpp<commit_after>/*
 * MeshGeneratorMarchingcube.cpp
 *
 *  Created on: Jun 6, 2016
 *      Author: hanyinbo
 */

#include "MeshGeneratorMarchingcube.h"
#include "utils/mesh/MeshIO.h"
#include "AppParams.h"
#include "cuda/CudaWrappers.h"
#include "cuda/CudaDeviceDataMan.h"
MeshGeneratorMarchingcube::MeshGeneratorMarchingcube() {
	// TODO Auto-generated constructor stub

}

MeshGeneratorMarchingcube::~MeshGeneratorMarchingcube() {
	// TODO Auto-generated destructor stub
}

void MeshGeneratorMarchingcube::generateMesh()
{

	cudaMarchingcube(AppParams::instance()->_switch_params.useRGBData ,
			300*AppParams::instance()->_volume_params.fVolumeMeterSize/AppParams::instance()->_volume_params.nResolution);
}
bool MeshGeneratorMarchingcube::copyTrianglesToCPU()
{
	MarchingcubeData marchingcube_data =CudaDeviceDataMan::instance()->_marchingcube_data;
	MarchingcubeData marchingcube_data_cpu;
	marchingcube_data_cpu.init(CPU);
	marchingcube_data_cpu.copyFrom(marchingcube_data);
	int triangle_num=marchingcube_data_cpu.triangleNums();
	cout << "Marching Cubes triangles = " <<triangle_num  << std::endl;
	if (triangle_num == 0)
	{
		return false;
	}
	_meshes.m_Vertices.resize( 3 * triangle_num);
	if (AppParams::instance()->_switch_params.useRGBData == true)
	{
		_meshes.m_Colors.resize(3* triangle_num);
	}

	//float3*  vc = (float3*) triangle;
	for (unsigned int i = 0; i <  triangle_num; i++) {
		Triangle* ptriangle=marchingcube_data_cpu.triangleData()+i;
		_meshes.m_Vertices[3*i] = ptriangle->v0.pos;
		_meshes.m_Vertices[3 * i + 1] = ptriangle->v1.pos;
		_meshes.m_Vertices[3 * i + 2] = ptriangle->v2.pos;
		if (AppParams::instance()->_switch_params.useRGBData == true)
		{
			_meshes.m_Colors[3 * i] = make_float4(ptriangle->v0.color.x,ptriangle->v0.color.y,ptriangle->v0.color.z, 1.0);
			_meshes.m_Colors[3 * i + 1] = make_float4(ptriangle->v1.color.x,ptriangle->v1.color.y,ptriangle->v1.color.z, 1.0);
			_meshes.m_Colors[3 * i + 2] = make_float4(ptriangle->v2.color.x,ptriangle->v2.color.y,ptriangle->v2.color.z, 1.0);
		}
	}

	marchingcube_data_cpu.destroy();
	return true;
}
bool MeshGeneratorMarchingcube::saveMesh(const string& filename)
{
	if(false==copyTrianglesToCPU())
	{
		cout<<"copy triangles to cpu failed"<<endl;
		return false;

	}
	//create index buffer (required for merging the triangle soup)
	_meshes.m_FaceIndicesVertices.resize(_meshes.m_Vertices.size());
	for (unsigned int i = 0; i < (unsigned int)_meshes.m_Vertices.size() / 3; i++) {
		_meshes.m_FaceIndicesVertices[i][0] = 3 * i + 0;
		_meshes.m_FaceIndicesVertices[i][1] = 3 * i + 1;
		_meshes.m_FaceIndicesVertices[i][2] = 3 * i + 2;
	}
	std::cout << "vertices:\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;
	std::cout << "merging close vertices... ";
	_meshes.mergeCloseVertices(0.0001f, true);
	std::cout << "done!" << std::endl;
	std::cout << "vertices e:\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;
	std::cout << "removing duplicate faces... ";
	_meshes.removeDuplicateFaces();
	std::cout << "done!" << std::endl;
	_meshes.computeVertexNormals();
	std::cout << "vertices :\t" << _meshes.m_Vertices.size() << std::endl;
	std::cout << "faces :\t" << _meshes.m_FaceIndicesVertices.size() << std::endl;

//	m_meshData.applyTransform(transform);

	std::cout << "saving mesh (" << filename << ") ...";
	ml::MeshIOf::saveToFile(filename, _meshes);
	std::cout << "done!" << std::endl;
	return 0;//textureMesh(filename);
}
<|endoftext|>