diff --git a/app/SandboxSetup/SandboxSetup.pro b/app/SandboxSetup/SandboxSetup.pro
index f08ee3c8bb3905bd8f14c122b4665a5c5ca8d0cb..3f86910a6f30b239aa152891445650b79b04a223 100644
--- a/app/SandboxSetup/SandboxSetup.pro
+++ b/app/SandboxSetup/SandboxSetup.pro
@@ -32,7 +32,8 @@ SOURCES += \
     maskedit.cpp \
     projectiongui.cpp \
     qtfullscreen.cpp \
-    beamerlocationgui.cpp
+    beamerlocationgui.cpp \
+    mainwindow.cpp
 
 HEADERS += \
     monitorgui.h \
@@ -41,7 +42,8 @@ HEADERS += \
     maskedit.h \
     projectiongui.h \
     qtfullscreen.h \
-    beamerlocationgui.h
+    beamerlocationgui.h \
+    mainwindow.h
 
 FORMS += \
     monitorgui.ui \
@@ -49,7 +51,8 @@ FORMS += \
     croppingmask.ui \
     maskedit.ui \
     projectiongui.ui \
-    beamerlocationgui.ui
+    beamerlocationgui.ui \
+    mainwindow.ui
 
 
 
diff --git a/app/SandboxSetup/beamerlocationgui.cpp b/app/SandboxSetup/beamerlocationgui.cpp
index 122b1d21a634991ce8d30212f6e805cd95aaf129..328275b512e23b9b5b11d364963c267bac594a91 100644
--- a/app/SandboxSetup/beamerlocationgui.cpp
+++ b/app/SandboxSetup/beamerlocationgui.cpp
@@ -6,10 +6,16 @@ BeamerLocationGui::BeamerLocationGui(SandboxSetup *_setup, MonitorGui *_mg, QWid
     ui(new Ui::BeamerLocationGui)
 {
     setup = _setup;
+    beamer = setup->getBeamer();
+    camera = setup->getCamera();
+    crosses = beamer->getCrossList();
     mg = _mg;
-    QScreen *sc = mg->getScreen();
-    winFullScreen = new QtFullScreen(sc, true);
+    winFullScreen = new QtFullScreen(mg->getResolution(), true, this);
     ui->setupUi(this);
+
+    timer = new QTimer(this);
+    connect(timer, &QTimer::timeout, this, &BeamerLocationGui::routineFrame);
+
 }
 
 BeamerLocationGui::~BeamerLocationGui()
@@ -17,20 +23,98 @@ BeamerLocationGui::~BeamerLocationGui()
     delete ui;
 }
 
