<commit_before><commit_msg>[brief] Starts fleshing out the hello_triangle example.<commit_after>#include <atlas/glx/Context.hpp>
#include <atlas/gui/GUI.hpp>
#include <fmt/printf.h>

using namespace atlas;

// We need to define an error callback function for GLFW, so we do that here.
void errorCallback(int code, char const* message)
{
    fmt::print("error ({}):{}\n", code, message);
}

int main()
{
    // First let's create the structs that we're going to be using. First the
    // window struct.
    glx::WindowSettings settings;
    settings.size.width  = 1280;
    settings.size.height = 720;
    settings.title       = "Hello Triangle";

    // Next, we create the structs needed for the GUI.
    gui::GuiRenderData guiRenderData;
    gui::GuiWindowData guiWindowData;

    // Next, let's make the callbacks struct.
    glx::WindowCallbacks callbacks;
    auto mousePressCallback = [&guiWindowData](int button, int action,
                                               int mode) {
        gui::mousePressedCallback(guiWindowData, button, action, mode);
    };

    auto mouseScrollCallback = [](double xOffset, double yOffset) {
        gui::mouseScrollCallback(xOffset, yOffset);
    };

    auto keyPressCallback = [](int key, int scancode, int action, int mods) {
        gui::keyPressCallback(key, scancode, action, mods);
    };

    auto charCallback = [](unsigned int codepoint) {
        gui::charCallback(codepoint);
    };

    glx::WindowCallbacks callbacks;
    callbacks.mousePressCallback  = mousePressCallback;
    callbacks.mouseScrollCallback = mouseScrollCallback;
    callbacks.keyPressCallback    = keyPressCallback;
    callbacks.charCallback        = charCallback;

    // Now that we have everything setup, let's start initializing things.
    // First, let's initialize GLFW.
    glx::initializeGLFW(errorCallback);

    // Next comes the window.
    auto window = createGLFWWindow(settings);

    // Bind the callbacks.
    glx::bindWindowCallbacks(window, callbacks);

    // Now bind the context.
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    // Create the OpenGL context.
    glx::createGLContext(window, settings.version);

    // Initialize ImGui next.
    ImGui::CreateContext();
    ImGui::StyleColorsDark();

    // Initialize the GUI structs. Remember to set the window!
    gui::initializeGuiWindowData(guiWindowData);
    gui::initializeGuiRenderData(guiRenderData);
    setGuiWindow(guiWindowData, window);

    // Now we are ready for our main loop.
    while (!glfwWindowShouldClose(window))
    {
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Do your GL stuff here.

        // Now draw the GUI elements.
        gui::newFrame(guiWindowData);
        ImGui::NewFrame();
        ImGui::Begin("HUD");
        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
                    1000.0f / ImGui::GetIO().Framerate,
                    ImGui::GetIO().Framerate);
        ImGui::End();

        // Render the GUI.
        ImGui::Render();
        gui::endFrame(guiWindowData, guiRenderData);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Clean up our resources.
    gui::destroyGuiRenderData(guiRenderData);
    gui::destroyGuiWindow(guiWindowData);
    ImGui::DestroyContext();

    glx::destroyGLFWWindow(window);
    glx::terminateGLFW();

    return 0;
}
<|endoftext|>


<commit_before>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface to create an OpenGL
// graphics window, and OSG for rendering.

#include <osg/Timer>
#include <osg/GraphicsContext>
#include <osg/GraphicsThread>

#include <osgUtil/UpdateVisitor>
#include <osgUtil/CullVisitor>
#include <osgUtil/SceneView>
#include <osgUtil/GLObjectsVisitor>

#include <osgDB/ReadFile>

#include <map>
#include <list>
#include <iostream>

////////////////////////////////////////////////////////////////////////////////
//
//
//  **************** THIS IS AN EXPERIMENTAL IMPLEMENTATION ***************
//  ************************** PLEASE DO NOT COPY  ************************
//
//
///////////////////////////////////////////////////////////////////////////////

// Compile operation, that compile OpenGL objects.
struct CompileOperation : public osg::GraphicsThread::Operation
{
    CompileOperation(osg::Node* scene):
        osg::GraphicsThread::Operation("Compile",false),
        _scene(scene)
    {
    }

    virtual void operator () (osg::GraphicsContext* context)
    {
        std::cout<<"Compile"<<std::endl;

        osgUtil::GLObjectsVisitor compileVisitor;
        compileVisitor.setState(context->getState());

        // do the compile traversal
        _scene->accept(compileVisitor);
    }

    osg::ref_ptr<osg::Node> _scene;
};

// Frame operation, that does a cull and draw on the scene graph.
struct FrameOperation : public osg::GraphicsThread::Operation
{
    FrameOperation(osg::CameraNode* camera, osg::FrameStamp* frameStamp):
        osg::GraphicsThread::Operation("Frame",true),
        _camera(camera),
        _frameStamp(frameStamp)
    {
        _sceneView = new osgUtil::SceneView;
        _sceneView->setDefaults();
        _sceneView->setFrameStamp(_frameStamp.get());

        if (camera->getNumChildren()>=1)
        {
            _sceneView->setSceneData(camera->getChild(0));
        }
    }

    virtual void operator () (osg::GraphicsContext* context)
    {
        _sceneView->setState(context->getState());
        _sceneView->setProjectionMatrix(_camera->getProjectionMatrix());
        _sceneView->setViewMatrix(_camera->getViewMatrix());
        _sceneView->setViewport(_camera->getViewport());

        _sceneView->cull();
        _sceneView->draw();
    }

    osg::ref_ptr<osg::CameraNode>    _camera;
    osg::ref_ptr<osg::FrameStamp>    _frameStamp;
    osg::ref_ptr<osgUtil::SceneView> _sceneView;
};

// main does the following steps to create a multi-thread, multiple camera/graphics context view of a scene graph.
//
// 1) load the scene graph
//
// 2) create a list of camera, each with their own graphis context, with a graphics thread for each context.
//
// 3) set up the graphic threads so that the do an initial compile OpenGL objects operation, this is done once, and then this compile op is disgarded
//
// 4) set up the graphics thread so that it has all the graphics ops required for the main loop, these ops are:
// 4.a) frame begin barrair, syncronizes all the waiting graphic threads so they don't run while update is occuring
// 4.b) frame operation - the cull and draw for each camera
// 4.c) frame end barrier, releases the update thread once all graphic threads have dispatched all their OpenGL commands
// 4.d) pre swap barrier, barrier which ensures that all graphics threads have sent their data down to the gfx card.
// 4.e) swap buffers, do the swap buffers on all the graphics contexts.
//
// 5. The main loop:
// 5.a) update
// 5.b) join the frame begin barrrier, releasing all the graphics threads to do their stuff
// 5.c) block on the frame end barrier, waiting till all the graphics threads have done their cull/draws.
// 5.d) check to see if any of the windows has been closed.
//
int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
    osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp;

    unsigned int frameNum = 0;

    osgUtil::UpdateVisitor updateVisitor;
    updateVisitor.setFrameStamp(frameStamp.get());

    unsigned int numberCameras = 3;
    unsigned int xpos = 0;
    unsigned int ypos = 400;
    unsigned int width = 400;
    unsigned int height = 400;

    typedef std::list< osg::ref_ptr<osg::CameraNode> > CameraList;
    typedef std::set< osg::GraphicsContext* > GraphicsContextSet;

    CameraList cameraList;
    GraphicsContextSet graphicsContextSet;

    // create the cameras, graphic contexts and graphic threads.
    bool shareContexts = false;
    osg::GraphicsContext* previousContext = 0;
    for(unsigned int i=0; i< numberCameras; ++i)
    {
        osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode;
        camera->addChild(loadedModel.get());

        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->_windowName = "osgcamera";
        traits->_x = xpos;
        traits->_y = ypos;
        traits->_width = width;
        traits->_height = height;
        traits->_windowDecoration = true;
        traits->_doubleBuffer = true;
        traits->_sharedContext = shareContexts ? previousContext : 0;

        xpos += width;

        osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get());

        if (!gfxc)
        {
            std::cout<<"Unable to create window."<<std::endl;
            return 1;
        }

        camera->setGraphicsContext(gfxc.get());

        // initialize the view to look at the center of the scene graph
        const osg::BoundingSphere& bs = loadedModel->getBound();
        osg::Matrix viewMatrix;
        viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

        camera->setViewport(0,0,traits->_width,traits->_height);
        camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f);
        camera->setViewMatrix(viewMatrix);

        // graphics thread will realize the window.
        gfxc->createGraphicsThread();

        cameraList.push_back(camera);

        previousContext = gfxc.get();
    }

    // build the list of unique graphics contexts.
    CameraList::iterator citr;
    for(citr = cameraList.begin();
        citr != cameraList.end();
        ++citr)
    {
        graphicsContextSet.insert(const_cast<osg::GraphicsContext*>((*citr)->getGraphicsContext()));
    }

    std::cout<<"Number of cameras = "<<cameraList.size()<<std::endl;
    std::cout<<"Number of graphics contexts = "<<graphicsContextSet.size()<<std::endl;

    // first the compile of the GL Objects, do it syncronously.
    GraphicsContextSet::iterator gitr;
    osg::ref_ptr<CompileOperation> compileOp = new CompileOperation(loadedModel.get());
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;
        context->getGraphicsThread()->add(compileOp.get(), true);
    }

    // second the begin frame barrier to all graphics threads
    osg::ref_ptr<osg::BarrierOperation> frameBeginBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;
        context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false);
    }

    // third add the frame for each camera.
    for(citr = cameraList.begin();
        citr != cameraList.end();
        ++citr)
    {
        osg::CameraNode* camera = citr->get();
        camera->getGraphicsContext()->getGraphicsThread()->add( new FrameOperation(camera, frameStamp.get()), false);
    }

    // fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread.
    // The frame end barrier tells the main thead that the draw dispatch/read phase of the scene graph is complete.
    // The pre swap barrier is an optional extra, which does a flush before joining the barrier, using this all graphics threads
    // are held back until they have all dispatched their fifo to the graphics hardware.
    // The swapOp just issues a swap buffers for each of the graphics contexts.
    // The post swap barrier is an optional extra which does a glFinish after the swap buffers.
    osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
    osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH);
    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
    osg::ref_ptr<osg::BarrierOperation> postSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FINISH);
    bool waitTillSwapBufferFinished = false;
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;
        context->getGraphicsThread()->add(frameEndBarrierOp.get(), false);
        context->getGraphicsThread()->add(preSwapBarrierOp.get(), false);
        context->getGraphicsThread()->add(swapOp.get(), false);
        if (waitTillSwapBufferFinished) context->getGraphicsThread()->add(postSwapBarrierOp.get(), false);
    }

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();
    osg::Timer_t previous_tick = start_tick;

    bool done = false;

    // main loop -  update scene graph, dispatch frame, wait for frame done.
    while( !done )
    {

        osg::Timer_t current_tick = osg::Timer::instance()->tick();

        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,current_tick));
        frameStamp->setFrameNumber(frameNum++);

        std::cout<<"Frame rate "<<1.0/osg::Timer::instance()->delta_s(previous_tick,current_tick)<<std::endl;
        previous_tick = current_tick;

        // do the update traversal.
        loadedModel->accept(updateVisitor);

        // dispatch the frame.
        frameBeginBarrierOp->block();

        // wait till the frame is done.
        frameEndBarrierOp->block();

        // check if any of the windows are closed
        for(gitr = graphicsContextSet.begin();
            gitr != graphicsContextSet.end();
            ++gitr)
        {
            osg::GraphicsContext* context = *gitr;
            if (!context->isRealized()) done = true;
        }

    }
    return 0;
}
<commit_msg>Seperated out the cull and draw traversals into their own operations, and added a glFinishBarrierOp which can be placed between the cull and the draw or after swap.<commit_after>// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface to create an OpenGL
// graphics window, and OSG for rendering.

