From f342d01f78e18145e634c2b270ebbb9ff170d0dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Mischler=20=28aka=20skarab=29?=
 <skarab@bluewin.ch>
Date: Sun, 20 Mar 2016 11:23:34 +0100
Subject: [PATCH] 2D Viewer done!

---
 index.html            |  4 +++
 js/main.js            | 77 ++++++++++++++++++++++++++++++++++++++++++---------
 js/slacer/viewer2d.js | 26 +++++++++++------
 js/slacer/viewer3d.js | 11 --------
 viewer2d.html         | 16 +++++++++--
 5 files changed, 98 insertions(+), 36 deletions(-)

diff --git a/index.html b/index.html
index 35fd88e..24dffa0 100644
--- a/index.html
+++ b/index.html
@@ -165,6 +165,10 @@ <h3 class="panel-title">Resin</h3>
                         <h3 class="panel-title">Screen</h3>
                     </div>
                     <div id="screen-body" class="panel-body collapse in">
+                        <div class="info">
+                            <span class="info-label">Dot pitch <small>(mm)</small></span>
+                            <span class="info-value" id="screen-dot-pitch">0</span>
+                        </div>
                         <div class="form-group">
                             <label for="screen-width">Width <small>(px)</small></label>
                             <input type="number" id="screen-width" class="form-control input-sm" placeholder="1680" min="0" />
