<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "tasnativeutils.h"

#include <taslogger.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <signal.h>

int pidOfXWindow(Display* display, Window win)
{
    int pid = -1;
    Atom atom;
    Atom actual_type;
    int actual_format;
    unsigned long nitems;
    unsigned long bytes_after;
    unsigned char *prop = 0;
    int status;
    if (win != None && win != 0) {
        atom = XInternAtom(display, "_NET_WM_PID", True);
        if (atom != None) {
            status = XGetWindowProperty(display, win, atom, 0, 1024,
                                        False, AnyPropertyType,
                                        &actual_type,
                                        &actual_format, &nitems,
                                        &bytes_after,
                                        &prop);
            if (status!=0 || !prop || actual_format == None) {
                //NOP
            } else {
                pid = prop[1] * 256;
                pid += prop[0];
            }
        }

    }
    if (prop) XFree(prop);
    return pid;
}

//#include <cstdio>

/*!
  \class TasNativeUtils
  \brief Provides platform dependent operations.
*/

// Window id of the currently active window

bool  dockWindow(Display* dpy, Window window)
{
    unsigned long nitems, after;
    int format;
    Atom type = None;
    unsigned char* data = NULL;
    Atom _NET_WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK",
                                           False);
    Atom WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);

    Atom curr_type;

    if (Success == XGetWindowProperty(dpy, window, WINDOW_TYPE, 0, 0x7FFFFFFF, False, AnyPropertyType,
                                      &type, &format, &nitems, &after, &data)) {
        if (!data) {
            return false;
        }
        for (int i = 0; i < (int)nitems; ++i) {
            curr_type = ((Atom*)data)[i];
            if (curr_type == _NET_WM_WINDOW_TYPE_DOCK) {
                XFree(data);
                return true;
            }
        }

    }

    if (data) XFree(data);
    return false;
}

long getstate(Display* display, Window window)
{
    static const long WM_STATE_ELEMENTS = 2L;

    unsigned long nitems;
    unsigned long leftover;
    Atom xa_WM_STATE, actual_type;
    int actual_format;
    int status;
    unsigned char* p = NULL;

    xa_WM_STATE = XInternAtom(display, "WM_STATE", True);

    if (window == None || window == 0) {
        return -1;
    }
    status = XGetWindowProperty(display, window,
                                xa_WM_STATE, 0L, WM_STATE_ELEMENTS,
                                False, xa_WM_STATE, &actual_type, &actual_format,
                                &nitems, &leftover, &p);
    long value = -1;

    if (status == 0) {
        if (p != NULL) {
            // Take first 8 bits
            // Wonder if this is the same on a 64 bit system?
            value = * (const unsigned long *) p & 0xffffffff;
            XFree(p);
        }

        return value;
    }

    if (p) XFree(p);
    return -1;
}

Window queryStack(Display* dpy, Window root, const QList<QString>& pids)
{
    Atom STACK = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
    unsigned long nitems, after;
    int format;
    Atom type = None;
    unsigned char* data = NULL;
    Window child;
    int i;

    if (!STACK) {
        return root;
    }
    if (Success == XGetWindowProperty(dpy, root, STACK, 0, 0x7FFFFFFF, False, XA_WINDOW,
                                      &type, &format, &nitems, &after, &data)) {
        for (i = (nitems-1); i >= 0; --i) {
            child = ((Window*)data)[i];
            if (!dockWindow(dpy, child) && getstate(dpy, child) == 1 &&
                pids.contains(QString::number(pidOfXWindow(dpy, child)))) {

                if (data) XFree(data);
                return child;
            }
        }

    }
    if (data) XFree(data);
    return None;

}

Window tryChildren(Display *dpy, Window win)
{
    Window root, parent;
    Window *children;
    unsigned int nchildren;
    int i;
    Window inf = 0;
    Window child;
    if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) {
        return 0;
    }
    // Traverse bottom-up direction
//    for (i = 0; !inf && (i < nchildren); i++) {
    for (i = nchildren-1; !inf && (i >= 0); i--) {
        // NormalState per ICCM
        if (getstate(dpy, children[i]) == 1) {
            inf = children[i];
        } else {
            child = tryChildren(dpy, children[i]);
            if (child) {
                inf = child;
            }
        }
    }
    if (children) {
        XFree(children);
    }

    return inf;
}

Window findActiveWindow(Display *dpy, Window win)
{
    Window inf;
    if (getstate(dpy, win) == 1) {
        return win;
    }
    inf = tryChildren(dpy, win);
    if (!inf)
        inf = win;
    return inf;
}

// Ignore errors related to the Window calls (of course, the pid is not resolved)
int errorHandler(Display*, XErrorEvent* e)
{
    TasLogger::logger()->warning("TasNativeUtils::errorHandler received X Error during request");
    if (e->error_code == BadWindow) {
        // More verbose on the most common one
        TasLogger::logger()->warning("TasNativeUtils::errorHandler BadWindow");
    } else {
        TasLogger::logger()->warning("TasNativeUtils::errorHandler code " +
                                   QString::number(e->error_code));
    }
    // XGetErrorText contains more info, if necessary
    return 0;
}

int TasNativeUtils::pidOfActiveWindow(const QHash<QString, TasClient*> clients)
{
    const QList<QString>& pids = clients.keys();
    TasLogger::logger()->debug("TasNativeUtils::pidOfActiveWindow Querying for active window");
    int pid = -1;
    Display* display = 0;
    display = XOpenDisplay(0);
    XSetErrorHandler(errorHandler);
    if (!display) return -1;

    int screen = XDefaultScreen(display);
    int window = RootWindow(display, screen);
    Window win = queryStack(display, window, pids);
    pid = pidOfXWindow(display, win);
    XCloseDisplay(display);

    TasLogger::logger()->debug("TasNativeUtils::pidOfActiveWindow Resolved " + QString::number(pid));
    return pid;
}

int TasNativeUtils::bringAppToForeground(TasClient& app)
{
    Q_UNUSED(app);
    return -1;
}

void TasNativeUtils::changeOrientation(QString)
{}

bool TasNativeUtils::killProcess(quint64 pid)
{
    printf("killing %d \n", int(pid));
    kill(pid, 9);
    return true;
}

bool TasNativeUtils::verifyProcess(quint64 pid)
{
    // kill(pid,0) ?
    char path[256];
    sprintf(path, "/proc/%d", int(pid));
    return access(path, F_OK) != -1;
}

bool TasNativeUtils::processExitStatus(quint64 pid, int &status)
{
    return true;
}

<commit_msg>unix impl of exit status<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "tasnativeutils.h"

#include <taslogger.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <signal.h>

int pidOfXWindow(Display* display, Window win)
{
    int pid = -1;
    Atom atom;
    Atom actual_type;
    int actual_format;
    unsigned long nitems;
    unsigned long bytes_after;
    unsigned char *prop = 0;
    int status;
    if (win != None && win != 0) {
        atom = XInternAtom(display, "_NET_WM_PID", True);
        if (atom != None) {
            status = XGetWindowProperty(display, win, atom, 0, 1024,
                                        False, AnyPropertyType,
                                        &actual_type,
                                        &actual_format, &nitems,
                                        &bytes_after,
                                        &prop);
            if (status!=0 || !prop || actual_format == None) {
                //NOP
            } else {
                pid = prop[1] * 256;
                pid += prop[0];
            }
        }

    }
    if (prop) XFree(prop);
    return pid;
}

//#include <cstdio>

/*!
  \class TasNativeUtils
  \brief Provides platform dependent operations.
*/

// Window id of the currently active window

bool  dockWindow(Display* dpy, Window window)
{
    unsigned long nitems, after;
    int format;
    Atom type = None;
    unsigned char* data = NULL;
    Atom _NET_WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK",
                                           False);
    Atom WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);

    Atom curr_type;

    if (Success == XGetWindowProperty(dpy, window, WINDOW_TYPE, 0, 0x7FFFFFFF, False, AnyPropertyType,
                                      &type, &format, &nitems, &after, &data)) {
        if (!data) {
            return false;
        }
        for (int i = 0; i < (int)nitems; ++i) {
            curr_type = ((Atom*)data)[i];
            if (curr_type == _NET_WM_WINDOW_TYPE_DOCK) {
                XFree(data);
                return true;
            }
        }

    }

    if (data) XFree(data);
    return false;
}