#include <osg/Timer>
#include <osg/GraphicsContext>
#include <osg/GraphicsThread>

#include <osgUtil/UpdateVisitor>
#include <osgUtil/CullVisitor>
#include <osgUtil/SceneView>
#include <osgUtil/GLObjectsVisitor>

#include <osgDB/ReadFile>

#include <map>
#include <list>
#include <iostream>

////////////////////////////////////////////////////////////////////////////////
//
//
//  **************** THIS IS AN EXPERIMENTAL IMPLEMENTATION ***************
//  ************************** PLEASE DO NOT COPY  ************************
//
//
///////////////////////////////////////////////////////////////////////////////

// Compile operation, that compile OpenGL objects.
struct CompileOperation : public osg::GraphicsThread::Operation
{
    CompileOperation(osg::Node* scene):
        osg::GraphicsThread::Operation("Compile",false),
        _scene(scene)
    {
    }

    virtual void operator () (osg::GraphicsContext* context)
    {
        std::cout<<"Compile"<<std::endl;

        osgUtil::GLObjectsVisitor compileVisitor;
        compileVisitor.setState(context->getState());

        // do the compile traversal
        _scene->accept(compileVisitor);
    }

    osg::ref_ptr<osg::Node> _scene;
};

// Cull operation, that does a cull on the scene graph.
struct CullOperation : public osg::GraphicsThread::Operation
{
    CullOperation(osg::CameraNode* camera, osgUtil::SceneView* sceneView):
        osg::GraphicsThread::Operation("Cull",true),
        _camera(camera),
        _sceneView(sceneView)
    {
    }

    virtual void operator () (osg::GraphicsContext* context)
    {
        _sceneView->setState(context->getState());
        _sceneView->setProjectionMatrix(_camera->getProjectionMatrix());
        _sceneView->setViewMatrix(_camera->getViewMatrix());
        _sceneView->setViewport(_camera->getViewport());

        _sceneView->cull();
    }

    osg::ref_ptr<osg::CameraNode>    _camera;
    osg::ref_ptr<osgUtil::SceneView> _sceneView;
};

// Draw operation, that does a draw on the scene graph.
struct DrawOperation : public osg::GraphicsThread::Operation
{
    DrawOperation(osgUtil::SceneView* sceneView):
        osg::GraphicsThread::Operation("Draw",true),
        _sceneView(sceneView)
    {
    }

    virtual void operator () (osg::GraphicsContext*)
    {
        _sceneView->draw();
    }

    osg::ref_ptr<osgUtil::SceneView> _sceneView;
};

// main does the following steps to create a multi-thread, multiple camera/graphics context view of a scene graph.
//
// 1) load the scene graph
//
// 2) create a list of camera, each with their own graphis context, with a graphics thread for each context.
//
// 3) set up the graphic threads so that the do an initial compile OpenGL objects operation, this is done once, and then this compile op is disgarded
//
// 4) set up the graphics thread so that it has all the graphics ops required for the main loop, these ops are:
// 4.a) frame begin barrair, syncronizes all the waiting graphic threads so they don't run while update is occuring
// 4.b) frame operation - the cull and draw for each camera
// 4.c) frame end barrier, releases the update thread once all graphic threads have dispatched all their OpenGL commands
// 4.d) pre swap barrier, barrier which ensures that all graphics threads have sent their data down to the gfx card.
// 4.e) swap buffers, do the swap buffers on all the graphics contexts.
//
// 5. The main loop:
// 5.a) update
// 5.b) join the frame begin barrrier, releasing all the graphics threads to do their stuff
// 5.c) block on the frame end barrier, waiting till all the graphics threads have done their cull/draws.
// 5.d) check to see if any of the windows has been closed.
//
int main( int argc, char **argv )
{
    if (argc<2)
    {
        std::cout << argv[0] <<": requires filename argument." << std::endl;
        return 1;
    }

    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }

    // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
    osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp;

    unsigned int frameNum = 0;

    osgUtil::UpdateVisitor updateVisitor;
    updateVisitor.setFrameStamp(frameStamp.get());

    unsigned int numberCameras = 3;
    unsigned int xpos = 0;
    unsigned int ypos = 400;
    unsigned int width = 400;
    unsigned int height = 400;

    typedef std::list< osg::ref_ptr<osg::CameraNode> > CameraList;
    typedef std::set< osg::GraphicsContext* > GraphicsContextSet;

    CameraList cameraList;
    GraphicsContextSet graphicsContextSet;

    // create the cameras, graphic contexts and graphic threads.
    bool shareContexts = false;
    osg::GraphicsContext* previousContext = 0;
    for(unsigned int i=0; i< numberCameras; ++i)
    {
        osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode;
        camera->addChild(loadedModel.get());

        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->_windowName = "osgcamera";
        traits->_x = xpos;
        traits->_y = ypos;
        traits->_width = width;
        traits->_height = height;
        traits->_windowDecoration = true;
        traits->_doubleBuffer = true;
        traits->_sharedContext = shareContexts ? previousContext : 0;

        xpos += width;

        osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get());

        if (!gfxc)
        {
            std::cout<<"Unable to create window."<<std::endl;
            return 1;
        }

        camera->setGraphicsContext(gfxc.get());

        // initialize the view to look at the center of the scene graph
        const osg::BoundingSphere& bs = loadedModel->getBound();
        osg::Matrix viewMatrix;
        viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

        camera->setViewport(0,0,traits->_width,traits->_height);
        camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f);
        camera->setViewMatrix(viewMatrix);

        // graphics thread will realize the window.
        gfxc->createGraphicsThread();

        cameraList.push_back(camera);

        previousContext = gfxc.get();
    }

    // build the list of unique graphics contexts.
    CameraList::iterator citr;
    for(citr = cameraList.begin();
        citr != cameraList.end();
        ++citr)
    {
        graphicsContextSet.insert(const_cast<osg::GraphicsContext*>((*citr)->getGraphicsContext()));
    }

    std::cout<<"Number of cameras = "<<cameraList.size()<<std::endl;
    std::cout<<"Number of graphics contexts = "<<graphicsContextSet.size()<<std::endl;

    // first the compile of the GL Objects, do it syncronously.
    GraphicsContextSet::iterator gitr;
    osg::ref_ptr<CompileOperation> compileOp = new CompileOperation(loadedModel.get());
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;
        context->getGraphicsThread()->add(compileOp.get(), false);
    }

    // second the begin frame barrier to all graphics threads
    osg::ref_ptr<osg::BarrierOperation> frameBeginBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;
        context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false);
    }

    osg::ref_ptr<osg::BarrierOperation> glFinishBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FINISH);

    // we can put a finish in to gate rendering throughput, so that each new frame starts with a clean sheet.
    // you should only enable one of these, doFinishBeforeNewDraw will allow for the better parallism of the two finish approaches
    bool doFinishBeforeNewDraw = true;
    bool doFinishAfterSwap = false;

    // third add the frame for each camera.
    for(citr = cameraList.begin();
        citr != cameraList.end();
        ++citr)
    {
        osg::CameraNode* camera = citr->get();

        // create a scene view to do the cull and draw
        osgUtil::SceneView* sceneView = new osgUtil::SceneView;
        sceneView->setDefaults();
        sceneView->setFrameStamp(frameStamp.get());

        if (camera->getNumChildren()>=1)
        {
            sceneView->setSceneData(camera->getChild(0));
        }

        // cull traversal operation
        camera->getGraphicsContext()->getGraphicsThread()->add( new CullOperation(camera, sceneView), false);

        // optionally add glFinish barrier to ensure that all OpenGL commands are completed before we start dispatching a new frame
        if (doFinishBeforeNewDraw) camera->getGraphicsContext()->getGraphicsThread()->add( glFinishBarrierOp.get(), false);

        // draw traversal operation.
        camera->getGraphicsContext()->getGraphicsThread()->add( new DrawOperation(sceneView), false);
    }

    // fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread.
    // The frame end barrier tells the main thead that the draw dispatch/read phase of the scene graph is complete.
    // The pre swap barrier is an optional extra, which does a flush before joining the barrier, using this all graphics threads
    // are held back until they have all dispatched their fifo to the graphics hardware.
    // The swapOp just issues a swap buffers for each of the graphics contexts.
    osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
    osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH);
    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
    for(gitr = graphicsContextSet.begin();
        gitr != graphicsContextSet.end();
        ++gitr)
    {
        osg::GraphicsContext* context = *gitr;

        context->getGraphicsThread()->add(frameEndBarrierOp.get(), false);
        context->getGraphicsThread()->add(preSwapBarrierOp.get(), false);
        context->getGraphicsThread()->add(swapOp.get(), false);

        // optionally add finish barrier to ensure that we don't do any other graphics work till the current OpenGL commands are complete.
        if (doFinishAfterSwap) context->getGraphicsThread()->add(glFinishBarrierOp.get(), false);
    }

    // record the timer tick at the start of rendering.
    osg::Timer_t start_tick = osg::Timer::instance()->tick();
    osg::Timer_t previous_tick = start_tick;

    bool done = false;

    // main loop -  update scene graph, dispatch frame, wait for frame done.
    while( !done )
    {

        osg::Timer_t current_tick = osg::Timer::instance()->tick();

        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,current_tick));
        frameStamp->setFrameNumber(frameNum++);

        std::cout<<"Frame rate "<<1.0/osg::Timer::instance()->delta_s(previous_tick,current_tick)<<std::endl;
        previous_tick = current_tick;

        // do the update traversal.
        loadedModel->accept(updateVisitor);

        // dispatch the frame.
        frameBeginBarrierOp->block();

        // wait till the frame is done.
        frameEndBarrierOp->block();

        // check if any of the windows are closed
        for(gitr = graphicsContextSet.begin();
            gitr != graphicsContextSet.end();
            ++gitr)
        {
            osg::GraphicsContext* context = *gitr;
            if (!context->isRealized()) done = true;
        }

    }
    return 0;
}
<|endoftext|>