-void BeamerLocationGui::imshow(cv::Mat frame){
-    winFullScreen->imShow(frame);
+void BeamerLocationGui::closeEvent (QCloseEvent *e){
+    QWidget::closeEvent(e);
+    endRoutine();
 }
 
-void BeamerLocationGui::findBeamer(){
-    if(ptrShowImage == nullptr){
-        std::cout << "Null Pointer, showImage method must be specified with \"setPtrShowImage\" in BeamerLocationGui" << std::endl;
-        exit(1);
+void BeamerLocationGui::keyPressEvent(QKeyEvent *e)
+{
+    std::cout << e->text().toStdString().at(0) << std::endl;
+
+    char keyCode = (char)(e->text().toStdString().at(0));
+    if (keyCode == 'b'){
+        userValidePoint();
     }
-    endSuccessfully = (setup->setupBeamerLocation(ptrShowImage)==0);
+}
+
+void BeamerLocationGui::startRoutine(){
+
+    profil = beamer->getProfil();
+    stepCross = 0;
+    directions = std::vector<cv::Point3d>();
+    bases = std::vector<cv::Point3d>();
+    capturedPoints = std::vector<cv::Point3f>();
+    circle = std::vector<cv::Point3i>();
+
+    if(!timer->isActive())
+        timer->start(500);
+
+}
+
+void BeamerLocationGui::routineFrame(){
+
+    if(capturedPoints.size() < beamer->MAX_LINEAR_LINE_POINTS && (uint)stepCross < crosses.size()){
+
+        cv::Point2i cross = crosses.at(stepCross);
+
+        // capture frame
+        camera->captureFrame();
+        depth = camera->getDepthFrame();
+        rgb = camera->getRGBFrame();
+
+        // Look for the circle target
+        circle = beamer->findCercleZ(rgb, profil->getContrast(), profil->getBrightness(), profil->getRadiusRatio(), profil->getUpperMinThreshold(), profil->getLowerMinThreshold());
+
+        // Show black screen with cross
+        cv::Mat frameImage = beamer->getCrossFrame(cross, capturedPoints.size()+1, beamer->MAX_LINEAR_LINE_POINTS, !circle.empty());
+        cv::cvtColor(frameImage, frameImage, CV_BGR2RGB);
+        winFullScreen->imShow(frameImage);
+    }
+}
+
+
+void BeamerLocationGui::userValidePoint(){
+
+    if(!circle.empty()){
+
+        capturedPoints.push_back( beamer->deprojectPixel(circle.at(0), &depth, camera) );
+
+        // enough points to perform linear regression and move into next step
+        if(capturedPoints.size() >= beamer->MAX_LINEAR_LINE_POINTS){
+
+            beamer->findLinearLineFrom(&capturedPoints, &bases, &directions);
+            capturedPoints = std::vector<cv::Point3f>();
+            circle = std::vector<cv::Point3i>();
+            stepCross++;
+
+            if((uint)stepCross >= crosses.size()){
+                endRoutine();
+            }
+        }
+    }
+}
+
+
+void BeamerLocationGui::endRoutine(){
+
+    if(timer->isActive())
+        timer->stop();
+
+    endSuccessfully = (bases.size() == beamer->MAX_LINEAR_LINE_POINTS && directions.size() == beamer->MAX_LINEAR_LINE_POINTS);
+
+    if(endSuccessfully)
+        beamer->setPosition( (cv::Point3f)beamer->approximatePosition(&bases, &directions) );
+
     winFullScreen->close();
 }
 
-void BeamerLocationGui::showEvent(QShowEvent *e){
-    QDialog::showEvent(e);
-    findBeamer();
+
+void BeamerLocationGui::on_btnStart_clicked()
+{
+    if(!isFullScreenInit){
+        winFullScreen->setGeometry(mg->getResolution());
+    }
+    startRoutine();
+
 }
diff --git a/app/SandboxSetup/beamerlocationgui.h b/app/SandboxSetup/beamerlocationgui.h
index 4f3968e8397f951d22573d2e717776cd5c4c32b6..86e5f576e61f2e7fc5b337998ad7c995db331067 100644
--- a/app/SandboxSetup/beamerlocationgui.h
+++ b/app/SandboxSetup/beamerlocationgui.h
@@ -2,6 +2,7 @@
 #define BEAMERLOCATIONGUI_H
 
 #include <QDialog>
+#include <QTimer>
 #include <opencv2/opencv.hpp>
 #include "qtfullscreen.h"
 #include "monitorgui.h"
@@ -18,22 +19,41 @@ class BeamerLocationGui : public QDialog
 public:
     explicit BeamerLocationGui(SandboxSetup *_setup, MonitorGui *_mg, QWidget *parent = 0);
     bool endedSuccessfully(){ return endSuccessfully; };
-    void setPtrShowImageFn(ShowImageFn ptr){ ptrShowImage = ptr; };
-    void imshow(cv::Mat);
     ~BeamerLocationGui();
 
 protected:
-    void showEvent(QShowEvent *e);
+    void keyPressEvent(QKeyEvent *e);
+    void closeEvent (QCloseEvent *event);
+
+private slots:
+    void on_btnStart_clicked();
 
 private:
     Ui::BeamerLocationGui *ui;
     QtFullScreen *winFullScreen;
     SandboxSetup *setup;
+    Beamer *beamer;
+    Camera *camera;
+    FrameProcessProfil *profil;
     MonitorGui *mg;
     bool endSuccessfully = false;
-    ShowImageFn ptrShowImage = nullptr;
-
-    void findBeamer();
+    int keypressed = -1;
+    bool isFullScreenInit = false;
+    bool isWaiting = true;
+    std::vector<cv::Point2i> crosses;
+    std::vector<cv::Point3d> directions;
+    std::vector<cv::Point3d> bases;
+    std::vector<cv::Point3f> capturedPoints;
+    cv::Mat depth;
+    cv::Mat rgb;
+    std::vector<cv::Point3i> circle;
+    int stepCross = 0;
+    QTimer *timer;
+
+    void startRoutine();
+    void routineFrame();
+    void userValidePoint();
+    void endRoutine();
 };
 
 #endif // BEAMERLOCATIONGUI_H
diff --git a/app/SandboxSetup/beamerlocationgui.ui b/app/SandboxSetup/beamerlocationgui.ui
index 252fe300ab06bbf902f9b45c3dd7c39ac796a227..10a18168312a78a55b66c02dffe9a724eb2efd34 100644
--- a/app/SandboxSetup/beamerlocationgui.ui
+++ b/app/SandboxSetup/beamerlocationgui.ui
@@ -13,17 +13,17 @@
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
-  <widget class="QCheckBox" name="checkBox">
+  <widget class="QPushButton" name="btnStart">
    <property name="geometry">
     <rect>
-     <x>100</x>
-     <y>70</y>
-     <width>92</width>
-     <height>23</height>
+     <x>210</x>
+     <y>210</y>
+     <width>89</width>
+     <height>25</height>
     </rect>
    </property>
    <property name="text">
-    <string>CheckBox</string>
+    <string>Start</string>
    </property>
   </widget>
  </widget>
diff --git a/app/SandboxSetup/camerafocus.cpp b/app/SandboxSetup/camerafocus.cpp
index 7b9f6438d130d3913d8447cfbfbb32bac092479f..91b07880369497ad1d5b4276a7d2a12fa3069551 100644
--- a/app/SandboxSetup/camerafocus.cpp
+++ b/app/SandboxSetup/camerafocus.cpp
@@ -41,7 +41,7 @@ void CameraFocus::refreshFrame(){
     cv::Mat gray;
     cv::Mat rgbFromGray;
     cv::Mat rgb = setup->getCamera()->getRGBFrame();
-    std::vector<int> crc;
+    std::vector<cv::Point3i> crc;
 
     if(profil->getUpperMinThreshold() >= profil->getLowerMinThreshold()){
 
@@ -64,7 +64,7 @@ void CameraFocus::refreshFrame(){
     cv::cvtColor(gray, rgbFromGray, CV_GRAY2BGR);
 
     if(!crc.empty()){
-        cv::circle(rgbFromGray, cv::Point(crc[0], crc[1]), crc[2], cv::Scalar(0,255,0), 2);
+        cv::circle(rgbFromGray, cv::Point(crc[0].x, crc[0].y), crc[0].z, cv::Scalar(0,255,0), 2);
     }
 
     QImage img = QImage((uchar *)rgbFromGray.data, (int)rgbFromGray.cols, (int)rgbFromGray.rows, static_cast<int>(rgbFromGray.step.buf[0]), QImage::Format_RGB888);
diff --git a/app/SandboxSetup/camerafocus.ui b/app/SandboxSetup/camerafocus.ui
index 75a52d0a786b622f10ceb0a1439610d3f3c2ece3..d3babc19024bcb94c3b007645ed6ef705bd38b9c 100644
--- a/app/SandboxSetup/camerafocus.ui
+++ b/app/SandboxSetup/camerafocus.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>635</width>
+    <width>653</width>
     <height>611</height>
    </rect>
   </property>
diff --git a/app/SandboxSetup/croppingmask.cpp b/app/SandboxSetup/croppingmask.cpp
index f2baa071065f35f2adc3e4bc6a99c0f3579bc1cc..fd3124fd9e33d3dce64cf9b2536a765599c17cd8 100644
--- a/app/SandboxSetup/croppingmask.cpp
+++ b/app/SandboxSetup/croppingmask.cpp
@@ -12,8 +12,7 @@ CroppingMask::CroppingMask(SandboxSetup *sandbox, MonitorGui *_mg, QWidget *pare
     maskEdit = new MaskEdit(ui->frame->geometry());
     ui->vLayout->addWidget(maskEdit, 1);
 
-    QScreen *sc = mg->getScreen();
-    projBlueScreen = new QtFullScreen(sc, true);
+    projBlueScreen = new QtFullScreen(mg->getResolution(), true, this);
 
     // TODO : try to load cropping mask from file
 
@@ -27,10 +26,14 @@ CroppingMask::~CroppingMask()
 void CroppingMask::on_btnTakePicture_clicked()
 {
     // take picture of blue screen
-    initFullScreen();
+    if(!blueScreenInitilized){
+        blueScreenInitilized = true;
+        projBlueScreen->setGeometry(mg->getResolution());
+    }
     cv::Mat blueMat = cv::Mat(1, 1, CV_8UC3, cv::Scalar(0, 0, 255));
     projBlueScreen->imShow(blueMat);
     QTimer::singleShot(1000, this, &CroppingMask::takePicture);
+    maskUpdated = true;
 }
 
 void CroppingMask::takePicture(){
@@ -50,16 +53,6 @@ void CroppingMask::takePicture(){
     maskEdit->updateFrame(&cameraRGBFrame, &rectPoints);
 }
 
-void CroppingMask::initFullScreen(){
-
-    if(!blueScreenInitilized){
-        blueScreenInitilized = true;
-        QScreen *sc = mg->getScreen();
-        QRect res = sc->geometry();
-        projBlueScreen->setGeometry(res.x(), res.y(), res.width(), res.height());
-    }
-}
-
 bool CroppingMask::maskValideInFrame(cv::Mat *rgb){
 
     if(rectPoints.empty())
diff --git a/app/SandboxSetup/croppingmask.h b/app/SandboxSetup/croppingmask.h
index b3220c05a39897e71b1b040249004dba5d5a5fc5..e5fa0f56620f81182137732aa9b05e0fc381c39c 100644
--- a/app/SandboxSetup/croppingmask.h
+++ b/app/SandboxSetup/croppingmask.h
@@ -21,6 +21,7 @@ public:
     explicit CroppingMask(SandboxSetup *sandbox, MonitorGui *_mg, QWidget *parent = 0);
     ~CroppingMask();
     std::vector<cv::Point> getRectPoints(){ return rectPoints; };
+    bool updated(){ return maskUpdated; };
     bool isOk(){ return state; };
 
 private slots:
@@ -37,9 +38,8 @@ private:
     MonitorGui *mg;
     QtFullScreen *projBlueScreen;
     bool blueScreenInitilized = false;
+    bool maskUpdated = false;
 
-
-    void initFullScreen();
     bool maskValideInFrame(cv::Mat *rgb);
     void takePicture();
 };
diff --git a/app/SandboxSetup/main.cpp b/app/SandboxSetup/main.cpp
index fb198396aa44c0fc6f778e4b728c3accb130ef4d..067b1649fa51679fdcb2cfc2d72ae6339aade790 100644
--- a/app/SandboxSetup/main.cpp
+++ b/app/SandboxSetup/main.cpp
@@ -1,116 +1,27 @@
+
 /*
 #include <QApplication>
+#include "mainwindow.h"
 
-#include <sandboxSetup.h>
-#include "monitorgui.h"
-#include "camerafocus.h"
-#include "croppingmask.h"
-#include "projectiongui.h"
-#include "beamerlocationgui.h"
-
-int argc = 0;
-char *argv[] = {""};
-QApplication app(argc, argv);
-SandboxSetup setup;
-MonitorGui mg;
-ProjectionGui pg(&setup, &mg);
-CameraFocus cf(&setup);
-CroppingMask cm(&setup, &mg);
-BeamerLocationGui bl(&setup, &mg);
-
-
-
-void beamerLocationShowImage(cv::Mat frame){
-    bl.imshow(frame);
-}
-
-void exit_msg(SandboxSetup *setup, std::string msg){
-    setup->getCamera()->stop();
-    std::cout << msg << std::endl;
-    exit(1);
-}
-
-int main(){
-
-    // Init
-    setup.getCamera()->start();
-
-
-    // Select output screen and projection's resolutions
-    mg.show();
-    app.exec();
-    if(!mg.isOk()){
-        exit_msg(&setup, "Cancel resolution");
-    }
-    setup.getBeamer()->setResolution(cv::Size(mg.getWidth(), mg.getHeight()));
-
-
-    // Setup camera and beamer physically
-    pg.show();
-    app.exec();
-
-
-    // Edit frame process profil for the setupBeamerLocation routine
-    cf.show();
-    app.exec();
-    if(!cf.isOk()){
-        exit_msg(&setup, "Cancel camera parameters");
-    }
-
-
-    // Setup the adjust matrix and cropping mask
-    cm.show();
-    app.exec();
-    if(!cm.isOk()){
-        exit_msg(&setup, "Cancel drop");
-    }
-
-    cv::Size s = setup.getCamera()->getDepthFrame().size();
-    cv::Point center(s.width / 2, s.height / 2);
-    std::vector<cv::Point> rectPoints = cm.getRectPoints();
-
-    setup.setupAdjustMatrix(rectPoints, center);
-    setup.setupCroppingMask(rectPoints);
-
-
-    // Setup the beamer location
-    bl.setPtrShowImageFn(beamerLocationShowImage);
-    bl.show();
-    app.exec();
-    if(!bl.endedSuccessfully()){
-        exit_msg(&setup, "Cancel beamer position");
-    }
-
-    // Save config in file
-    if(setup.saveConfig()){
-        exit_msg(&setup, "Failed to save configuration");
-    }
-
-    setup.getCamera()->stop();
-    return 0;
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+    MainWindow main;
+    main.show();
+    return app.exec();
 }
 */
 
-
 #include <QApplication>
-
 #include "monitorgui.h"
 #include "camerafocus.h"
 #include "croppingmask.h"
 #include "projectiongui.h"
 #include "qtfullscreen.h"
+#include "beamerlocationgui.h"
 #include <sandboxSetup.h>
 
 
-//QScreen *sc = nullptr;
-char wname[] = "Image";
-
-void showImage(cv::Mat frame){
-    //QtFullScreen *winFullScreen = new QtFullScreen(sc, true);
-    //winFullScreen->imShow(frame);
-    cv::imshow(wname, frame);
-}
-
 void exit_msg(SandboxSetup *setup, std::string msg){
     setup->getCamera()->stop();
     std::cout << msg << std::endl;
@@ -119,13 +30,14 @@ void exit_msg(SandboxSetup *setup, std::string msg){
 
 int main(int argc, char *argv[])
 {
-
     QApplication app(argc, argv);
+
     SandboxSetup setup;
     MonitorGui mg;
     ProjectionGui pg(&setup, &mg);
     CameraFocus cf(&setup);
     CroppingMask cm(&setup, &mg);
+    BeamerLocationGui bl(&setup, &mg);
 
     setup.getCamera()->start();
 
@@ -137,7 +49,7 @@ int main(int argc, char *argv[])
         exit_msg(&setup, "Cancel resolution");
     }
     setup.getBeamer()->setResolution(cv::Size(mg.getWidth(), mg.getHeight()));
-    //sc = mg.getScreen();
+
 
     // Setup camera and beamer physically
     pg.show();
@@ -158,24 +70,21 @@ int main(int argc, char *argv[])
     if(!cm.isOk()){
         exit_msg(&setup, "Cancel drop");
     }
+    if(cm.updated()){
+        cv::Size s = setup.getCamera()->getDepthFrame().size();
+        cv::Point center(s.width / 2, s.height / 2);
+        std::vector<cv::Point> rectPoints = cm.getRectPoints();
 
-    cv::Size s = setup.getCamera()->getDepthFrame().size();
-    cv::Point center(s.width / 2, s.height / 2);
-    std::vector<cv::Point> rectPoints = cm.getRectPoints();
-
-    setup.setupAdjustMatrix(rectPoints, center);
-    setup.setupCroppingMask(rectPoints);
-
+        setup.setupAdjustMatrix(rectPoints, center);
+        setup.setupCroppingMask(rectPoints);
+    }
 
     // Setup the beamer location
-    cv::namedWindow(wname, CV_WINDOW_NORMAL);
-    cv::setWindowProperty(wname, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
-
-    if(setup.setupBeamerLocation(showImage)){
+    bl.show();
+    app.exec();
+    if(!bl.endedSuccessfully()){
         exit_msg(&setup, "Cancel beamer position");
     }
-    cv::destroyAllWindows();
-
 
     // Save config in file
     if(setup.saveConfig()){
@@ -184,5 +93,6 @@ int main(int argc, char *argv[])
 
     setup.getCamera()->stop();
     return 0;
-}
 
+
+}
diff --git a/app/SandboxSetup/mainwindow.cpp b/app/SandboxSetup/mainwindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..49f9a781dca7dd1b9d703d4518072d4e9c286f62
--- /dev/null
+++ b/app/SandboxSetup/mainwindow.cpp
@@ -0,0 +1,163 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent) :
+    QMainWindow(parent),
+    ui(new Ui::MainWindow)
+{
+    ui->setupUi(this);
+    ui->apps->setGeometry(QRect(0, 0, 670, 630));
+    ui->btnPrev->setVisible(false);
+    ui->btnNext->setEnabled(false);
+
+    setup = new SandboxSetup;
+    mg = new MonitorGui(this);
+    pg = new ProjectionGui(setup, mg, this);
+    cf = new CameraFocus(setup, this);
+    cm = new CroppingMask(setup, mg, this);
+    bl = new BeamerLocationGui(setup, mg, this);
+
+    applist.push_back(mg);
+    applist.push_back(pg);
+    applist.push_back(cf);
+    applist.push_back(cm);
+    applist.push_back(bl);
+/*
+    checkapplist.push_back(checkResolution);
+    checkapplist.push_back(checkProj);
+    checkapplist.push_back(checkProcessProfil);
+    checkapplist.push_back(checkCroppingMask);
+    checkapplist.push_back(checkBeamerLocation);
+    */
+}
+
+MainWindow::~MainWindow()
+{
+    delete ui;
+}
+
+void MainWindow::showEvent(QShowEvent *event){
+    QWidget::showEvent(event);
+    QTimer::singleShot(0, this, &MainWindow::initCamera);
+}
+
+void MainWindow::exit_msg(std::string msg){
+    setup->getCamera()->stop();
+    std::cout << msg << std::endl;
+    exit(1);
+}
+
+
+//
+//  STEPS
+//
+
+void MainWindow::closeApp(){
+    applist.at(step)->close();
+    if(ui->apps->count() > 0){
+        ui->apps->removeWidget(applist.at(step));
+    }
+}
+
+void MainWindow::loadApp(){
+    ui->apps->addWidget(applist.at(step));
+    applist.at(step)->show();
+}
+
+bool MainWindow::verifyApp(){
+    return true;//checkapplist.at(step)();
+}
+
+void MainWindow::nextApp(){
+    if(verifyApp()){
+        closeApp();
+        step++;
+        loadApp();
+    }else{
+        exit_msg("Failed setup at step : " + step);
+    }
+}
+
+void MainWindow::prevApp(){
+    if(step > 0){
+        closeApp();
+        step--;
+        loadApp();
+    }
+}
+
+void MainWindow::initCamera(){
+
+    std::cout << "init camera" << std::endl;
+    setup->getCamera()->start();
+    std::cout << "camera ready" << std::endl;
+    ui->btnNext->setEnabled(true);
+    loadApp();
+}
+
+void MainWindow::finishConfig(){
+    // Save config in file
+    if(setup->saveConfig()){
+        exit_msg("Failed to save configuration");
+    }
+
+    setup->getCamera()->stop();
+}
+
+bool MainWindow::checkResolution(){
+    if(!mg->isOk()){
+        //exit_msg("Cancel resolution");
+        return false;
+    }
+    setup->getBeamer()->setResolution(cv::Size(mg->getWidth(), mg->getHeight()));
+    return true;
+}
+
+bool MainWindow::checkProj(){ return true; }
+
+bool MainWindow::checkProcessProfil(){
+    if(!cf->isOk()){
+        //exit_msg("Cancel camera parameters");
+        return false;
+    }
+    return true;
+}
+
+bool MainWindow::checkCroppingMask(){
+    if(!cm->isOk()){
+        //exit_msg("Cancel drop");
+        return false;
+    }
+    if(cm->updated()){
+        cv::Size s = setup->getCamera()->getDepthFrame().size();
+        cv::Point center(s.width / 2, s.height / 2);
+        std::vector<cv::Point> rectPoints = cm->getRectPoints();
+
+        setup->setupAdjustMatrix(rectPoints, center);
+        setup->setupCroppingMask(rectPoints);
+    }
+    return true;
+}
+
+bool MainWindow::checkBeamerLocation(){
+    if(!bl->endedSuccessfully()){
+        //exit_msg("Cancel beamer position");
+        return false;
+    }
+    return true;
+}
+
+
+void MainWindow::on_btnNext_clicked()
+{
+    if(step == 0)
+        ui->btnPrev->setVisible(true);
+    nextApp();
+}
+
+void MainWindow::on_btnPrev_clicked()
+{
+    if(step == 0)
+        ui->btnPrev->setVisible(false);
+    prevApp();
+}
diff --git a/app/SandboxSetup/mainwindow.h b/app/SandboxSetup/mainwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8a78e790b33bef9c89969846488541cd748fcbe
--- /dev/null
+++ b/app/SandboxSetup/mainwindow.h
@@ -0,0 +1,65 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include "monitorgui.h"
+#include "camerafocus.h"
+#include "croppingmask.h"
+#include "projectiongui.h"
+#include "qtfullscreen.h"
+#include "beamerlocationgui.h"
+#include <sandboxSetup.h>
+
+#include <QTimer>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    explicit MainWindow(QWidget *parent = 0);
+    ~MainWindow();
+
+private slots:
+    void on_btnNext_clicked();
+
+    void on_btnPrev_clicked();
+
+protected:
+    void showEvent(QShowEvent *event);
+
+private:
+    Ui::MainWindow *ui;
+    SandboxSetup *setup;
+    MonitorGui *mg;
+    ProjectionGui *pg;
+    CameraFocus *cf;
+    CroppingMask *cm;
+    BeamerLocationGui *bl;
+    int step = 0;
+    std::vector<QWidget*> applist;
+    std::vector<bool(MainWindow::*)()> checkapplist;
+
+    void loadApp();
+    void closeApp();
+    bool verifyApp();
+    void nextApp();
+    void prevApp();
+
+    void initCamera();
+    void finishConfig();
+
+    bool checkResolution();
+    bool checkProj();
+    bool checkProcessProfil();
+    bool checkCroppingMask();
+    bool checkBeamerLocation();
+
+    void exit_msg(std::string msg);
+};
+
+#endif // MAINWINDOW_H
diff --git a/app/SandboxSetup/mainwindow.ui b/app/SandboxSetup/mainwindow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..295c9f5a36f0b2f44b9ca4627bf2b6f86ed94ded
--- /dev/null
+++ b/app/SandboxSetup/mainwindow.ui
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="focusPolicy">
+   <enum>Qt::StrongFocus</enum>
+  </property>
+  <property name="windowTitle">
+   <string>Sandbox setup</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QWidget" name="verticalLayoutWidget">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>0</y>
+      <width>160</width>
+      <height>80</height>
+     </rect>
+    </property>
+    <layout class="QVBoxLayout" name="apps"/>
+   </widget>
+   <widget class="QPushButton" name="btnNext">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>650</x>
+      <y>530</y>
+      <width>89</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Next</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="btnPrev">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>530</x>
+      <y>530</y>
+      <width>89</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Previous</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/app/SandboxSetup/monitorgui.cpp b/app/SandboxSetup/monitorgui.cpp
index 51ccf34e81c970a588bec1706990492e0c88af49..aa28da2499bfd7809f35a4942d28f6f4fabca2c1 100644
--- a/app/SandboxSetup/monitorgui.cpp
+++ b/app/SandboxSetup/monitorgui.cpp
@@ -6,6 +6,7 @@ MonitorGui::MonitorGui(QWidget *parent) :
     ui(new Ui::MonitorGui)
 {
     ui->setupUi(this);
+    resolution = new QRect;
 
     std::string path = ".monitors.tmp";
     monitors = std::map<std::string, std::vector<std::string>>();
@@ -27,7 +28,7 @@ MonitorGui::~MonitorGui()
     delete ui;
 }
 
-QScreen* MonitorGui::getScreen(){
+QScreen* MonitorGui::getMonitor(){
 
     QScreen *sc = QApplication::screens().at(0);
     QList<QScreen *> lst = sc->virtualSiblings();
@@ -58,6 +59,12 @@ void MonitorGui::on_btnbxMonitors_accepted()
     std::vector<std::string> res = splitResolution(selectedRes.toStdString());
     width = std::stoi(res[0]);
     height = std::stoi(res[1]);
+
+    QScreen *sc = getMonitor();
+    resolution->setX(sc->geometry().x());
+    resolution->setY(sc->geometry().y());
+    resolution->setWidth(width);
+    resolution->setHeight(height);
 }
 
 
diff --git a/app/SandboxSetup/monitorgui.h b/app/SandboxSetup/monitorgui.h
index 6b1b40763995f7b939a5e094ba1c80e985d97b87..7eedcdf6aedc5fa7afa677f55b558a3a29caf5de 100644
--- a/app/SandboxSetup/monitorgui.h
+++ b/app/SandboxSetup/monitorgui.h
@@ -26,7 +26,7 @@ public:
     int getHeight(){ return height; };
     int getWidth(){ return width; };
     std::string getOutput(){ return outputName.toStdString(); };
-    QScreen* getScreen();
+    QRect getResolution(){ return *resolution; }
 
     bool isOk(){ return valideState; };
 
@@ -42,8 +42,9 @@ private:
     int height = 0;
     int width = 0;
     QString outputName = "";
+    QRect *resolution;
 
-
+    QScreen* getMonitor();
     void loadResolutionsOf(QScreen* screen);
     std::vector<std::string> splitResolution(std::string s);
     bool isResolution(std::string s);
diff --git a/app/SandboxSetup/projectiongui.cpp b/app/SandboxSetup/projectiongui.cpp
index bc39af1b93f99b615cdab45400496bf6bf27c660..d8730873b0eda2890ccfb402f7dd5af8f4ebfd46 100644
--- a/app/SandboxSetup/projectiongui.cpp
+++ b/app/SandboxSetup/projectiongui.cpp
@@ -30,10 +30,10 @@ void ProjectionGui::on_btnSkip_clicked()
 // Note : Screens should be in extented mode, not mirror (to avoid loop noise from the capture of the screen)
 void ProjectionGui::on_btnStart_clicked()
 {
-    QScreen *sc = mg->getScreen();
+    QRect reso = mg->getResolution();
     // open blue screen on the selected output
     cv::Mat blue = cv::Mat(1, 1, CV_8UC3, cv::Scalar(0, 0, 255));
-    blueScreen = new QtFullScreen(sc, true);
+    blueScreen = new QtFullScreen(reso, true);
     blueScreen->imShow(blue);
 
     cameraUsed = true;
diff --git a/app/SandboxSetup/qtfullscreen.cpp b/app/SandboxSetup/qtfullscreen.cpp
index 47b8b0bdb5aa2fe3c7fa93ee971cdf758a021e6e..3213a0c1083450ae4d74b4e58e5cbb78be0c851d 100644
--- a/app/SandboxSetup/qtfullscreen.cpp
+++ b/app/SandboxSetup/qtfullscreen.cpp
@@ -1,18 +1,30 @@
 #include "qtfullscreen.h"
 
-QtFullScreen::QtFullScreen(QScreen *_sc, bool isBorderless, QWidget *parent) : QWidget(parent)
+QtFullScreen::QtFullScreen(QRect _resolution, bool _isBorderless, QWidget *parent) : QWidget(parent)
 {
+    p = parent;
     win = new QDialog;
-    screen = _sc;
-    win->setGeometry(screen->geometry());
-    if(isBorderless)
-        win->setWindowState(Qt::WindowFullScreen);
+    resolution = &_resolution;
+    isBorderless = _isBorderless;
+    win->setGeometry(*resolution);
 
     image = new QLabel(win);
     image->setGeometry(0, 0 , win->geometry().width(), win->geometry().height());
     image->setScaledContents(true);
 }
 
+void QtFullScreen::showEvent(QShowEvent* event){
+
+    QWidget::showEvent( event );
+    if(p != nullptr)
+        p->setFocus();
+}
+
+void QtFullScreen::setGeometry(QRect reso){
+    setGeometry(reso.x(), reso.y(), reso.width(), reso.height());
+}
+
+
 void QtFullScreen::setGeometry(int x, int y, int w, int h){
     win->setGeometry(x, y, w, h);
     image->setGeometry(0 , 0, w, h);
@@ -24,6 +36,9 @@ void QtFullScreen::imShow(cv::Mat frame){
     QPixmap px = QPixmap::fromImage(src);
     image->setPixmap(px);
 
+    if(isBorderless && !win->windowState().testFlag(Qt::WindowFullScreen))
+        win->setWindowState(Qt::WindowFullScreen);
+
     if(!win->isVisible())
         win->show();
 }
diff --git a/app/SandboxSetup/qtfullscreen.h b/app/SandboxSetup/qtfullscreen.h
index c09a3fe7386076f2d3aa44877b762e6d12c393ee..1a2a8252c44b3aa99e666b54d154157afbc36cbd 100644
--- a/app/SandboxSetup/qtfullscreen.h
+++ b/app/SandboxSetup/qtfullscreen.h
@@ -11,19 +11,26 @@ class QtFullScreen : public QWidget
 {
     Q_OBJECT
 public:
-    explicit QtFullScreen(QScreen *sc, bool isBorderless=false, QWidget *parent = nullptr);
+    explicit QtFullScreen(QRect resolution, bool isBorderless=false, QWidget *parent = nullptr);
     void imShow(cv::Mat frame);
     void close();
+    void setGeometry(QRect resolution);
     void setGeometry(int x, int y, int w, int h);
 
 signals:
 
 public slots:
 
+protected:
+    void showEvent(QShowEvent* event);
+
 private:
     QDialog *win;
     QLabel *image;
     QScreen *screen;
+    QRect *resolution;
+    QWidget *p;
+    bool isBorderless = false;
 };
 
 #endif // QTFULLSCREEN_H
diff --git a/inc/beamer.h b/inc/beamer.h
index 83fb6d311a9337cf8b5224574d16a592fad1e51e..15196d800d4b3d90b24c8f047edc5a5c3cd9d2de 100644
--- a/inc/beamer.h
+++ b/inc/beamer.h
@@ -3,9 +3,6 @@
 #include <opencv2/opencv.hpp>
 #include "camera.h"
 
-#define ESCAPE_CHAR 27
-
-typedef void (*ShowImageFn)(cv::Mat);
 
 class FrameProcessProfil{
     private:
@@ -46,11 +43,14 @@ class Beamer{
         FrameProcessProfil profil = FrameProcessProfil();
 
         cv::Point3f intersection(cv::Vec3f v1, cv::Point3f p1, cv::Vec3f v2, cv::Point3f p2, cv::Vec3f v3, cv::Point3f p3, bool &isFound);
-        cv::Point3d approximatePosition(std::vector<cv::Point3d> points1, std::vector<cv::Point3d> points2);
-
+        
     public:
         Beamer();
 
+        const char ESCAPE_CHAR = 27;
+        const unsigned int MAX_LINEAR_LINE_POINTS = 3; //number of point to calculate 1 vector
+        const double LINEAR_REGRESSION_FACT = -20.0; // used for linear regression
+
         cv::Point3f getPosition(){ return beamerPosition; };
         void setPosition(cv::Point3f pos){ beamerPosition = pos; };
         
@@ -66,9 +66,14 @@ class Beamer{
         FrameProcessProfil* getProfil(){ return &profil; };
         void setProfil(FrameProcessProfil p){ profil = p; };
 
-        int findBeamerFrom(Camera camera, void (*showImage)(cv::Mat));
+        int findBeamerFrom(Camera *camera);
         cv::Mat editContrast(cv::Mat image, double contrast, int brightness);
-        std::vector<int> findCercleZ(cv::Mat &rgb, double contrast, int brightness, int ratioRadius, int upperMinThreshold, int lowerMinThreshold);
+        cv::Point3f deprojectPixel(cv::Point3i circle, cv::Mat *depth, Camera *camera);
+        std::vector<cv::Point2i> getCrossList();
+        cv::Mat getCrossFrame(cv::Point2i projectedCross, int step, int max, bool circlesFound);
+        cv::Point3d approximatePosition(std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions);
+        void findLinearLineFrom(std::vector<cv::Point3f> *capturedPoints, std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions);
+        std::vector<cv::Point3i> findCercleZ(cv::Mat &rgb, double contrast, int brightness, int ratioRadius, int upperMinThreshold, int lowerMinThreshold);
         void printPosition();
         
 };
diff --git a/inc/borderedit.h b/inc/borderedit.h
index dc996005e52a7d0cba973194597e897c0bd28602..15a2796e1a5920f42523ec2f048dd319574ac096 100644
--- a/inc/borderedit.h
+++ b/inc/borderedit.h
@@ -3,8 +3,6 @@
 
 #include <opencv2/opencv.hpp>
 
-#define ESCAPE_CHAR 27
-
 class BorderEdit{
     private:
         static const int margeClick = 10;
@@ -15,6 +13,7 @@ class BorderEdit{
         static void drawSquare(cv::Point *p, int n);
         static int findPoints(int x, int y, std::vector<cv::Point> &posSandbox);
         static void mouseHandler(int event, int x, int y, int, void *param);
+        static const char ESCAPE_CHAR = 27;
 
     public:
         static int edit(cv::Mat frame, std::vector<cv::Point> *posSandbox);
diff --git a/inc/sandboxSetup.h b/inc/sandboxSetup.h
index cf34f7c99d67f242907435f9672910d3b3b03712..3460544e1c43b9d4a13c2783ee63570c04ec30db 100644
--- a/inc/sandboxSetup.h
+++ b/inc/sandboxSetup.h
@@ -33,12 +33,13 @@ class SandboxSetup{
         int loadFrameProcessProfil();
 
         // edit variables of config => not persistant
-        void captureBlueScreen(int delay);
         void setupAdjustMatrix(std::vector<cv::Point> rectPoints, cv::Point center);
         void setupCroppingMask(std::vector<cv::Point> rectPoints);
-        int setupProjection();
-        int setupBeamerResolution();
-        int setupBeamerLocation(void (*showImage)(cv::Mat));
+        
+        void defaultCaptureBlueScreen(int delay);
+        int defaultSetupProjection();
+        int defaultSetupBeamerResolution();
+        int defaultSetupBeamerLocation();
 
 };
 
diff --git a/src/components/beamer.cpp b/src/components/beamer.cpp
index b6aaf36badd02af7fdbc01f4fbfc1710b756f4d8..666b1c1f4411804c30026807f947b33d48fd1ff7 100644
--- a/src/components/beamer.cpp
+++ b/src/components/beamer.cpp
@@ -13,83 +13,111 @@ Beamer::Beamer(){
 */
 
 
-int Beamer::findBeamerFrom(Camera camera, ShowImageFn imshow)
-{
-    cv::Mat depth;
-    cv::Mat rgb;
-    cv::Mat frameImage(resolution, CV_8UC3, cv::Scalar(0, 0, 0));
+int Beamer::findBeamerFrom(Camera *camera){
 
-    unsigned int nbPoint = 3; //number of point to calculate 1 vector
-    std::vector<cv::Point3d> directions;  //vectors calculate for each point
-    std::vector<cv::Point3d> bases;  //1 point for each vector (to calculate constante d)
-    double fact = -20.0;
+    char wname[] = "beamer location";
+    cv::namedWindow(wname, CV_WINDOW_NORMAL);
+    cv::setWindowProperty(wname, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
 
     // Setup cross for calibration
-    std::vector<cv::Point> points;
-    points.push_back( cv::Point( getWidth() * 5/14, getHeight() * 5/14));
-    points.push_back( cv::Point( getWidth() * 5/7 , getHeight() * 3/14));
-    points.push_back( cv::Point( getWidth() * 3/14, getHeight() * 4/7 ));
+    std::vector<cv::Point2i> crosses = getCrossList();
+    std::vector<cv::Point3d> directions;  //vectors calculate for each point
+    std::vector<cv::Point3d> bases;  //1 point for each vector (to calculate constante d)
 
-    for (int i = 0; i < (int)points.size(); i++)
-    {
-        std::vector<cv::Point3f> capturedPoints;
-        cv::Point projCross = points[i];
+    for (cv::Point2i cross : crosses){ 
         
-        while (capturedPoints.size() < nbPoint){
+        std::vector<cv::Point3f> capturedPoints;
+        cv::Mat depth;
+        cv::Mat rgb;
+
+        while( capturedPoints.size() < MAX_LINEAR_LINE_POINTS ){
 
             // capture frame
-            camera.captureFrame();
-            depth = camera.getDepthFrame();
-            rgb = camera.getRGBFrame();
+            camera->captureFrame();
+            depth = camera->getDepthFrame();
+            rgb = camera->getRGBFrame();
 
             // Look for the circle target
-            std::vector<int> crc = findCercleZ(rgb, profil.getContrast(), profil.getBrightness(), profil.getRadiusRatio(), profil.getUpperMinThreshold(), profil.getLowerMinThreshold());
-            cv::Scalar color = (!crc.empty()) ? cv::Scalar(0, 255, 0) : cv::Scalar(0, 0, 255);
+            std::vector<cv::Point3i> circle = findCercleZ(rgb, profil.getContrast(), profil.getBrightness(), profil.getRadiusRatio(), profil.getUpperMinThreshold(), profil.getLowerMinThreshold());
             
             // Show black screen with cross
-            cv::line(frameImage, cv::Point(projCross.x, 0), cv::Point(projCross.x, frameImage.rows - 1), color, 4);
-            cv::line(frameImage, cv::Point(0, projCross.y), cv::Point(frameImage.cols - 1, projCross.y), color, 4);
-            cv::putText( frameImage,
-                         std::to_string(capturedPoints.size() + 1) + "/" + std::to_string(nbPoint),
-                         cv::Point( getWidth()/2, getHeight()/2 ),
-                         cv::FONT_HERSHEY_SIMPLEX,
-                         1,
-                         cv::Scalar(255, 255, 255));
-            imshow(frameImage);
+            cv::Mat frameImage = getCrossFrame(cross, capturedPoints.size()+1, MAX_LINEAR_LINE_POINTS, !circle.empty());
+            
+            cv::imshow(wname, frameImage);
 
             // Wait for interaction
-            char keyCode = cv::waitKey(500);
-            if (keyCode == ESCAPE_CHAR){
-                return 1;
-            }
-            else if (keyCode == ' ' && !crc.empty()){
-                // Point validate
-                float coord[2] = {(float)crc[0], (float)crc[1]};
-                float z = static_cast<float>(depth.at<uint16_t>(crc[1], crc[0]));
-                cv::Point3f p = camera.deprojectPixelToPoint(coord, z / 1000.0);
-                capturedPoints.push_back(p);
+            int keypressed = cv::waitKey(500);
+            if(keypressed != -1){
+                char keyCode = (char)keypressed;
+                if (keyCode == ESCAPE_CHAR){
+                    return 1;
+                }
+                else if (keyCode == ' '){
+                    if(!circle.empty()){
+                        capturedPoints.push_back( deprojectPixel(circle.at(0), &depth, camera) );
+                    }
+                }
             }
-            
-            // clear frame
-            frameImage.setTo(cv::Scalar(0, 0, 0));
         }
 
-        cv::Vec6f line;
-        cv::fitLine(capturedPoints, line, CV_DIST_L2, 0, 0.01, 0.01);
-        directions.push_back(cv::Point3d(line[3] * fact, line[4] * fact, line[5] * fact));
-        bases.push_back(cv::Point3d(line[0], line[1], line[2]));
+        findLinearLineFrom(&capturedPoints, &bases, &directions);
     }
 
-    cv::Point3d beamerPoint = approximatePosition(directions, bases);
 
-    //set beamer position
-    beamerPosition.x = (float)beamerPoint.x;
-    beamerPosition.y = (float)beamerPoint.y;
-    beamerPosition.z = (float)beamerPoint.z;
+    setPosition( (cv::Point3f)approximatePosition(&bases, &directions) );
+
+    cv::destroyAllWindows();
 
     return 0;
 }
 
+cv::Point3f Beamer::deprojectPixel(cv::Point3i circle, cv::Mat *depth, Camera *camera){
+    float coord[2] = {(float)circle.x, (float)circle.y};
+    float z = static_cast<float>(depth->at<uint16_t>(circle.y, circle.x));
+    return camera->deprojectPixelToPoint(coord, z / 1000.0);
+}
+
+void Beamer::findLinearLineFrom(std::vector<cv::Point3f> *capturedPoints, std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions){
+    
+    cv::Vec6f line;
+    cv::fitLine(*capturedPoints, line, CV_DIST_L2, 0, 0.01, 0.01);
+
+    cv::Point3d base = cv::Point3d(line[0], line[1], line[2]);
+    cv::Point3d direction = cv::Point3d( LINEAR_REGRESSION_FACT * line[3],
+                                         LINEAR_REGRESSION_FACT * line[4],
+                                         LINEAR_REGRESSION_FACT * line[5] );
+    
+    bases->push_back(base);
+    directions->push_back(direction);
+}
+
+std::vector<cv::Point2i> Beamer::getCrossList(){
+
+    std::vector<cv::Point2i> points;
+
+    points.push_back( cv::Point( getWidth() * 5/14, getHeight() * 5/14));
+    points.push_back( cv::Point( getWidth() * 5/7 , getHeight() * 3/14));
+    points.push_back( cv::Point( getWidth() * 3/14, getHeight() * 4/7 ));
+
+    return points;
+}
+
+
+cv::Mat Beamer::getCrossFrame(cv::Point projectedCross, int step, int max, bool circlesFound){
+
+    cv::Mat frameImage(resolution, CV_8UC3, cv::Scalar(0, 0, 0));
+    cv::Scalar color = (circlesFound) ? cv::Scalar(0, 255, 0) : cv::Scalar(0, 0, 255);
+
+    cv::line(frameImage, cv::Point(projectedCross.x, 0), cv::Point(projectedCross.x, frameImage.rows - 1), color, 4);
+    cv::line(frameImage, cv::Point(0, projectedCross.y), cv::Point(frameImage.cols - 1, projectedCross.y), color, 4);
+    cv::putText( frameImage,
+                 std::to_string(step) + "/" + std::to_string(max),
+                 cv::Point( getWidth()/2, getHeight()/2 ),
+                 cv::FONT_HERSHEY_SIMPLEX,
+                 1,
+                 cv::Scalar(255, 255, 255));
+    return frameImage;
+}
 
 void Beamer::printPosition(){
     cv::Point3f pos = getPosition();
@@ -181,7 +209,7 @@ cv::Mat Beamer::editContrast(cv::Mat image, double contrast, int brightness){
     return new_image;
 }
 
-std::vector<int> Beamer::findCercleZ(cv::Mat &rgb, double contrast, int brightness, int ratioRadius, int upperMinThreshold, int lowerMinThreshold)
+std::vector<cv::Point3i> Beamer::findCercleZ(cv::Mat &rgb, double contrast, int brightness, int ratioRadius, int upperMinThreshold, int lowerMinThreshold)
 {
     cv::Mat src_gray;
     cv::cvtColor(rgb, src_gray, CV_BGR2GRAY);
@@ -199,33 +227,33 @@ std::vector<int> Beamer::findCercleZ(cv::Mat &rgb, double contrast, int brightne
     cv::HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, minRadius, (double)upperMinThreshold, (double)lowerMinThreshold, 0, 0);
     //doit tester si le cercle est bon (rayon);
 
-    std::vector<int> result;
+    std::vector<cv::Point3i> result;
     if (!circles.empty())
     {
-        for (int i = 0; i < 3; i++)
-        {
-            result.push_back(round(circles[0][i]));
-        }
+        cv::Vec3f first = circles[0];
+        result.push_back( cv::Point3i(round(first[0]), round(first[1]), round(first[2])) );
     }
     return result;
 }
 
 
-cv::Point3d Beamer::approximatePosition(std::vector<cv::Point3d> directions, std::vector<cv::Point3d> bases){
+cv::Point3d Beamer::approximatePosition(std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions){
 
     cv::Point3d pa, pb;
     double mua;
     double mub;
     std::vector<cv::Point3d> beamerPoints;
-    LineLineIntersect(directions[0], bases[0], directions[1], bases[1], &pa, &pb, &mua, &mub);
-    beamerPoints.push_back(pa);
-    beamerPoints.push_back(pb);
-    LineLineIntersect(directions[0], bases[0], directions[2], bases[2], &pa, &pb, &mua, &mub);
-    beamerPoints.push_back(pa);
-    beamerPoints.push_back(pb);
-    LineLineIntersect(directions[1], bases[1], directions[2], bases[2], &pa, &pb, &mua, &mub);
-    beamerPoints.push_back(pa);
-    beamerPoints.push_back(pb);
+    int selected[3][2] = { {0,1}, {0,2}, {1,2} };
+
+    for(int i=0; i < 3; i++){
+        LineLineIntersect( directions->at(selected[i][0]),
+                           bases->at(selected[i][0]),
+                           directions->at(selected[i][1]), 
+                           bases->at(selected[i][1]), 
+                           &pa, &pb, &mua, &mub);
+        beamerPoints.push_back(pa);
+        beamerPoints.push_back(pb);
+    }
 
     cv::Point3d beamerPoint(0.0, 0.0, 0.0);
     for (unsigned int i = 0; i < beamerPoints.size(); i++)
diff --git a/src/lib/sandboxSetup.cpp b/src/lib/sandboxSetup.cpp
index ed72f4cb94432887ccab6fc3973e43621abc6e75..246c8258de8c07a17be57839c45cc083d563e603 100644
--- a/src/lib/sandboxSetup.cpp
+++ b/src/lib/sandboxSetup.cpp
@@ -5,6 +5,10 @@ SandboxSetup::SandboxSetup(){
     
 }
 
+//
+//  PUBLIC
+//
+
 
 // return 1 when config can't be saved in file
 int SandboxSetup::saveConfigFrom(char *path){
@@ -36,12 +40,31 @@ int SandboxSetup::loadFrameProcessProfil(){
 }
 
 
+void SandboxSetup::setupAdjustMatrix(std::vector<cv::Point> rectPoints, cv::Point center){
+
+    // Set adjusting matrix for the projection
+    int widthTop = rectPoints[3].x - rectPoints[0].x;
+    double angle1 = atan((double)(rectPoints[3].y - rectPoints[0].y) / widthTop);
+    cv::Mat matRotation = cv::getRotationMatrix2D(center, toDegrees(angle1), 1); // adjustingMatrix
+    projection.setAdjustingMatrix(matRotation);
+}
+
+void SandboxSetup::setupCroppingMask(std::vector<cv::Point> rectPoints){
+
+    // Set cropping mask
+    int widthTop = rectPoints[3].x - rectPoints[0].x;
+    cv::Size rectSize = cv::Size(widthTop, cvRound(widthTop / 1.33333) + 5);
+    cv::Point p = projection.rotatePixel(rectPoints[0]);
+    camera.setCroppingMask(cv::Rect(p, rectSize)); // croppingMask
+}
+
+
 
 //
 // Default setup routines
 //
 
-int SandboxSetup::setupBeamerResolution(){
+int SandboxSetup::defaultSetupBeamerResolution(){
     int width = 0;
     int height = 0;
 
@@ -64,16 +87,16 @@ int SandboxSetup::setupBeamerResolution(){
 
 
 // return 1 when user exits process
-int SandboxSetup::setupBeamerLocation(void (*showImage)(cv::Mat)){
+int SandboxSetup::defaultSetupBeamerLocation(){
 
-    return beamer.findBeamerFrom(camera, showImage);
+    return beamer.findBeamerFrom(&camera);
 }
 
 
 // return 1 when user exits process
-int SandboxSetup::setupProjection(){
+int SandboxSetup::defaultSetupProjection(){
 
-    captureBlueScreen(300);
+    defaultCaptureBlueScreen(300);
 
     cv::Mat frameData = camera.getDepthFrame();
     cv::Mat coloredFrame = camera.getRGBFrame();
@@ -99,7 +122,7 @@ int SandboxSetup::setupProjection(){
 }
 
 
-void SandboxSetup::captureBlueScreen(int delay){
+void SandboxSetup::defaultCaptureBlueScreen(int delay){
     
     // Blue screen 
     char windowName[] = "BlueScreen";
@@ -115,23 +138,10 @@ void SandboxSetup::captureBlueScreen(int delay){
 }
 
 
-void SandboxSetup::setupAdjustMatrix(std::vector<cv::Point> rectPoints, cv::Point center){
-
-    // Set adjusting matrix for the projection
-    int widthTop = rectPoints[3].x - rectPoints[0].x;
-    double angle1 = atan((double)(rectPoints[3].y - rectPoints[0].y) / widthTop);
-    cv::Mat matRotation = cv::getRotationMatrix2D(center, toDegrees(angle1), 1); // adjustingMatrix
-    projection.setAdjustingMatrix(matRotation);
-}
-
-void SandboxSetup::setupCroppingMask(std::vector<cv::Point> rectPoints){
 
-    // Set cropping mask
-    int widthTop = rectPoints[3].x - rectPoints[0].x;
-    cv::Size rectSize = cv::Size(widthTop, cvRound(widthTop / 1.33333) + 5);
-    cv::Point p = projection.rotatePixel(rectPoints[0]);
-    camera.setCroppingMask(cv::Rect(p, rectSize)); // croppingMask
-}
+//
+//  PRIVATE
+//
 
 
 double SandboxSetup::toDegrees(double radians){