long getstate(Display* display, Window window)
{
    static const long WM_STATE_ELEMENTS = 2L;

    unsigned long nitems;
    unsigned long leftover;
    Atom xa_WM_STATE, actual_type;
    int actual_format;
    int status;
    unsigned char* p = NULL;

    xa_WM_STATE = XInternAtom(display, "WM_STATE", True);

    if (window == None || window == 0) {
        return -1;
    }
    status = XGetWindowProperty(display, window,
                                xa_WM_STATE, 0L, WM_STATE_ELEMENTS,
                                False, xa_WM_STATE, &actual_type, &actual_format,
                                &nitems, &leftover, &p);
    long value = -1;

    if (status == 0) {
        if (p != NULL) {
            // Take first 8 bits
            // Wonder if this is the same on a 64 bit system?
            value = * (const unsigned long *) p & 0xffffffff;
            XFree(p);
        }

        return value;
    }

    if (p) XFree(p);
    return -1;
}

Window queryStack(Display* dpy, Window root, const QList<QString>& pids)
{
    Atom STACK = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
    unsigned long nitems, after;
    int format;
    Atom type = None;
    unsigned char* data = NULL;
    Window child;
    int i;

    if (!STACK) {
        return root;
    }
    if (Success == XGetWindowProperty(dpy, root, STACK, 0, 0x7FFFFFFF, False, XA_WINDOW,
                                      &type, &format, &nitems, &after, &data)) {
        for (i = (nitems-1); i >= 0; --i) {
            child = ((Window*)data)[i];
            if (!dockWindow(dpy, child) && getstate(dpy, child) == 1 &&
                pids.contains(QString::number(pidOfXWindow(dpy, child)))) {

                if (data) XFree(data);
                return child;
            }
        }

    }
    if (data) XFree(data);
    return None;

}

Window tryChildren(Display *dpy, Window win)
{
    Window root, parent;
    Window *children;
    unsigned int nchildren;
    int i;
    Window inf = 0;
    Window child;
    if (!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) {
        return 0;
    }
    // Traverse bottom-up direction
//    for (i = 0; !inf && (i < nchildren); i++) {
    for (i = nchildren-1; !inf && (i >= 0); i--) {
        // NormalState per ICCM
        if (getstate(dpy, children[i]) == 1) {
            inf = children[i];
        } else {
            child = tryChildren(dpy, children[i]);
            if (child) {
                inf = child;
            }
        }
    }
    if (children) {
        XFree(children);
    }

    return inf;
}

Window findActiveWindow(Display *dpy, Window win)
{
    Window inf;
    if (getstate(dpy, win) == 1) {
        return win;
    }
    inf = tryChildren(dpy, win);
    if (!inf)
        inf = win;
    return inf;
}

// Ignore errors related to the Window calls (of course, the pid is not resolved)
int errorHandler(Display*, XErrorEvent* e)
{
    TasLogger::logger()->warning("TasNativeUtils::errorHandler received X Error during request");
    if (e->error_code == BadWindow) {
        // More verbose on the most common one
        TasLogger::logger()->warning("TasNativeUtils::errorHandler BadWindow");
    } else {
        TasLogger::logger()->warning("TasNativeUtils::errorHandler code " +
                                   QString::number(e->error_code));
    }
    // XGetErrorText contains more info, if necessary
    return 0;
}

int TasNativeUtils::pidOfActiveWindow(const QHash<QString, TasClient*> clients)
{
    const QList<QString>& pids = clients.keys();
    TasLogger::logger()->debug("TasNativeUtils::pidOfActiveWindow Querying for active window");
    int pid = -1;
    Display* display = 0;
    display = XOpenDisplay(0);
    XSetErrorHandler(errorHandler);
    if (!display) return -1;

    int screen = XDefaultScreen(display);
    int window = RootWindow(display, screen);
    Window win = queryStack(display, window, pids);
    pid = pidOfXWindow(display, win);
    XCloseDisplay(display);

    TasLogger::logger()->debug("TasNativeUtils::pidOfActiveWindow Resolved " + QString::number(pid));
    return pid;
}

int TasNativeUtils::bringAppToForeground(TasClient& app)
{
    Q_UNUSED(app);
    return -1;
}

void TasNativeUtils::changeOrientation(QString)
{}

bool TasNativeUtils::killProcess(quint64 pid)
{
    kill(pid, 9);
    return true;
}

bool TasNativeUtils::verifyProcess(quint64 pid)
{
    // kill(pid,0) ?
    char path[256];
    sprintf(path, "/proc/%d", int(pid));
    return access(path, F_OK) != -1;
}

bool TasNativeUtils::processExitStatus(quint64 pid, int &status)
{
    if (verifyProcess) return false;
    status = 0;
    return true;
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
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.

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 HOLDER 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 <fclaw2d_global.h>

#include <fclaw2d_forestclaw.h>
#include <fclaw2d_partition.h>
#include <fclaw2d_exchange.h>
#include <fclaw2d_physical_bc.h>
#include <fclaw2d_regrid.h>
#include <fclaw2d_clawpatch.h>
#include <fclaw2d_ghost_fill.h>

#if defined(_OPENMP)
#include <omp.h>
#endif

#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif

/* -----------------------------------------------------------------
   Initial grid
   ----------------------------------------------------------------- */
static
void cb_initialize (fclaw2d_domain_t *domain,
                    fclaw2d_patch_t *this_patch,
                    int this_block_idx,
                    int this_patch_idx,
                    void *user)
{
    fclaw2d_vtable_t vt;
    fclaw2d_build_mode_t build_mode = FCLAW2D_BUILD_FOR_UPDATE;

    fclaw2d_patch_data_new(domain,this_patch);
    fclaw2d_clawpatch_build(domain,this_patch,
                            this_block_idx,
                            this_patch_idx,
                            (void*) &build_mode);

    vt = fclaw2d_get_vtable(domain);
    FCLAW_ASSERT(vt.patch_initialize != NULL);
    vt.patch_initialize(domain,this_patch,this_block_idx,this_patch_idx);
}

/* -----------------------------------------------------------------
   Public interface
   ----------------------------------------------------------------- */

void fclaw2d_initialize (fclaw2d_domain_t **domain)
{
    int time_interp = 0;
    char basename[BUFSIZ];
    const fclaw2d_vtable_t vt = fclaw2d_get_vtable(*domain);
    const amr_options_t *gparms = get_domain_parms(*domain);

    fclaw2d_domain_data_t* ddata = fclaw2d_domain_get_data(*domain);

    /* This mapping context is needed by fortran mapping functions */
    fclaw2d_map_context_t *cont = fclaw2d_domain_get_map_context(*domain);
    SET_CONTEXT(&cont);

    int maxthreads = 0;
#if defined(_OPENMP)
    maxthreads = omp_get_max_threads();
#endif
    fclaw_global_essentialf("Max threads set to %d\n",maxthreads);

    int minlevel = gparms->minlevel;
    int maxlevel = gparms->maxlevel;

    /* Initialize all timers */
    ddata->is_latest_domain = 1;
    for (int i = 0; i < FCLAW2D_TIMER_COUNT; ++i) {
        fclaw2d_timer_init (&ddata->timers[i]);
    }

    /* start timing */
    fclaw2d_domain_barrier (*domain);
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);

    /* User defined problem setup */
    if (vt.problem_setup != NULL)
    {
        vt.problem_setup(*domain);
    }

    /* set specific refinement strategy */
    fclaw2d_domain_set_refinement
        (*domain, gparms->smooth_refine, gparms->smooth_refine_level,
         gparms->coarsen_delay);

    /* ------------------------------------------------
       Set up initial domain.

       This needs to be set as if it were going to be used
       for updating.
       ------------------------------------------------ */

    /* Get an initial domain */
    fclaw2d_domain_setup(NULL,*domain);

    /* Initialize patches on uniformly refined level minlevel */
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);
    fclaw2d_domain_iterate_level(*domain, minlevel, cb_initialize,
                                 (void *) NULL);
    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);

    /* Set up ghost patches */
    fclaw2d_exchange_setup(*domain,FCLAW2D_TIMER_INIT);

    /* This is normally called from regrid */
    fclaw2d_regrid_set_neighbor_types(*domain);

    /* We need a user option here to set ghost values after initialization */
    if (gparms->init_ghostcell){
        fclaw2d_ghost_update(*domain,minlevel,maxlevel,0.0,time_interp,FCLAW2D_TIMER_INIT);
        fclaw2d_physical_set_bc(*domain,minlevel,0.0,time_interp);
    }

    // VTK output during amrinit
    if (gparms->vtkout & 1) {
        // into timer
        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
        fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);

        // output
        snprintf (basename, BUFSIZ, "%s_init_level_%02d",
                  gparms->prefix, minlevel);
        fclaw2d_output_write_vtk (*domain, basename);

        // out of timer
        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);
        fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);
    }
    /* ------------------------------------------------
       Done with initial setup.
       ------------------------------------------------ */

    /* ------------------------------------------------
       Build up an initial refinement.
       ------------------------------------------------ */
    if (minlevel < maxlevel)
    {
        int domain_init = 1;
        for (int level = minlevel; level < maxlevel; level++)
        {
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_TAGGING]);
            fclaw2d_domain_iterate_level(*domain, level,
                                         cb_fclaw2d_regrid_tag4refinement,
                                         (void *) &domain_init);
            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_TAGGING]);

            // Construct new domain based on tagged patches.
            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_ADAPT_COMM]);
            fclaw2d_domain_t *new_domain = fclaw2d_domain_adapt(*domain);

            int have_new_refinement = new_domain != NULL;

            if (have_new_refinement)
            {
                /* Have to get a new ddata */
                fclaw2d_domain_setup(*domain,new_domain);
                ddata = fclaw2d_domain_get_data(new_domain);
            }

            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_ADAPT_COMM]);
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);

            if (have_new_refinement)
            {
                fclaw_global_infof(" -- Have new initial refinement\n");

                /* Re-initialize new grids.   Ghost cell values needed for
                   interpolation have already been set by initialization */
                fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);
                fclaw2d_domain_iterate_adapted(*domain, new_domain,
                                               cb_fclaw2d_regrid_repopulate,
                                               (void *) &domain_init);

                fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);

                // free all memory associated with old domain
                fclaw2d_domain_reset(domain);
                *domain = new_domain;
                new_domain = NULL;

                // VTK output during amrinit
                if (gparms->vtkout & 1) {
                    // into timer
                    ddata = fclaw2d_domain_get_data (*domain);
                    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
                    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);

                    // output
                    snprintf (basename, BUFSIZ, "%s_init_level_%02d_adapt",
                              gparms->prefix, level);
                    fclaw2d_output_write_vtk (*domain, basename);

                    /* out of timer */
                    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);
                    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);
                    ddata = NULL;
                }

                /* Repartition domain to new processors.   Second arg is the
                   mode for VTK output */
                fclaw2d_partition_domain(domain,level,FCLAW2D_TIMER_INIT);

                /* Need a new timer */
                ddata = fclaw2d_domain_get_data(*domain);

                /* Set up ghost patches.  This probably doesn't need to be done
                   each time we add a new level. */
                fclaw2d_exchange_setup(*domain,FCLAW2D_TIMER_INIT);

                /* This is normally called from regrid, once the initial domain
                   has been set up */
                fclaw2d_regrid_set_neighbor_types(*domain);