<commit_before>
#include <GL/glew.h>

#include <glow/Window.h>
#include <glow/ContextFormat.h>
#include <glow/Context.h>
#include <glow/Error.h>
#include <glow/WindowEventHandler.h>

#include <glow/logging.h>

using namespace glow;

class EventHandler : public WindowEventHandler
{
public:
    EventHandler()
    {
    }

    virtual ~EventHandler()
    {
    }

    virtual void initializeEvent(Window & window)
    {
        glClearColor(0.2f, 0.3f, 0.4f, 1.f);
    }

    virtual void resizeEvent(
        Window & window
    ,   const unsigned int width
    ,   const unsigned int height)
    {
        glViewport(0, 0, width, height);
    }

    virtual void paintEvent(Window & window)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        CheckGLError();
    }

    virtual void idleEvent(Window & window)
    {
        window.repaint();
    }
};

/** This example shows how to create a single window, probably in fullscreen
    mode. All window and system events are handled with the event handler.
*/
int main(int argc, char** argv)
{
    glewExperimental = GL_TRUE;

    ContextFormat format;
    EventHandler handler;

    Window window;
    window.attach(&handler);

    window.create(format, "Single Context Example");
    window.show();

    return Window::run();
}
<commit_msg>ref #15 change vsync in single context<commit_after>
#include <GL/glew.h>

#include <glow/Window.h>
#include <glow/ContextFormat.h>
#include <glow/Context.h>
#include <glow/Error.h>
#include <glow/WindowEventHandler.h>

#include <glow/logging.h>

using namespace glow;

class EventHandler : public WindowEventHandler
{
public:
    EventHandler()
    {
    }

    virtual ~EventHandler()
    {
    }

    virtual void initializeEvent(Window & window)
    {
        glClearColor(0.2f, 0.3f, 0.4f, 1.f);
    }

    virtual void resizeEvent(
        Window & window
    ,   const unsigned int width
    ,   const unsigned int height)
    {
        glViewport(0, 0, width, height);
    }

    virtual void paintEvent(Window & window)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }

    virtual void idleEvent(Window & window)
    {
        window.repaint();
    }
};

/** This example shows how to create a single window, probably in fullscreen
    mode. All window and system events are handled with the event handler.
*/
int main(int argc, char** argv)
{
    glewExperimental = GL_TRUE;

    ContextFormat format;
    EventHandler handler;

    Window window;
    window.attach(&handler);

    window.create(format, "Single Context Example");
    window.context()->setSwapInterval(Context::VerticalSyncronization);
    window.show();

    return Window::run();
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#include "grins_config.h"

#include <iostream>

// GRINS
#include "grins/simulation.h"
#include "grins/gaussian_xy_profile.h"

// GRVY
#ifdef GRINS_HAVE_GRVY
#include "grvy.h"
#endif

// libMesh
#include "libmesh/parallel.h"

class VortexBCFactory : public GRINS::BoundaryConditionsFactory
{
public:

  VortexBCFactory( )
    : GRINS::BoundaryConditionsFactory()
  { return; };

  ~VortexBCFactory(){return;};

  std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > build_dirichlet( );
};

// Function for getting initial temperature field
Real initial_values( const Point& p, const Parameters &params,
		     const std::string& system_name, const std::string& unknown_name );

int main(int argc, char* argv[])
{
#ifdef GRINS_USE_GRVY_TIMERS
  GRVY::GRVY_Timer_Class grvy_timer;
  grvy_timer.Init("GRINS Timer");
#endif

  // Check command line count.
  if( argc < 2 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify libMesh input file." << std::endl;
      exit(1); // TODO: something more sophisticated for parallel runs?
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = argv[1];

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.BeginTimer("Initialize Solver");
#endif

  // Initialize libMesh library.
  LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  std::tr1::shared_ptr<VortexBCFactory> bc_factory( new VortexBCFactory );

  sim_builder.attach_bc_factory( bc_factory );

  GRINS::Simulation grins( libMesh_inputfile,
			   sim_builder );

  //FIXME: We need to move this to within the Simulation object somehow...
  std::string restart_file = libMesh_inputfile( "restart-options/restart_file", "none" );

  if( restart_file == "none" )
    {
      // Asssign initial temperature value
      std::string system_name = libMesh_inputfile( "screen-options/system_name", "GRINS" );
      std::tr1::shared_ptr<libMesh::EquationSystems> es = grins.get_equation_system();
      const libMesh::System& system = es->get_system(system_name);

      Parameters &params = es->parameters;
      Real T_base = libMesh_inputfile("InitialConditions/T_base", 0.0);
      Real T_top = libMesh_inputfile("InitialConditions/T_top", 0.0);

      Real u_theta = libMesh_inputfile("InitialConditions/u_theta", 0.0);

      Real jet_width = libMesh_inputfile("InitialConditions/jet_width", 0.0);

      Real w0 = libMesh_inputfile("InitialConditions/w0", 0.0);

      Real& dummy_Tb  = params.set<Real>("T_base");
      dummy_Tb = T_base;

      Real& dummy_Tt  = params.set<Real>("T_top");
      dummy_Tt = T_top;

      Real& dummy_u = params.set<Real>("u_theta");
      dummy_u = u_theta;

      Real& dummy_jw = params.set<Real>("jet_width");
      dummy_jw = jet_width;

      Real& dummy_w0 = params.set<Real>("w0");
      dummy_w0 = w0;

      std::cout << "==========================================================" << std::endl
		<< " Beginning Solution Projection" << std::endl
		<< "==========================================================" << std::endl;

      system.project_solution( initial_values, NULL, params );

      std::cout << "==========================================================" << std::endl
		<< " Finished Solution Projection" << std::endl
		<< "==========================================================" << std::endl;
    }

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.EndTimer("Initialize Solver");

  // Attach GRVY timer to solver
  grins.attach_grvy_timer( &grvy_timer );
#endif

  grins.run();

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.Finalize();

  if( Parallel::Communicator_World.rank() == 0 ) grvy_timer.Summarize();
#endif

  return 0;
}

Real initial_values( const Point& p, const Parameters &params,
		     const std::string& , const std::string& unknown_name )
{
  Real x = p(0);
  Real y = p(1);
  Real z = p(2);

  std::string uvar = "u";
  std::string wvar = "w";

  /*
  x = p(2);
  z = p(0);

  uvar = "w";
  wvar = "u";
  */

  if( unknown_name == "T" )
    {
      const Real T_base = params.get<Real>("T_base");
      const Real T_top = params.get<Real>("T_top");
      return (T_top - T_base)*z + T_base;
    }

  Real r = std::sqrt( x*x + y*y );

  Real theta = 0.0;

  if( r > 1.0e-6)
    {
      if( x >= 0.0 )
	theta = std::asin(y/r);
      else
	theta = -std::asin(y/r) + pi;
    }

  Real u_theta = params.get<Real>("u_theta");

  Real rc = 0.2;
  Real sigma = 0.2/4;

  Real vert_scaling = 0.0;

  if( z >= 0.1 || z <= 0.9 )
    vert_scaling = 1.0;

  if( z < 0.1 )
    {
      vert_scaling = 10.0*z;
    }

  if( z > 0.9 )
    vert_scaling = 10.0*(1.0 - z);

  if( unknown_name == uvar )
    {
      return -vert_scaling*std::sin(theta)*u_theta*std::exp( -(r-rc)*(r-rc)/(2*sigma*sigma));
    }
  else if( unknown_name == "v" )
    {
      return  vert_scaling*std::cos(theta)*u_theta*std::exp( -(r-rc)*(r-rc)/(2*sigma*sigma));
    }

  const Real jet_width = params.get<Real>("jet_width");
  const Real w0 = params.get<Real>("w0");

  if( std::fabs(x) <= jet_width/2.0 && std::fabs(y) <= jet_width/2.0 )
    {
      if( unknown_name == wvar )
	{
	  return vert_scaling*w0;
	}
    }
  else
    {
      if( unknown_name == wvar )
	{
	  const Real A0 = jet_width*jet_width;
	  const Real A1 = 1.0-A0;
	  return -vert_scaling*w0*A0/A1;
	}
    }

  return 0.0;
}

std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > VortexBCFactory::build_dirichlet( )
{
  std::tr1::shared_ptr<libMesh::FunctionBase<Number> > vel_func( new ZeroFunction<Number> );

  // No-flow at top.
  GRINS::DBCContainer cont3;
  cont3.add_var_name( "w" );
  cont3.add_bc_id( 5 );
  //cont3.add_bc_id( 0 );

  // Reuse zero function
  cont3.set_func( vel_func );

  // No-flow at xmin,xmax face
  GRINS::DBCContainer cont4;
  cont4.add_var_name( "u" );
  cont4.add_bc_id( 2 );
  cont4.add_bc_id( 4 );
  // Reuse zero function
  cont4.set_func( vel_func );

  // No-flow at ymin,ymax face
  GRINS::DBCContainer cont5;
  cont5.add_var_name( "v" );
  cont5.add_bc_id( 3 );
  cont5.add_bc_id( 1 );
  // Reuse zero function
  cont5.set_func( vel_func );

  // Now pack it all up.
  std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > mymap;

  //mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont) );

  //mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont2) );

  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont3) );
  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont4) );
  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont5) );

  return mymap;
}
<commit_msg>Include necessary headers<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-
//
// $Id$
//
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#include "grins_config.h"