diff --git a/js/main.js b/js/main.js
index 8fe82ea..a25ba5c 100644
--- a/js/main.js
+++ b/js/main.js
@@ -68,7 +68,7 @@ function errorHandler(error) {
 // Slicer
 // -----------------------------------------------------------------------------
 var slicer = new SLAcer.Slicer();
-var shapes;
+var shapes, slices;
 
 function removeShapes() {
     if (shapes && shapes.length) {
@@ -78,11 +78,24 @@ function removeShapes() {
     }
 }
 
+function removeSlices() {
+    if (slices && slices.length) {
+        for (var i = 0, il = slices.length; i < il; i++) {
+            viewer2d.removeObject(slices[i]);
+        }
+    }
+
+    viewer2dWin && (viewer2dWin.document.body.style.backgroundImage = 'none');
+}
+
+
 function slice(layerNumber) {
     // remove old shapes
+    removeSlices();
     removeShapes();
 
     if (layerNumber < 1) {
+        viewer2d.render();
         viewer3d.render();
         return;
     }
@@ -99,15 +112,31 @@ function slice(layerNumber) {
     shapes = slice.shapes;
     zPosition -= viewer3d.buildVolume.size.z / 2;
 
+    // slices
+    slices = [];
+
     // add new shapes
     for (var i = 0, il = shapes.length; i < il; i++) {
+        slices[i] = shapes[i].clone();
+        slices[i].material = slices[i].material.clone();
+        slices[i].material.color.setHex(0xffffff);
+        viewer2d.addObject(slices[i]);
+
         shapes[i].position.z = zPosition;
         shapes[i].material.depthTest = false;
         viewer3d.scene.add(shapes[i]);
     }
 
-    // render
+    // render 3D view
     viewer3d.render();
+
+    // render 2D view
+    if (viewer2dWin) {
+        var body = viewer2dWin.document.body;
+        viewer2d.screenshot(function(dataURL) {
+            body.style.backgroundImage = 'url(' + dataURL + ')';
+        });
+    }
 }
 
 // -----------------------------------------------------------------------------
@@ -131,22 +160,37 @@ THREE.Triangulation.setLibrary('earcut');
 //THREE.Triangulation.setLibrary('poly2tri');
 
 // Viewer 2D
-var viewer2d  = null;
-$openViewer2D = $('#open-viewer-2d');
+var viewer2dWin   = null;
+var $openViewer2D = $('#open-viewer-2d');
+
+var viewer2d = new SLAcer.Viewer2D({
+    target     : null, // off-screen
+    color      : 0x000000,
+    buildPlate : {
+        size   : settings.get('buildVolume.size'),
+        unit   : settings.get('buildVolume.unit'),
+        color  : 0x000000,
+        opacity: 0 // hide build plate
+    },
+    size: settings.get('screen')
+});
 
 $openViewer2D.click(function(e) {
-    if (! viewer2d) {
-        var screen = settings.get('screen');
-        var size   = 'width=' + screen.width + ', height=' + screen.height;
-        var opts   = 'menubar=0, toolbar=0, location=0, directories=0, personalbar=0, status=0, resizable=1, dependent=0'
-        viewer2d   = window.open('viewer2d.html', 'SLAcer.viewer2d', size + ', ' + opts);
-
-        $(viewer2d).on('beforeunload', function(e) {
-            viewer2d = null;
+    if (! viewer2dWin) {
+        var screen  = settings.get('screen');
+        var size    = 'width=' + screen.width + ', height=' + screen.height;
+        var opts    = 'menubar=0, toolbar=0, location=0, directories=0, personalbar=0, status=0, resizable=1, dependent=0'
+        viewer2dWin = window.open('viewer2d.html', 'SLAcer.viewer2d', size + ', ' + opts);
+
+        $(viewer2dWin).on('beforeunload', function(e) {
+            viewer2dWin = null;
+        })
+        .load(function(e) {
+            slice($sliderInput.slider('getValue'));
         });
     }
 
-    viewer2d.focus();
+    viewer2dWin.focus();
     return false;
 });
 
@@ -370,6 +414,7 @@ var $screenBody         = initPanel('screen');
 var $screenWidth        = $screenBody.find('#screen-width');
 var $screenHeight       = $screenBody.find('#screen-height');
 var $screenDiagonalSize = $screenBody.find('#screen-diagonal-size');
+var $screenDotPitch     = $screenBody.find('#screen-dot-pitch');
 
 function updateScreenUI() {
     var screen = settings.get('screen');
@@ -377,6 +422,9 @@ function updateScreenUI() {
     $screenWidth.val(screen.width);
     $screenHeight.val(screen.height);
     $screenDiagonalSize.val(screen.diagonal.size);
+    $screenDotPitch.html(viewer2d.dotPitch.toFixed(2));
+
+    viewer2d.setScreenResolution(screen);
 }
 
 function updateScreenSettings() {
@@ -396,6 +444,9 @@ function updateScreenSettings() {
             unit: unit
         }
     });
+
+    viewer2d.setScreenResolution(settings.get('screen'));
+    $screenDotPitch.html(viewer2d.dotPitch.toFixed(2));
 }
 
 $('#screen-diagonal-unit-' + settings.get('screen.diagonal.unit')).prop('checked', true);
diff --git a/js/slacer/viewer2d.js b/js/slacer/viewer2d.js
index 616e3d4..cc1aecb 100644
--- a/js/slacer/viewer2d.js
+++ b/js/slacer/viewer2d.js
@@ -8,13 +8,14 @@ var SLAcer = SLAcer || {};
         screen: {
             width   : 1680, // px
             height  : 1050, // px
-            diagonal: 22    // in
+            diagonal: { size: 22, unit: 'in' }
         },
         buildPlate: {
             size: {
                 x: 100, // mm
                 y: 100  // mm
             },
+            unit: 'mm',
             color: 0xff0000,
             opacity: 0.1
         }
@@ -30,11 +31,6 @@ var SLAcer = SLAcer || {};
         this.setBuildPlate(this.settings.buildPlate);
         this.setView();
         this.render();
-
-        /*this.screenshot(function(dataURL) {
-            //window.open(dataURL);
-            //console.log(dataURL);
-        });*/
     }
 
     // extends
@@ -44,24 +40,36 @@ var SLAcer = SLAcer || {};
     // -------------------------------------------------------------------------
 
     Viewer2D.prototype.updatePixelDensity = function() {
-        var diagonal = Math.sqrt(Math.pow(this.screen.width, 2) + Math.pow(this.screen.height, 2));
-        var pixelPerCentimeter = diagonal / this.screen.diagonal / 2.54;
+        var diagonalPixels     = Math.sqrt(Math.pow(this.screen.width, 2) + Math.pow(this.screen.height, 2));
+        var pixelPerCentimeter = diagonalPixels / this.screen.diagonal.size * 10;
+
+        if (this.screen.diagonal.unit == 'in') {
+            pixelPerCentimeter = pixelPerCentimeter / 25.4;
+        }
+
         this.dotPitch = 10 / pixelPerCentimeter;
     };
 
     Viewer2D.prototype.setScreenResolution = function(settings) {
-        this.screen = _.defaults(settings, this.screen);
+        this.screen = _.defaultsDeep(settings, this.screen);
         this.updatePixelDensity();
         this.setSize(this.screen);
+        this.setView();
     };
 
     Viewer2D.prototype.setBuildPlate = function(settings) {
         this.buildPlate = _.defaultsDeep(settings, this.buildPlate);
 
         var size    = this.buildPlate.size;
+        var unit    = this.buildPlate.unit;
         var color   = this.buildPlate.color;
         var opacity = this.buildPlate.opacity;
 
+        if (unit == 'in') { // -> mm
+            size.x *= 25.4;
+            size.y *= 25.4;
+        }
+
         var geometry = new THREE.PlaneGeometry(size.x, size.y, 1);
         var material = new THREE.MeshBasicMaterial({
             color: color,
diff --git a/js/slacer/viewer3d.js b/js/slacer/viewer3d.js
index 2e59a13..118ba03 100644
--- a/js/slacer/viewer3d.js
+++ b/js/slacer/viewer3d.js
@@ -75,17 +75,6 @@ var SLAcer = SLAcer || {};
     };
 
     Viewer3D.prototype.addObject = function(object) {
-        /*var size   = object.geometry.boundingBox.size();
-        var volume = this.buildVolume.size;
-
-        // is in build volume
-        if (size.x > volume.x || size.y > volume.y || size.z > volume.z) {
-            throw new RangeError('Object size exceeds the build volume.');
-        }
-
-        // drop object on build plate
-        object.position.z = -((volume.z - size.z) / 2);*/
-
         // drop object on build plate
         this.dropObject(object);
 
diff --git a/viewer2d.html b/viewer2d.html
index ef800d2..1f14446 100644
--- a/viewer2d.html
+++ b/viewer2d.html
@@ -5,8 +5,18 @@
         <meta http-equiv="X-UA-Compatible" content="IE=edge" />
         <meta name="viewport" content="width=device-width, initial-scale=1" />
         <title>Viewer 2D - SLAcer.js (bêta)</title>
+        <style>
+            html, body {
+                width: 100%;
+                height: 100%;
+                overflow: hidden;
+            }
+            body {
+                background-color: #000000;
+                background-position: center;
+                background-repeat: no-repeat;
+            }
+        </style>
     </head>
-    <body>
-        <h1>Viewer 2D</h1>
-    </body>
+    <body id="slice"></body>
 </html>