// #if 0
                /* We only need to update the physical ghost cells because we
                   assume the initialization procedure handles all internal
                   boundaries. */
                int new_level = level + 1;

                /* Add 2016/07/26, need to update ghost cell value here. If
                   didn't and there is a refinement, the refined grids' ghost
                   cells will not be initialized */
                if (gparms->init_ghostcell){
                    fclaw2d_ghost_update(*domain,minlevel,maxlevel,0.0,time_interp,FCLAW2D_TIMER_INIT);
                    fclaw2d_physical_set_bc(*domain,new_level,0.0,time_interp);
                }
                // fclaw2d_physical_set_bc(*domain,new_level,time_interp);
// #endif
            }
            else
            {
                /* We don't have a new refinement, and so can break out of level loop */
                break;
            }
        }  /* Level loop (minlevel --> maxlevel) */
    }

    /* Print global minimum and maximum levels */
    fclaw_global_infof("Global minlevel %d maxlevel %d\n",
                (*domain)->global_minlevel, (*domain)->global_maxlevel);

    /* Stop timer */
    ddata = fclaw2d_domain_get_data(*domain);
    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
}

#ifdef __cplusplus
#if 0
{
#endif
}
#endif
<commit_msg>(geoclaw/fillghostcell) change fclaw2d_physical_set_bc place<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
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.

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 HOLDER 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 <fclaw2d_global.h>

#include <fclaw2d_forestclaw.h>
#include <fclaw2d_partition.h>
#include <fclaw2d_exchange.h>
#include <fclaw2d_physical_bc.h>
#include <fclaw2d_regrid.h>
#include <fclaw2d_clawpatch.h>
#include <fclaw2d_ghost_fill.h>

#if defined(_OPENMP)
#include <omp.h>
#endif

#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif

/* -----------------------------------------------------------------
   Initial grid
   ----------------------------------------------------------------- */
static
void cb_initialize (fclaw2d_domain_t *domain,
                    fclaw2d_patch_t *this_patch,
                    int this_block_idx,
                    int this_patch_idx,
                    void *user)
{
    fclaw2d_vtable_t vt;
    fclaw2d_build_mode_t build_mode = FCLAW2D_BUILD_FOR_UPDATE;

    fclaw2d_patch_data_new(domain,this_patch);
    fclaw2d_clawpatch_build(domain,this_patch,
                            this_block_idx,
                            this_patch_idx,
                            (void*) &build_mode);

    vt = fclaw2d_get_vtable(domain);
    FCLAW_ASSERT(vt.patch_initialize != NULL);
    vt.patch_initialize(domain,this_patch,this_block_idx,this_patch_idx);
}

/* -----------------------------------------------------------------
   Public interface
   ----------------------------------------------------------------- */