#include <iostream>

// GRINS
#include "grins/bc_factory.h"
#include "grins/gaussian_xy_profile.h"
#include "grins/simulation.h"
#include "grins/simulation_builder.h"

// GRVY
#ifdef GRINS_HAVE_GRVY
#include "grvy.h"
#endif

// libMesh
#include "libmesh/parallel.h"
#include "libmesh/zero_function.h"

class VortexBCFactory : public GRINS::BoundaryConditionsFactory
{
public:

  VortexBCFactory( )
    : GRINS::BoundaryConditionsFactory()
  { return; };

  ~VortexBCFactory(){return;};

  std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > build_dirichlet( );
};

// Function for getting initial temperature field
Real initial_values( const Point& p, const Parameters &params,
		     const std::string& system_name, const std::string& unknown_name );

int main(int argc, char* argv[])
{
#ifdef GRINS_USE_GRVY_TIMERS
  GRVY::GRVY_Timer_Class grvy_timer;
  grvy_timer.Init("GRINS Timer");
#endif

  // Check command line count.
  if( argc < 2 )
    {
      // TODO: Need more consistent error handling.
      std::cerr << "Error: Must specify libMesh input file." << std::endl;
      exit(1); // TODO: something more sophisticated for parallel runs?
    }

  // libMesh input file should be first argument
  std::string libMesh_input_filename = argv[1];

  // Create our GetPot object.
  GetPot libMesh_inputfile( libMesh_input_filename );

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.BeginTimer("Initialize Solver");
#endif

  // Initialize libMesh library.
  LibMeshInit libmesh_init(argc, argv);

  GRINS::SimulationBuilder sim_builder;

  std::tr1::shared_ptr<VortexBCFactory> bc_factory( new VortexBCFactory );

  sim_builder.attach_bc_factory( bc_factory );

  GRINS::Simulation grins( libMesh_inputfile,
			   sim_builder );

  //FIXME: We need to move this to within the Simulation object somehow...
  std::string restart_file = libMesh_inputfile( "restart-options/restart_file", "none" );

  if( restart_file == "none" )
    {
      // Asssign initial temperature value
      std::string system_name = libMesh_inputfile( "screen-options/system_name", "GRINS" );
      std::tr1::shared_ptr<libMesh::EquationSystems> es = grins.get_equation_system();
      const libMesh::System& system = es->get_system(system_name);

      Parameters &params = es->parameters;
      Real T_base = libMesh_inputfile("InitialConditions/T_base", 0.0);
      Real T_top = libMesh_inputfile("InitialConditions/T_top", 0.0);

      Real u_theta = libMesh_inputfile("InitialConditions/u_theta", 0.0);

      Real jet_width = libMesh_inputfile("InitialConditions/jet_width", 0.0);

      Real w0 = libMesh_inputfile("InitialConditions/w0", 0.0);

      Real& dummy_Tb  = params.set<Real>("T_base");
      dummy_Tb = T_base;

      Real& dummy_Tt  = params.set<Real>("T_top");
      dummy_Tt = T_top;

      Real& dummy_u = params.set<Real>("u_theta");
      dummy_u = u_theta;

      Real& dummy_jw = params.set<Real>("jet_width");
      dummy_jw = jet_width;

      Real& dummy_w0 = params.set<Real>("w0");
      dummy_w0 = w0;

      std::cout << "==========================================================" << std::endl
		<< " Beginning Solution Projection" << std::endl
		<< "==========================================================" << std::endl;

      system.project_solution( initial_values, NULL, params );

      std::cout << "==========================================================" << std::endl
		<< " Finished Solution Projection" << std::endl
		<< "==========================================================" << std::endl;
    }

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.EndTimer("Initialize Solver");

  // Attach GRVY timer to solver
  grins.attach_grvy_timer( &grvy_timer );
#endif

  grins.run();

#ifdef GRINS_USE_GRVY_TIMERS
  grvy_timer.Finalize();

  if( Parallel::Communicator_World.rank() == 0 ) grvy_timer.Summarize();
#endif

  return 0;
}

Real initial_values( const Point& p, const Parameters &params,
		     const std::string& , const std::string& unknown_name )
{
  Real x = p(0);
  Real y = p(1);
  Real z = p(2);

  std::string uvar = "u";
  std::string wvar = "w";

  /*
  x = p(2);
  z = p(0);

  uvar = "w";
  wvar = "u";
  */

  if( unknown_name == "T" )
    {
      const Real T_base = params.get<Real>("T_base");
      const Real T_top = params.get<Real>("T_top");
      return (T_top - T_base)*z + T_base;
    }

  Real r = std::sqrt( x*x + y*y );

  Real theta = 0.0;

  if( r > 1.0e-6)
    {
      if( x >= 0.0 )
	theta = std::asin(y/r);
      else
	theta = -std::asin(y/r) + pi;
    }

  Real u_theta = params.get<Real>("u_theta");

  Real rc = 0.2;
  Real sigma = 0.2/4;

  Real vert_scaling = 0.0;

  if( z >= 0.1 || z <= 0.9 )
    vert_scaling = 1.0;

  if( z < 0.1 )
    {
      vert_scaling = 10.0*z;
    }

  if( z > 0.9 )
    vert_scaling = 10.0*(1.0 - z);

  if( unknown_name == uvar )
    {
      return -vert_scaling*std::sin(theta)*u_theta*std::exp( -(r-rc)*(r-rc)/(2*sigma*sigma));
    }
  else if( unknown_name == "v" )
    {
      return  vert_scaling*std::cos(theta)*u_theta*std::exp( -(r-rc)*(r-rc)/(2*sigma*sigma));
    }

  const Real jet_width = params.get<Real>("jet_width");
  const Real w0 = params.get<Real>("w0");

  if( std::fabs(x) <= jet_width/2.0 && std::fabs(y) <= jet_width/2.0 )
    {
      if( unknown_name == wvar )
	{
	  return vert_scaling*w0;
	}
    }
  else
    {
      if( unknown_name == wvar )
	{
	  const Real A0 = jet_width*jet_width;
	  const Real A1 = 1.0-A0;
	  return -vert_scaling*w0*A0/A1;
	}
    }

  return 0.0;
}

std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > VortexBCFactory::build_dirichlet( )
{
  std::tr1::shared_ptr<libMesh::FunctionBase<Number> > vel_func( new ZeroFunction<Number> );

  // No-flow at top.
  GRINS::DBCContainer cont3;
  cont3.add_var_name( "w" );
  cont3.add_bc_id( 5 );
  //cont3.add_bc_id( 0 );

  // Reuse zero function
  cont3.set_func( vel_func );

  // No-flow at xmin,xmax face
  GRINS::DBCContainer cont4;
  cont4.add_var_name( "u" );
  cont4.add_bc_id( 2 );
  cont4.add_bc_id( 4 );
  // Reuse zero function
  cont4.set_func( vel_func );

  // No-flow at ymin,ymax face
  GRINS::DBCContainer cont5;
  cont5.add_var_name( "v" );
  cont5.add_bc_id( 3 );
  cont5.add_bc_id( 1 );
  // Reuse zero function
  cont5.set_func( vel_func );

  // Now pack it all up.
  std::multimap< GRINS::PhysicsName, GRINS::DBCContainer > mymap;

  //mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont) );

  //mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont2) );

  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont3) );
  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont4) );
  mymap.insert( std::pair<GRINS::PhysicsName, GRINS::DBCContainer >(GRINS::incompressible_navier_stokes,  cont5) );

  return mymap;
}
<|endoftext|>


<commit_before>#include "ConfigServer.h"

static ConfigServer * confServer;

void ConfigServer::returnOK()
{
  sendHeader("Connection", "close");
  sendHeader("Access-Control-Allow-Origin", "*");
  send(200, "text/plain", "Configuration updated. Rebooting in 10 seconds...\r\n");
  delay (10000);
  ESP.restart();
}

void ConfigServer::returnFail(String msg)
{
  sendHeader("Connection", "close");
  sendHeader("Access-Control-Allow-Origin", "*");
  send(500, "text/plain", msg + "\r\n");
}

void ConfigServer::writeConfigField(int index, String str){

    eepromConfig.stageWriteField(index, str);
}

