Skip to content
Permalink
Branch: gh-pages
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1586 lines (1313 sloc) 51.9 KB
// -----------------------------------------------------------------------------
// Variables
// -----------------------------------------------------------------------------
//window.localStorage.clear();
var settings = new SLAcer.Settings({
file: {
panel: {
collapsed: false,
position : 0
},
printer: 'Custom'
},
slicer: {
layers: {
height: 100, // μm
bottom: 3
},
light: {
on : 12000,
bottom: 60000,
off: 500,
strength: 225
},
zip: true,
folder: false,
output: 'wow',
speed: true,
speedDelay: 10, // ms
panel: {
collapsed: false,
position : 1
},
lifting: {
speed : 30, // mm/min
decline: 100, // mm/min
height: 5, // mm
}
},
mesh: {
panel: {
collapsed: false,
position : 2
}
},
transform: {
panel: {
collapsed: false,
position : 3
},
mirror: false
},
buildVolume: {
size : { x: 102, y: 56, z: 125 }, // mm
unit : 'mm', // mm or in
color : 0xcccccc,
opacity : 0.1,
panel : {
collapsed: false,
position : 4
}
},
resin: {
density : 1.1, // g/cm3
price : 60, // $
panel : {
collapsed: false,
position : 5
}
},
screen: {
width : 854,//window.screen.width,
height : 480,//window.screen.height,
diagonal : { size: 4.6, unit: 'in' },
panel : {
collapsed: false,
position : 6
}
},
colors: {
mesh : '#eb0984',
slice: '#88ee11',
panel: {
collapsed: false,
position : 7
}
},
gcode: {
start : getDefaultGcodeStart(),
end: getDefaultGcodeEnd(),
panel: {
collapsed: true,
position : 8
}
},
viewer3d: {
color: 0xffffff
}
});
// -----------------------------------------------------------------------------
// Error handler
// -----------------------------------------------------------------------------
function errorHandler(error) {
console.error(error);
}
// -----------------------------------------------------------------------------
// Slicer
// -----------------------------------------------------------------------------
var slicer = new SLAcer.Slicer();
var shapes, slices;
function removeShapes() {
if (shapes && shapes.length) {
for (var i = 0, il = shapes.length; i < il; i++) {
viewer3d.removeObject(shapes[i]);
}
}
}
function removeSlices() {
if (slices && slices.length) {
for (var i = 0, il = slices.length; i < il; i++) {
viewer2d.removeObject(slices[i]);
}
}
sliceImage('none');
}
function hexToDec(hex) {
return parseInt(hex.toString().replace('#', ''), 16);
}
function sliceImage(dataURL) {
settings.set('slice.dataURL', dataURL || 'none');
}
function getSlice(layerNumber) {
// remove old shapes
removeSlices();
removeShapes();
// debug
// console.log("layerNumber", layerNumber)
// ...
$slicerLayerValue.html(layerNumber);
if (layerNumber < 1) {
viewer2d.render();
viewer3d.render();
return;
}
if (transformations.update) {
throw 'transformations not applyed...';
}
// get position
layerHeight = settings.get('slicer.layers.height') / 1000;
zPosition = layerNumber * layerHeight;
// get faces
var faces = slicer.getFaces(zPosition);
//console.log('layer number:', layerNumber);
//console.log('z position :', zPosition);
// get new shapes list
shapes = faces.meshes;
zPosition -= viewer3d.buildVolume.size.z / 2;
// slices
slices = [];
var slice, shape;
var sliceColor = hexToDec(settings.get('colors.slice'));
// add new shapes
for (var i = 0, il = shapes.length; i < il; i++) {
shape = shapes[i];
slice = shape.clone();
slice.material = slice.material.clone();
slice.material.color.setHex(0xffffff);
viewer2d.addObject(slice);
slices.push(slice);
shape.material.color.setHex(sliceColor);
shape.material.depthTest = false;
shape.position.z = zPosition;
viewer3d.scene.add(shape);
}
// render 3D view
viewer3d.render();
// render 2D view
viewer2d.screenshot(function(dataURL) {
sliceImage(dataURL);
if (PNGExport) {
var fileName = layerNumber + '.png';
var imgData = dataURL.substr(dataURL.indexOf(',') + 1);
if (settings.get('slicer.folder')) {
zipFolder.file(fileName, imgData, {base64: true});
}
} else if (FHDExport) {
// image file
var fileName = 'slice (' + layerNumber + ').png';
var imgData = dataURL.substr(dataURL.indexOf(',') + 1);
zipFolder.file(fileName, imgData, {base64: true});
// gcode
wowFile += "M106 S0;\n"; // UV lights off
wowFile += "G1 Z" + settings.get('slicer.lifting.height') + " F" + settings.get('slicer.lifting.speed') + ";\n"; // raise bed up specified height and speed
wowFile += "G1 Z-" + (settings.get('slicer.lifting.height') - settings.get('slicer.layers.height') / 1000) + " F" + settings.get('slicer.lifting.decline') + ";\n"; // lower bed down specified height and speed
//bottom layer
var exposure_time;
if(layerNumber<=settings.get('slicer.layers.bottom')){
exposure_time = settings.get('slicer.light.bottom');
}else{
exposure_time = settings.get('slicer.light.on');
}
wowFile += "{" + fileName + "};\n"; // link to layer image
wowFile += "M106 S"+settings.get('slicer.light.strength')+";\n"; // UV lights on specified strength
wowFile += "G4 S" + exposure_time / 1000 + ";\n"; // wait specified layer cure time
}else if (WOWExport) {
//console.log('layer number:', layerNumber);
//console.log('z position :', zPosition);
convertURIToImageData(dataURL).then(function(imageData) {
// Here you can use imageData
/*
var red = data[i];
var green = data[i+1];
var blue = data[i+2];
var alpha = data[i+3];
2 Options:
Black red=0, green=0, blue=0, alpha=255;
White red=255, green=255, blue=255, alpha=255;
*/
var width = settings.get('screen.width');
var height = settings.get('screen.height');
var pixel = 0;
var array = new Uint8Array(width*height/8);
var data = imageData.data;
for(var w=0; w<data.length/height*4; w+=4) {
for(var h=w; h<width*height*4; h+=(4*width)) {
if(data[h]!==0){
array[~~(pixel/8)] += Math.pow(2,(pixel%8))
}
pixel++;
}
}
if(WOWExport) {// GCode logic
wowFile += ";L:" + layerNumber + ";\nM106 S0;\nG1 Z" + settings.get('slicer.lifting.height') +
" F" + settings.get('slicer.lifting.speed') +
";\nG1 Z-" + (settings.get('slicer.lifting.height') - settings.get('slicer.layers.height') / 1000) +
" F" + settings.get('slicer.lifting.decline') + ";\n{{\n"
//var binary_layer = (new TextDecoder("utf-8")).decode(array)
wowFile += bin2string(array);
//wowFile += array.map(intBytetoHexBin);
wowFile += "\n";
if (settings.get('slicer.folder')) {
// Backup text file
zipFolder.file(layerNumber + ".txt", array);
}
//bottom layer
var exposure_time;
if(layerNumber<=settings.get('slicer.layers.bottom')){
exposure_time = settings.get('slicer.light.bottom');
}else{
exposure_time = settings.get('slicer.light.on');
}
wowFile += "}}\nM106 S"+settings.get('slicer.light.strength')+";\nG4 S" + exposure_time / 1000 + ";\n"
}
});
}
});
// SVG export
if (SVGExport) {
// offset for positive coords
var xOffset = Math.abs(slicer.mesh.geometry.boundingBox.min.x);
var yOffset = Math.abs(slicer.mesh.geometry.boundingBox.min.y);
function SVGPath(actions, dir) {
var path = [];
var area = 0;
var a, b, c, x, y;
if (dir != 'ccw') {
dir = 'cw';
}
actions.push({ action: 'lineTo', args: actions[0].args });
for (var i = 0, il = actions.length; i < il; i++) {
a = actions[i];
if (i > 0) {
b = actions[i - 1];
area += a.args[0] * b.args[1];
area -= b.args[0] * a.args[1];
}
c = a.action == 'moveTo' ? 'M' : 'L';
x = (a.args[0] + xOffset);
y = (a.args[1] + yOffset);
path.push(c + x + ' ' + y);
}
if (dir == 'cw' && area < 0 || dir == 'ccw' && area > 0) {
path = path.reverse();
path[0] = path[0].replace(/^L/, 'M');
path[actions.length - 1] = path[actions.length - 1].replace(/^M/, 'L');
}
return path.join(' ') + ' Z ';
}
// svg start
var size = slicer.mesh.getSize();
var svg = '<svg version="1.1" width="' + size.x + '" height="' + size.y + '" baseProfile="full" xmlns="http://www.w3.org/2000/svg">\n';
// svg background
svg += '<rect x="0" y="0" width="100%" height="100%" style="fill:black; stroke:none"/>\n';
// fix coordinate system (rotate 180°)
svg += '<g transform="translate(0, ' + size.y + ') scale(1, -1)">\n';
// draw main paths
var actions;
for (var i = 0, il = faces.shapes.length; i < il; i++) {
actions = faces.shapes[i].actions;
// path start
svg += '<path d="';
// main paths
svg += SVGPath(actions, 'cw');
// holes paths
var holes = faces.shapes[i].holes;
for (var j = 0, jl = holes.length; j < jl; j++) {
svg += SVGPath(holes[j].actions, 'ccw');
}
// path end
svg += '" style="fill:white; stroke:none" />\n';
}
// svg end
svg += '</g>';
svg += '</svg>';
if (settings.get('slicer.folder')) {
// add svg file to zip
zipFolder.file(layerNumber + '.svg', svg);
}
}
}
function convertURIToImageData(URI) {
return new Promise(function(resolve, reject) {
if (URI == null) return reject();
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
image = new Image();
image.addEventListener('load', function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(context.getImageData(0, 0, canvas.width, canvas.height));
}, false);
image.src = URI;
});
}
function bin2string(array){
var result = "";
for(var i = 0; i < array.length; ++i){
result+= (String.fromCharCode(array[i]));
//result+= intBytetoHexBin(array[i]);
}
return result;
}
// array.map(intBytetoHexBin);
function intBytetoHexBin(value){
//var hex_array = ["\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F","\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2A","\x2B","\x2C","\x2D","\x2E","\x2F","\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3A","\x3B","\x3C","\x3D","\x3E","\x3F","\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4A","\x4B","\x4C","\x4D","\x4E","\x4F","\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5A","\x5B","\x5C","\x5D","\x5E","\x5F","\x60","\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6A","\x6B","\x6C","\x6D","\x6E","\x6F","\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78","\x79","\x7A","\x7B","\x7C","\x7D","\x7E","\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86","\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E","\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E","\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6","\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE","\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6","\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE","\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF"];
//return hex_array[value];
return ["\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F","\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2A","\x2B","\x2C","\x2D","\x2E","\x2F","\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3A","\x3B","\x3C","\x3D","\x3E","\x3F","\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4A","\x4B","\x4C","\x4D","\x4E","\x4F","\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5A","\x5B","\x5C","\x5D","\x5E","\x5F","\x60","\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6A","\x6B","\x6C","\x6D","\x6E","\x6F","\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78","\x79","\x7A","\x7B","\x7C","\x7D","\x7E","\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86","\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E","\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E","\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6","\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE","\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6","\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE","\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6","\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE","\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6","\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE","\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6","\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE","\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6","\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE","\xFF"][value];
}
function BinToText(input) {
return parseInt(input,2).toString(10);
}
function uintToString(buffer) {
var encodedString = String.fromCharCode.apply(null, buffer),
decodedString = decodeURIComponent(escape(encodedString));
return decodedString;
}
function convertHexToString(input) {
// split input into groups of two
var hex = input.match(/[\s\S]{2}/g) || [];
var output = '';
// build a hex-encoded representation of your string
for (var i = 0, j = hex.length; i < j; i++) {
output += '%' + ('0' + hex[i]).slice(-2);
}
// decode it using this trick
output = decodeURIComponent(output);
return output;
}
function arrayToHEXString(input) {
var result = "";
for(var i = 0; i < input.length; ++i){
result+= "\X"+input[i].toString(16);
}
return result;
}
// -----------------------------------------------------------------------------
// UI
// -----------------------------------------------------------------------------
// Main container
var $main = $('#main');
// Viewer 3D
var $viewer3d = $('#viewer3d');
var viewer3d = new SLAcer.Viewer3D({
color : settings.get('viewer3d.color'),
buildVolume: settings.get('buildVolume'),
target : $viewer3d[0]
});
// Triangulation algorithm
//THREE.Triangulation.setTimer(true);
THREE.Triangulation.setLibrary('earcut');
//THREE.Triangulation.setLibrary('libtess');
//THREE.Triangulation.setLibrary('poly2tri');
// 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 (viewer2dWin == null || viewer2dWin.closed) {
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', 'SLAcerViewer2D', size + ', ' + opts);
$(viewer2dWin).on('beforeunload', function(e) {
viewer2dWin = null;
})
.load(function(e) {
getSlice($sliderInput.slider('getValue'));
});
}
else {
viewer2dWin.focus();
}
return false;
});
// Slider
var $sliderInput = $('#slider input');
$sliderInput.slider({ reversed : true }).on('change', function(e) {
getSlice(e.value.newValue);
});
var $sliderElement = $('#slider .slider');
var $sliderMaxValue = $('#slider .max');
function updateSliderUI() {
var layersHeight = settings.get('slicer.layers.height') / 1000;
var layersNumber = Math.floor(slicer.mesh.getSize().z / layersHeight);
// console.log("layersHeight", layersHeight);
// console.log("layersNumber", layersNumber);
$sliderInput.slider('setAttribute', 'max', layersNumber);
$sliderMaxValue.html(layersNumber);
$slicerLayersValue.html(layersNumber);
$printTimeValue.html(msToTime(calcPrintTime(layersHeight, layersNumber)));
}
function calcPrintTime(layersHeight, layersNumber){
// ([object height]/[layer height])([exposure time]+[uplift time]+[downlift time])+3([ground exposure time]-[exposure time])
var result = 0;
var uplift_time = settings.get('slicer.lifting.height')/settings.get('slicer.lifting.speed')*60*1000
var downlift_time = (settings.get('slicer.lifting.height')-layersHeight)/settings.get('slicer.lifting.decline')*60*1000
result = layersNumber*(parseInt(settings.get('slicer.light.on'))+uplift_time+downlift_time)+
settings.get('slicer.layers.bottom')*(settings.get('slicer.light.bottom')-settings.get('slicer.light.on'))
/*
console.log("slicer.light.on (ms)", settings.get('slicer.light.on'));
console.log("slicer.layers.bottom)", settings.get('slicer.layers.bottom'));
console.log("slicer.light.bottom)", settings.get('slicer.light.bottom'));
console.log("downlift_time (ms)", downlift_time);
console.log("uplift_time (ms)", uplift_time);
console.log("tmp 0 (ms)", parseInt(settings.get('slicer.light.on')) + uplift_time );
console.log("tmp 1 (ms)", layersNumber*(parseInt(settings.get('slicer.light.on'))+uplift_time+downlift_time));
console.log("tmp 2 (ms)", settings.get('slicer.layers.bottom')*(settings.get('slicer.light.bottom')-settings.get('slicer.light.on')));
console.log("result (ms)", result);
*/
return result;
}
function msToTime(duration) {
var milliseconds = parseInt((duration%1000)/100)
, seconds = parseInt((duration/1000)%60)
, minutes = parseInt((duration/(1000*60))%60)
, hours = parseInt((duration/(1000*60*60))%24);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
}
// Sidebar
var $sidebar = $('#sidebar');
var $panels = $sidebar.find('.panel');
$sidebar.sortable({
axis : 'y',
handle : '.panel-heading',
cancel : '.panel-toggle',
placeholder: 'panel-placeholder', forcePlaceholderSize: true,
// update panel position
stop: function(e, ui) {
$sidebar.find('.panel').each(function(i, element) {
settings.set(_.camelCase(element.id) + '.panel.position', i);
});
}
});
// Sort panels
var panels = [];
var panel;
_.forEach(settings.settings, function(item, namespace) {
if (item && item.panel) {
panels[item.panel.position] = $('#' + _.kebabCase(namespace));
}
});
for (var i in panels) {
$sidebar.append(panels[i]);
}
// Init panel
function initPanel(name) {
var id = _.kebabCase(name);
var name = _.camelCase(name);
var $body = $('#' + id + '-body');
$body.on('hidden.bs.collapse', function () {
settings.set(name + '.panel.collapsed', true);
});
$body.on('shown.bs.collapse', function () {
settings.set(name + '.panel.collapsed', false);
});
if (settings.get(name + '.panel.collapsed')) {
$body.collapse('hide');
}
return $body;
}
// Unit converter
function parseUnit(value, unit) {
return parseFloat(unit == 'in' ? (value / 25.4) : (value * 25.4));
}
// File panel
var $fileBody = initPanel('file');
var $fileInput = $fileBody.find('#file-input');
var $printerType = $fileBody.find('#printer-type');
var loadedFile = null;
$fileInput.on('change', function(e) {
resetTransformValues();
loadedFile = e.target.files[0];
loader.loadFile(loadedFile);
});
$printerType.on('change', function(e) {
newPrinterType = $printerType.val();
if (newPrinterType == 'Custom') {
// update printerType setting only
settings.set('file.printer', newPrinterType);
}
else {
// TODO: need to fix slider errors when using jquery-ui full (as opposed to .min). Then we can use this confirm dialog
// // make sure user is willing to update screen, build volume, and outputType settings
// $("#dialog-confirm").html("Are you sure you want to replace screen, build volume, gcode, and outputType settings with \"" + newPrinterType + "\" defaults?");
// $("#dialog-confirm").dialog({
// resizable: false,
// modal: true,
// title: "Update Settings?",
// height: 250,
// width: 400,
// buttons: {
// "Yes": function () {
// $(this).dialog('close');
// update settings
settings.set('file.printer', newPrinterType);
printerDefaults(newPrinterType);
// },
// "No": function () {
// $(this).dialog('close');
// // revert printerType input to the old printer-type value from settings
// $printerType.val(settings.get('file.printer'));
// }
// }
// });
}
});
$printerType.val(settings.get('file.printer'));
function printerDefaults(printerType) {
// update settings and UI
if (printerType == 'Sparkmaker') {
// screen
settings.set('screen', {
width : 854,
height : 480,
diagonal: {
size: 4.6,
unit: 'in'
}
});
$('#screen-diagonal-unit-' + settings.get('screen.diagonal.unit')).prop('checked', true);
updateScreenUI();
// build volume x,y,z,unit
settings.set('buildVolume', {
size: {
x: 102,
y: 56,
z: 125
},
unit: 'mm'
});
$('#build-volume-unit-' + settings.get('buildVolume.unit')).prop('checked', true);
updateBuildVolumeUI()
// outputType
settings.set('slicer.output', 'wow');
$outputType.val(settings.get('slicer.output'));
// gcode
resetGcodeStart(); // gcode prefix and suffix are the same for both Sparkmaker and Sparkmaker FHD for now
resetGcodeEnd();
}
else if (printerType == 'Sparkmaker FHD') {
// screen
settings.set('screen', {
width : 1920,
height : 1080,
diagonal: {
size: 4.9686,
unit: 'in'
}
});
$('#screen-diagonal-unit-' + settings.get('screen.diagonal.unit')).prop('checked', true);
updateScreenUI();
// build volume
settings.set('buildVolume', {
size: {
x: 110.016,
y: 61.8357,
z: 125
},
unit: 'mm'
});
$('#build-volume-unit-' + settings.get('buildVolume.unit')).prop('checked', true);
updateBuildVolumeUI()
// outputType
settings.set('slicer.output', 'fhd');
$outputType.val(settings.get('slicer.output'));
// gcode
resetGcodeStart(); // gcode prefix and suffix are the same for both Sparkmaker and Sparkmaker FHD for now
resetGcodeEnd();
}
// reload 3d view with new screen and build-volume settings
updateBuildVolumeSettings();
updateScreenSettings();
}
// Mesh panel
var $meshBody = initPanel('mesh');
var $meshFaces = $meshBody.find('#mesh-faces');
var $meshVolume = $meshBody.find('#mesh-volume');
var $meshWeight = $meshBody.find('#mesh-weight');
var $meshCost = $meshBody.find('#mesh-cost');
var $meshSizeX = $meshBody.find('#mesh-size-x');
var $meshSizeY = $meshBody.find('#mesh-size-y');
var $meshSizeZ = $meshBody.find('#mesh-size-z');
var $meshSizeUnit = $meshBody.find('.mesh-size-unit');
function updateMeshInfoUI() {
var mesh = slicer.mesh;
var size = mesh.getSize();
var unit = settings.get('buildVolume.unit');
updateSliderUI();
$meshSizeUnit.html(unit);
if (unit == 'in') {
size.x = parseUnit(size.x, 'in');
size.y = parseUnit(size.y, 'in');
size.z = parseUnit(size.z, 'in');
}
$meshSizeX.html(size.x.toFixed(2));
$meshSizeY.html(size.y.toFixed(2));
$meshSizeZ.html(size.z.toFixed(2));
var volume = parseInt(mesh.getVolume() / 1000); // cm3/ml
var weight = (volume * settings.get('resin.density')).toFixed(2); // g
var cost = volume * settings.get('resin.price') / 1000;
$meshFaces.html(mesh.geometry.faces.length);
// mirror bugfix
$meshVolume.html(Math.abs(volume));
$meshWeight.html(Math.abs(weight));
$meshCost.html(Math.abs(weight));
}
// Slicer panel
var $slicerBody = initPanel('slicer');
var $slicerLayerHeight = $slicerBody.find('#slicer-layers-height');
var $slicerLayersValue = $slicerBody.find('#slicer-layers-value');
var $slicerLayerValue = $slicerBody.find('#slicer-layer-value');
var $slicerLightOff = $slicerBody.find('#slicer-light-off');
var $slicerLightOn = $slicerBody.find('#slicer-light-on');
//new
var $slicerLightStrength = $slicerBody.find('#slicer-light-strength');
var $slicerLightBottum = $slicerBody.find('#slicer-light-bottom');
var $slicerDeclineSpeed = $slicerBody.find('#slicer-decline-speed');
var $slicerBottomLayers = settings.get('slicer.layers.bottom');
var $printTimeValue = $slicerBody.find('#print-time');
var $slicerLiftingSpeed = $slicerBody.find('#slicer-lifting-speed');
var $slicerLiftingHeight = $slicerBody.find('#slicer-lifting-height');
var $outputType = $slicerBody.find('#output-type');
var $slicerSpeedYes = $slicerBody.find('#slicer-speed-yes');
var $slicerSpeedNo = $slicerBody.find('#slicer-speed-no');
var $slicerSpeedDelay = $slicerBody.find('#slicer-speed-delay');
var $slicerMakeZipYes = $slicerBody.find('#slicer-make-zip-yes');
var $slicerMakeZipNo = $slicerBody.find('#slicer-make-zip-no');
//new
var $slicerMakeFolderYes = $slicerBody.find('#slicer-make-folder-yes');
var $slicerMakeFolderNo = $slicerBody.find('#slicer-make-folder-no');
var $sliceButton = $sidebar.find('#slice-button');
var $abortButton = $sidebar.find('#abort-button');
var $zipButton = $sidebar.find('#zip-button');
function updateSlicerUI() {
var slicer = settings.get('slicer');
$slicerSpeedDelay.val(slicer.speedDelay);
$slicerLayerHeight.val(slicer.layers.height);
$slicerLightOff.val(slicer.light.off);
$slicerLightOn.val(slicer.light.on);
//new
$slicerLightStrength.val(slicer.light.strength);
$slicerLightBottum.val(slicer.light.bottom);
$slicerDeclineSpeed.val(slicer.lifting.decline);
//$slicerBottomLayers.val(slicer.layers.bottom);
$slicerLiftingSpeed.val(slicer.lifting.speed);
$slicerLiftingHeight.val(slicer.lifting.height);
}
function updateSlicerSettings() {
settings.set('slicer.layers.height', $slicerLayerHeight.val());
settings.set('slicer.light.off', $slicerLightOff.val());
settings.set('slicer.light.on', $slicerLightOn.val());
//new
settings.set('slicer.light.strength', $slicerLightStrength.val());
settings.set('slicer.light.bottom', $slicerLightBottum.val());
settings.set('slicer.lifting.decline', $slicerDeclineSpeed.val());
//settings.set('slicer.layers.bottom', $slicerBottomLayers.val());
settings.set('slicer.lifting.speed', $slicerLiftingSpeed.val());
settings.set('slicer.lifting.height', $slicerLiftingHeight.val());
settings.set('slicer.output', $outputType.val());
settings.set('slicer.zip', $slicerMakeZipYes[0].checked);
//new
settings.set('slicer.folder', $slicerMakeFolderYes[0].checked);
settings.set('slicer.speed', $slicerSpeedYes[0].checked);
settings.set('slicer.speedDelay', $slicerSpeedDelay.val());
getSlice($sliderInput.slider('getValue'));
updateSliderUI();
}
var sliceInterval;
var expectedSliceInterval;
var currentSliceNumber;
var slicesNumber;
var zipFile;
var zipFolder;
var wowFile;
var WOWExport;
var FHDExport;
var SVGExport;
var PNGExport;
var layerHeight;
var zPosition;
var exposureTime;
var liftingSpeed;
var liftingHeight;
var liftingTime;
var estimatedTime;
function slice() {
currentSliceNumber++;
if (currentSliceNumber > slicesNumber) {
return endSlicing();
}
// debug
// console.log("currentSliceNumber", currentSliceNumber)
getSlice(currentSliceNumber);
$sliderInput.slider('setValue', currentSliceNumber);
var time = Date.now();
var diff = time - expectedSliceInterval;
!settings.get('slicer.speed') && viewer2dWin && setTimeout(function() {
sliceImage('none');
}, settings.get('slicer.light.on'));
expectedSliceInterval += sliceInterval;
setTimeout(slice, Math.max(0, sliceInterval - diff));
}
function endSlicing() {
if(WOWExport) {// GCode & export logic
// add gcode footer from settings
var gcode = settings.get('gcode');
wowFile += gcode.end;
zipFile.file("print.wow", wowFile, {binary: true});
// hotfix for mirror bug
flipGeometry();
} else if (FHDExport) {
// add gcode footer from settings
var gcode = settings.get('gcode'); // I believe same end gcode is valid for FHD as for standard sparkmaker - Adam
wowFile += gcode.end;
zipFolder.file("print.wow", wowFile, {binary: true}); // probably don't need binary, but doesn't seem to hurt
// hotfix for mirror bug
flipGeometry();
}
sliceImage('none');
$sidebar.find('input, button').prop('disabled', false);
$sliderInput.slider('enable');
$abortButton.addClass('hidden');
$sliceButton.removeClass('hidden');
$zipButton.prop('disabled', !zipFile);
}
function startSlicing() {
var times = settings.get('slicer.light');
if (settings.get('slicer.speed')) {
sliceInterval = parseInt(settings.get('slicer.speedDelay'));
}
else {
sliceInterval = parseInt(times.on) + parseInt(times.off);
}
expectedSliceInterval = Date.now() + sliceInterval;
slicesNumber = parseInt($slicerLayersValue.html());
currentSliceNumber = 0;
zipFile = null;
zipFolder = null;
wowFile = null;
WOWExport = null;
FHDExport = null;
SVGExport = null;
PNGExport = null;
if (settings.get('slicer.zip')) {
zipFile = new JSZip();
if (settings.get('slicer.folder')) {
zipFolder = zipFile.folder('slices');
}
zipFile.file("README.txt", 'Generated by SLAcer.js for SparkMaker\r\nhttps://n0sr3v.github.io/SLAcer.js/\r\n\r\nProject based on: \r\nhttps://github.com/lautr3k/SLAcer.js\r\nAppreciate this work!\r\n');
zipFile.file("slacer.json", JSON.stringify({
imageExtension: settings.get('slicer.output'),
imageDirectoryCreated: settings.get('slicer.folder') ? 'false' : 'true',
imageDirectory: !settings.get('slicer.folder') ? '' : 'slices',
screenWidth : settings.get('screen.width'),
screenHeight : settings.get('screen.height'),
screenSize : settings.get('screen.diagonal.size'),
screenUnit : settings.get('screen.diagonal.unit'),
layersNumber : slicesNumber,
layersHeight : settings.get('slicer.layers.height') / 1000, // mm
exposureTime : parseInt(settings.get('slicer.light.on')), // ms
exposureStrength : parseInt(settings.get('slicer.light.strength')), // ms
bottomExposureTime : parseInt(settings.get('slicer.light.bottom')), // ms
liftingSpeed : parseInt(settings.get('slicer.lifting.speed')), // mm/min
declineSpeed : parseInt(settings.get('slicer.lifting.decline')), // mm/min
liftingHeight : parseInt(settings.get('slicer.lifting.height')) // mm
}, null, 2));
if ($outputType.val() == 'wow') {
WOWExport = true;
}
else if ($outputType.val() == 'fhd') {
FHDExport = true;
}
else if ($outputType.val() == 'svg') {
SVGExport = true;
}
else if ($outputType.val() == 'png') {
PNGExport = true;
}
if (FHDExport) {
zipFolder = zipFile.folder('print-FHD');
}
}
if(WOWExport){// GCode logic
// hotfix for first layer bug - before flip geometry!
$sliderInput.slider('setValue', currentSliceNumber);
// hotfix for mirror bug
flipGeometry();
wowFile = "";
// Tests
/*
var array = new Uint8Array(2);
array[1]=255;
console.log(array);
var textDecoder = new TextDecoder("utf-8");
var binary_layer = textDecoder.decode(array);
console.log(binary_layer);
*/
//console.log(textDecoder.encode(binary_layer));
// use gcode header from settings
var gcode = settings.get('gcode');
wowFile += gcode.start;
} else if (FHDExport) {
// hotfix for first layer bug - before flip geometry!
$sliderInput.slider('setValue', currentSliceNumber);
// hotfix for mirror bug
flipGeometry();
wowFile = "";
// use gcode header from settings
var gcode = settings.get('gcode'); // I believe same start gcode is valid for FHD as for standard sparkmaker - Adam
wowFile += gcode.start;
}
slicesNumber && slice();
}
function waitForZeroLayer(callback){
if(currentSliceNumber === 0){
callback();
}
else{
setTimeout(waitForZeroLayer(callback), 250);
}
}
$zipButton.on('click', function(e) {
if (zipFile) {
var name = 'SLAcer';
if (loadedFile && loadedFile.name) {
name = loadedFile.name;
}
saveAs(zipFile.generate({type: 'blob'}), name + '.zip');
}
});
$sliceButton.on('click', function(e) {
$sidebar.find('input, button').prop('disabled', true);
$('.panel-heading button').prop('disabled', false);
$openViewer2D.prop('disabled', false);
$sliderInput.slider('disable');
$abortButton.prop('disabled', false);
$abortButton.removeClass('hidden');
$sliceButton.addClass('hidden');
startSlicing();
});
$abortButton.on('click', function(e) {
currentSliceNumber = slicesNumber + 1;
endSlicing();
});
$outputType.val(settings.get('slicer.output'));
$('#slicer-make-zip-' + (settings.get('slicer.zip') ? 'yes' : 'no')).prop('checked', true);
//new
$('#slicer-make-folder-' + (settings.get('slicer.folder') ? 'yes' : 'no')).prop('checked', true);
$('#slicer-speed-' + (settings.get('slicer.speed') ? 'yes' : 'no')).prop('checked', true);
$('#slicer input').on('input, change', updateSlicerSettings);
$('#slicer select').on('change', updateSlicerSettings);
updateSlicerUI();
// Build volume panel
var $buildVolumeBody = initPanel('buildVolume');
var $buildVolumeX = $buildVolumeBody.find('#build-volume-x');
var $buildVolumeY = $buildVolumeBody.find('#build-volume-y');
var $buildVolumeZ = $buildVolumeBody.find('#build-volume-z');
function updateBuildVolumeUI() {
var buildVolume = settings.get('buildVolume');
$buildVolumeX.val(buildVolume.size.x);
$buildVolumeY.val(buildVolume.size.y);
$buildVolumeZ.val(buildVolume.size.z);
updateBuildVolumeSizeStep();
}
function updateBuildVolumeSizeStep() {
var step = (settings.get('buildVolume.unit') == 'in') ? 0.01 : 1;
$buildVolumeX.prop('step', step);
$buildVolumeY.prop('step', step);
$buildVolumeZ.prop('step', step);
}
function updateBuildVolumeSettings() {
var unit = $('#build-volume input[type=radio]:checked').val();
if (unit != settings.get('buildVolume.unit')) {
var size = settings.get('buildVolume.size');
$buildVolumeX.val(parseUnit(size.x, unit));
$buildVolumeY.val(parseUnit(size.y, unit));
$buildVolumeZ.val(parseUnit(size.z, unit));
}
settings.set('buildVolume', {
size: {
x: $buildVolumeX.val(),
y: $buildVolumeY.val(),
z: $buildVolumeZ.val()
},
unit: unit
});
viewer3d.setBuildVolume(settings.get('buildVolume'));
slicer.mesh && viewer3d.dropObject(slicer.mesh);
viewer3d.render();
size && updateMeshInfoUI();
updateBuildVolumeSizeStep();
getSlice($sliderInput.slider('getValue'));
}
$('#build-volume-unit-' + settings.get('buildVolume.unit')).prop('checked', true);
$('#build-volume input[type=radio]').on('change', updateBuildVolumeSettings);
$('#build-volume input').on('input', updateBuildVolumeSettings);
updateBuildVolumeUI();
// Resin panel
var $resinBody = initPanel('resin');
var $resinPrice = $resinBody.find('#resin-price');
var $resinDensity = $resinBody.find('#resin-density');
function updateResinUI() {
var resin = settings.get('resin');
$resinDensity.val(resin.density);
$resinPrice.val(resin.price);
}
function updateResinSettings() {
settings.set('resin.price' , $resinPrice.val());
settings.set('resin.density', $resinDensity.val());
updateMeshInfoUI();
}
$('#resin input').on('input', updateResinSettings);
updateResinUI();
// Screen
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');
$screenWidth.val(screen.width);
$screenHeight.val(screen.height);
$screenDiagonalSize.val(screen.diagonal.size);
$screenDotPitch.html(viewer2d.dotPitch.toFixed(2));
viewer2d.setScreenResolution(screen);
}
function updateScreenSettings() {
var unit = $('#screen input[type=radio]:checked').val();
if (unit != settings.get('screen.diagonal.unit')) {
$screenDiagonalSize.val(
parseUnit(settings.get('screen.diagonal.size'), unit)
);
}
settings.set('screen', {
width : $screenWidth.val(),
height : $screenHeight.val(),
diagonal: {
size: $screenDiagonalSize.val(),
unit: unit
}
});
viewer2d.setScreenResolution(settings.get('screen'));
$screenDotPitch.html(viewer2d.dotPitch.toFixed(2));
getSlice($sliderInput.slider('getValue'));
}
$('#screen-diagonal-unit-' + settings.get('screen.diagonal.unit')).prop('checked', true);
$('#screen input[type=radio]').on('change', updateScreenSettings);
$('#screen input').on('input', updateScreenSettings);
updateScreenUI();
// Colors
var $colorsBody = initPanel('colors');
var $meshColor = $colorsBody.find('#mesh-color');
var $sliceColor = $colorsBody.find('#slice-color');
function updateColorsUI() {
var colors = settings.get('colors');
$meshColor.val(colors.mesh);
$sliceColor.val(colors.slice);
}
updateColorsUI();
$meshColor.colorpicker({ format: 'hex' });
$sliceColor.colorpicker({ format: 'hex' });
$meshColor.colorpicker().on('changeColor.colorpicker', function(e) {
if (slicer.mesh && slicer.mesh.material) {
var hexString = e.color.toHex();
var hexInteger = hexToDec(hexString);
settings.set('colors.mesh', hexString);
slicer.mesh.material.color.setHex(hexInteger);
viewer3d.render();
}
});
$sliceColor.colorpicker().on('changeColor.colorpicker', function(e) {
if (shapes && shapes.length) {
var hexString = e.color.toHex();
var hexInteger = hexToDec(hexString);
settings.set('colors.slice', hexString);
for (var i = 0, il = shapes.length; i < il; i++) {
shapes[i].material.color.setHex(hexInteger);
}
viewer3d.render();
}
});
// gcode
var $gcodeBody = initPanel('gcode');
var $gcodeStart = $gcodeBody.find('#start');
var $gcodeEnd = $gcodeBody.find('#end');
var $gcodeResetStart = $gcodeBody.find('#resetStart');
var $gcodeResetEnd = $gcodeBody.find('#resetEnd');
function updateGcodeUI() {
var gcode = settings.get('gcode');
$gcodeStart.val(gcode.start);
$gcodeEnd.val(gcode.end);
}
function updateGcodeSettings() {
var startText = $gcodeStart.val();
var endText = $gcodeEnd.val();
settings.set('gcode', {
start : $gcodeStart.val(),
end : $gcodeEnd.val(),
});
}
function resetGcodeStart() {
$gcodeStart.val(getDefaultGcodeStart());
updateGcodeSettings();
}
function resetGcodeEnd() {
$gcodeEnd.val(getDefaultGcodeEnd());
updateGcodeSettings();
}
function getDefaultGcodeStart() {
return 'G21;\nG91;\nM17;\nM106 S0;\nG28 Z0;\n;W:480;\n;H:854;\n'; // see https://github.com/bastirichter/Sparkmaker/blob/master/file_format.md for details
}
function getDefaultGcodeEnd() {
return 'M106 S0;\nG1 Z20.0;\nG4 S300;\nM18;'; // see https://github.com/bastirichter/Sparkmaker/blob/master/file_format.md for details
}
$gcodeStart.on('change', updateGcodeSettings);
$gcodeEnd.on('change', updateGcodeSettings);
$gcodeResetStart.on('click', resetGcodeStart);
$gcodeResetEnd.on('click', resetGcodeEnd);
updateGcodeUI();
// Alert
var $alertPanel = $('#alert');
var $alertMessage = $alertPanel.find('.message');
// Transform
var $transformBody = initPanel('transform');
var $transformAction = $transformBody.find('#transform-action');
var $transformUniform = $transformBody.find('#transform-uniform');
var $transformX = $transformBody.find('#transform-x');
var $transformY = $transformBody.find('#transform-y');
var $transformZ = $transformBody.find('#transform-z');
var $transformButtons = $transformBody.find('button');
var $transformMirrorYes = $transformBody.find('#transform-mirror-yes');
var $transformMirrorNo = $transformBody.find('#transform-mirror-no');
var transformAction, transformations;
function resetTransformValues() {
transformAction = 'scale';
transformations = {
scale : { x:1, y:1 , z:1 },
rotate : { x:0, y:0 , z:0 },
translate: { x:0, y:0 , z:0 }
};
updateTransformAction();
}
function updateTransformAction() {
transformAction = $transformAction.val();
var axis = transformations[transformAction];
var min, max, step;
if (transformAction == 'scale') {
min = 0.01;
max = 999;
step = 0.01;
}
else if (transformAction == 'rotate') {
min = 0;
max = 360;
step = 1;
}
else {
min = -9999;
max = 9999;
step = 1;
}
$transformUniform.toggleClass('hidden', transformAction != 'scale');
$transformZ.parent().toggleClass('hidden', transformAction == 'translate');
$transformX.prop('min', min);
$transformY.prop('min', min);
$transformZ.prop('min', min);
$transformX.prop('max', max);
$transformY.prop('max', max);
$transformZ.prop('max', max);
$transformX.prop('step', step);
$transformY.prop('step', step);
$transformZ.prop('step', step);
$transformX.val(axis.x);
$transformY.val(axis.y);
$transformZ.val(axis.z);
}
function updateTransformValues() {
var current = transformations[transformAction];
var uniform = $('#transform-uniform input[type=radio]:checked').val() == 'yes';
var input = {
x: parseFloat($transformX.val()),
y: parseFloat($transformY.val()),
z: parseFloat($transformZ.val())
};
input.x = isNaN(input.x) ? current.x : input.x;
input.y = isNaN(input.y) ? current.y : input.y;
input.z = isNaN(input.z) ? current.z : input.z;
$transformX.val(input.x);
$transformY.val(input.y);
$transformZ.val(input.z);
if (transformAction == 'scale') {
if (uniform) {
if (input.x != current.x) {
var ratio = current.x / input.x;
input.y = (current.y / ratio).toFixed(2);
input.z = (current.z / ratio).toFixed(2);
$transformY.val(input.y);
$transformZ.val(input.z);
}
else if (input.y != current.y) {
var ratio = current.y / input.y;
input.x = (current.x / ratio).toFixed(2);
input.z = (current.z / ratio).toFixed(2);
$transformX.val(input.x);
$transformZ.val(input.z);
}
else if (input.z != current.z) {
var ratio = current.z / input.z;
input.x = (current.x / ratio).toFixed(2);
input.y = (current.y / ratio).toFixed(2);
$transformX.val(input.x);
$transformY.val(input.y);
}
}
input.x <= 0 && (input.x = 1);
input.y <= 0 && (input.y = 1);
input.z <= 0 && (input.z = 1);
slicer.mesh.geometry.scale(
input.x / current.x,
input.y / current.y,
input.z / current.z
);
}
else if (transformAction == 'rotate') {
var deg = Math.PI / 180;
var offsets = {
x: input.x - current.x,
y: input.y - current.y,
z: input.z - current.z
};
slicer.mesh.geometry.rotateX(offsets.x * deg);
slicer.mesh.geometry.rotateY(offsets.y * deg);
slicer.mesh.geometry.rotateZ(offsets.z * deg);
}
else {
var offsets = {
x: input.x - current.x,
y: input.y - current.y
};
slicer.mesh.geometry.translate(offsets.x, offsets.y, 0);
}
current.x = input.x;
current.y = input.y;
current.z = input.z;
if (transformAction != 'translate') {
loadGeometry(slicer.mesh.geometry, false);
// stay at current position
var current = transformations['translate'];
slicer.mesh.geometry.translate(current.x, current.y, current.z);
}
getSlice($sliderInput.slider('getValue'));
}
$transformButtons.on('click', function(e) {
var $this = $(this);
var axis = $this.data('axis');
var action = $this.data('action');
var value = transformations[transformAction][axis];
var $target = $transformBody.find('#transform-' + axis);
$target.val(value + (action == '+' ? 1 : -1));
updateTransformValues();
});
function flipGeometry() {
settings.set('transform.mirror', $transformMirrorYes[0].checked);
loadGeometry(slicer.mesh.geometry, true);
getSlice($sliderInput.slider('getValue'));
}
$transformMirrorYes.on('change', flipGeometry);
$transformMirrorNo.on('change', flipGeometry);
$('#transform-mirror-' + (settings.get('transform.mirror') ? 'yes' : 'no')).prop('checked', true);
$('#transform select').on('change', updateTransformAction);
$('#transform input').on('change', updateTransformValues);
resetTransformValues();
// UI resize
function resizeUI() {
var width = $main.width();
var height = $main.height();
$sliderElement.height(height - 80);
viewer3d.setSize({ width : width, height: height });
viewer3d.render();
}
$(window).resize(resizeUI);
resizeUI();
// -----------------------------------------------------------------------------
// STL loader
// -----------------------------------------------------------------------------
// Loader instance
var loader = new MeshesJS.STLLoader($main[0]); // drop target
// Load an geometry
function loadGeometry(geometry, mirror) {
try {
// remove old mesh and plane
slicer.mesh && viewer3d.removeObject(slicer.mesh);
// remove old shapes
removeShapes();
// flip geometry
if (mirror) {
geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
}
// load new mesh in slicer
slicer.loadMesh(new SLAcer.Mesh(geometry, new THREE.MeshPhongMaterial({
color: hexToDec(settings.get('colors.mesh')), side: THREE.DoubleSide
})));
// add new mesh and render view
viewer3d.addObject(slicer.mesh);
viewer3d.render();
// update mesh info
updateMeshInfoUI();
// get first slice
//getSlice(1);
}
catch(e) {
errorHandler(e);
}
}
// Haaaaaaaaaaaaaaaaaa!!!!
function ultraMegaDirtyFix() {
$transformBody.find('#transform-x').val(1.1);
$transformBody.find('#transform-y').val(1.1);
$transformBody.find('#transform-z').val(1.1);
updateTransformValues();
$transformBody.find('#transform-x').val(1);
$transformBody.find('#transform-y').val(1);
$transformBody.find('#transform-z').val(1);
updateTransformValues();
}
// On Geometry loaded
loader.onGeometry = function(geometry) {
resetTransformValues();
loadGeometry(geometry, settings.get('transform.mirror'));
ultraMegaDirtyFix();
};
// On loading error
loader.onError = errorHandler;
// -----------------------------------------------------------------------------
// load example
// -----------------------------------------------------------------------------
// example STL file
//var stl = 'stl/Octocat-v2.stl';
var stl = 'stl/StressTest.stl';
//var stl = 'stl/SLAcer.stl';
//var stl = 'stl/SparkMaker.stl';
//var stl = 'stl/SparkMaker_fixed.stl';
// File url
// var url = 'http://' + window.location.hostname + window.location.pathname + stl;
var url = window.location.href + stl;
// Create http request object
var xmlhttp = new XMLHttpRequest();
// Get the file contents
xmlhttp.open("GET", url);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if(xmlhttp.status == 200){
loader.loadString(xmlhttp.responseText);
}else{
errorHandler('xmlhttp: ' + xmlhttp.statusText);
}
}
}
xmlhttp.send();
You can’t perform that action at this time.