void fclaw2d_initialize (fclaw2d_domain_t **domain)
{
    int time_interp = 0;
    char basename[BUFSIZ];
    const fclaw2d_vtable_t vt = fclaw2d_get_vtable(*domain);
    const amr_options_t *gparms = get_domain_parms(*domain);

    fclaw2d_domain_data_t* ddata = fclaw2d_domain_get_data(*domain);

    /* This mapping context is needed by fortran mapping functions */
    fclaw2d_map_context_t *cont = fclaw2d_domain_get_map_context(*domain);
    SET_CONTEXT(&cont);

    int maxthreads = 0;
#if defined(_OPENMP)
    maxthreads = omp_get_max_threads();
#endif
    fclaw_global_essentialf("Max threads set to %d\n",maxthreads);

    int minlevel = gparms->minlevel;
    int maxlevel = gparms->maxlevel;

    /* Initialize all timers */
    ddata->is_latest_domain = 1;
    for (int i = 0; i < FCLAW2D_TIMER_COUNT; ++i) {
        fclaw2d_timer_init (&ddata->timers[i]);
    }

    /* start timing */
    fclaw2d_domain_barrier (*domain);
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);

    /* User defined problem setup */
    if (vt.problem_setup != NULL)
    {
        vt.problem_setup(*domain);
    }

    /* set specific refinement strategy */
    fclaw2d_domain_set_refinement
        (*domain, gparms->smooth_refine, gparms->smooth_refine_level,
         gparms->coarsen_delay);

    /* ------------------------------------------------
       Set up initial domain.

       This needs to be set as if it were going to be used
       for updating.
       ------------------------------------------------ */

    /* Get an initial domain */
    fclaw2d_domain_setup(NULL,*domain);

    /* Initialize patches on uniformly refined level minlevel */
    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);
    fclaw2d_domain_iterate_level(*domain, minlevel, cb_initialize,
                                 (void *) NULL);
    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);

    /* Set up ghost patches */
    fclaw2d_exchange_setup(*domain,FCLAW2D_TIMER_INIT);

    /* This is normally called from regrid */
    fclaw2d_regrid_set_neighbor_types(*domain);

    /* We need a user option here to set ghost values after initialization */
    if (gparms->init_ghostcell){
        fclaw2d_ghost_update(*domain,minlevel,maxlevel,0.0,time_interp,FCLAW2D_TIMER_INIT);
    }
    fclaw2d_physical_set_bc(*domain,minlevel,0.0,time_interp);

    // VTK output during amrinit
    if (gparms->vtkout & 1) {
        // into timer
        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
        fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);

        // output
        snprintf (basename, BUFSIZ, "%s_init_level_%02d",
                  gparms->prefix, minlevel);
        fclaw2d_output_write_vtk (*domain, basename);

        // out of timer
        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);
        fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);
    }
    /* ------------------------------------------------
       Done with initial setup.
       ------------------------------------------------ */

    /* ------------------------------------------------
       Build up an initial refinement.
       ------------------------------------------------ */
    if (minlevel < maxlevel)
    {
        int domain_init = 1;
        for (int level = minlevel; level < maxlevel; level++)
        {
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_TAGGING]);
            fclaw2d_domain_iterate_level(*domain, level,
                                         cb_fclaw2d_regrid_tag4refinement,
                                         (void *) &domain_init);
            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_TAGGING]);

            // Construct new domain based on tagged patches.
            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_ADAPT_COMM]);
            fclaw2d_domain_t *new_domain = fclaw2d_domain_adapt(*domain);

            int have_new_refinement = new_domain != NULL;

            if (have_new_refinement)
            {
                /* Have to get a new ddata */
                fclaw2d_domain_setup(*domain,new_domain);
                ddata = fclaw2d_domain_get_data(new_domain);
            }

            fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_ADAPT_COMM]);
            fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);

            if (have_new_refinement)
            {
                fclaw_global_infof(" -- Have new initial refinement\n");

                /* Re-initialize new grids.   Ghost cell values needed for
                   interpolation have already been set by initialization */
                fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);
                fclaw2d_domain_iterate_adapted(*domain, new_domain,
                                               cb_fclaw2d_regrid_repopulate,
                                               (void *) &domain_init);

                fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_REGRID_BUILD]);

                // free all memory associated with old domain
                fclaw2d_domain_reset(domain);
                *domain = new_domain;
                new_domain = NULL;

                // VTK output during amrinit
                if (gparms->vtkout & 1) {
                    // into timer
                    ddata = fclaw2d_domain_get_data (*domain);
                    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
                    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);

                    // output
                    snprintf (basename, BUFSIZ, "%s_init_level_%02d_adapt",
                              gparms->prefix, level);
                    fclaw2d_output_write_vtk (*domain, basename);

                    /* out of timer */
                    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_OUTPUT]);
                    fclaw2d_timer_start (&ddata->timers[FCLAW2D_TIMER_INIT]);
                    ddata = NULL;
                }

                /* Repartition domain to new processors.   Second arg is the
                   mode for VTK output */
                fclaw2d_partition_domain(domain,level,FCLAW2D_TIMER_INIT);

                /* Need a new timer */
                ddata = fclaw2d_domain_get_data(*domain);

                /* Set up ghost patches.  This probably doesn't need to be done
                   each time we add a new level. */
                fclaw2d_exchange_setup(*domain,FCLAW2D_TIMER_INIT);

                /* This is normally called from regrid, once the initial domain
                   has been set up */
                fclaw2d_regrid_set_neighbor_types(*domain);

// #if 0
                /* We only need to update the physical ghost cells because we
                   assume the initialization procedure handles all internal
                   boundaries. */
                int new_level = level + 1;

                /* Add 2016/07/26, need here???*/
                if (gparms->init_ghostcell){
                    fclaw2d_ghost_update(*domain,minlevel,new_level,0.0,time_interp,FCLAW2D_TIMER_INIT);
                }
                fclaw2d_physical_set_bc(*domain,new_level,0.0,time_interp);
                // fclaw2d_physical_set_bc(*domain,new_level,time_interp);
// #endif
            }
            else
            {
                /* We don't have a new refinement, and so can break out of level loop */
                break;
            }
        }  /* Level loop (minlevel --> maxlevel) */
    }

    /* Print global minimum and maximum levels */
    fclaw_global_infof("Global minlevel %d maxlevel %d\n",
                (*domain)->global_minlevel, (*domain)->global_maxlevel);

    /* Stop timer */
    ddata = fclaw2d_domain_get_data(*domain);
    fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_INIT]);
}

#ifdef __cplusplus
#if 0
{
#endif
}
#endif
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// class interface header
#include "cURLManager.h"

// common implementation headers
#include "bzfio.h"

bool                    cURLManager::inited      = false;
CURLM                  *cURLManager::multiHandle = NULL;
std::map<CURL*,
	 cURLManager*>  cURLManager::cURLMap;

cURLManager::cURLManager()
{
  CURLcode result;

  theData   = NULL;
  theLen    = 0;
  errorCode = CURLE_OK;
  added     = false;

  if (!inited)
    setup();

  easyHandle = curl_easy_init();
  if (!easyHandle) {
    DEBUG1("Something wrong with CURL\n");
    return;
  }
#if LIBCURL_VERSION_NUM >= 0x070a00
  result = curl_easy_setopt(easyHandle, CURLOPT_NOSIGNAL, true);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_NOSIGNAL error: %d\n", result);
  }
#endif

  result = curl_easy_setopt(easyHandle, CURLOPT_WRITEFUNCTION,
			    cURLManager::writeFunction);
  if (result != CURLE_OK)
    DEBUG1("CURLOPT_WRITEFUNCTION error: %d\n", result);

  result = curl_easy_setopt(easyHandle, CURLOPT_WRITEDATA, this);
  if (result != CURLE_OK)
    DEBUG1("CURLOPT_FILE error: %d\n", result);

}

cURLManager::~cURLManager()
{
  if (added)
    removeHandle();
  curl_easy_cleanup(easyHandle);
  free(theData);
}

void cURLManager::setup()
{
  CURLcode result;

  DEBUG1("LIBCURL: %s\n", curl_version());
#if LIBCURL_VERSION_NUM >= 0x070a00
  if ((result = curl_global_init(CURL_GLOBAL_NOTHING)))
    DEBUG1("Unexpected error from libcurl; Error: %d\n", result);
#endif
  multiHandle = curl_multi_init();
  if (!multiHandle)
    DEBUG1("Unexpected error creating multi handle from libcurl \n");
  inited = true;
}

size_t cURLManager::writeFunction(void *ptr, size_t size, size_t nmemb,
				  void *stream)
{
  int len = size * nmemb;
  ((cURLManager*)stream)->collectData((char*)ptr, len);
  return len;
}

void cURLManager::setTimeout(long timeout)
{
  CURLcode result;

  result = curl_easy_setopt(easyHandle, CURLOPT_TIMEOUT, timeout);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_TIMEOUT error: %d\n", result);
  }
}

void cURLManager::setNoBody()
{
  CURLcode result;
  long     nobody = 1;

  result = curl_easy_setopt(easyHandle, CURLOPT_NOBODY, nobody);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_NOBODY error: %d\n", result);
  }
}

void cURLManager::setGetMode()
{
  CURLcode result;
  long     get = 1;

  result = curl_easy_setopt(easyHandle, CURLOPT_HTTPGET, get);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_GET error: %d\n", result);
  }
}

void cURLManager::setURL(std::string url)
{
  CURLcode result;

  if (url == "")
    result = curl_easy_setopt(easyHandle, CURLOPT_URL, NULL);
  else
    result = curl_easy_setopt(easyHandle, CURLOPT_URL, url.c_str());
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_URL error: %d\n", result);
  }
}

void cURLManager::setProgressFunction(curl_progress_callback func, void* data)
{
  CURLcode result;
  if (func != NULL) {
    result = curl_easy_setopt(easyHandle, CURLOPT_PROGRESSFUNCTION, func);
    if (result == CURLE_OK)
      result = curl_easy_setopt(easyHandle, CURLOPT_PROGRESSDATA, data);
    if (result == CURLE_OK)
      result = curl_easy_setopt(easyHandle, CURLOPT_NOPROGRESS, 0);
  } else {
   result = curl_easy_setopt(easyHandle, CURLOPT_NOPROGRESS, 1);
  }
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_SET_PROGRESS error: %d\n", result);
  }
}

void cURLManager::setRequestFileTime(bool request)
{
  CURLcode result;
  long     requestFileTime = request ? 1 : 0;
  result = curl_easy_setopt(easyHandle, CURLOPT_FILETIME, requestFileTime);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_FILETIME error: %d\n", result);
  }
}

void cURLManager::addHandle()
{
  CURLMcode result = curl_multi_add_handle(multiHandle, easyHandle);
  if (result != CURLM_OK)
    DEBUG1("Unexpected error from libcurl; Error: %d\n", result);
  cURLMap[easyHandle] = this;
  added = true;
}