void ConfigServer::handleRoot()
{
   if (confServer->args() > 1){
      Serial.println("Field update requested");
      String sensorName = confServer->arg("SENSOR_NAME");
      String wifiName   = confServer->arg("WIFI_NAME");
      String wifiPwd    = confServer->arg("WIFI_PWD");
      String mqttIp     = confServer->arg("MQTT_IP");
      String mqttPort   = confServer->arg("MQTT_PORT");

      Serial.print("sensorName :");
      Serial.println(sensorName);
      Serial.print("wifiName :");
      Serial.println(wifiName);
      Serial.print("wifiPwd :");
      Serial.println(wifiPwd);
      Serial.print("mqttIp :");
      Serial.println(mqttIp);
      Serial.print("mqttPort :");
      Serial.println(mqttPort);

      confServer->writeConfigField(0, sensorName);
      confServer->writeConfigField(1, wifiName);
      confServer->writeConfigField(2, wifiPwd);
      confServer->writeConfigField(3, mqttIp);
      confServer->writeConfigField(4, mqttPort);

      confServer->eepromConfig.commit();
      confServer->returnOK();

  }
  else {
    Serial.println("no  arg");
    confServer->send(200, "text/html", confServer->getHtmlPage().c_str());
  }

}

String ConfigServer::getHtmlPage(){
   String result =
"<!DOCTYPE HTML>"
""
""
"<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0\">"
"<title>ESP8266 Web Form Demo</title>"
""
""
""
"
Device Config
"
"<FORM action=\"/\" method=\"post\">"
"
"
"Sensor name : "
"<INPUT type=\"text\" name=\"SENSOR_NAME\" value=\"" + config.sensorName + "\"
"
"WIFI access point :"
"<INPUT type=\"text\" name=\"WIFI_NAME\" value=\"" + config.wifiName + "\"
"
"WIFI password :"
"<INPUT type=\"text\" name=\"WIFI_PWD\" value=\"" + config.wifiPwd + "\"
"
"MQTT broker IP address : "
"<INPUT type=\"text\" name=\"MQTT_IP\" value=\"" + config.mqttIp + "\"
"
"MQTT port : "
"<INPUT type=\"text\" name=\"MQTT_PORT\" value=\"" + config.mqttPort + "\"
"
"<INPUT type=\"submit\" value=\"Send\"> <INPUT type=\"reset\">"
"
"
"</FORM>"
""
"";

   return result;

}

    ConfigServer::ConfigServer(IPAddress ip) : ESP8266WebServer(DEFAULT_PORT){
        serverIP = ip;
        //Ugly but not other solution found...
        //Would need to pass context to callback regitrations in ESP8266WebServer API
        confServer = this;
        eepromConfig.readAll();
        config.sensorName = eepromConfig.readField(0);
        config.wifiName   = eepromConfig.readField(1);
        config.wifiPwd    = eepromConfig.readField(2);
        config.mqttIp     = eepromConfig.readField(3);
        config.mqttPort   = eepromConfig.readField(4);

    }

    MqttConfig ConfigServer::getMqttConfig(){
        return config;

    }

    void ConfigServer::start(){

        Serial.println("starting config server");
        WiFi.mode(WIFI_AP);
        WiFi.softAPConfig(serverIP, serverIP, IPAddress(255, 255, 255, 0));
        int result = WiFi.softAP("ESP_CONFIG");
        if(result == true)
        {
            Serial.println("Config server ready");
        }
        else
        {
            Serial.println("Config server failed to start!");
        }

        on("/", &ConfigServer::handleRoot);
        //on("/", fn_wrapper);

        begin();
   }

<commit_msg>Add mac address to the wifi AP name use in config mode<commit_after>#include "ConfigServer.h"

static ConfigServer * confServer;

void ConfigServer::returnOK()
{
  sendHeader("Connection", "close");
  sendHeader("Access-Control-Allow-Origin", "*");
  send(200, "text/plain", "Configuration updated. Rebooting in 10 seconds...\r\n");
  delay (10000);
  ESP.restart();
}

void ConfigServer::returnFail(String msg)
{
  sendHeader("Connection", "close");
  sendHeader("Access-Control-Allow-Origin", "*");
  send(500, "text/plain", msg + "\r\n");
}

void ConfigServer::writeConfigField(int index, String str){

    eepromConfig.stageWriteField(index, str);
}

void ConfigServer::handleRoot()
{
   if (confServer->args() > 1){
      Serial.println("Field update requested");
      String sensorName = confServer->arg("SENSOR_NAME");
      String wifiName   = confServer->arg("WIFI_NAME");
      String wifiPwd    = confServer->arg("WIFI_PWD");
      String mqttIp     = confServer->arg("MQTT_IP");
      String mqttPort   = confServer->arg("MQTT_PORT");

      Serial.print("sensorName :");
      Serial.println(sensorName);
      Serial.print("wifiName :");
      Serial.println(wifiName);
      Serial.print("wifiPwd :");
      Serial.println(wifiPwd);
      Serial.print("mqttIp :");
      Serial.println(mqttIp);
      Serial.print("mqttPort :");
      Serial.println(mqttPort);

      confServer->writeConfigField(0, sensorName);
      confServer->writeConfigField(1, wifiName);
      confServer->writeConfigField(2, wifiPwd);
      confServer->writeConfigField(3, mqttIp);
      confServer->writeConfigField(4, mqttPort);

      confServer->eepromConfig.commit();
      confServer->returnOK();

  }
  else {
    Serial.println("no  arg");
    confServer->send(200, "text/html", confServer->getHtmlPage().c_str());
  }

}

String ConfigServer::getHtmlPage(){
   String result =
"<!DOCTYPE HTML>"
""
""
"<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0\">"
"<title>ESP8266 Web Form Demo</title>"
""
""
""
"
Device Config
"
"<FORM action=\"/\" method=\"post\">"
"
"
"Sensor name : "
"<INPUT type=\"text\" name=\"SENSOR_NAME\" value=\"" + config.sensorName + "\"
"
"WIFI access point :"
"<INPUT type=\"text\" name=\"WIFI_NAME\" value=\"" + config.wifiName + "\"
"
"WIFI password :"
"<INPUT type=\"text\" name=\"WIFI_PWD\" value=\"" + config.wifiPwd + "\"
"
"MQTT broker IP address : "
"<INPUT type=\"text\" name=\"MQTT_IP\" value=\"" + config.mqttIp + "\"
"
"MQTT port : "
"<INPUT type=\"text\" name=\"MQTT_PORT\" value=\"" + config.mqttPort + "\"
"
"<INPUT type=\"submit\" value=\"Send\"> <INPUT type=\"reset\">"
"
"
"</FORM>"
""
"";

   return result;

}

    ConfigServer::ConfigServer(IPAddress ip) : ESP8266WebServer(DEFAULT_PORT){
        serverIP = ip;
        //Ugly but not other solution found...
        //Would need to pass context to callback regitrations in ESP8266WebServer API
        confServer = this;
        eepromConfig.readAll();
        config.sensorName = eepromConfig.readField(0);
        config.wifiName   = eepromConfig.readField(1);
        config.wifiPwd    = eepromConfig.readField(2);
        config.mqttIp     = eepromConfig.readField(3);
        config.mqttPort   = eepromConfig.readField(4);

    }

    MqttConfig ConfigServer::getMqttConfig(){
        return config;

    }

    void ConfigServer::start(){

        Serial.println("starting config server :");
        WiFi.mode(WIFI_AP);
        WiFi.softAPConfig(serverIP, serverIP, IPAddress(255, 255, 255, 0));
        String configWifiName = String(WiFi.macAddress()) + "_DEVICE_CONFIG";
        Serial.println(configWifiName);
        int result = WiFi.softAP(configWifiName.c_str());

        if(result == true)
        {
            Serial.println("Config server ready");
        }
        else
        {
            Serial.println("Config server failed to start!");
        }

        on("/", &ConfigServer::handleRoot);
        //on("/", fn_wrapper);

        begin();
   }

<|endoftext|>


<commit_before>#include "Texture.hpp"

#include "Error.hpp"
#include "InvalidObject.hpp"

PyObject * MGLTexture_tp_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) {
	MGLTexture * self = (MGLTexture *)type->tp_alloc(type, 0);

	#ifdef MGL_VERBOSE
	printf("MGLTexture_tp_new %p\n", self);
	#endif

	if (self) {
	}

	return (PyObject *)self;
}

void MGLTexture_tp_dealloc(MGLTexture * self) {

	#ifdef MGL_VERBOSE
	printf("MGLTexture_tp_dealloc %p\n", self);
	#endif

	MGLTexture_Type.tp_free((PyObject *)self);
}

int MGLTexture_tp_init(MGLTexture * self, PyObject * args, PyObject * kwargs) {
	MGLError * error = MGLError_New(TRACE, "Cannot create ModernGL.Texture manually");
	PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
	return -1;
}

PyObject * MGLTexture_tp_str(MGLTexture * self) {
	return PyUnicode_FromFormat("<ModernGL.Texture>");
}

PyObject * MGLTexture_use(MGLTexture * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"index", 0};

	int index = 0;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"|I",
		(char **)kwlist,
		&index
	);

	if (!args_ok) {
		return 0;
	}

	const GLMethods & gl = self->context->gl;
	gl.ActiveTexture(GL_TEXTURE0 + index);
	gl.BindTexture(GL_TEXTURE_2D, self->texture_obj);

	Py_RETURN_NONE;
}

const char * MGLTexture_use_doc = R"(
	use(index = 0)

	Args:
		optional index: The texture location.
			Same as the integer value that is used for sampler2D uniforms in the shaders.
			The value ``0`` will bind the texture to the ``GL_TEXTURE0`` binding point.

	Returns:
		:py:data:`None`
)";

PyObject * MGLTexture_release(MGLTexture * self) {
	MGLTexture_Invalidate(self);
	Py_RETURN_NONE;
}

const char * MGLTexture_release_doc = R"(
	release()

	Release the texture.
)";

PyMethodDef MGLTexture_tp_methods[] = {
	{"use", (PyCFunction)MGLTexture_use, METH_VARARGS | METH_KEYWORDS, MGLTexture_use_doc},
	{"release", (PyCFunction)MGLTexture_release, METH_NOARGS, MGLTexture_release_doc},
	{0},
};

