diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionController.java b/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionController.java
index 1414654ec11f2cbbc85c5213c2e5cc36f1c0b7a6..8f9905bc2dc12339c6c6b625504359c2358102d5 100644
--- a/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionController.java
+++ b/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionController.java
@@ -28,42 +28,24 @@
  */
 package fr.pasteur.ida.zellige.gui;
 
-import fr.pasteur.ida.zellige.element.Pixels;
-import fr.pasteur.ida.zellige.element.ReferenceSurface;
-import fr.pasteur.ida.zellige.element.Surface;
-import fr.pasteur.ida.zellige.gui.task.AbstractTask;
-import fr.pasteur.ida.zellige.gui.task.ConstructionCompletionTask;
-import fr.pasteur.ida.zellige.gui.task.RunFirstConstructionTask;
-import fr.pasteur.ida.zellige.gui.task.RunSecondConstructionTask;
-import fr.pasteur.ida.zellige.steps.construction.exception.FirstRoundConstructionException;
-import fr.pasteur.ida.zellige.steps.construction.exception.SecondRoundConstructionException;
 import javafx.beans.property.SimpleBooleanProperty;
-import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ChangeListener;
 import javafx.fxml.FXML;
 import javafx.fxml.Initializable;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.img.ImgFactory;
 import net.imglib2.type.NativeType;
 import net.imglib2.type.numeric.RealType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.ResourceBundle;
 
 public class ConstructionController< T extends RealType< T > & NativeType< T > > implements Initializable
 {
     private final static Logger LOGGER = LoggerFactory.getLogger( ConstructionController.class );
-    SimpleObjectProperty< ArrayList< Surface > > firstRoundSurfaces = new SimpleObjectProperty<>();
-    SimpleObjectProperty< ArrayList< Surface > > secondRoundSurfaces = new SimpleObjectProperty<>();
-    SimpleObjectProperty< ArrayList< ReferenceSurface< T > > > referenceSurfaces = new SimpleObjectProperty<>();
-    private RandomAccessibleInterval< T > input;
-    private ImgFactory< T > factory;
-    SimpleObjectProperty< Pixels[][] > maximums = new SimpleObjectProperty<>();
-    private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty();
 
+    private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty();
+    private ConstructionModel< T > constructionModel;
     @FXML
     private ParameterSliderDouble c1;
     @FXML
@@ -83,10 +65,22 @@ public class ConstructionController< T extends RealType< T > & NativeType< T > >
     @Override
     public void initialize( URL url, ResourceBundle resourceBundle )
     {
+        // model
+        constructionModel = new ConstructionModel<>();
+
+        //link Model with View
+        constructionModel.c1Property().bind( c1.sliderProperty() );
+        constructionModel.r1Property().bind( r1.sliderProperty() );
+        constructionModel.st1Property().bind( st1.sliderProperty() );
+        constructionModel.c2Property().bind( c2.sliderProperty() );
+        constructionModel.r2Property().bind( r2.sliderProperty() );
+        constructionModel.st2Property().bind( st2.sliderProperty() );
+        constructionModel.surfaceSizeProperty().bind( surfaceSize.sliderProperty() );
+
         /* Component */
         ChangeListener< ? super Number > firstRoundListener = ( observable, oldValue, newValue ) ->
         {
-            firstRoundSurfaces.setValue( null );
+            constructionModel.firstRoundSurfacesProperty().setValue( null );
             changedParameters.setValue( true );
         };
         c1.sliderProperty().addListener( firstRoundListener );
@@ -96,7 +90,7 @@ public class ConstructionController< T extends RealType< T > & NativeType< T > >
         ChangeListener< ? super Number > secondRoundListener = ( observable, oldValue, newValue ) ->
         {
             changedParameters.setValue( true );
-            secondRoundSurfaces.setValue( null );
+            constructionModel.secondRoundSurfacesProperty().setValue( null );
         };
         c2.sliderProperty().addListener( secondRoundListener );
         r2.sliderProperty().addListener( secondRoundListener );
@@ -104,163 +98,55 @@ public class ConstructionController< T extends RealType< T > & NativeType< T > >
         surfaceSize.sliderProperty().addListener( secondRoundListener );
 
         /* Properties*/
-        maximums.addListener( ( observable, oldValue, newValue ) ->
+        constructionModel.maximumsProperty().addListener( ( observable, oldValue, newValue ) ->
         {
             if ( newValue != null )
             {
                 LOGGER.debug( "Max is not null" );
-                firstRound();
+                constructionModel.firstRound();
             }
             else
             {
                 LOGGER.debug( "MAX is NULL" );
-                firstRoundSurfaces.setValue( null );
+                constructionModel.firstRoundSurfacesProperty().setValue( null );
             }
         } );
-        firstRoundSurfaces.addListener( ( observableValue, surfaces, t1 ) ->
+        constructionModel.firstRoundSurfacesProperty().addListener( ( observableValue, surfaces, t1 ) ->
         {
             if ( t1 == null )
             {
                 LOGGER.debug( "FIRST_ROUND_SURFACE  is NULL" );
-                secondRoundSurfaces.setValue( null );
+                constructionModel.secondRoundSurfacesProperty().setValue( null );
             }
             else
             {
-                secondRound();
+                constructionModel.secondRound();
             }
         } );
-        secondRoundSurfaces.addListener( ( observableValue, surfaces, t1 ) ->
+        constructionModel.secondRoundSurfacesProperty().addListener( ( observableValue, surfaces, t1 ) ->
         {
             if ( t1 == null )
             {
                 LOGGER.debug( "SECOND_ROUND_SURFACE  is NULL" );
-                referenceSurfaces.setValue( null );
+                constructionModel.referenceSurfacesProperty().setValue( null );
             }
             else
             {
-                constructionCompletion();
-            }
-        } );
-
-    }
-
-    private void firstRound()
-    {
-        LOGGER.info( "Computing first round construction..." );
-        AbstractTask< ArrayList< Surface > > firstRoundTask = new RunFirstConstructionTask( maximums.getValue(), getSt1(), getR1(), getC1(), getSurfaceSize() );
-        firstRoundTask.setOnSucceeded( workerStateEvent ->
-        {
-            firstRoundSurfaces.setValue( firstRoundTask.getValue() );
-            if ( firstRoundTask.getValue() == null )
-            {
-                LOGGER.info( "" ); //TODO write right message
-                MainController.showError( new FirstRoundConstructionException() );
-            }
-        } );
-
-        LOGGER.info( "First round construction done." );
-        firstRoundTask.start();
-    }
-
-    private void secondRound()
-    {
-        LOGGER.info( "Computing second round construction..." );
-        AbstractTask< ArrayList< Surface > > secondRoundTask = new RunSecondConstructionTask( firstRoundSurfaces.getValue(), getSt2(), getR2(), getC2(), getSurfaceSize() );
-        secondRoundTask.setOnSucceeded( workerStateEvent ->
-        {
-            secondRoundSurfaces.setValue( secondRoundTask.getValue() );
-            if ( secondRoundTask.getValue() == null )
-            {
-                LOGGER.info( "" ); //TODO write right message
-                MainController.showError( new SecondRoundConstructionException() );
+                constructionModel.constructionCompletion();
             }
         } );
-        LOGGER.info( "Second round construction done." );
-        secondRoundTask.start();
     }
 
-    private void constructionCompletion()
-    {
-        AbstractTask< ArrayList< ReferenceSurface< T > > > constructionCompletionTask = new ConstructionCompletionTask<>( input, factory, secondRoundSurfaces.getValue() );
-        constructionCompletionTask.setOnSucceeded( workerStateEvent ->
-                referenceSurfaces.setValue( constructionCompletionTask.getValue() ) );
-        constructionCompletionTask.start();
-    }
 
 
-    public void runConstruction()
-    {
-        LOGGER.debug( "Run construction" );
-        if ( firstRoundSurfacesProperty().getValue() == null )
-        {
-            firstRound();
-        }
-        else if ( secondRoundSurfaces.getValue() == null )
-        {
-            secondRound();
-        }
-    }
-
-
-    public double getC1()
-    {
-        return c1.getSlider().getValue();
-    }
-
-    public double getC2()
-    {
-        return c2.getSlider().getValue();
-    }
-
-    public int getR1()
-    {
-        return ( int ) r1.getSlider().getValue();
-    }
-
-    public int getR2()
-    {
-        return ( int ) r2.getSlider().getValue();
-    }
-
-    public double getSt1()
-    {
-        return st1.getSlider().getValue();
-    }
-
-    public double getSt2()
-    {
-        return st2.getSlider().getValue();
-    }
-
     public double getSurfaceSize()
     {
         return surfaceSize.getSlider().getValue();
     }
 
-    public RandomAccessibleInterval< T > getInput()
-    {
-        return input;
-    }
-
-    public void setInput( RandomAccessibleInterval< T > input )
-    {
-        this.input = input;
-    }
-
-
-    public void setFactory( ImgFactory< T > factory )
-    {
-        this.factory = factory;
-    }
-
-    public SimpleObjectProperty< ArrayList< ReferenceSurface< T > > > referenceSurfacesProperty()
-    {
-        return referenceSurfaces;
-    }
-
-    public SimpleObjectProperty< ArrayList< Surface > > firstRoundSurfacesProperty()
+    public ConstructionModel< T > getConstructionModel()
     {
-        return firstRoundSurfaces;
+        return constructionModel;
     }
 
     public SimpleBooleanProperty changedParametersProperty()
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d3aa64d7a746be1203239e90937fe1191cc5468
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/gui/ConstructionModel.java
@@ -0,0 +1,240 @@
+package fr.pasteur.ida.zellige.gui;
+
+import fr.pasteur.ida.zellige.element.Pixels;
+import fr.pasteur.ida.zellige.element.ReferenceSurface;
+import fr.pasteur.ida.zellige.element.Surface;
+import fr.pasteur.ida.zellige.gui.task.AbstractTask;
+import fr.pasteur.ida.zellige.gui.task.ConstructionCompletionTask;
+import fr.pasteur.ida.zellige.gui.task.RunFirstConstructionTask;
+import fr.pasteur.ida.zellige.gui.task.RunSecondConstructionTask;
+import fr.pasteur.ida.zellige.steps.construction.exception.FirstRoundConstructionException;
+import fr.pasteur.ida.zellige.steps.construction.exception.SecondRoundConstructionException;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.RealType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+public class ConstructionModel< T extends RealType< T > & NativeType< T > >
+{
+
+    private final static Logger LOGGER = LoggerFactory.getLogger( ConstructionModel.class );
+
+    private final DoubleProperty c1;
+    private final DoubleProperty c2;
+    private final DoubleProperty r1;
+    private final DoubleProperty r2;
+    private final DoubleProperty st1;
+    private final DoubleProperty st2;
+    private final DoubleProperty surfaceSize;
+    private final SimpleObjectProperty< ArrayList< Surface > > firstRoundSurfaces = new SimpleObjectProperty<>();
+    private final SimpleObjectProperty< ArrayList< Surface > > secondRoundSurfaces = new SimpleObjectProperty<>();
+    private final SimpleObjectProperty< ArrayList< ReferenceSurface< T > > > referenceSurfaces = new SimpleObjectProperty<>();
+    SimpleObjectProperty< Pixels[][] > maximums = new SimpleObjectProperty<>();
+    private RandomAccessibleInterval< T > input;
+    private ImgFactory< T > factory;
+
+    public ConstructionModel()
+    {
+        c1 = new SimpleDoubleProperty();
+        c2 = new SimpleDoubleProperty();
+        r1 = new SimpleDoubleProperty();
+        r2 = new SimpleDoubleProperty();
+        st1 = new SimpleDoubleProperty();
+        st2 = new SimpleDoubleProperty();
+        surfaceSize = new SimpleDoubleProperty();
+    }
+
+    public void firstRound()
+    {
+        LOGGER.info( "Computing first round construction..." );
+        AbstractTask< ArrayList< Surface > > firstRoundTask = new RunFirstConstructionTask( maximums.getValue(), st1.doubleValue(), r1.intValue(), c1.doubleValue(), surfaceSize.doubleValue() );
+        firstRoundTask.setOnSucceeded( workerStateEvent ->
+        {
+            firstRoundSurfaces.setValue( firstRoundTask.getValue() );
+            if ( firstRoundTask.getValue() == null )
+            {
+                LOGGER.info( "" ); //TODO write right message
+                MainController.showError( new FirstRoundConstructionException() );
+            }
+        } );
+        LOGGER.info( "First round construction done." );
+        firstRoundTask.start();
+    }
+
+
+    public void secondRound()
+    {
+        LOGGER.info( "Computing second round construction..." );
+        AbstractTask< ArrayList< Surface > > secondRoundTask = new RunSecondConstructionTask( firstRoundSurfacesProperty().getValue(), st2.getValue(), r2.intValue(), c2.doubleValue(), surfaceSize.doubleValue() );
+        secondRoundTask.setOnSucceeded( workerStateEvent ->
+        {
+            secondRoundSurfacesProperty().setValue( secondRoundTask.getValue() );
+            if ( secondRoundTask.getValue() == null )
+            {
+                LOGGER.info( "" ); //TODO write right message
+                MainController.showError( new SecondRoundConstructionException() );
+            }
+        } );
+        LOGGER.info( "Second round construction done." );
+        secondRoundTask.start();
+    }
+
+    public void runConstruction()
+    {
+        LOGGER.debug( "Run construction" );
+        if ( firstRoundSurfacesProperty().getValue() == null )
+        {
+            firstRound();
+        }
+        else if ( secondRoundSurfaces.getValue() == null )
+        {
+            secondRound();
+        }
+    }
+
+
+    public void constructionCompletion()
+    {
+        AbstractTask< ArrayList< ReferenceSurface< T > > > constructionCompletionTask = new ConstructionCompletionTask<>( input, factory, secondRoundSurfaces.getValue() );
+        constructionCompletionTask.setOnSucceeded( workerStateEvent ->
+                referenceSurfacesProperty().setValue( constructionCompletionTask.getValue() ) );
+        constructionCompletionTask.start();
+    }
+
+    public double getC1()
+    {
+        return c1.get();
+    }
+
+    public DoubleProperty c1Property()
+    {
+        return c1;
+    }
+
+    public double getC2()
+    {
+        return c2.get();
+    }
+
+    public DoubleProperty c2Property()
+    {
+        return c2;
+    }
+
+    public double getR1()
+    {
+        return r1.get();
+    }
+
+    public DoubleProperty r1Property()
+    {
+        return r1;
+    }
+
+    public double getR2()
+    {
+        return r2.get();
+    }
+
+    public DoubleProperty r2Property()
+    {
+        return r2;
+    }
+
+    public double getSt1()
+    {
+        return st1.get();
+    }
+
+    public DoubleProperty st1Property()
+    {
+        return st1;
+    }
+
+    public double getSt2()
+    {
+        return st2.get();
+    }
+
+    public DoubleProperty st2Property()
+    {
+        return st2;
+    }
+
+    public double getSurfaceSize()
+    {
+        return surfaceSize.get();
+    }
+
+    public DoubleProperty surfaceSizeProperty()
+    {
+        return surfaceSize;
+    }
+
+    public ArrayList< Surface > getFirstRoundSurfaces()
+    {
+        return firstRoundSurfaces.get();
+    }
+
+    public SimpleObjectProperty< ArrayList< Surface > > firstRoundSurfacesProperty()
+    {
+        return firstRoundSurfaces;
+    }
+
+    public ArrayList< Surface > getSecondRoundSurfaces()
+    {
+        return secondRoundSurfaces.get();
+    }
+
+    public SimpleObjectProperty< ArrayList< Surface > > secondRoundSurfacesProperty()
+    {
+        return secondRoundSurfaces;
+    }
+
+    public ArrayList< ReferenceSurface< T > > getReferenceSurfaces()
+    {
+        return referenceSurfaces.get();
+    }
+
+    public SimpleObjectProperty< ArrayList< ReferenceSurface< T > > > referenceSurfacesProperty()
+    {
+        return referenceSurfaces;
+    }
+
+    public RandomAccessibleInterval< T > getInput()
+    {
+        return input;
+    }
+
+    public void setInput( RandomAccessibleInterval< T > input )
+    {
+        this.input = input;
+    }
+
+    public ImgFactory< T > getFactory()
+    {
+        return factory;
+    }
+
+    public void setFactory( ImgFactory< T > factory )
+    {
+        this.factory = factory;
+    }
+
+    public Pixels[][] getMaximums()
+    {
+        return maximums.get();
+    }
+
+    public SimpleObjectProperty< Pixels[][] > maximumsProperty()
+    {
+        return maximums;
+    }
+}
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/MainController.java b/src/main/java/fr/pasteur/ida/zellige/gui/MainController.java
index 97fa0ec4c65f4a766660ef8ab762eac3ee90f641..a68b8150bcbb78a4610bc0bdf6358b150d7ab42b 100644
--- a/src/main/java/fr/pasteur/ida/zellige/gui/MainController.java
+++ b/src/main/java/fr/pasteur/ida/zellige/gui/MainController.java
@@ -160,8 +160,8 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme
         /* Binding properties*/
         selectionController.getSelectionModel().pretreatedImgProperty().bind( pretreatedImg );
         selectionController.getSelectionModel().imagesProperty().bind( images );
-        constructionController.maximums.bind( selectionController.getSelectionModel().selectedPixelsProperty() );
-        projectionController.referenceSurfacesProperty().bind( constructionController.referenceSurfacesProperty() );
+        constructionController.getConstructionModel().maximumsProperty().bind( selectionController.getSelectionModel().selectedPixelsProperty() );
+        projectionController.referenceSurfacesProperty().bind( constructionController.getConstructionModel().referenceSurfacesProperty() );
         changedParameters.bindBidirectional( selectionController.changedParametersProperty() );
         selectionController.changedParametersProperty().bindBidirectional( constructionController.changedParametersProperty() );
         constructionController.changedParametersProperty().bindBidirectional( projectionController.changedParametersProperty() );
@@ -346,13 +346,13 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme
 
         if ( selectionController.getSelectionModel().selectedPixelsProperty().getValue() != null )
         {
-            if ( constructionController.referenceSurfaces.getValue() != null )
+            if ( constructionController.getConstructionModel().referenceSurfacesProperty().getValue() != null )
             {
                 projectionController.runProjection();
             }
             else
             {
-                constructionController.runConstruction();
+                constructionController.getConstructionModel().runConstruction();
             }
         }
         else
@@ -402,8 +402,8 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme
             {
                 currentDataset.setValue( dataset );
                 Img< T > input = ( ImgPlus< T > ) dataset.getImgPlus();
-                constructionController.setInput( input );
-                constructionController.setFactory( input.factory() );
+                constructionController.getConstructionModel().setInput( input );
+                constructionController.getConstructionModel().setFactory( input.factory() );
             }
         }
     }