void cURLManager::removeHandle()
{
  if (!added)
    return;
  cURLMap.erase(easyHandle);
  CURLMcode result = curl_multi_remove_handle(multiHandle, easyHandle);
  if (result != CURLM_OK)
    DEBUG1("Unexpected error from libcurl; Error: %d\n", result);
  added = false;
}

void cURLManager::finalization(char *, unsigned int, bool)
{
}

void cURLManager::collectData(char* ptr, int len)
{
  unsigned char *newData = (unsigned char *)realloc(theData, theLen + len);
  if (!newData) {
    DEBUG1("memory exhausted\n");
  } else {
    memcpy(newData + theLen, ptr, len);
    theLen += len;
    theData = newData;
  }
}

int cURLManager::perform()
{
  if (!inited)
    setup();

  int activeTransfers = 0;
  CURLMcode result;
  while (true) {
    result = curl_multi_perform(multiHandle, &activeTransfers);
    if (result != CURLM_CALL_MULTI_PERFORM)
      break;
  }
  if (result != CURLM_OK)
    DEBUG1("Unexpected error from libcurl; Error: %d\n", result);

  int      msgs_in_queue;
  CURLMsg *pendingMsg;
  CURL    *easy;

  while (true) {
    pendingMsg = curl_multi_info_read(multiHandle, &msgs_in_queue);
    if (!pendingMsg)
      break;

    easy        = pendingMsg->easy_handle;

    cURLMap[easy]->infoComplete(pendingMsg->data.result);

    if (msgs_in_queue <= 0)
      break;
  }

  return activeTransfers;
}

void cURLManager::infoComplete(CURLcode result)
{
  if (result != CURLE_OK)
    DEBUG1("Unexpected error from libcurl; Error: %d\n", result);
  finalization((char *)theData, theLen, result == CURLE_OK);
  free(theData);
  removeHandle();
  theData = NULL;
  theLen  = 0;
}

bool cURLManager::getFileTime(time_t &t)
{
  long filetime;
  CURLcode result;
  result = curl_easy_getinfo(easyHandle, CURLINFO_FILETIME, &filetime);
  if (result) {
    DEBUG1("CURLINFO_FILETIME error: %d\n", result);
    return false;
  }
  t = (time_t)filetime;
  return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Different diagnostic for each point of error<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// class interface header
#include "cURLManager.h"

// common implementation headers
#include "bzfio.h"

bool                    cURLManager::inited      = false;
CURLM                  *cURLManager::multiHandle = NULL;
std::map<CURL*,
	 cURLManager*>  cURLManager::cURLMap;

cURLManager::cURLManager()
{
  CURLcode result;

  theData   = NULL;
  theLen    = 0;
  errorCode = CURLE_OK;
  added     = false;

  if (!inited)
    setup();

  easyHandle = curl_easy_init();
  if (!easyHandle) {
    DEBUG1("Something wrong with CURL\n");
    return;
  }
#if LIBCURL_VERSION_NUM >= 0x070a00
  result = curl_easy_setopt(easyHandle, CURLOPT_NOSIGNAL, true);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_NOSIGNAL error: %d\n", result);
  }
#endif

  result = curl_easy_setopt(easyHandle, CURLOPT_WRITEFUNCTION,
			    cURLManager::writeFunction);
  if (result != CURLE_OK)
    DEBUG1("CURLOPT_WRITEFUNCTION error: %d\n", result);

  result = curl_easy_setopt(easyHandle, CURLOPT_WRITEDATA, this);
  if (result != CURLE_OK)
    DEBUG1("CURLOPT_WRITEDATA error: %d\n", result);

}

cURLManager::~cURLManager()
{
  if (added)
    removeHandle();
  curl_easy_cleanup(easyHandle);
  free(theData);
}

void cURLManager::setup()
{
  CURLcode result;

  DEBUG1("LIBCURL: %s\n", curl_version());
#if LIBCURL_VERSION_NUM >= 0x070a00
  if ((result = curl_global_init(CURL_GLOBAL_NOTHING)))
    DEBUG1("cURL Global init Error: %d\n", result);
#endif
  multiHandle = curl_multi_init();
  if (!multiHandle)
    DEBUG1("Unexpected error creating multi handle from libcurl \n");
  inited = true;
}

size_t cURLManager::writeFunction(void *ptr, size_t size, size_t nmemb,
				  void *stream)
{
  int len = size * nmemb;
  ((cURLManager*)stream)->collectData((char*)ptr, len);
  return len;
}

void cURLManager::setTimeout(long timeout)
{
  CURLcode result;

  result = curl_easy_setopt(easyHandle, CURLOPT_TIMEOUT, timeout);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_TIMEOUT error: %d\n", result);
  }
}

void cURLManager::setNoBody()
{
  CURLcode result;
  long     nobody = 1;

  result = curl_easy_setopt(easyHandle, CURLOPT_NOBODY, nobody);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_NOBODY error: %d\n", result);
  }
}

void cURLManager::setGetMode()
{
  CURLcode result;
  long     get = 1;

  result = curl_easy_setopt(easyHandle, CURLOPT_HTTPGET, get);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_GET error: %d\n", result);
  }
}

void cURLManager::setURL(std::string url)
{
  CURLcode result;

  if (url == "")
    result = curl_easy_setopt(easyHandle, CURLOPT_URL, NULL);
  else
    result = curl_easy_setopt(easyHandle, CURLOPT_URL, url.c_str());
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_URL error: %d\n", result);
  }
}

void cURLManager::setProgressFunction(curl_progress_callback func, void* data)
{
  CURLcode result;
  if (func != NULL) {
    result = curl_easy_setopt(easyHandle, CURLOPT_PROGRESSFUNCTION, func);
    if (result == CURLE_OK)
      result = curl_easy_setopt(easyHandle, CURLOPT_PROGRESSDATA, data);
    if (result == CURLE_OK)
      result = curl_easy_setopt(easyHandle, CURLOPT_NOPROGRESS, 0);
  } else {
   result = curl_easy_setopt(easyHandle, CURLOPT_NOPROGRESS, 1);
  }
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_SET_PROGRESS error: %d\n", result);
  }
}

void cURLManager::setRequestFileTime(bool request)
{
  CURLcode result;
  long     requestFileTime = request ? 1 : 0;
  result = curl_easy_setopt(easyHandle, CURLOPT_FILETIME, requestFileTime);
  if (result != CURLE_OK) {
    errorCode = result;
    DEBUG1("CURLOPT_FILETIME error: %d\n", result);
  }
}

void cURLManager::addHandle()
{
  CURLMcode result = curl_multi_add_handle(multiHandle, easyHandle);
  if (result != CURLM_OK)
    DEBUG1("Error while adding easy handle from libcurl; Error: %d\n", result);
  cURLMap[easyHandle] = this;
  added = true;
}

void cURLManager::removeHandle()
{
  if (!added)
    return;
  cURLMap.erase(easyHandle);
  CURLMcode result = curl_multi_remove_handle(multiHandle, easyHandle);
  if (result != CURLM_OK)
    DEBUG1("Error while removing easy handle from libcurl; Error: %d\n", result);
  added = false;
}

void cURLManager::finalization(char *, unsigned int, bool)
{
}

void cURLManager::collectData(char* ptr, int len)
{
  unsigned char *newData = (unsigned char *)realloc(theData, theLen + len);
  if (!newData) {
    DEBUG1("memory exhausted\n");
  } else {
    memcpy(newData + theLen, ptr, len);
    theLen += len;
    theData = newData;
  }
}

int cURLManager::perform()
{
  if (!inited)
    setup();

  int activeTransfers = 0;
  CURLMcode result;
  while (true) {
    result = curl_multi_perform(multiHandle, &activeTransfers);
    if (result != CURLM_CALL_MULTI_PERFORM)
      break;
  }
  if (result != CURLM_OK)
    DEBUG1("Error while doing multi_perform from libcurl; Error: %d\n", result);

  int      msgs_in_queue;
  CURLMsg *pendingMsg;
  CURL    *easy;

  while (true) {
    pendingMsg = curl_multi_info_read(multiHandle, &msgs_in_queue);
    if (!pendingMsg)
      break;

    easy        = pendingMsg->easy_handle;

    cURLMap[easy]->infoComplete(pendingMsg->data.result);

    if (msgs_in_queue <= 0)
      break;
  }

  return activeTransfers;
}