PyObject * MGLTexture_get_width(MGLTexture * self, void * closure) {
	return PyLong_FromLong(self->width);
}

char MGLTexture_width_doc[] = R"(
	width

	The width
)";

PyObject * MGLTexture_get_height(MGLTexture * self, void * closure) {
	return PyLong_FromLong(self->height);
}

char MGLTexture_height_doc[] = R"(
	height

	The height
)";

PyObject * MGLTexture_get_size(MGLTexture * self, void * closure) {
	return PyTuple_Pack(2, PyLong_FromLong(self->width), PyLong_FromLong(self->height));
}

char MGLTexture_size_doc[] = R"(
	size

	The size
)";

PyGetSetDef MGLTexture_tp_getseters[] = {
	{(char *)"width", (getter)MGLTexture_get_width, 0, MGLTexture_width_doc, 0},
	{(char *)"height", (getter)MGLTexture_get_height, 0, MGLTexture_height_doc, 0},
	{(char *)"size", (getter)MGLTexture_get_size, 0, MGLTexture_size_doc, 0},
	{0},
};

const char * MGLTexture_tp_doc = R"(
	Texture
)";

PyTypeObject MGLTexture_Type = {
	PyVarObject_HEAD_INIT(0, 0)
	"ModernGL.Texture",                                     // tp_name
	sizeof(MGLTexture),                                     // tp_basicsize
	0,                                                      // tp_itemsize
	(destructor)MGLTexture_tp_dealloc,                      // tp_dealloc
	0,                                                      // tp_print
	0,                                                      // tp_getattr
	0,                                                      // tp_setattr
	0,                                                      // tp_reserved
	(reprfunc)MGLTexture_tp_str,                            // tp_repr
	0,                                                      // tp_as_number
	0,                                                      // tp_as_sequence
	0,                                                      // tp_as_mapping
	0,                                                      // tp_hash
	0,                                                      // tp_call
	(reprfunc)MGLTexture_tp_str,                            // tp_str
	0,                                                      // tp_getattro
	0,                                                      // tp_setattro
	0,                                                      // tp_as_buffer
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               // tp_flags
	MGLTexture_tp_doc,                                      // tp_doc
	0,                                                      // tp_traverse
	0,                                                      // tp_clear
	0,                                                      // tp_richcompare
	0,                                                      // tp_weaklistoffset
	0,                                                      // tp_iter
	0,                                                      // tp_iternext
	MGLTexture_tp_methods,                                  // tp_methods
	0,                                                      // tp_members
	MGLTexture_tp_getseters,                                // tp_getset
	&MGLFramebufferAttachment_Type,                         // tp_base
	0,                                                      // tp_dict
	0,                                                      // tp_descr_get
	0,                                                      // tp_descr_set
	0,                                                      // tp_dictoffset
	(initproc)MGLTexture_tp_init,                           // tp_init
	0,                                                      // tp_alloc
	MGLTexture_tp_new,                                      // tp_new
};

MGLTexture * MGLTexture_New() {
	MGLTexture * self = (MGLTexture *)MGLTexture_tp_new(&MGLTexture_Type, 0, 0);
	return self;
}

void MGLTexture_Invalidate(MGLTexture * texture) {
	if (Py_TYPE(texture) == &MGLInvalidObject_Type) {

		#ifdef MGL_VERBOSE
		printf("MGLTexture_Invalidate %p already released\n", texture);
		#endif

		return;
	}

	#ifdef MGL_VERBOSE
	printf("MGLTexture_Invalidate %p\n", texture);
	#endif

	texture->context->gl.DeleteTextures(1, (GLuint *)&texture->texture_obj);

	Py_DECREF(texture->context);

	Py_TYPE(texture) = &MGLInvalidObject_Type;

	Py_DECREF(texture);
}
<commit_msg>update texture<commit_after>#include "Texture.hpp"

#include "Error.hpp"
#include "InvalidObject.hpp"

PyObject * MGLTexture_tp_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) {
	MGLTexture * self = (MGLTexture *)type->tp_alloc(type, 0);

	#ifdef MGL_VERBOSE
	printf("MGLTexture_tp_new %p\n", self);
	#endif

	if (self) {
	}

	return (PyObject *)self;
}

void MGLTexture_tp_dealloc(MGLTexture * self) {

	#ifdef MGL_VERBOSE
	printf("MGLTexture_tp_dealloc %p\n", self);
	#endif

	MGLTexture_Type.tp_free((PyObject *)self);
}

int MGLTexture_tp_init(MGLTexture * self, PyObject * args, PyObject * kwargs) {
	MGLError * error = MGLError_New(TRACE, "Cannot create ModernGL.Texture manually");
	PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
	return -1;
}

PyObject * MGLTexture_tp_str(MGLTexture * self) {
	return PyUnicode_FromFormat("<ModernGL.Texture>");
}

PyObject * MGLTexture_update(MGLTexture * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"data", "size", "offset", 0};

	PyObject * data;
	PyObject * size = Py_None;
	PyObject * offset = Py_None;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"O|OO",
		(char **)kwlist,
		&data,
		&size,
		&offset
	);

	if (!args_ok) {
		return 0;
	}

	int x;
	int y;

	int width;
	int height;

	Py_buffer buffer_view;

	if (size != Py_None) {
		if (Py_TYPE(size) != &PyTuple_Type) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}

		if (PyTuple_GET_SIZE(size) != 2) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}

		width = PyLong_AsLong(PyTuple_GET_ITEM(size, 0));
		height = PyLong_AsLong(PyTuple_GET_ITEM(size, 1));

		if (PyErr_Occurred()) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}
	} else {
		width = self->width;
		height = self->height;
	}

	if (offset != Py_None) {
		if (Py_TYPE(offset) != &PyTuple_Type) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}

		if (PyTuple_GET_SIZE(offset) != 2) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}

		x = PyLong_AsLong(PyTuple_GET_ITEM(offset, 0));
		y = PyLong_AsLong(PyTuple_GET_ITEM(offset, 1));

		if (PyErr_Occurred()) {
			PyErr_Format(PyExc_Exception, "Unknown error in %s (%s:%d)", __FUNCTION__, __FILE__, __LINE__);
			return 0;
		}
	} else {
		x = 0;
		y = 0;
	}

	int expected_size = self->floats ? (width * height * self->components * 4) : (height * ((width * self->components + 3) & ~3));

	PyObject_GetBuffer(data, &buffer_view, PyBUF_SIMPLE);

	if (buffer_view.len != expected_size) {
		MGLError * error = MGLError_New(TRACE, "data size mismatch %d != %d", buffer_view.len, expected_size);
		PyErr_SetObject((PyObject *)&MGLError_Type, (PyObject *)error);
		if (data != Py_None) {
			PyBuffer_Release(&buffer_view);
		}
		return 0;
	}

	const int formats[] = {0, GL_RED, GL_RG, GL_RGB, GL_RGBA};

	int pixel_type = self->floats ? GL_FLOAT : GL_UNSIGNED_BYTE;
	int format = formats[self->components];

	const GLMethods & gl = self->context->gl;

	gl.ActiveTexture(GL_TEXTURE0 + self->context->default_texture_unit);
	gl.BindTexture(GL_TEXTURE_2D, self->texture_obj);

	gl.TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, format, pixel_type, buffer_view.buf);

	PyBuffer_Release(&buffer_view);

	Py_RETURN_NONE;
}

const char * MGLTexture_update_doc = R"(
	update()
)";

PyObject * MGLTexture_use(MGLTexture * self, PyObject * args, PyObject * kwargs) {
	static const char * kwlist[] = {"index", 0};

	int index = 0;

	int args_ok = PyArg_ParseTupleAndKeywords(
		args,
		kwargs,
		"|I",
		(char **)kwlist,
		&index
	);

	if (!args_ok) {
		return 0;
	}

	const GLMethods & gl = self->context->gl;
	gl.ActiveTexture(GL_TEXTURE0 + index);
	gl.BindTexture(GL_TEXTURE_2D, self->texture_obj);

	Py_RETURN_NONE;
}

const char * MGLTexture_use_doc = R"(
	use(index = 0)

	Args:
		optional index: The texture location.
			Same as the integer value that is used for sampler2D uniforms in the shaders.
			The value ``0`` will bind the texture to the ``GL_TEXTURE0`` binding point.

	Returns:
		:py:data:`None`
)";

PyObject * MGLTexture_release(MGLTexture * self) {
	MGLTexture_Invalidate(self);
	Py_RETURN_NONE;
}

const char * MGLTexture_release_doc = R"(
	release()

	Release the texture.
)";

PyMethodDef MGLTexture_tp_methods[] = {
	{"update", (PyCFunction)MGLTexture_update, METH_VARARGS | METH_KEYWORDS, MGLTexture_update_doc},
	{"use", (PyCFunction)MGLTexture_use, METH_VARARGS | METH_KEYWORDS, MGLTexture_use_doc},
	{"release", (PyCFunction)MGLTexture_release, METH_NOARGS, MGLTexture_release_doc},
	{0},
};

PyObject * MGLTexture_get_width(MGLTexture * self, void * closure) {
	return PyLong_FromLong(self->width);
}

char MGLTexture_width_doc[] = R"(
	width

	The width
)";

PyObject * MGLTexture_get_height(MGLTexture * self, void * closure) {
	return PyLong_FromLong(self->height);
}

char MGLTexture_height_doc[] = R"(
	height

	The height
)";

PyObject * MGLTexture_get_size(MGLTexture * self, void * closure) {
	return PyTuple_Pack(2, PyLong_FromLong(self->width), PyLong_FromLong(self->height));
}

char MGLTexture_size_doc[] = R"(
	size

	The size
)";

PyGetSetDef MGLTexture_tp_getseters[] = {
	{(char *)"width", (getter)MGLTexture_get_width, 0, MGLTexture_width_doc, 0},
	{(char *)"height", (getter)MGLTexture_get_height, 0, MGLTexture_height_doc, 0},
	{(char *)"size", (getter)MGLTexture_get_size, 0, MGLTexture_size_doc, 0},
	{0},
};

