Compare commits

...

30 Commits

Author SHA1 Message Date
peteruithoven f8032d7411 Merge branch 'develop' 2017-06-23 12:36:16 +02:00
peteruithoven 2acb06c3ed Adding forgotten grunt task to make file: template
@companje This would add build info, create main.js.out which was used in later concat tasks. Without this task the final code would lack the main.js code.
2017-06-23 12:28:35 +02:00
peteruithoven daed62937c Merged master into develop 2016-07-26 15:24:38 +02:00
peteruithoven 058fff8b34 Handle multiple tags in buildinfo 2016-06-15 14:50:09 +02:00
peteruithoven 28808078ad Enable using common npm start script 2016-06-15 14:49:46 +02:00
peteruithoven 4e18fa0f56 Execute new gitinfo in OpenWRT build 2016-05-11 13:28:44 +02:00
peteruithoven 225a173da7 Altered Build/Compile to run from shared folder
so grunt can access git info
2016-05-11 13:28:15 +02:00
peteruithoven d2bc62b092 Fix stopping while sending
Fixes https://github.com/Doodle3D/WiFi-Box/issues/9
2016-05-11 12:22:54 +02:00
peteruithoven 28ce8ff479 OpenWRT Build/Prepare fix
Copy js files to build dir so grunt can use them
Relevant for #307
2016-05-10 16:06:27 +02:00
peteruithoven fbcdaad54a Fix OpenWRT makefile Build/Compile step
Fixes #307
2016-05-10 15:21:49 +02:00
Wouter R 4a3da30ebd Log git/version information in web console (#305).
The information is dynamically inserted when grunt is run.
2016-04-23 17:36:35 +02:00
Wouter R 533968bb04 Stability fixes on unstable network (#304):
- when a sequence number mismatch is received and the wifibox expects the chunk immediately following the current one, skip ahead; this often happens after a network disconnect.
- retry sending a print part when the wifibox was disconnected (i.e. checkStatus failed and set state to WIFIBOX_DISCONNECTED_STATE).
2016-04-19 18:03:52 +02:00
Wouter R 0a9ceee49a Log statement fixes. 2016-04-19 18:03:17 +02:00
Wouter R 50d964e611 Change several log statements for Safari to print on one line instead of multiple. 2016-04-19 00:28:55 +02:00
Wouter R 656e37670e Log more information on AJAX failure and explicitly log when buffer is full. 2016-03-11 15:49:32 +01:00
Wouter R 4752199cfb Remove outdated comment. 2016-02-17 18:52:17 +01:00
Wouter R c742740078 Include sequence numbers in console.log message when sending print. 2016-02-14 17:29:23 +01:00
Wouter R 578fba4f63 Sequence numbering + stop button:
- send sequence numbers along with gcode to wifibox;
- remove 'disable stop button hack';
- show error to user in case of sequencing errors, except when in stopping state.

Should fix #226.
2016-02-14 17:13:13 +01:00
Wouter R bca548def5 js/Printer.js: partly clean up sendPrinterPart. 2016-02-14 16:42:21 +01:00
Wouter R a5d3e88f0a js/Printer.js:
- change this.sendLength to Printer.MAX_LINES_PER_POST;
- re-order object variable declarations.
2016-02-14 16:21:52 +01:00
Wouter R 456531b15f Change 'first' parameter of printer/print call to 'clear'. 2016-02-14 00:37:17 +01:00
Wouter R 4f5e1143b4 Send total number of lines to be printed along with every gcode chunk. 2016-02-13 23:45:48 +01:00
Wouter R a9f7fe1c78 Use bufferSize and maxBufferSize from printer progress to wait until buffer load drops below given ratio after buffer_full has been received. 2016-02-12 17:34:05 +01:00
Wouter R 8f0943a53b Update license-spec.lua for changed directory structure. 2016-02-12 17:06:03 +01:00
Wouter R 5c07947fe5 Code refactoring. 2016-01-06 20:35:19 +01:00
Wouter R d48944e448 Add checkbox for new setting 'printer.bottomEnableTraveling'.
Implement bottom layer traveling in GCode generation as well as sketch rendering.
2016-01-06 19:26:07 +01:00
Wouter R 46bcd54a1a Only show warning about verbose logging when level is set to verbose or bulk.
Small improvements to when log level warnings are shown.
2016-01-06 16:38:59 +01:00
peteruithoven 25c51c3e5c settings log level layout 2016-01-06 16:11:34 +01:00
Wouter R c2f5f890c7 Add dropdown menu to settings window for log level selection with appropriate warnings. 2016-01-06 14:25:17 +01:00
peteruithoven 09fcdbea31 Month fix #294 2015-09-15 10:42:45 +02:00
21 changed files with 325 additions and 130 deletions

9
.gitignore vendored
View File

@ -18,18 +18,11 @@ img/logo/logo_smaller.png
img/logo/logo_smaller_8bit.png
img/logo/logo_smaller_wide_8bit.png
img/logo/logo_smallest.png
css/_backup20131010/*
css/_backup20131011/*
d3d_btns.css
index.html.orig
js/Thermometer.js.orig
js/buttonbehaviors.js.orig
js/gcodeGenerating_v01.js.orig
js/init_layout backup20130918.js
js/main.js.orig
js/previewRendering_v02.js.orig
less/verticalshapes.css
less/verticalshapes_backup.css
__settings.html
css/_settings.css
node_modules/*
js/main.js.out

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
included=//*.js

View File

@ -10,6 +10,32 @@ module.exports = function(grunt) {
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
gitinfo: {
options: {},
commands: { 'tag': ['tag', '--points-at', 'HEAD'] }
},
template: {
'add_build_info': {
options: {
data: function() {
grunt.task.requires('gitinfo');
var gi = grunt.config('gitinfo');
var lbc = gi.local.branch.current;
var tags = (gi.tag == '') ? 'no_tag' : gi.tag;
tags = tags.split('\n').join(',');
var commitMsg = lbc.lastCommitMessage.slice(1, -1).split('\n')[0].replace(/"/g, '\\\"');
var buildInfo = lbc.shortSHA + "/" + lbc.name + "/" + tags +
" (" + lbc.lastCommitTime.slice(1, -1) + "; \'" + commitMsg + "'";
return { 'build_info': buildInfo };
}
},
files: {
'js/main.js.out': ['js/main.js']
}
}
},
concat: {
options: {
// separator: ';'
@ -22,7 +48,8 @@ module.exports = function(grunt) {
'js/*.js',
// make sure we put main.js last
'!js/main.js',
'js/main.js', ],
'js/main.js.out'
],
dest: 'www/js/<%= pkg.name %>.js'
}
},
@ -129,6 +156,8 @@ module.exports = function(grunt) {
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-gitinfo');
grunt.loadNpmTasks('grunt-template');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
@ -139,6 +168,8 @@ module.exports = function(grunt) {
// Default task.
grunt.registerTask('default', [
'gitinfo',
'template',
'less',
'autoprefixer',
'cssmin',

View File

@ -34,6 +34,7 @@ endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) js $(PKG_BUILD_DIR)/
$(CP) less $(PKG_BUILD_DIR)/
$(CP) www $(PKG_BUILD_DIR)/
$(CP) Gruntfile.js $(PKG_BUILD_DIR)/
@ -43,12 +44,16 @@ define Build/Prepare
endef
define Build/Compile
# We're running grunt in the shared folder, so
# grunt can access git info
npm install
ifeq ($(CONFIG_DOODLE3D_CLIENT_MINIFY_JS),y)
grunt less autoprefixer cssmin concat uglify
grunt gitinfo template less autoprefixer cssmin concat uglify
else
grunt less autoprefixer cssmin concat
grunt gitinfo template less autoprefixer cssmin concat
endif
# Copy compiled files to build dir
$(CP) www $(PKG_BUILD_DIR)/
endef
define Package/doodle3d-client/install

View File

@ -25,7 +25,7 @@ function Message() {
this.$element = $element;
}
this.set = function(contents,mode,autoHide,disableEffect) {
console.log("Message:set: ",contents,mode,autoHide,disableEffect);
//console.log("Message:set: ",contents,mode,autoHide,disableEffect);
if(disableEffect) {
self.fill(contents,mode,autoHide)
} else{

View File

@ -19,6 +19,7 @@ function setPrintprogress(val) {
//*/
function Printer() {
/* CONSTANTS */
Printer.WIFIBOX_DISCONNECTED_STATE = "wifibox disconnected";
Printer.UNKNOWN_STATE = "unknown"; // happens when a printer is connection but there isn't communication yet
@ -32,11 +33,29 @@ function Printer() {
Printer.ON_BEFORE_UNLOAD_MESSAGE = "You're doodle is still being sent to the printer, leaving will result in a incomplete 3D print";
//after buffer full message has been received, wait until the buffer load is below this ratio before sending new data
Printer.GCODE_BUFFER_WAIT_LOAD_RATIO = 0.75;
Printer.BUFFER_SPACE_WAIT_TIMEOUT = 30000; // how often to recheck buffer load
//time to wait when wifibox connection is lost while printing
Printer.DISCONNECTED_RETRY_DELAY = 5000;
Printer.MAX_LINES_PER_POST = 500; // max amount of gcode lines per post (limited because WiFi box can't handle too much)
Printer.MAX_GCODE_SIZE = 10; // max size of gcode in MB's (estimation)
// Events
Printer.UPDATE = "update";
/* MEMBER VARIABLES */
this.temperature = 0;
this.targetTemperature = 0;
this.currentLine = 0;
this.totalLines = 0;
this.bufferedLines = 0;
this.bufferSize = 0;
this.maxBufferSize = 0;
this.state = Printer.UNKNOWN_STATE;
this.hasControl = true; // whether this client has control access
@ -47,8 +66,8 @@ function Printer() {
this.timeoutTime = 3000;
this.sendPrintPartTimeoutTime = 5000;
this.gcode; // gcode to be printed
this.sendLength = 500; // max amount of gcode lines per post (limited because WiFi box can't handle too much)
this.gcode = []; // gcode to be printed
this.gcodeNumChunks = 0; //number of chunks to be sent (used for sequence numbering)
this.retryDelay = 2000; // retry setTimout delay
this.retrySendPrintPartDelay; // retry setTimout instance
@ -56,12 +75,10 @@ function Printer() {
this.retryStopDelay; // retry setTimout instance
this.retryPreheatDelay; // retry setTimout instance
Printer.MAX_GCODE_SIZE = 10; // max size of gcode in MB's (estimation)
this.stateOverruled = false;
// Events
Printer.UPDATE = "update";
/* FUNCTIONS */
var self = this;
@ -120,6 +137,7 @@ function Printer() {
this.sendIndex = 0;
this.gcode = gcode;
this.gcodeNumChunks = Math.ceil(this.gcode.length / Printer.MAX_LINES_PER_POST);
//console.log(" gcode[20]: ",gcode[20]);
var gcodeLineSize = this.byteSize(gcode[20]);
@ -142,7 +160,7 @@ function Printer() {
//this.targetTemperature = settings["printer.temperature"]; // slight hack
this.sendPrintPart(this.sendIndex, this.sendLength);
this.sendPrintPart(this.sendIndex, Printer.MAX_LINES_PER_POST);
}
this.byteSize = function(s){
@ -150,26 +168,43 @@ function Printer() {
}
this.sendPrintPart = function(sendIndex,sendLength) {
console.log("Printer:sendPrintPart sendIndex: " + sendIndex + "/" + this.gcode.length + ", sendLength: " + sendLength);
var sendPercentage = Math.round(sendIndex/this.gcode.length*100);
message.set("Sending doodle to printer: "+sendPercentage+"%",Message.NOTICE,false,true);
var firstOne = (sendIndex == 0)? true : false;
var start = firstOne; // start printing right away
var self = this;
// Abort if stopping
// sendPrintPart can be called by delayed retry after request timeout for example
if (self.state === Printer.STOPPING_STATE) return;
var completed = false;
if (this.gcode.length < (sendIndex + sendLength)) {
console.log(" sending less than max sendLength (and last)");
sendLength = this.gcode.length - sendIndex;
//lastOne = true;
completed = true;
}
var gcodePart = this.gcode.slice(sendIndex, sendIndex+sendLength);
var postData = { gcode: gcodePart.join("\n"), first: firstOne, start: start};
var self = this;
/* prepare post data */
var gcodePart = this.gcode.slice(sendIndex, sendIndex + sendLength);
var firstOne = (sendIndex == 0) ? true : false;
var start = firstOne; // start printing right away
var seqNum = Math.floor(sendIndex / Printer.MAX_LINES_PER_POST);
var postData = {
gcode: gcodePart.join("\n"), total_lines: this.gcode.length,
clear: firstOne, start: start,
seq_number: seqNum, seq_total: this.gcodeNumChunks
};
/* inform user what's going on */
var lessThanMaxText = completed ? " (last one, max=" + Printer.MAX_LINES_PER_POST + ")" : "";
console.log("Printer:sendPrintPart: sendIndex=" + sendIndex + "/" + this.gcode.length +
", sendLength=" + sendLength + lessThanMaxText +
", sequence numbers: " + seqNum + "/" + this.gcodeNumChunks);
var sendPercentage = Math.round(sendIndex / this.gcode.length * 100);
message.set("Sending doodle to printer: " + sendPercentage + "%", Message.NOTICE, false, true);
/* send data */
if (communicateWithWifibox) {
$.ajax({
url: this.wifiboxURL + "/printer/print",
@ -178,13 +213,13 @@ function Printer() {
dataType: 'json',
timeout: this.sendPrintPartTimeoutTime,
success: function(data){
console.log("Printer:sendPrintPart response: ",data);
//console.log("Printer:sendPrintPart success response: ", data);
if(data.status == "success") {
if (completed) {
console.log("Printer:sendPrintPart:gcode sending completed");
console.log("Printer:sendPrintPart: gcode sending completed");
this.gcode = [];
btnStop.css("display","block"); // hack
this.gcodeNumChunks = 0;
self.removeLeaveWarning();
message.set("Doodle has been sent to printer...",Message.INFO,true);
//self.targetTemperature = settings["printer.temperature"]; // slight hack
@ -195,23 +230,48 @@ function Printer() {
if(self.state == Printer.PRINTING_STATE || self.state == Printer.BUFFERING_STATE) {
//console.log("Printer:sendPrintPart:sending next part");
self.sendPrintPart(sendIndex + sendLength, sendLength);
} else if (Printer.WIFIBOX_DISCONNECTED_STATE) {
console.warn("Printer:sendPrintPart: wifibox connection lost while printing, retrying in " + (Printer.DISCONNECTED_RETRY_DELAY / 1000) + " seconds");
clearTimeout(self.retrySendPrintPartDelay);
self.retrySendPrintPartDelay = setTimeout(function() {
console.log("Printer:sendPrintPart: retrying after wifibox disconnect was detected");
self.sendPrintPart(sendIndex, sendLength);
}, Printer.DISCONNECTED_RETRY_DELAY);
}
}
} else if (data.status == "fail") {
if (data.data.status == "buffer_full") {
console.log("Printer:sendPrintPart: print server reported buffer full, pausing data transmission");
//this will wait in a setTimeout loop until enough room is available and then call sendPrintPart again.
self.waitForBufferSpace(sendIndex, sendLength);
} else if (data.data.status == "seq_num_mismatch" && data.data.seq_number == seqNum) {
console.warn("Printer:sendPrintPart: received sequence error, server is one chunk ahead. Proceeding with next chunk...");
self.sendPrintPart(sendIndex + sendLength, sendLength);
} else {
console.error("Printer:sendPrintPart: unexpected failure response for API endpoint printer/print (" +
data.data.status + ", current server seq. info: " + data.data.seq_number + "/" + data.data.seq_total + ")");
//sequence errors should not occur, except perhaps when 'stop' was clicked while still sending (https://github.com/Doodle3D/doodle3d-client/issues/226).
if (self.state != Printer.STOPPING_STATE) {
message.set("Unexpected error sending doodle to printer (" + data.data.status + "), please retry", Message.ERROR, false, true);
}
}
}
// after we know the first gcode packed has bin received or failed
// after we know the first gcode part has been received or failed
// (and the driver had time to update the printer.state)
// we start checking the status again
if(sendIndex == 0) {
self.startStatusCheckInterval();
}
}
}).fail(function() {
console.log("Printer:sendPrintPart: failed");
}).fail(function(jqXHr, textStatus, errorThrown) {
console.error("Printer:sendPrintPart: failed (AJAX status: '" + textStatus + "') AJAX exception (if any):", errorThrown);
console.warn("Printer:sendPrintPart: retrying in " + (Printer.DISCONNECTED_RETRY_DELAY / 1000) + " seconds");
clearTimeout(self.retrySendPrintPartDelay);
self.retrySendPrintPartDelay = setTimeout(function() {
console.log("request printer:sendPrintPart failed retry");
console.log("Printer:sendPrintPart: retrying after AJAX failure");
self.sendPrintPart(sendIndex, sendLength)
},self.retryDelay); // retry after delay
}, Printer.DISCONNECTED_RETRY_DELAY);
// after we know the gcode packed has bin received or failed
// (and the driver had time to update the printer.state)
@ -222,13 +282,47 @@ function Printer() {
console.log ("Printer >> f:sendPrintPart() >> communicateWithWifibox is false, so not executing this function");
}
}
/*
* Called by sendPrintPart when a buffer_full fail response is received.
* This function keeps calling itself until the GCodeBuffer's load ratio
* drops below a predefined value and then calls sendPrintPart again.
*/
this.waitForBufferSpace = function(sendIndex,sendLength) {
var fillRatio = this.bufferSize / this.maxBufferSize;
var self = this;
//console.log("buffer fill state: " + self.bufferSize + "/" + self.maxBufferSize + " (" + fillPercent + "%)");
if (fillRatio >= Printer.GCODE_BUFFER_WAIT_LOAD_RATIO) {
var fillPercent = (fillRatio * 100).toFixed(2);
console.log("Printer:waitForBufferSpace: waiting until gcode buffer load ratio is below " +
(Printer.GCODE_BUFFER_WAIT_LOAD_RATIO * 100) + "% (current: " + fillPercent + "% of " +
(self.maxBufferSize / 1024) + "KiB)");
self.waitForBufferSpaceDelay = setTimeout(function() { self.waitForBufferSpace(sendIndex, sendLength); }, Printer.BUFFER_SPACE_WAIT_TIMEOUT);
} else {
if(self.state == Printer.PRINTING_STATE || self.state == Printer.BUFFERING_STATE) {
console.log("Printer:waitForBufferSpace: load ratio dropped below " + (Printer.GCODE_BUFFER_WAIT_LOAD_RATIO * 100) + "%, calling sendPrintPart...");
self.sendPrintPart(sendIndex, sendLength);
} else {
console.log("Printer:waitForBufferSpace: load ratio dropped far enough but printer state is not printing or buffering anymore, not resuming.");
}
}
}
this.stop = function() {
console.log("Printer:stop");
var self = this;
if (self.retrySendPrintPartDelay !== undefined) {
clearTimeout(self.retrySendPrintPartDelay);
}
if (self.waitForBufferSpaceDelay !== undefined) {
clearTimeout(self.waitForBufferSpaceDelay);
}
endCode = generateEndCode();
console.log(" endCode: ",endCode);
var postData = { gcode: endCode.join("\n")};
var self = this;
if (communicateWithWifibox) {
$.ajax({
url: this.wifiboxURL + "/printer/stop",
@ -325,7 +419,9 @@ function Printer() {
// progress
self.currentLine = data.current_line;
self.totalLines = data.total_lines;
self.bufferedLines = data.buffered_lines
self.bufferedLines = data.buffered_lines;
self.bufferSize = data.buffer_size;
self.maxBufferSize = data.max_buffer_size;
// access
self.hasControl = data.has_control;

View File

@ -25,7 +25,7 @@ function shapeMoveTo(x,y) {
_points.push([x, y, true]);
adjustBounds(x, y);
adjustPreviewTransformation();
draw(x, y, .5);
draw(x, y, -1);
}
function shapeLineTo(x,y) {

View File

@ -116,7 +116,7 @@ function loadFromSvg(svgData) {
adjustBounds(x, y);
adjustPreviewTransformation();
if (isMove) draw(x, y, .5);
if (isMove) draw(x, y, -1);
else draw(x, y);
}
p++;

View File

@ -232,8 +232,6 @@ function print(e) {
//setState(Printer.BUFFERING_STATE,printer.hasControl);
printer.overruleState(Printer.BUFFERING_STATE);
btnStop.css("display","none"); // hack
// we put the gcode generation in a little delay
// so that for example the print button is disabled right away
clearTimeout(gcodeGenerateDelayer);
@ -358,7 +356,7 @@ function setState(newState,newHasControl) {
prevState = state;
console.log("setState: ",prevState," > ",newState," ( ",newHasControl,")");
console.log("setState: " + prevState + " > " + newState + " ( " + newHasControl + ")");
setDebugText("State: "+newState);
// print button

View File

@ -97,52 +97,66 @@ function initDoodleDrawing() {
* CANVAS DRAWING FUNCTION
*
* * * * * * * * * */
function draw(_x, _y, _width) {
//console.log("canvasDrawing:draw");
// console.log("f:draw() >> _width: " + _width);
if (prevX == 0 && prevY ==0) {
//If _width is not specified, it is calculated from the distance between this and the previous point.
//If _width is negative, the path is 'floating', and only drawn if the setting printer.bottomEnableTraveling is true.
function draw(_x, _y, _width) {
//console.log("canvasDrawing:draw");
//console.log("f:draw() >> _width: " + _width);
if (prevX == 0 && prevY == 0) {
prevX = _x;
prevY = _y;
}
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(_x, _y);
if (_width != undefined) {
ctx.lineWidth = _width;
} else {
if (drawVariableLineWeight) {
var dist = Math.sqrt(Math.pow((prevX - _x), 2) + Math.pow((prevY - _y), 2));
if (dist < 10) {
lineweight += .25;
} else if (dist < 20) {
lineweight += .5;
} else if (dist < 30) {
lineweight += .75;
} else if (dist < 50) {
lineweight += 1;
} else if (dist < 80) {
lineweight += 1.5;
} else if (dist < 120) {
lineweight += 2.25;
} else if (dist < 170) {
lineweight += 3.5;
} else {
lineweight += 2;
}
lineweight = Math.min(lineweight, 30);
lineweight *= 0.90;
lineweight = Math.max(lineweight, 1.0);
var lineWeight = null;
if (_width != undefined && _width < 0) {
if (settings['printer.bottomEnableTraveling']) {
ctx.moveTo(_x, _y);
} else {
lineweight = 2;
lineWeight = 0.5;
}
} else {
if (_width != undefined) {
lineWeight = _width;
} else {
if (drawVariableLineWeight) {
var dist = Math.sqrt(Math.pow((prevX - _x), 2) + Math.pow((prevY - _y), 2));
if (dist < 10) {
lineWeight += .25;
} else if (dist < 20) {
lineWeight += .5;
} else if (dist < 30) {
lineWeight += .75;
} else if (dist < 50) {
lineWeight += 1;
} else if (dist < 80) {
lineWeight += 1.5;
} else if (dist < 120) {
lineWeight += 2.25;
} else if (dist < 170) {
lineWeight += 3.5;
} else {
lineWeight += 2;
}
lineWeight = Math.min(lineWeight, 30);
lineWeight *= 0.90;
lineWeight = Math.max(lineWeight, 1.0);
} else {
lineWeight = 2;
}
}
ctx.lineWidth = lineweight;
}
ctx.lineCap = 'round';
ctx.stroke();
if (lineWeight != null) {
ctx.lineCap = 'round';
ctx.lineWidth = lineWeight;
ctx.lineTo(_x, _y);
ctx.stroke();
}
prevX = _x;
prevY = _y;
@ -202,7 +216,7 @@ function redrawDoodle(recalcBoundsAndTransforms) {
for (var i = 0; i < _points.length; i++) {
// console.log(" drawing points " + _points[i]);
if (_points[i][2] == true) {
draw(_points[i][0], _points[i][1], 0.5);
draw(_points[i][0], _points[i][1], -1);
} else {
draw(_points[i][0], _points[i][1]);
}
@ -301,7 +315,7 @@ function onCanvasMouseDown(e) {
_points.push([x, y, true]);
adjustBounds(x, y);
adjustPreviewTransformation();
draw(x, y, 0.5);
draw(x, y, -1);
}
var prevPoint = {x:-1, y:-1};
@ -323,18 +337,9 @@ function onCanvasMouseMove(e) {
y = e.layerY;
}
if (prevPoint.x != -1 || prevPoint.y != -1) {
var dist = Math.sqrt(((prevPoint.x - x) * (prevPoint.x - x)) + ((prevPoint.y - y) * (prevPoint.y - y)));
if (dist > 5) { // replace by setting: doodle3d.simplify.minDistance
_points.push([x, y, false]);
adjustBounds(x, y);
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
prevPoint.y = y;
}
} else {
// this is called once, every time you start to draw a line
var prevPresent = prevPoint.x != -1 || prevPoint.y != -1;
var dist = prevPresent ? Math.sqrt(Math.pow((prevPoint.x - x), 2) + Math.pow((prevPoint.y - y), 2)) : undefined;
if (!prevPresent || dist > 5) { // replace dist check by setting: doodle3d.simplify.minDistance
_points.push([x, y, false]);
adjustBounds(x, y);
adjustPreviewTransformation();
@ -342,7 +347,7 @@ function onCanvasMouseMove(e) {
prevPoint.x = x;
prevPoint.y = y;
}
// DEBUG
// $("#textdump").text("");
// $("#textdump").append("doodlebounds:" + doodleBounds + "\n");
@ -401,7 +406,7 @@ function onCanvasTouchDown(e) {
_points.push([x, y, true]);
adjustBounds(x, y);
adjustPreviewTransformation();
draw(x, y, .5);
draw(x, y, -1);
movementCounter = 0;
@ -424,19 +429,11 @@ function onCanvasTouchMove(e) {
//console.log("f:onCanvasTouchMove >> x,y = "+x+","+y+" , e: " , e);
if (prevPoint.x != -1 || prevPoint.y != -1) {
var dist = Math.sqrt(Math.pow((prevPoint.x - x), 2) + Math.pow((prevPoint.y - y), 2));
if (dist > 5) {
_points.push([x, y, false]);
adjustBounds(x, y)
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
prevPoint.y = y;
}
} else {
var prevPresent = prevPoint.x != -1 || prevPoint.y != -1;
var dist = prevPresent ? Math.sqrt(Math.pow((prevPoint.x - x), 2) + Math.pow((prevPoint.y - y), 2)) : undefined;
if (!prevPresent || dist > 5) { // replace dist check by setting: doodle3d.simplify.minDistance
_points.push([x, y, false]);
adjustBounds(x, y)
adjustBounds(x, y);
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
@ -489,8 +486,3 @@ function onCanvasTouchEnd(e) {
function prevent(e) {
e.preventDefault();
}

View File

@ -20,6 +20,7 @@ function generate_gcode() {
var bottomSpeed = settings["printer.bottomLayerSpeed"];
var firstLayerSlow = settings["printer.firstLayerSlow"];
var bottomFlowRate = settings["printer.bottomFlowRate"];
var bottomEnableTraveling = settings["printer.bottomEnableTraveling"];
var travelSpeed = settings["printer.travelSpeed"]
var filamentThickness = settings["printer.filamentThickness"];
var wallThickness = settings["printer.wallThickness"];
@ -159,8 +160,10 @@ function generate_gcode() {
var isTraveling = !isLoop && i==0;
var doRetract = retractionEnabled && prev.distance(to) > retractionminDistance;
//Always travel to first point, then optionally disable traveling for first two layers and use settings for remainder of print.
var firstPointEver = (layer == 0 && i == 0 && j == 0);
if (firstPointEver || layer > 2 && enableTraveling && isTraveling) { //always travel to first point, then disable traveling for first two layers and use settings for remainder of print
var travelingAllowed = firstPointEver || bottomEnableTraveling || layer > 2;
if (travelingAllowed && enableTraveling && isTraveling) {
if (!firstPointEver && doRetract) gcode.push("G0 E" + (extruder - retractionamount).toFixed(3) + " F" + (retractionspeed * 60).toFixed(3)); //retract
gcode.push("G0 X" + to.x.toFixed(3) + " Y" + to.y.toFixed(3) + " Z" + z.toFixed(3) + " F" + (travelSpeed * 60).toFixed(3));
if (!firstPointEver && doRetract) gcode.push("G0 E" + extruder.toFixed(3) + " F" + (retractionspeed * 60).toFixed(3)); // return to normal

View File

@ -34,7 +34,8 @@ var POPUP_SHOW_DURATION = 175;
var BUTTON_GROUP_SHOW_DURATION = 80;
$(function() {
console.log("ready");
console.log("Doodle3D client ready");
console.log("Build information - <%= build_info %>)");
if (getURLParameter("d") != "null") debugMode = (getURLParameter("d") == "1");
if (getURLParameter("p") != "null") sendPrintCommands = (getURLParameter("p") == "1");

View File

@ -34,7 +34,8 @@ function SettingsWindow() {
var _networkPanel = new NetworkPanel();
var _networkAPI = new NetworkAPI();
var _restoreStateField
var _restoreStateField;
var _initialLogLevel = undefined;
var self = this;
@ -115,6 +116,10 @@ function SettingsWindow() {
settingsPopup.close();
self.signin();
}
//FIXME: instead of this rather ugly call, implement events for changes to settings so we can keep code decoupled
redrawDoodle(false);
_btnOK.removeAttr("disabled");
});
};
@ -123,6 +128,12 @@ function SettingsWindow() {
_form.loadAllSettings(function(loadedSettings){
console.log("Settings:loaded settings: ",loadedSettings);
settings = loadedSettings;
//only set the initial level once, to make behaviour of restart warning as correctly as possible
if (_initialLogLevel == undefined)
_initialLogLevel = loadedSettings['system.log.level'];
updateLogLevelWarningsVisibility();
_form.fillForm(settings);
$(document).trigger(SettingsWindow.SETTINGS_LOADED);
if(complete) complete();
@ -180,6 +191,31 @@ function SettingsWindow() {
this.openFileManager = function() {
location.href = "filemanager/"+location.search;
}
this.logLevelChanged = function() {
updateLogLevelWarningsVisibility();
}
/***** LOCAL FUNCTIONS *****/
function updateLogLevelWarningsVisibility() {
var showHideAnimDuration = 100;
newLevel = $('#logLevel').val();
if (_initialLogLevel != newLevel) {
$('#logging-restart-warning').show(showHideAnimDuration);
} else {
$('#logging-restart-warning').hide(showHideAnimDuration);
}
switch (newLevel) {
case "verbose": case "bulk":
$('#logging-verbose-warning').show(showHideAnimDuration);
break;
default:
$('#logging-verbose-warning').hide(showHideAnimDuration);
}
}
}
/*************************

View File

@ -204,7 +204,7 @@ function UpdatePanel() {
this.setState = function(newState,refresh) {
//console.log("UpdatePanel:setState");
if(!refresh && this.state == newState) return;
console.log("UpdatePanel:setState: ",this.state," > ",newState,"(",this.stateText,") (in Access Point Mode: ",_inAccessPointMode,") (newestVersion: ",self.newestVersion,") (refresh: ",refresh,")");
console.log("UpdatePanel:setState: " + this.state + " > " + newState + "(" + this.stateText + ") (in Access Point Mode: " + _inAccessPointMode + ") (newestVersion: " + self.newestVersion + ") (refresh: " + refresh + ")");
this.state = newState;
// should personal sketches and settings be retained over update?
@ -314,7 +314,7 @@ function UpdatePanel() {
var fields = [ ts.substr(0, 4), ts.substr(4, 2), ts.substr(6, 2) ];
if (!fields || fields.length != 3 || fields[1] > 12) return null;
var abbrMonths = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Sep', 'Aug', 'Oct', 'Nov', 'Dec' ];
var abbrMonths = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
return abbrMonths[fields[1] - 1] + " " + fields[2] + ", " + fields[0];
}

View File

@ -41,7 +41,7 @@ function setSketchModified(_isModified) {
}
function updateSketchButtonStates() {
console.log('sketch: isModified',isModified,'curSketch',curSketch,'sketches.length',sketches.length);
console.log('sketch: isModified: ' + isModified + ', curSketch: ' + curSketch + ', sketches.length: ' + sketches.length);
if (isModified) {
btnSave.enable();
@ -72,7 +72,7 @@ function loadSketch(_curSketch) {
var id = sketches[curSketch];
console.log('sketch: loadSketch curSketch',curSketch,'id',id);
console.log('sketch: loadSketch curSketch:' + curSketch + ', id: ' + id);
$.get(wifiboxURL + "/sketch", {id:id}, function(response) {
if (response.status=='success') {

View File

@ -3,6 +3,16 @@
SETTINGS POPUP
*/
.warn-box {
color: #bb0;
border: 1px solid #bb0;
width: 99%;
border-radius: 5px;
margin: 7px 0;
padding: 2px;
display: none;
}
#popupSettings {
top: 0;
left: 0;

View File

@ -1,8 +1,10 @@
local M = {
BASE_PATH = 'js_src',
BASE_PATH = 'js',
EXCLUDE_FILES = {},
PROCESS_FILES = {
['js_src/[^/]*%.js'] = 'cstyle'
['js/[^/]*%.js'] = 'cstyle',
['js/api/[^/]*%.js'] = 'cstyle',
['js/settings/[^/]*%.js'] = 'cstyle'
},
IGNORE_GIT_CHANGED = false
}

View File

@ -9,7 +9,7 @@
"author": "Peter Uithoven, Adriaan Wormgoor, Rick Companje, Wouter Reckman",
"readmeFilename": "README.md",
"devDependencies": {
"grunt": "~0.4.1",
"grunt": "~0.4.5",
"grunt-cli": "~0.1.9",
"grunt-contrib-less": "~0.7.0",
"grunt-contrib-watch": "~0.5.3",
@ -17,6 +17,11 @@
"grunt-contrib-jshint": "~0.6.4",
"grunt-autoprefixer": "~0.4.0",
"grunt-contrib-cssmin": "~0.6.2",
"grunt-contrib-concat": "~0.3.0"
"grunt-contrib-concat": "~0.3.0",
"grunt-gitinfo": "~0.1.7",
"grunt-template": "~0.2.3"
},
"scripts": {
"start": "grunt"
}
}

View File

@ -76,6 +76,10 @@ form fieldset.collapsed legend {
center left;
}
#debugPanel label {
min-width: 59px;
}
form label {
min-width: 150px;
display: block;

View File

@ -22,7 +22,7 @@
</li>
<li data-id="btnsPrevNext" data-button="Next" data-options="tipLocation:right;tipAdjustmentY:-25">
<h2>View saved doodles</h2>
<p>Use the buttons '<' and '>' to flip through all the saved doodles on your Wi-Fi box.</p>
<p>Use the buttons '&lt;' and '&gt;' to flip through all the saved doodles on your Wi-Fi box.</p>
</li>
<li data-id="btnOops" data-button="Next" data-options="tipLocation:right">
<h2>Oops</h2>

View File

@ -99,6 +99,7 @@
<label for="bottomLayerSpeed">Bottom layer speed:</label><input id="bottomLayerSpeed" type="number" name="printer.bottomLayerSpeed" class="small">mm/s<br>
<label for="travelSpeed">Travel speed:</label><input id="travelSpeed" type="number" name="printer.travelSpeed" class="small">mm/s<br>
<label for="enableTraveling">Enable traveling:</label><input id="enableTraveling" type="checkbox" name="printer.enableTraveling" value="enableTraveling"><br>
<label for="bottomEnableTraveling">Bottom layers traveling:</label><input id="bottomEnableTraveling" type="checkbox" name="printer.bottomEnableTraveling" value="bottomEnableTraveling"><br>
<label for="firstLayerSlow">Bottom layers slow:</label><input id="firstLayerSlow" type="checkbox" name="printer.firstLayerSlow" value="firstLayerSlow"><br>
<label for="bottomFlowRate">Bottom layers flow rate*:</label><input id="bottomFlowRate" type="number" name="printer.bottomFlowRate" class="small"><br>
<small>* Multiplier for extrusion rate in first few layers</small>
@ -179,11 +180,27 @@
<input type="button" onclick="settingsWindow.downloadGcode()" name="downloadGcode" value="Download GCODE" class="button" id="downloadGcode"/>
<input type="button" onclick="settingsWindow.downloadSvg()" name="downloadSvg" value="Download SVG" class="button" id="downloadSvg"/>
</fieldset>
<fieldset id="debugPanel">
<legend>Debug</legend>
<input type="button" onclick="settingsWindow.downloadlogs()" name="downloadlogs" value="Download logs" class="button" id="downloadlogs"
/>
<label for="logLevel">Log level:</label>
<select id="logLevel" name="system.log.level" onchange="settingsWindow.logLevelChanged()">
<option value="" disabled="disabled" selected="selected">Please choose a log level</option>
<option value="quiet">Quiet</option>
<option value="error">Error</option>
<option value="warning">Warning</option>
<option value="info">Info</option>
<option value="verbose">Verbose</option>
<option value="bulk">Bulk</option>
</select><br/>
<div id="logging-restart-warning" class="warn-box">
Restart the wifibox for the new log level to take effect.
</div>
<div id="logging-verbose-warning" class="warn-box">
<em>Be careful</em>: when setting a log level higher than info, the Wifibox may quickly run out of memory, causing crashes and other unwanted behaviour.
</div>
<br/>
<input type="button" onclick="settingsWindow.downloadlogs()" name="downloadlogs" value="Download logs" class="button" id="downloadlogs"/>
</fieldset>
<fieldset id="restorePanel">