void cURLManager::infoComplete(CURLcode result)
{
  if (result != CURLE_OK)
    DEBUG1("File transfer terminated with error from libcurl; Error: %d\n", result);
  finalization((char *)theData, theLen, result == CURLE_OK);
  free(theData);
  removeHandle();
  theData = NULL;
  theLen  = 0;
}

bool cURLManager::getFileTime(time_t &t)
{
  long filetime;
  CURLcode result;
  result = curl_easy_getinfo(easyHandle, CURLINFO_FILETIME, &filetime);
  if (result) {
    DEBUG1("CURLINFO_FILETIME error: %d\n", result);
    return false;
  }
  t = (time_t)filetime;
  return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/**
 * \file vtkFbxHelper.cpp
 * 2012-04-24 LB Initial implementation
 *
 */

// ** INCLUDES **
#include "VtkFbxHelper.h"

#include <vtkActor.h>
#include <vtkPolyDataNormals.h>
 #include <vtkPolyDataMapper.h>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkXMLRectilinearGridReader.h>
#include <vtkXMLStructuredGridReader.h>
#include <vtkXMLUnstructuredGridReader.h>
#include <vtkDataSetMapper.h>
#include <vtkGenericDataObjectReader.h>
#include <vtkGeometryFilter.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkImageMapper.h>

#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>

using namespace std;

void replaceExt(string& s, const string& newExt)
{
    string::size_type i = s.rfind('.', s.length());
    if (i != string::npos)
        s.replace(i + 1, newExt.length(), newExt);
}

string getFileExt(const string& s)
{
    size_t i = s.rfind('.', s.length());
    if (i != string::npos)
        return s.substr(i + 1, s.length() - i);
    return "";
}

string getFilename(const string& s)
{
	char sep = '/';
#ifdef _WIN32
	sep = '\\';
#endif

	size_t i = s.rfind(sep, s.length());
	if (i != string::npos)
		return (s.substr(i + 1, s.length() - 1));

	return ("");
}

vtkActor* readVtkFile(const string& filename)
{
    cout << "Opening file " << filename << " ... " << endl << flush;
    string fileExt = getFileExt(filename);

    vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
    vtkXMLDataReader* reader = NULL;
    vtkGenericDataObjectReader* oldStyleReader = NULL;
    if (fileExt.find("vti") != string::npos)
    {
        reader = vtkXMLImageDataReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkImageDataGeometryFilter> geoFilter =
                vtkSmartPointer<vtkImageDataGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    if (fileExt.find("vtr") != string::npos)
    {
        reader = vtkXMLRectilinearGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vts") != string::npos)
    {
        reader = vtkXMLStructuredGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vtp") != string::npos)
    {
        reader = vtkXMLPolyDataReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        mapper->SetInputConnection(reader->GetOutputPort());
    }
    else if (fileExt.find("vtu") != string::npos)
    {
        reader = vtkXMLUnstructuredGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();

        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->MergingOff();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        geoFilter->Update();

        if(!GetPointNormals(geoFilter->GetOutput()))
        {
            // Generate normals
            std::cout << "Generating normals ..." << std::endl;
            vtkSmartPointer<vtkPolyDataNormals> normalGenerator =
                vtkSmartPointer<vtkPolyDataNormals>::New();
            normalGenerator->SetInputConnection(geoFilter->GetOutputPort());
            normalGenerator->ComputePointNormalsOn();
            normalGenerator->ComputeCellNormalsOff();
            //normalGenerator->Update();
            mapper->SetInputConnection(normalGenerator->GetOutputPort());
        }
        else
            mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vtk") != string::npos)
    {
        oldStyleReader = vtkGenericDataObjectReader::New();
        oldStyleReader->SetFileName(filename.c_str());
        oldStyleReader->Update();
        if(oldStyleReader->IsFilePolyData())
            mapper->SetInputConnection(oldStyleReader->GetOutputPort());
        else
        {
            vtkSmartPointer<vtkGeometryFilter> geoFilter =
                    vtkSmartPointer<vtkGeometryFilter>::New();
            geoFilter->SetInputConnection(oldStyleReader->GetOutputPort());
            mapper->SetInputConnection(geoFilter->GetOutputPort());
        }
    }
    else
    {
        cout << "Not a valid vtk file ending (vti, vtr, vts, vtp, vtu, vtk)" <<
        endl;
        return NULL;
    }

    vtkActor* actor = vtkActor::New();
    mapper->Update();
    actor->SetMapper(mapper);

    if (reader)
        reader->Delete();
    if (oldStyleReader)
        oldStyleReader->Delete();

    return actor;
}

void TestPointNormals(vtkPolyData* polydata)
{
  std::cout << "In TestPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  // Try to read normals directly
  bool hasPointNormals = GetPointNormals(polydata);

  if(!hasPointNormals)
    {
    std::cout << "No point normals were found. Computing normals..." << std::endl;

    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOn();
    normalGenerator->ComputeCellNormalsOff();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */

    polydata = normalGenerator->GetOutput();

    // Try to read normals again
    hasPointNormals = GetPointNormals(polydata);

    std::cout << "On the second try, has point normals? " << hasPointNormals << std::endl;

    }
  else
    {
    std::cout << "Point normals were found!" << std::endl;
    }
}

void TestCellNormals(vtkPolyData* polydata)
{
  // Try to read normals directly
  bool hasCellNormals = GetCellNormals(polydata);

  if(!hasCellNormals)
    {
    std::cout << "No cell normals were found. Computing normals..." << std::endl;

    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOff();
    normalGenerator->ComputeCellNormalsOn();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */

    polydata = normalGenerator->GetOutput();

    // Try to read normals again
    hasCellNormals = GetCellNormals(polydata);

    std::cout << "On the second try, has cell normals? " << hasCellNormals << std::endl;

    }
  else
    {
    std::cout << "Cell normals were found!" << std::endl;
    }
}

bool GetPointNormals(vtkPolyData* polydata)
{
  std::cout << "In GetPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  std::cout << "Looking for point normals..." << std::endl;

  // Count points
  vtkIdType numPoints = polydata->GetNumberOfPoints();
  std::cout << "There are " << numPoints << " points." << std::endl;

  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));

  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));

  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetNormals());

  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetNormals());

  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }

  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetPointData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;

    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);

    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;

    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);

    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }

  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;

}

bool GetCellNormals(vtkPolyData* polydata)
{
  std::cout << "Looking for cell normals..." << std::endl;

  // Count points
  vtkIdType numCells = polydata->GetNumberOfCells();
  std::cout << "There are " << numCells << " cells." << std::endl;

  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));

  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));

  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetNormals());

  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetNormals());

  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }

  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetCellData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;

    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);

    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;

    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);

    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }

  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;

}
<commit_msg>Normals must be flipped?<commit_after>/**
 * \file vtkFbxHelper.cpp
 * 2012-04-24 LB Initial implementation
 *
 */

// ** INCLUDES **
#include "VtkFbxHelper.h"

#include <vtkActor.h>
#include <vtkPolyDataNormals.h>
 #include <vtkPolyDataMapper.h>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkXMLRectilinearGridReader.h>
#include <vtkXMLStructuredGridReader.h>
#include <vtkXMLUnstructuredGridReader.h>
#include <vtkDataSetMapper.h>
#include <vtkGenericDataObjectReader.h>
#include <vtkGeometryFilter.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkImageMapper.h>

#include <vtkCellData.h>
#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>

using namespace std;

void replaceExt(string& s, const string& newExt)
{
    string::size_type i = s.rfind('.', s.length());
    if (i != string::npos)
        s.replace(i + 1, newExt.length(), newExt);
}

string getFileExt(const string& s)
{
    size_t i = s.rfind('.', s.length());
    if (i != string::npos)
        return s.substr(i + 1, s.length() - i);
    return "";
}

string getFilename(const string& s)
{
	char sep = '/';
#ifdef _WIN32
	sep = '\\';
#endif

	size_t i = s.rfind(sep, s.length());
	if (i != string::npos)
		return (s.substr(i + 1, s.length() - 1));

	return ("");
}