const char * MGLTexture_tp_doc = R"(
	Texture
)";

PyTypeObject MGLTexture_Type = {
	PyVarObject_HEAD_INIT(0, 0)
	"ModernGL.Texture",                                     // tp_name
	sizeof(MGLTexture),                                     // tp_basicsize
	0,                                                      // tp_itemsize
	(destructor)MGLTexture_tp_dealloc,                      // tp_dealloc
	0,                                                      // tp_print
	0,                                                      // tp_getattr
	0,                                                      // tp_setattr
	0,                                                      // tp_reserved
	(reprfunc)MGLTexture_tp_str,                            // tp_repr
	0,                                                      // tp_as_number
	0,                                                      // tp_as_sequence
	0,                                                      // tp_as_mapping
	0,                                                      // tp_hash
	0,                                                      // tp_call
	(reprfunc)MGLTexture_tp_str,                            // tp_str
	0,                                                      // tp_getattro
	0,                                                      // tp_setattro
	0,                                                      // tp_as_buffer
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               // tp_flags
	MGLTexture_tp_doc,                                      // tp_doc
	0,                                                      // tp_traverse
	0,                                                      // tp_clear
	0,                                                      // tp_richcompare
	0,                                                      // tp_weaklistoffset
	0,                                                      // tp_iter
	0,                                                      // tp_iternext
	MGLTexture_tp_methods,                                  // tp_methods
	0,                                                      // tp_members
	MGLTexture_tp_getseters,                                // tp_getset
	&MGLFramebufferAttachment_Type,                         // tp_base
	0,                                                      // tp_dict
	0,                                                      // tp_descr_get
	0,                                                      // tp_descr_set
	0,                                                      // tp_dictoffset
	(initproc)MGLTexture_tp_init,                           // tp_init
	0,                                                      // tp_alloc
	MGLTexture_tp_new,                                      // tp_new
};

MGLTexture * MGLTexture_New() {
	MGLTexture * self = (MGLTexture *)MGLTexture_tp_new(&MGLTexture_Type, 0, 0);
	return self;
}

void MGLTexture_Invalidate(MGLTexture * texture) {
	if (Py_TYPE(texture) == &MGLInvalidObject_Type) {

		#ifdef MGL_VERBOSE
		printf("MGLTexture_Invalidate %p already released\n", texture);
		#endif

		return;
	}

	#ifdef MGL_VERBOSE
	printf("MGLTexture_Invalidate %p\n", texture);
	#endif

	texture->context->gl.DeleteTextures(1, (GLuint *)&texture->texture_obj);

	Py_DECREF(texture->context);

	Py_TYPE(texture) = &MGLInvalidObject_Type;

	Py_DECREF(texture);
}
<|endoftext|>


<commit_before>#include "boost/filesystem.hpp"

#include <assert.h>
#include "itkCenteredSimilarity2DTransform.h"
#include "itkLBFGSBOptimizer.h"
// TEMP
#include "itkNormalizedCorrelationImageToImageMetric.h"
#include "itkMattesMutualInformationImageToImageMetric.h"
// TEMP

// my files
#include "Stack.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "StackTransforms.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "Profiling.hpp"

void checkUsage(int argc, char const *argv[]) {
  if( argc < 3 )
  {
    cerr << "\nUsage: " << endl;
    cerr << argv[0] << " dataSet outputDir (slice)\n\n";
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char const *argv[]) {
	// Verify the number of parameters in the command line
	checkUsage(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet(argv[1]);
  string outputDir(Dirs::ResultsDir() + argv[2] + "/");
  vector< string > LoResFileNames, HiResFileNames;
  if( argc >= 4)
  {
    LoResFileNames.push_back(Dirs::BlockDir() + argv[3]);
    HiResFileNames.push_back(Dirs::SliceDir() + argv[3]);
  }
  else
  {
    LoResFileNames = getFileNames(Dirs::BlockDir(), Dirs::SliceFile());
    HiResFileNames = getFileNames(Dirs::SliceDir(), Dirs::SliceFile());
  }

	// initialise stack objects
  typedef Stack< float > StackType;
  StackType::VolumeType::SpacingType LoResSpacings, HiResSpacings;
	for(unsigned int i=0; i<3; i++) {
    imageDimensions()["LoResSpacings"][i] >> LoResSpacings[i];
    imageDimensions()["HiResSpacings"][i] >> HiResSpacings[i];
  }

  StackType::SliceType::SizeType LoResSize;
  itk::Vector< double, 2 > LoResTranslation;
  for(unsigned int i=0; i<2; i++) {
    imageDimensions()["LoResSize"][i] >> LoResSize[i];
    imageDimensions()["LoResTranslation"][i] >> LoResTranslation[i];
  }

  StackType LoResStack(LoResFileNames, LoResSpacings , LoResSize);

  StackType::SliceType::SpacingType HiResOriginalSpacings;
  for(unsigned int i=0; i<2; i++) HiResOriginalSpacings[i] = HiResSpacings[i];

  StackType HiResStack(HiResFileNames, HiResOriginalSpacings,
        LoResStack.GetSpacings(), LoResStack.GetResamplerSize());

  // Assert stacks have the same number of slices
  assert(LoResStack.GetSize() == HiResStack.GetSize());

  // initialize stacks' transforms so that 2D images line up at their centres.
  StackTransforms::InitializeWithTranslation( LoResStack, LoResTranslation );
  StackTransforms::InitializeToCommonCentre( HiResStack );
  StackTransforms::SetMovingStackCORWithFixedStack( LoResStack, HiResStack );

  // Generate fixed images to register against
  if( argc < 4)
  {
    LoResStack.updateVolumes();
    writeImage< StackType::VolumeType >( LoResStack.GetVolume(), outputDir + "LoResStack.mha" );
  }

  // initialise registration framework
  typedef RegistrationBuilder< StackType > RegistrationBuilderType;
  RegistrationBuilderType registrationBuilder;
  RegistrationBuilderType::RegistrationType::Pointer registration = registrationBuilder.GetRegistration();
  StackAligner< StackType > stackAligner(LoResStack, HiResStack, registration);

  // Scale parameter space
  StackTransforms::SetOptimizerScalesForCenteredRigid2DTransform( registration->GetOptimizer() );

  // Add time and memory probes
  itkProbesCreate();

  // perform centered rigid 2D registration on each pair of slices
  itkProbesStart( "Aligning stacks" );
  stackAligner.Update();
  itkProbesStop( "Aligning stacks" );

  // Report the time and memory taken by the registration
  itkProbesReport( std::cout );

  // write rigid transforms
  if( argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResRigidStack.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack.Get3DMask()->GetImage(), outputDir + "HiResRigidMask.mha" );
  }
  StackTransforms::InitializeFromCurrentTransforms< StackType, itk::CenteredSimilarity2DTransform< double > >(HiResStack);

  // Scale parameter space
  StackTransforms::SetOptimizerScalesForCenteredSimilarity2DTransform( registration->GetOptimizer() );

  // perform similarity rigid 2D registration
  stackAligner.Update();

  // write similarity transforms
  if(argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResSimilarityStack.mha" );
  }

  // repeat registration with affine transform
  StackTransforms::InitializeFromCurrentTransforms< StackType, itk::CenteredAffineTransform< double, 2 > >(HiResStack);
  StackTransforms::SetOptimizerScalesForCenteredAffineTransform( registration->GetOptimizer() );
  stackAligner.Update();

  if(argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResAffineStack.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack.Get3DMask()->GetImage(), outputDir + "HiResAffineMask.mha" );
  }

  // Update LoRes as the masks might have shrunk
  LoResStack.updateVolumes();

  // persist mask numberOfTimesTooBig
  saveNumberOfTimesTooBig(HiResStack, outputDir + "numberOfTimesTooBig.txt");

  // Write final transforms to file
  using namespace boost::filesystem;
  string LoResTransformsDir = outputDir + "LoResTransforms";
  string HiResTransformsDir = outputDir + "HiResTransforms";
  create_directory(LoResTransformsDir);
  create_directory(HiResTransformsDir);
  Save(LoResStack, LoResTransformsDir);
  Save(HiResStack, HiResTransformsDir);

  return EXIT_SUCCESS;
}
<commit_msg>Fixed updateVolumes bug.<commit_after>#include "boost/filesystem.hpp"

#include <assert.h>
#include "itkCenteredSimilarity2DTransform.h"
#include "itkLBFGSBOptimizer.h"
// TEMP
#include "itkNormalizedCorrelationImageToImageMetric.h"
#include "itkMattesMutualInformationImageToImageMetric.h"
// TEMP

// my files
#include "Stack.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "StackTransforms.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "Profiling.hpp"

void checkUsage(int argc, char const *argv[]) {
  if( argc < 3 )
  {
    cerr << "\nUsage: " << endl;
    cerr << argv[0] << " dataSet outputDir (slice)\n\n";
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char const *argv[]) {
	// Verify the number of parameters in the command line
	checkUsage(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet(argv[1]);
  string outputDir(Dirs::ResultsDir() + argv[2] + "/");
  vector< string > LoResFileNames, HiResFileNames;
  if( argc >= 4)
  {
    LoResFileNames.push_back(Dirs::BlockDir() + argv[3]);
    HiResFileNames.push_back(Dirs::SliceDir() + argv[3]);
  }
  else
  {
    LoResFileNames = getFileNames(Dirs::BlockDir(), Dirs::SliceFile());
    HiResFileNames = getFileNames(Dirs::SliceDir(), Dirs::SliceFile());
  }

	// initialise stack objects
  typedef Stack< float > StackType;
  StackType::VolumeType::SpacingType LoResSpacings, HiResSpacings;
	for(unsigned int i=0; i<3; i++) {
    imageDimensions()["LoResSpacings"][i] >> LoResSpacings[i];
    imageDimensions()["HiResSpacings"][i] >> HiResSpacings[i];
  }

  StackType::SliceType::SizeType LoResSize;
  itk::Vector< double, 2 > LoResTranslation;
  for(unsigned int i=0; i<2; i++) {
    imageDimensions()["LoResSize"][i] >> LoResSize[i];
    imageDimensions()["LoResTranslation"][i] >> LoResTranslation[i];
  }

  StackType LoResStack(LoResFileNames, LoResSpacings , LoResSize);

  StackType::SliceType::SpacingType HiResOriginalSpacings;
  for(unsigned int i=0; i<2; i++) HiResOriginalSpacings[i] = HiResSpacings[i];

  StackType HiResStack(HiResFileNames, HiResOriginalSpacings,
        LoResStack.GetSpacings(), LoResStack.GetResamplerSize());

  // Assert stacks have the same number of slices
  assert(LoResStack.GetSize() == HiResStack.GetSize());

  // initialize stacks' transforms so that 2D images line up at their centres.
  StackTransforms::InitializeWithTranslation( LoResStack, LoResTranslation );
  StackTransforms::InitializeToCommonCentre( HiResStack );
  StackTransforms::SetMovingStackCORWithFixedStack( LoResStack, HiResStack );

  // Generate fixed images to register against
  LoResStack.updateVolumes();
  if( argc < 4)
  {
    writeImage< StackType::VolumeType >( LoResStack.GetVolume(), outputDir + "LoResStack.mha" );
  }

  // initialise registration framework
  typedef RegistrationBuilder< StackType > RegistrationBuilderType;
  RegistrationBuilderType registrationBuilder;
  RegistrationBuilderType::RegistrationType::Pointer registration = registrationBuilder.GetRegistration();
  StackAligner< StackType > stackAligner(LoResStack, HiResStack, registration);

  // Scale parameter space
  StackTransforms::SetOptimizerScalesForCenteredRigid2DTransform( registration->GetOptimizer() );

  // Add time and memory probes
  itkProbesCreate();

  // perform centered rigid 2D registration on each pair of slices
  itkProbesStart( "Aligning stacks" );
  stackAligner.Update();
  itkProbesStop( "Aligning stacks" );

  // Report the time and memory taken by the registration
  itkProbesReport( std::cout );

  // write rigid transforms
  if( argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResRigidStack.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack.Get3DMask()->GetImage(), outputDir + "HiResRigidMask.mha" );
  }
  StackTransforms::InitializeFromCurrentTransforms< StackType, itk::CenteredSimilarity2DTransform< double > >(HiResStack);

  // Scale parameter space
  StackTransforms::SetOptimizerScalesForCenteredSimilarity2DTransform( registration->GetOptimizer() );

  // perform similarity rigid 2D registration
  stackAligner.Update();

  // write similarity transforms
  if(argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResSimilarityStack.mha" );
  }

  // repeat registration with affine transform
  StackTransforms::InitializeFromCurrentTransforms< StackType, itk::CenteredAffineTransform< double, 2 > >(HiResStack);
  StackTransforms::SetOptimizerScalesForCenteredAffineTransform( registration->GetOptimizer() );
  stackAligner.Update();

  if(argc < 4)
  {
    HiResStack.updateVolumes();
    writeImage< StackType::VolumeType >( HiResStack.GetVolume(), outputDir + "HiResAffineStack.mha" );
    // writeImage< StackType::MaskVolumeType >( HiResStack.Get3DMask()->GetImage(), outputDir + "HiResAffineMask.mha" );
  }

  // Update LoRes as the masks might have shrunk
  LoResStack.updateVolumes();

  // persist mask numberOfTimesTooBig
  saveNumberOfTimesTooBig(HiResStack, outputDir + "numberOfTimesTooBig.txt");

  // Write final transforms to file
  using namespace boost::filesystem;
  string LoResTransformsDir = outputDir + "LoResTransforms";
  string HiResTransformsDir = outputDir + "HiResTransforms";
  create_directory(LoResTransformsDir);
  create_directory(HiResTransformsDir);
  Save(LoResStack, LoResTransformsDir);
  Save(HiResStack, HiResTransformsDir);

  return EXIT_SUCCESS;
}
<|endoftext|>


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

#include <pcl/console/parse.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>
#include <pcl/registration/icp_nl.h>
#include <pcl/registration/transformation_estimation_lm.h>
#include <pcl/registration/warp_point_rigid_3d.h>

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;

int
main (int argc, char **argv)
{
  double dist = 0.05;
  pcl::console::parse_argument (argc, argv, "-d", dist);

  double rans = 0.05;
  pcl::console::parse_argument (argc, argv, "-r", rans);

  int iter = 50;
  pcl::console::parse_argument (argc, argv, "-i", iter);

  std::vector<int> pcd_indices;
  pcd_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");

  CloudPtr model (new Cloud);
  if (pcl::io::loadPCDFile (argv[pcd_indices[0]], *model) == -1)
  {
    std::cout << "Could not read file" << std::endl;
    return -1;
  }
  std::cout << argv[pcd_indices[0]] << " width: " << model->width << " height: " << model->height << std::endl;

  std::string result_filename (argv[pcd_indices[0]]);
  result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
  pcl::io::savePCDFile (result_filename.c_str (), *model);
  std::cout << "saving first model to " << result_filename << std::endl;

  Eigen::Matrix4f t (Eigen::Matrix4f::Identity ());

  for (size_t i = 1; i < pcd_indices.size (); i++)
  {
    CloudPtr data (new Cloud);
    if (pcl::io::loadPCDFile (argv[pcd_indices[i]], *data) == -1)
    {
      std::cout << "Could not read file" << std::endl;
      return -1;
    }
    std::cout << argv[pcd_indices[i]] << " width: " << data->width << " height: " << data->height << std::endl;

    pcl::IterativeClosestPointNonLinear<PointType, PointType> icp;

    boost::shared_ptr<pcl::WarpPointRigid3D<PointType, PointType> > warp_fcn
      (new pcl::WarpPointRigid3D<PointType, PointType>);

    // Create a TransformationEstimationLM object, and set the warp to it
    boost::shared_ptr<pcl::registration::TransformationEstimationLM<PointType, PointType> > te (new pcl::registration::TransformationEstimationLM<PointType, PointType>);
    te->setWarpFunction (warp_fcn);

    // Pass the TransformationEstimation objec to the ICP algorithm
    icp.setTransformationEstimation (te);

    icp.setMaximumIterations (iter);
    icp.setMaxCorrespondenceDistance (dist);
    icp.setRANSACOutlierRejectionThreshold (rans);

    icp.setInputTarget (model);

    icp.setInputCloud (data);

    CloudPtr tmp (new Cloud);
    icp.align (*tmp);

    t = icp.getFinalTransformation () * t;

    pcl::transformPointCloud (*data, *tmp, t);

    std::cout << icp.getFinalTransformation () << std::endl;

    *model = *data;

    std::string result_filename (argv[pcd_indices[i]]);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *tmp);
    std::cout << "saving result to " << result_filename << std::endl;
  }

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

#include <pcl/console/parse.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>
#include <pcl/registration/icp_nl.h>
#include <pcl/registration/transformation_estimation_lm.h>
#include <pcl/registration/warp_point_rigid_3d.h>

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;

int
main (int argc, char **argv)
{
  double dist = 0.05;
  pcl::console::parse_argument (argc, argv, "-d", dist);

  double rans = 0.05;
  pcl::console::parse_argument (argc, argv, "-r", rans);

  int iter = 50;
  pcl::console::parse_argument (argc, argv, "-i", iter);

  std::vector<int> pcd_indices;
  pcd_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");

  CloudPtr model (new Cloud);
  if (pcl::io::loadPCDFile (argv[pcd_indices[0]], *model) == -1)
  {
    std::cout << "Could not read file" << std::endl;
    return -1;
  }
  std::cout << argv[pcd_indices[0]] << " width: " << model->width << " height: " << model->height << std::endl;

  std::string result_filename (argv[pcd_indices[0]]);
  result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
  pcl::io::savePCDFile (result_filename.c_str (), *model);
  std::cout << "saving first model to " << result_filename << std::endl;

  Eigen::Matrix4f t (Eigen::Matrix4f::Identity ());

  for (size_t i = 1; i < pcd_indices.size (); i++)
  {
    CloudPtr data (new Cloud);
    if (pcl::io::loadPCDFile (argv[pcd_indices[i]], *data) == -1)
    {
      std::cout << "Could not read file" << std::endl;
      return -1;
    }
    std::cout << argv[pcd_indices[i]] << " width: " << data->width << " height: " << data->height << std::endl;

    pcl::IterativeClosestPointNonLinear<PointType, PointType> icp;

    boost::shared_ptr<pcl::registration::WarpPointRigid3D<PointType, PointType> > warp_fcn
      (new pcl::registration::WarpPointRigid3D<PointType, PointType>);

    // Create a TransformationEstimationLM object, and set the warp to it
    boost::shared_ptr<pcl::registration::TransformationEstimationLM<PointType, PointType> > te (new pcl::registration::TransformationEstimationLM<PointType, PointType>);
    te->setWarpFunction (warp_fcn);

    // Pass the TransformationEstimation objec to the ICP algorithm
    icp.setTransformationEstimation (te);

    icp.setMaximumIterations (iter);
    icp.setMaxCorrespondenceDistance (dist);
    icp.setRANSACOutlierRejectionThreshold (rans);

    icp.setInputTarget (model);

    icp.setInputCloud (data);

    CloudPtr tmp (new Cloud);
    icp.align (*tmp);

    t = icp.getFinalTransformation () * t;

    pcl::transformPointCloud (*data, *tmp, t);

    std::cout << icp.getFinalTransformation () << std::endl;

    *model = *data;

    std::string result_filename (argv[pcd_indices[i]]);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *tmp);
    std::cout << "saving result to " << result_filename << std::endl;
  }

  return 0;
}
<|endoftext|>