vtkActor* readVtkFile(const string& filename)
{
    cout << "Opening file " << filename << " ... " << endl << flush;
    string fileExt = getFileExt(filename);

    vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
    vtkXMLDataReader* reader = NULL;
    vtkGenericDataObjectReader* oldStyleReader = NULL;
    if (fileExt.find("vti") != string::npos)
    {
        reader = vtkXMLImageDataReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkImageDataGeometryFilter> geoFilter =
                vtkSmartPointer<vtkImageDataGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    if (fileExt.find("vtr") != string::npos)
    {
        reader = vtkXMLRectilinearGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vts") != string::npos)
    {
        reader = vtkXMLStructuredGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vtp") != string::npos)
    {
        reader = vtkXMLPolyDataReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();
        mapper->SetInputConnection(reader->GetOutputPort());
    }
    else if (fileExt.find("vtu") != string::npos)
    {
        reader = vtkXMLUnstructuredGridReader::New();
        reader->SetFileName(filename.c_str());
        reader->Update();

        vtkSmartPointer<vtkGeometryFilter> geoFilter =
                vtkSmartPointer<vtkGeometryFilter>::New();
        geoFilter->MergingOff();
        geoFilter->SetInputConnection(reader->GetOutputPort());
        geoFilter->Update();

        if(!GetPointNormals(geoFilter->GetOutput()))
        {
            // Generate normals
            std::cout << "Generating normals ..." << std::endl;
            vtkSmartPointer<vtkPolyDataNormals> normalGenerator =
                vtkSmartPointer<vtkPolyDataNormals>::New();
            normalGenerator->SetInputConnection(geoFilter->GetOutputPort());
            normalGenerator->ComputePointNormalsOn();
            normalGenerator->ComputeCellNormalsOff();
            normalGenerator->FlipNormalsOn();
            //normalGenerator->Update();
            mapper->SetInputConnection(normalGenerator->GetOutputPort());
        }
        else
            mapper->SetInputConnection(geoFilter->GetOutputPort());
    }
    else if (fileExt.find("vtk") != string::npos)
    {
        oldStyleReader = vtkGenericDataObjectReader::New();
        oldStyleReader->SetFileName(filename.c_str());
        oldStyleReader->Update();
        if(oldStyleReader->IsFilePolyData())
            mapper->SetInputConnection(oldStyleReader->GetOutputPort());
        else
        {
            vtkSmartPointer<vtkGeometryFilter> geoFilter =
                    vtkSmartPointer<vtkGeometryFilter>::New();
            geoFilter->SetInputConnection(oldStyleReader->GetOutputPort());
            mapper->SetInputConnection(geoFilter->GetOutputPort());
        }
    }
    else
    {
        cout << "Not a valid vtk file ending (vti, vtr, vts, vtp, vtu, vtk)" <<
        endl;
        return NULL;
    }

    vtkActor* actor = vtkActor::New();
    mapper->Update();
    actor->SetMapper(mapper);

    if (reader)
        reader->Delete();
    if (oldStyleReader)
        oldStyleReader->Delete();

    return actor;
}

void TestPointNormals(vtkPolyData* polydata)
{
  std::cout << "In TestPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  // Try to read normals directly
  bool hasPointNormals = GetPointNormals(polydata);

  if(!hasPointNormals)
    {
    std::cout << "No point normals were found. Computing normals..." << std::endl;

    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOn();
    normalGenerator->ComputeCellNormalsOff();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */

    polydata = normalGenerator->GetOutput();

    // Try to read normals again
    hasPointNormals = GetPointNormals(polydata);

    std::cout << "On the second try, has point normals? " << hasPointNormals << std::endl;

    }
  else
    {
    std::cout << "Point normals were found!" << std::endl;
    }
}

void TestCellNormals(vtkPolyData* polydata)
{
  // Try to read normals directly
  bool hasCellNormals = GetCellNormals(polydata);

  if(!hasCellNormals)
    {
    std::cout << "No cell normals were found. Computing normals..." << std::endl;

    // Generate normals
    vtkSmartPointer<vtkPolyDataNormals> normalGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
#if VTK_MAJOR_VERSION <= 5
    normalGenerator->SetInput(polydata);
#else
    normalGenerator->SetInputData(polydata);
#endif
    normalGenerator->ComputePointNormalsOff();
    normalGenerator->ComputeCellNormalsOn();
    normalGenerator->Update();
    /*
    // Optional settings
    normalGenerator->SetFeatureAngle(0.1);
    normalGenerator->SetSplitting(1);
    normalGenerator->SetConsistency(0);
    normalGenerator->SetAutoOrientNormals(0);
    normalGenerator->SetComputePointNormals(1);
    normalGenerator->SetComputeCellNormals(0);
    normalGenerator->SetFlipNormals(0);
    normalGenerator->SetNonManifoldTraversal(1);
    */

    polydata = normalGenerator->GetOutput();

    // Try to read normals again
    hasCellNormals = GetCellNormals(polydata);

    std::cout << "On the second try, has cell normals? " << hasCellNormals << std::endl;

    }
  else
    {
    std::cout << "Cell normals were found!" << std::endl;
    }
}

bool GetPointNormals(vtkPolyData* polydata)
{
  std::cout << "In GetPointNormals: " << polydata->GetNumberOfPoints() << std::endl;
  std::cout << "Looking for point normals..." << std::endl;

  // Count points
  vtkIdType numPoints = polydata->GetNumberOfPoints();
  std::cout << "There are " << numPoints << " points." << std::endl;

  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));

  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetArray("Normals"));

  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetPointData()->GetNormals());

  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetPointData()->GetNormals());

  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }

  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetPointData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;

    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);

    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;

    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);

    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }

  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;

}

bool GetCellNormals(vtkPolyData* polydata)
{
  std::cout << "Looking for cell normals..." << std::endl;

  // Count points
  vtkIdType numCells = polydata->GetNumberOfCells();
  std::cout << "There are " << numCells << " cells." << std::endl;

  // Count triangles
  vtkIdType numPolys = polydata->GetNumberOfPolys();
  std::cout << "There are " << numPolys << " polys." << std::endl;

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkDoubleArray* normalDataDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));

  if(normalDataDouble)
    {
    int nc = normalDataDouble->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Double normals in an array
  vtkFloatArray* normalDataFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetArray("Normals"));

  if(normalDataFloat)
    {
    int nc = normalDataFloat->GetNumberOfTuples();
    std::cout << "There are " << nc
            << " components in normalDataFloat" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkDoubleArray* normalsDouble =
    vtkDoubleArray::SafeDownCast(polydata->GetCellData()->GetNormals());

  if(normalsDouble)
    {
    std::cout << "There are " << normalsDouble->GetNumberOfComponents()
              << " components in normalsDouble" << std::endl;
    return true;
    }

  ////////////////////////////////////////////////////////////////
  // Point normals
  vtkFloatArray* normalsFloat =
    vtkFloatArray::SafeDownCast(polydata->GetCellData()->GetNormals());

  if(normalsFloat)
    {
    std::cout << "There are " << normalsFloat->GetNumberOfComponents()
              << " components in normalsFloat" << std::endl;
    return true;
    }

  /////////////////////////////////////////////////////////////////////
  // Generic type point normals
  vtkDataArray* normalsGeneric = polydata->GetCellData()->GetNormals(); //works
  if(normalsGeneric)
    {
    std::cout << "There are " << normalsGeneric->GetNumberOfTuples()
              << " normals in normalsGeneric" << std::endl;

    double testDouble[3];
    normalsGeneric->GetTuple(0, testDouble);

    std::cout << "Double: " << testDouble[0] << " "
              << testDouble[1] << " " << testDouble[2] << std::endl;

    // Can't do this:
    /*
    float testFloat[3];
    normalsGeneric->GetTuple(0, testFloat);

    std::cout << "Float: " << testFloat[0] << " "
              << testFloat[1] << " " << testFloat[2] << std::endl;
    */
    return true;
    }

  // If the function has not yet quit, there were none of these types of normals
  std::cout << "Normals not found!" << std::endl;
  return false;

}
<|endoftext|>


<commit_before>#include "Players/UCI_Mediator.h"

#include <string>
#include <future>
#include <numeric>
#include <algorithm>

#include "Players/Player.h"
#include "Game/Board.h"
#include "Game/Clock.h"
#include "Game/Game_Result.h"
#include "Moves/Move.h"

#include "Utility/String.h"

UCI_Mediator::UCI_Mediator(const Player& player)
{
    send_command("id name " + player.name());
    send_command("id author " + player.author());
    send_command("uciok");
}

void UCI_Mediator::setup_turn(Board& board, Clock& clock)
{
    while(true)
    {
        auto command = receive_uci_command(board, clock, false);
        if(command == "ucinewgame")
        {
            log("stopping thinking and clocks");
            board.pick_move_now();
            clock.stop();
        }
        else if(String::starts_with(command, "position "))
        {
            auto parse = String::split(command);
            if(parse.at(1) == "startpos")
            {
                board = Board();
            }
            else if(parse.at(1) == "fen")
            {
                auto fen = std::accumulate(std::next(parse.begin(), 3), std::next(parse.begin(), 8),
                                           parse.at(2),
                                           [](const auto& so_far, const auto& next)
                                           {
                                               return so_far + " " + next;
                                           });
                board = Board(fen);
            }

            auto moves_iter = std::find(parse.begin(), parse.end(), "moves");
            if(moves_iter != parse.end())
            {
                std::for_each(std::next(moves_iter), parse.end(),
                                [&board](const auto& move)
                                {
                                    board.submit_move(board.create_move(move));
                                });
                log("All moves applied");
            }

            log("Board ready for play");
            board.set_thinking_mode(UCI);
        }
        else if(String::starts_with(command, "go"))
        {
            if(board.whose_turn() == WHITE)
            {
                indent = "\t\t";
            }
            else
            {
                indent = "\t\t\t";
            }

            auto go_parse = String::split(command);
            for(size_t i = 1; i < go_parse.size(); ++i)
            {
                auto option = go_parse.at(i);
                double new_time = 0.0;
                if(String::ends_with(option, "time") || String::ends_with(option, "inc"))
                {
                    // All times received are in milliseconds
                    new_time = std::stod(go_parse.at(++i))/1000;
                }

                if(option == "wtime")
                {
                    log("Setting White's time to " + std::to_string(new_time));
                    clock.set_time(WHITE, new_time);
                }
                else if(option == "btime")
                {
                    log("Setting Black's time to " + std::to_string(new_time));
                    clock.set_time(BLACK, new_time);
                }
                else if(option == "winc")
                {
                    log("Setting White's increment time to " + std::to_string(new_time));
                    clock.set_increment(WHITE, new_time);
                }
                else if(option == "binc")
                {
                    log("Setting Black's increment time to " + std::to_string(new_time));
                    clock.set_increment(BLACK, new_time);
                }
                else if(option == "movestogo")
                {
                    auto moves_to_reset = String::string_to_size_t(go_parse.at(++i));
                    log("Next time control in " + std::to_string(moves_to_reset));
                    clock.set_next_time_reset(moves_to_reset);
                }
                else if(option == "movetime")
                {
                    clock.set_time(board.whose_turn(), new_time);
                    clock.set_next_time_reset(1);
                }
                else
                {
                    log("Ignoring go command: " + option);
                }
            }

            log("Telling AI to choose a move at leisure");
            board.choose_move_at_leisure();
            return;
        }
    }
}

void UCI_Mediator::listen(Board& board, Clock& clock)
{
    last_listening_result = std::async(std::launch::async, &UCI_Mediator::listener, this, std::ref(board), std::ref(clock));
}

void UCI_Mediator::handle_move(Board& board, const Move& move)
{
    board.submit_move(move);
    send_command("bestmove " + move.coordinate_move());
}

bool UCI_Mediator::pondering_allowed() const
{
    return true;
}

std::string UCI_Mediator::listener(Board& board, Clock& clock)
{
        return receive_uci_command(board, clock, true);
}

std::string UCI_Mediator::receive_uci_command(Board& board, Clock& clock, bool while_listening)
{
    clock.do_not_stop_game();

    while(true)
    {
        std::string command;
        if(while_listening)
        {
            command = receive_command();
        }
        else
        {
            command = last_listening_result.valid() ? last_listening_result.get() : receive_command();
        }

        if(command == "isready")
        {
            send_command("readyok");
        }
        else if(command == "stop")
        {
            log("Stopping local AI thinking");
            board.pick_move_now();
        }
        else
        {
            return command;
        }
    }
}
<commit_msg>Fix indentation<commit_after>#include "Players/UCI_Mediator.h"

#include <string>
#include <future>
#include <numeric>
#include <algorithm>

#include "Players/Player.h"
#include "Game/Board.h"
#include "Game/Clock.h"
#include "Game/Game_Result.h"
#include "Moves/Move.h"

#include "Utility/String.h"

UCI_Mediator::UCI_Mediator(const Player& player)
{
    send_command("id name " + player.name());
    send_command("id author " + player.author());
    send_command("uciok");
}

void UCI_Mediator::setup_turn(Board& board, Clock& clock)
{
    while(true)
    {
        auto command = receive_uci_command(board, clock, false);
        if(command == "ucinewgame")
        {
            log("stopping thinking and clocks");
            board.pick_move_now();
            clock.stop();
        }
        else if(String::starts_with(command, "position "))
        {
            auto parse = String::split(command);
            if(parse.at(1) == "startpos")
            {
                board = Board();
            }
            else if(parse.at(1) == "fen")
            {
                auto fen = std::accumulate(std::next(parse.begin(), 3), std::next(parse.begin(), 8),
                                           parse.at(2),
                                           [](const auto& so_far, const auto& next)
                                           {
                                               return so_far + " " + next;
                                           });
                board = Board(fen);
            }

            auto moves_iter = std::find(parse.begin(), parse.end(), "moves");
            if(moves_iter != parse.end())
            {
                std::for_each(std::next(moves_iter), parse.end(),
                                [&board](const auto& move)
                                {
                                    board.submit_move(board.create_move(move));
                                });
                log("All moves applied");
            }

            log("Board ready for play");
            board.set_thinking_mode(UCI);
        }
        else if(String::starts_with(command, "go"))
        {
            if(board.whose_turn() == WHITE)
            {
                indent = "\t\t";
            }
            else
            {
                indent = "\t\t\t";
            }

            auto go_parse = String::split(command);
            for(size_t i = 1; i < go_parse.size(); ++i)
            {
                auto option = go_parse.at(i);
                double new_time = 0.0;
                if(String::ends_with(option, "time") || String::ends_with(option, "inc"))
                {
                    // All times received are in milliseconds
                    new_time = std::stod(go_parse.at(++i))/1000;
                }

                if(option == "wtime")
                {
                    log("Setting White's time to " + std::to_string(new_time));
                    clock.set_time(WHITE, new_time);
                }
                else if(option == "btime")
                {
                    log("Setting Black's time to " + std::to_string(new_time));
                    clock.set_time(BLACK, new_time);
                }
                else if(option == "winc")
                {
                    log("Setting White's increment time to " + std::to_string(new_time));
                    clock.set_increment(WHITE, new_time);
                }
                else if(option == "binc")
                {
                    log("Setting Black's increment time to " + std::to_string(new_time));
                    clock.set_increment(BLACK, new_time);
                }
                else if(option == "movestogo")
                {
                    auto moves_to_reset = String::string_to_size_t(go_parse.at(++i));
                    log("Next time control in " + std::to_string(moves_to_reset));
                    clock.set_next_time_reset(moves_to_reset);
                }
                else if(option == "movetime")
                {
                    clock.set_time(board.whose_turn(), new_time);
                    clock.set_next_time_reset(1);
                }
                else
                {
                    log("Ignoring go command: " + option);
                }
            }

            log("Telling AI to choose a move at leisure");
            board.choose_move_at_leisure();
            return;
        }
    }
}

void UCI_Mediator::listen(Board& board, Clock& clock)
{
    last_listening_result = std::async(std::launch::async, &UCI_Mediator::listener, this, std::ref(board), std::ref(clock));
}

void UCI_Mediator::handle_move(Board& board, const Move& move)
{
    board.submit_move(move);
    send_command("bestmove " + move.coordinate_move());
}

bool UCI_Mediator::pondering_allowed() const
{
    return true;
}

std::string UCI_Mediator::listener(Board& board, Clock& clock)
{
    return receive_uci_command(board, clock, true);
}

std::string UCI_Mediator::receive_uci_command(Board& board, Clock& clock, bool while_listening)
{
    clock.do_not_stop_game();

    while(true)
    {
        std::string command;
        if(while_listening)
        {
            command = receive_command();
        }
        else
        {
            command = last_listening_result.valid() ? last_listening_result.get() : receive_command();
        }

        if(command == "isready")
        {
            send_command("readyok");
        }
        else if(command == "stop")
        {
            log("Stopping local AI thinking");
            board.pick_move_now();
        }
        else
        {
            return command;
        }
    }
}
<|endoftext|>