diff --git a/public/js/simple-cam.js b/public/js/simple-cam.js
index 7c941556..749960de 100644
--- a/public/js/simple-cam.js
+++ b/public/js/simple-cam.js
@@ -172,6 +172,16 @@ function fillEasyCam() {
mm/s
+
@@ -204,7 +214,7 @@ function fillEasyCam() {
layerprep += template;
}
} else if (objectsInScene[i].type == 'Mesh') {
-
+
if (typeof(object) != 'undefined') {
scene.remove(object);
};
@@ -216,7 +226,7 @@ function fillEasyCam() {
var xpos = objectsInScene[i].position.x
var ypos = objectsInScene[i].position.y
// var seq = objectsInScene[i].userData.seq;
-
+
var scale = objectsInScene[i].scale.y;
// scale was already initialized during bitmap load, and may have been changed
// We want to set the UI to the actual scale value instead of a default value here
diff --git a/public/js/threegcode.js b/public/js/threegcode.js
index 8942702f..d39d23ee 100644
--- a/public/js/threegcode.js
+++ b/public/js/threegcode.js
@@ -1,6 +1,6 @@
/*
- AUTHOR: Peter van der Walt
- Based on code from: John Lauer, Todd Fleming, Nicholas Raynaud and others
+AUTHOR: Peter van der Walt
+Based on code from: John Lauer, Todd Fleming, Nicholas Raynaud and others
*/
var inflateGrp, fileParentGroup, svgPath, y, shape, lines, line;
var options = {};
@@ -8,112 +8,115 @@ var options = {};
$(document).ready(function() {
- $('#generategcode').on('click', function() {
- console.group("Generating GCODE");
- for (j = 0; j < objectsInScene.length; j++) {
- // Cleanup Existing GCODE
- objectsInScene[j].userData.gcode = "";
- }
- if (typeof(fileObject) == 'undefined') {
- printLog('No file loaded. do, File -> Open, first!', errorcolor, "file")
- };
- // Lets get the machine specific Gcode from the settings Modal (:
- var startgcode = document.getElementById('startgcode').value;
- var laseron = document.getElementById('laseron').value;
- var laseroff = document.getElementById('laseroff').value;
- var lasermultiply = document.getElementById('lasermultiply').value;
- var homingseq = document.getElementById('homingseq').value;
- var endgcode = document.getElementById('endgcode').value;
- cncMode = $('#cncMode').val()
- if (cncMode == "Enable") {
- var clearanceHeight = document.getElementById('clearanceHeight').value;
- } else {
- var clearanceHeight = 0
- }
-
- // Remove old Gcode
- // document.getElementById('gcodepreview').value = "";
- $('#gcodejobs').empty();
- lineObjects = null;
- lineObjects = new THREE.Object3D();
- var total = scene.children.length
- for (var j = 6; j < total; j++) {
- scene.remove(scene.children[j]);
- }
- for (var j = 0; j < objectsInScene.length; j++) {
- // console.log('added object ' + j)
- scene.add(objectsInScene[j]);
- }
+ $('#generategcode').on('click', function() {
+ console.group("Generating GCODE");
+ for (j = 0; j < objectsInScene.length; j++) {
+ // Cleanup Existing GCODE
+ objectsInScene[j].userData.gcode = "";
+ }
+ if (typeof(fileObject) == 'undefined') {
+ printLog('No file loaded. do, File -> Open, first!', errorcolor, "file")
+ };
+ // Lets get the machine specific Gcode from the settings Modal (:
+ var startgcode = document.getElementById('startgcode').value;
+ var laseron = document.getElementById('laseron').value;
+ var laseroff = document.getElementById('laseroff').value;
+ var lasermultiply = document.getElementById('lasermultiply').value;
+ var homingseq = document.getElementById('homingseq').value;
+ var endgcode = document.getElementById('endgcode').value;
+
+ cncMode = $('#cncMode').val()
+ if (cncMode == "Enable") {
+ var clearanceHeight = document.getElementById('clearanceHeight').value;
+ } else {
+ var clearanceHeight = 0
+ }
- scene.updateMatrixWorld();
- pwr = [];
- cutSpeed = [];
-
- for (j = 0; j < objectsInScene.length; j++) {
- printLog('Processing ' + objectsInScene[j].name, msgcolor, "file");
- // This step converts each object in objectsInScene, to gcode and puts that gcode into objectsInScene[j].userData.gcode - to be later assembled into a gcode file with proper sequence
- objectsInScene[j].updateMatrix();
- if (objectsInScene[j].name != 'object') {
- if (objectsInScene[j].type == "Mesh") {
- console.log('Object: '+objectsInScene[j].name+' is a Raster')
- runRaster(j)
- } else {
- console.log('Object: '+objectsInScene[j].name+' is a Vector');
- var cutSpeed0 = parseFloat( $("#speed"+(j)).val() ) * 60;
- var pwr0 = parseFloat( $("#power"+(j)).val() );
- var plungeSpeed0 = parseFloat( $("#plungespeed"+(j)).val() ) * 60;
- var passes = parseInt( $("#passes"+(j)).val() );
- var passdepth = parseFloat( $("#depth"+(j)).val() );
- var rapidSpeed = parseFloat($("#rapidspeed").val() ) * 60;
- if (objectsInScene[j].userData.inflated) {
- // g += generateGcode(objectsInScene[j].userData.inflated, j, cutSpeed0, plungeSpeed0, pwr0, rapidSpeed, laseron, laseroff, clearanceHeight);
- printLog('Separate Operation for ' + objectsInScene[j].name, msgcolor, "file")
- objectsInScene[j].userData.gcode = generateGcode(objectsInScene[j].userData.inflated, j, cutSpeed0, plungeSpeed0, pwr0, rapidSpeed, laseron, laseroff, clearanceHeight);
- } else {
- // g += generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight);
- if (passes > 1) {
- console.log("Mulipass Layers to generate: " + passes);
- var gcodewithmultipass = "";
- for (m = 0; m < passes; m++) {
- console.log("Mulipass Layer: " + m);
- var zoffset = passdepth * m;
- gcodewithmultipass += generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset);
- }
- objectsInScene[j].userData.gcode = gcodewithmultipass;
- } else {
- objectsInScene[j].userData.gcode = generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset);
- }
-
- }
- var template = `
- `
-
- $('#gcodejobs').append(template);
-
- $('#gcode'+i).val(objectsInScene[j].userData.gcode);
-
- var startgcode = document.getElementById('startgcode').value;
- var endgcode = document.getElementById('endgcode').value;
-
- $('#startgcodefinal').val(startgcode)
- $('#endgcodefinal').val(endgcode);
-
- printLog('Gcode Data Generated for ' +objectsInScene[j].name , successcolor, "file");
- // prepgcodefile();
+ // Remove old Gcode
+ // document.getElementById('gcodepreview').value = "";
+ $('#gcodejobs').empty();
+ lineObjects = null;
+ lineObjects = new THREE.Object3D();
+ var total = scene.children.length
+ for (var j = 6; j < total; j++) {
+ scene.remove(scene.children[j]);
+ }
+ for (var j = 0; j < objectsInScene.length; j++) {
+ // console.log('added object ' + j)
+ scene.add(objectsInScene[j]);
+ }
+ scene.updateMatrixWorld();
+ pwr = [];
+ cutSpeed = [];
+
+ for (j = 0; j < objectsInScene.length; j++) {
+ printLog('Processing ' + objectsInScene[j].name, msgcolor, "file");
+ // This step converts each object in objectsInScene, to gcode and puts that gcode into objectsInScene[j].userData.gcode - to be later assembled into a gcode file with proper sequence
+ objectsInScene[j].updateMatrix();
+ if (objectsInScene[j].name != 'object') {
+ if (objectsInScene[j].type == "Mesh") {
+ console.log('Object: '+objectsInScene[j].name+' is a Raster')
+ runRaster(j)
+ } else {
+ console.log('Object: '+objectsInScene[j].name+' is a Vector');
+ var cutSpeed0 = parseFloat( $("#speed"+(j)).val() ) * 60;
+ var pwr0 = parseFloat( $("#power"+(j)).val() );
+ var plungeSpeed0 = parseFloat( $("#plungespeed"+(j)).val() ) * 60;
+ var passes = parseInt( $("#passes"+(j)).val() );
+ var passdepth = parseFloat( $("#depth"+(j)).val() );
+ var rapidSpeed = parseFloat($("#rapidspeed").val() ) * 60;
+ //"none"=doesn't change cutting order, "standard"=optimize using cartesian distance, "manhattan"=optimize using manhattan distance.
+ var optimization = $("#optimization_mode"+(j)).val();
+ if (objectsInScene[j].userData.inflated) {
+ // g += generateGcode(objectsInScene[j].userData.inflated, j, cutSpeed0, plungeSpeed0, pwr0, rapidSpeed, laseron, laseroff, clearanceHeight);
+ printLog('Separate Operation for ' + objectsInScene[j].name, msgcolor, "file")
+ objectsInScene[j].userData.gcode = generateGcode(objectsInScene[j].userData.inflated, j, cutSpeed0, plungeSpeed0, pwr0, rapidSpeed, laseron, laseroff, clearanceHeight, optimization);
+ } else {
+ // g += generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight);
+ if (passes > 1) {
+ console.log("Mulipass Layers to generate: " + passes);
+ var gcodewithmultipass = "";
+ for (m = 0; m < passes; m++) {
+ console.log("Mulipass Layer: " + m);
+ var zoffset = passdepth * m;
+ gcodewithmultipass += generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset, optimization);
}
+ objectsInScene[j].userData.gcode = gcodewithmultipass;
+ } else {
+ objectsInScene[j].userData.gcode = generateGcode(objectsInScene[j], j, cutSpeed0, plungeSpeed0 ,pwr0, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset, optimization);
}
+
+ }
+ var template = `
+
`
+
+ $('#gcodejobs').append(template);
+
+ $('#gcode'+i).val(objectsInScene[j].userData.gcode);
+
+ var startgcode = document.getElementById('startgcode').value;
+ var endgcode = document.getElementById('endgcode').value;
+
+ $('#startgcodefinal').val(startgcode)
+ $('#endgcodefinal').val(endgcode);
+
+ printLog('Gcode Data Generated for ' +objectsInScene[j].name , successcolor, "file");
+ // prepgcodefile();
+
}
- scene.remove(inflateGrp);
+ }
+ }
+ scene.remove(inflateGrp);
- $('#gcode-menu').click();
- console.groupEnd();
- console.log('running openGCodeFromText')
- openGCodeFromText();
- });
+ $('#gcode-menu').click();
+ console.groupEnd();
+ console.log('running openGCodeFromText')
+ openGCodeFromText();
+ });
});
function prepgcodefile() {
@@ -132,14 +135,14 @@ function prepgcodefile() {
}
for (j = 0; j < objectsInScene.length; j++) {
- printLog('Preparing Gcode File: ' + objectsInScene[j].name, msgcolor, "file");
- console.log('Preparing Gcode File: ' + objectsInScene[j].name);
- // document.getElementById('gcodepreview').value = "";
- if (typeof(objectsInScene[j].userData.gcode) != "undefined") {
- g += objectsInScene[j].userData.gcode;
- } else {
- console.log(objectsInScene[j].name + ' does not have valid gcode yet');
- }
+ printLog('Preparing Gcode File: ' + objectsInScene[j].name, msgcolor, "file");
+ console.log('Preparing Gcode File: ' + objectsInScene[j].name);
+ // document.getElementById('gcodepreview').value = "";
+ if (typeof(objectsInScene[j].userData.gcode) != "undefined") {
+ g += objectsInScene[j].userData.gcode;
+ } else {
+ console.log(objectsInScene[j].name + ' does not have valid gcode yet');
+ }
}
g += "\n";
if (endgcode) {
@@ -149,174 +152,271 @@ function prepgcodefile() {
return g;
}
-function generateGcode(threeGroup, objectseq, cutSpeed, plungeSpeed, laserPwr, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset) {
+function get_cut_begin_point( threeGroup, i ){
+ var localPt = threeGroup.children[i].geometry.vertices[0];
+ var worldPt = threeGroup.localToWorld(localPt.clone());
+ var xpos = worldPt.x + (parseFloat(laserxmax) / 2);
+ var ypos = worldPt.y + (parseFloat(laserymax) / 2);
- var laserPwrVal = 0.0;
- // console.log('inside generateGcode')
- // console.log('Group', threeGroup);
- // console.log('CutSpeed', cutSpeed);
- // console.log('plungeSpeed', plungeSpeed);
- // console.log('Laser Power %', laserPwr);
- var lasermultiply = $('#lasermultiply').val();
- // console.log('Laser Multiplier', lasermultiply);
+ var xpos_offset = threeGroup.children[i].position.x;
+ var ypos_offset = threeGroup.children[i].position.y;
- if (lasermultiply <= 1) {
- var laserPwrVal = laserPwr / 100;
- laserPwrVal = parseFloat(laserPwrVal).toFixed(2);
- } else {
- var laserPwrVal = laserPwr * (lasermultiply / 100);
- laserPwrVal = laserPwrVal.toFixed(0);
- }
- // console.log('Laser Power Value', laserPwrVal, ' type of ', typeof(laserPwrVal));
+ if (threeGroup.children[i].geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
+
+ return new THREE.Vector2( xpos, ypos );
+}
+
+function get_cut_end_point( threeGroup, i ){
+ var localPt = threeGroup.children[i].geometry.vertices[ threeGroup.children[i].geometry.vertices.length - 1 ];
+ var worldPt = threeGroup.localToWorld(localPt.clone());
+ var xpos = worldPt.x + (parseFloat(laserxmax) / 2);
+ var ypos = worldPt.y + (parseFloat(laserymax) / 2);
+
+ var xpos_offset = threeGroup.children[i].position.x;
+ var ypos_offset = threeGroup.children[i].position.y;
+
+ if (threeGroup.children[i].geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
- var g = "";
- // get the THREE.Group() that is the txt3d
+ return new THREE.Vector2( xpos, ypos );
+}
+
+function generateGcode(threeGroup, objectseq, cutSpeed, plungeSpeed, laserPwr, rapidSpeed, laseron, laseroff, clearanceHeight, zoffset, optimization) {
+
+ var laserPwrVal = 0.0;
+ // console.log('inside generateGcode')
+ // console.log('Group', threeGroup);
+ // console.log('CutSpeed', cutSpeed);
+ // console.log('plungeSpeed', plungeSpeed);
+ // console.log('Laser Power %', laserPwr);
+ var lasermultiply = $('#lasermultiply').val();
+ // console.log('Laser Multiplier', lasermultiply);
+
+ if (lasermultiply <= 1) {
+ var laserPwrVal = laserPwr / 100;
+ laserPwrVal = parseFloat(laserPwrVal).toFixed(2);
+ } else {
+ var laserPwrVal = laserPwr * (lasermultiply / 100);
+ laserPwrVal = laserPwrVal.toFixed(0);
+ }
+ // console.log('Laser Power Value', laserPwrVal, ' type of ', typeof(laserPwrVal));
+
+ var g = "";
+ // get the THREE.Group() that is the txt3d
+
+ var txtGrp = threeGroup;
+ var that = this;
+ var isLaserOn = false;
+ var isAtClearanceHeight = false;
+ var isFeedrateSpecifiedAlready = false;
+ var isSeekrateSpecifiedAlready = false;
- var txtGrp = threeGroup;
- var that = this;
- var isLaserOn = false;
- var isAtClearanceHeight = false;
- var isFeedrateSpecifiedAlready = false;
- var isSeekrateSpecifiedAlready = false;
+ var cncMode = false;
- var cncMode = false;
+ if ($('#cncMode').val() == "Enable") {
+ cncMode = true;
+ }
+
+ // var subj_path2 = [];
+ // var subj_paths = [];
+ // console.log(txtGrp);
+ // console.log(rapidSpeed)
+ // console.log(cutSpeed);
+
+ // txtGrp.updateMatrixWorld();
+
+ var toCut = txtGrp.clone();
+ var current_position = new THREE.Vector2( 0, 0 );
+
+ while( toCut.children.length > 0 ){
+ var opt_cut = 0;
+ var cut_reverse = 0;
+ //If is found a cut at a distance 0 from the current_position, there is no need
+ //to add a G0 move that turns off the laser.
+ var need_move_to = 1;
+
+
+ if( optimization != "none" ){
+ var opt_distance;
+ if( optimization == "manhattan" )
+ opt_distance = current_position.distanceToManhattan( get_cut_begin_point( toCut, 0 ) );
+ else
+ opt_distance = current_position.distanceToSquared( get_cut_begin_point( toCut, 0 ) );
+
+ for( i = 0; i < toCut.children.length; i++ ){
+ var distance;
+ if( optimization == "manhattan" )
+ distance = current_position.distanceToManhattan( get_cut_begin_point( toCut, i ) );
+ else
+ distance = current_position.distanceToSquared( get_cut_begin_point( toCut, i ) );
+ if( distance < opt_distance ){
+ opt_distance = distance;
+ opt_cut = i;
+ cut_reverse = 0;
+
+ if( opt_distance == 0 ){ //If opt_distance == 0 no more optimization can be performed, time saving instruction.
+ break; //Exit from for cycle.
+ }
+ }
+ }
+
+ for( i = 0; i < toCut.children.length; i++ ){
+ var distance;
+ if( optimization == "manhattan" )
+ distance = current_position.distanceToManhattan( get_cut_end_point( toCut, i ) );
+ else
+ distance = current_position.distanceToSquared( get_cut_end_point( toCut, i ) );
+
+ if( distance < opt_distance ){
+ opt_distance = distance;
+ opt_cut = i;
+ cut_reverse = 1;
+
+ if( opt_distance == 0 ){ //If opt_distance == 0 no more optimization can be performed, time saving instruction.
+ break; //Exit form for cycle.
+ }
+ }
+ }
- if ($('#cncMode').val() == "Enable") {
- cncMode = true;
+ if( opt_distance == 0 ) need_move_to = 0;
}
- // var subj_path2 = [];
- // var subj_paths = [];
- // console.log(txtGrp);
- // console.log(rapidSpeed)
- // console.log(cutSpeed);
-
- // txtGrp.updateMatrixWorld();
-
- txtGrp.traverse(function(child) {
- // console.log(child);
- if (child.type == "Line") {
-
- var xpos_offset = child.position.x;
- var ypos_offset = child.position.y;
-
-
- // let's create gcode for all points in line
- for (i = 0; i < child.geometry.vertices.length; i++) {
-
- // Convert to World Coordinates
- var localPt = child.geometry.vertices[i];
- var worldPt = txtGrp.localToWorld(localPt.clone());
- var xpos = worldPt.x + (parseFloat(laserxmax) / 2);
- var ypos = worldPt.y + (parseFloat(laserymax) / 2);
-
-
- if (child.geometry.type == "CircleGeometry") {
- xpos = (xpos + xpos_offset);
- ypos = (ypos + ypos_offset);
- }
-
-
- var zpos = worldPt.z;
-
- if (zoffset) {
- zpos = zpos - zoffset;
- }
-
-
- // First Move To
- if (i == 0) {
- // first point in line where we start lasering/milling
- var seekrate;
- if (isSeekrateSpecifiedAlready) {
- seekrate = "";
- } else {
- // console.log('Rapid Speed: ', rapidSpeed);
- if (rapidSpeed) {
- seekrate = " F" + rapidSpeed;
- isSeekrateSpecifiedAlready = true;
- } else {
- seekrate = "";
- }
-
- }
- if (cncMode) {
- if (!isAtClearanceHeight) {
- g += "\nG0 Z" + clearanceHeight + "\n"; // Position Before Plunge!
- }
- };
- g += "G0" + seekrate;
- g += " X" + xpos.toFixed(4) + " Y" + ypos.toFixed(4) + "\n";
- if (cncMode) {
- g += "\nG0 Z1\n"; // G0 to Z0 then Plunge!
- g += "G1 F"+plungeSpeed+" Z" + zpos.toFixed(4) + "\n"; // Plunge!!!!
- } else {
- if (isFeedrateSpecifiedAlready) {
- } else {
- // console.log('Cut Speed: ', cutSpeed);
- if (cutSpeed) {
- feedrate = " F" + cutSpeed;
- isFeedrateSpecifiedAlready = true;
- } else {
- feedrate = "";
- }
- }
- g += "G1" + feedrate + " X" + xpos.toFixed(4) + " Y" + ypos.toFixed(4) + " Z" + zpos.toFixed(4) + "\n";
- };
- isAtClearanceHeight = false;
- // Else Cut move
- } else {
- // we are in a non-first line so this is normal moving
- // if the laser is not on, we need to turn it on
- if (!isLaserOn) {
- if (laseron) {
- g += laseron
- g += '\n'
- } else {
- // Nothing - most of the firmware used G0 = move, G1 = cut and doesnt need a laseron/laseroff command
- };
- isLaserOn = true;
- }
-
- // do normal feedrate move
- var feedrate;
- if (isFeedrateSpecifiedAlready) {
- } else {
- console.log('Cut Speed: ', cutSpeed);
- if (cutSpeed) {
- feedrate = " F" + cutSpeed;
- isFeedrateSpecifiedAlready = true;
- } else {
- feedrate = "";
- }
- }
- g += "G1" + feedrate;
- g += " X" + xpos.toFixed(4);
- g += " Y" + ypos.toFixed(4);
- g += " Z" + zpos.toFixed(4);
- g += " S" + laserPwrVal + "\n";
- }
- }
+ if( cut_reverse )
+ current_position = get_cut_begin_point( toCut, opt_cut );
+ else
+ current_position = get_cut_end_point( toCut, opt_cut );
+
+ child = toCut.children[opt_cut].clone();
+
+ if (child.type == "Line") {
+ var xpos_offset = child.position.x;
+ var ypos_offset = child.position.y;
+ if( cut_reverse )
+ child.geometry.vertices = child.geometry.vertices.reverse();
+ // let's create gcode for all points in line
+ for (i = 0; i < child.geometry.vertices.length; i++) {
+
+ // Convert to World Coordinates
+ var localPt = child.geometry.vertices[i];
+ var worldPt = txtGrp.localToWorld(localPt.clone());
+ var xpos = worldPt.x + (parseFloat(laserxmax) / 2);
+ var ypos = worldPt.y + (parseFloat(laserymax) / 2);
+
+
+ if (child.geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
- // make feedrate have to get specified again on next line if there is one
- isFeedrateSpecifiedAlready = false;
- isLaserOn = false;
- // if (firmware.indexOf('Grbl') == 0) {
- if (laseroff) {
- g += laseroff
- g += '\n'
+ var zpos = worldPt.z;
+
+ if (zoffset) {
+ zpos = zpos - zoffset;
+ }
+
+
+ // First Move To
+ if (i == 0 && need_move_to == 1 ){
+ // first point in line where we start lasering/milling
+ var seekrate;
+ if (isSeekrateSpecifiedAlready) {
+ seekrate = "";
+ } else {
+ // console.log('Rapid Speed: ', rapidSpeed);
+ if (rapidSpeed) {
+ seekrate = " F" + rapidSpeed;
+ isSeekrateSpecifiedAlready = true;
+ } else {
+ seekrate = "";
+ }
+
+ }
+ if (cncMode) {
+ if (!isAtClearanceHeight) {
+ g += "\nG0 Z" + clearanceHeight + "\n"; // Position Before Plunge!
+ }
+ };
+ g += "G0" + seekrate;
+ g += " X" + xpos.toFixed(4) + " Y" + ypos.toFixed(4) + "\n";
+ if (cncMode) {
+ g += "\nG0 Z1\n"; // G0 to Z0 then Plunge!
+ g += "G1 F"+plungeSpeed+" Z" + zpos.toFixed(4) + "\n"; // Plunge!!!!
+ } else {
+ if (isFeedrateSpecifiedAlready) {
+ } else {
+ // console.log('Cut Speed: ', cutSpeed);
+ if (cutSpeed) {
+ feedrate = " F" + cutSpeed;
+ isFeedrateSpecifiedAlready = true;
+ } else {
+ feedrate = "";
+ }
+ }
+ g += "G1" + feedrate + " X" + xpos.toFixed(4) + " Y" + ypos.toFixed(4) + " Z" + zpos.toFixed(4) + "\n";
+ };
+ isAtClearanceHeight = false;
+ // Else Cut move
+ } else {
+ // we are in a non-first line so this is normal moving
+ // if the laser is not on, we need to turn it on
+ if (!isLaserOn) {
+ if (laseron) {
+ g += laseron
+ g += '\n'
+ } else {
+ // Nothing - most of the firmware used G0 = move, G1 = cut and doesnt need a laseron/laseroff command
+ };
+ isLaserOn = true;
+ }
+
+ // do normal feedrate move
+ var feedrate;
+ if (isFeedrateSpecifiedAlready) {
+ } else {
+ console.log('Cut Speed: ', cutSpeed);
+ if (cutSpeed) {
+ feedrate = " F" + cutSpeed;
+ isFeedrateSpecifiedAlready = true;
} else {
- // Nothing - most of the firmware used G0 = move, G1 = cut and doesnt need a laseron/laseroff command
+ feedrate = "";
}
+ }
+ g += "G1" + feedrate;
+ g += " X" + xpos.toFixed(4);
+ g += " Y" + ypos.toFixed(4);
+ g += " Z" + zpos.toFixed(4);
+ g += " S" + laserPwrVal + "\n";
}
- });
- console.log("Generated gcode. length:", g.length);
- console.log(" ");
- isGcodeInRegeneratingState = false;
- return g;
+ }
+
+
+
+ // make feedrate have to get specified again on next line if there is one
+ isFeedrateSpecifiedAlready = false;
+ isLaserOn = false;
+ // if (firmware.indexOf('Grbl') == 0) {
+ if (laseroff) {
+ g += laseroff
+ g += '\n'
+ } else {
+ // Nothing - most of the firmware used G0 = move, G1 = cut and doesnt need a laseron/laseroff command
+ }
+ }
+
+ toCut.remove( toCut.children[opt_cut] );
+ }
+ console.log("Generated gcode. length:", g.length);
+ console.log(" ");
+ isGcodeInRegeneratingState = false;
+ return g;
};
addOperation = function(index, operation, zstep, zdepth) {
@@ -346,334 +446,334 @@ addOperation = function(index, operation, zstep, zdepth) {
};
inflatePath = function(infobject, inflateVal, zstep, zdepth) {
- var zstep = parseFloat(zstep, 2);
- var zdepth = parseFloat(zdepth, 2);
- var inflateGrpZ = new THREE.Group();
- if (typeof(inflateGrp) != 'undefined') {
- scene.remove(inflateGrp);
- inflateGrp = null;
- }
- // if (inflateVal != 0) {
- console.log("user wants to inflate. val:", inflateVal);
- infobject.updateMatrix();
- var grp = infobject;
- var clipperPaths = [];
- grp.traverse(function(child) {
- console.log('Traverse: ', child)
- if (child.name == "inflatedGroup") {
- console.log("this is the inflated path from a previous run. ignore.");
- return;
- } else if (child.type == "Line") {
- // let's inflate the path for this line. it may not be closed
- // so we need to check that.
- var clipperArr = [];
- // Fix world Coordinates
- for (i = 0; i < child.geometry.vertices.length; i++) {
- var localPt = child.geometry.vertices[i];
- var worldPt = grp.localToWorld(localPt.clone());
- var xpos = worldPt.x;
- var ypos = worldPt.y;
-
- var xpos_offset = (parseFloat(child.position.x.toFixed(3)));
- var ypos_offset = (parseFloat(child.position.y.toFixed(3)));
-
- if (child.geometry.type == "CircleGeometry") {
- xpos = (xpos + xpos_offset);
- ypos = (ypos + ypos_offset);
- }
-
- clipperArr.push({
- X: xpos,
- Y: ypos
- });
- }
- clipperPaths.push(clipperArr);
- } else if (child.type == "Points") {
- child.visible = false;
- } else {
- console.log("type of ", child.type, " being skipped");
- }
+ var zstep = parseFloat(zstep, 2);
+ var zdepth = parseFloat(zdepth, 2);
+ var inflateGrpZ = new THREE.Group();
+ if (typeof(inflateGrp) != 'undefined') {
+ scene.remove(inflateGrp);
+ inflateGrp = null;
+ }
+ // if (inflateVal != 0) {
+ console.log("user wants to inflate. val:", inflateVal);
+ infobject.updateMatrix();
+ var grp = infobject;
+ var clipperPaths = [];
+ grp.traverse(function(child) {
+ console.log('Traverse: ', child)
+ if (child.name == "inflatedGroup") {
+ console.log("this is the inflated path from a previous run. ignore.");
+ return;
+ } else if (child.type == "Line") {
+ // let's inflate the path for this line. it may not be closed
+ // so we need to check that.
+ var clipperArr = [];
+ // Fix world Coordinates
+ for (i = 0; i < child.geometry.vertices.length; i++) {
+ var localPt = child.geometry.vertices[i];
+ var worldPt = grp.localToWorld(localPt.clone());
+ var xpos = worldPt.x;
+ var ypos = worldPt.y;
+
+ var xpos_offset = (parseFloat(child.position.x.toFixed(3)));
+ var ypos_offset = (parseFloat(child.position.y.toFixed(3)));
+
+ if (child.geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
+
+ clipperArr.push({
+ X: xpos,
+ Y: ypos
});
+ }
+ clipperPaths.push(clipperArr);
+ } else if (child.type == "Points") {
+ child.visible = false;
+ } else {
+ console.log("type of ", child.type, " being skipped");
+ }
+ });
- console.log("clipperPaths:", clipperPaths);
+ console.log("clipperPaths:", clipperPaths);
- // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
- var newClipperPaths = simplifyPolygons(clipperPaths);
+ // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
+ var newClipperPaths = simplifyPolygons(clipperPaths);
- if (newClipperPaths.length < 1) {
- console.error("Clipper Simplification Failed!:");
- printLog('Clipper Simplification Failed!', errorcolor, "viewer");
- }
+ if (newClipperPaths.length < 1) {
+ console.error("Clipper Simplification Failed!:");
+ printLog('Clipper Simplification Failed!', errorcolor, "viewer");
+ }
- // get the inflated/deflated path
- var inflatedPaths = getInflatePath(newClipperPaths, inflateVal);
+ // get the inflated/deflated path
+ var inflatedPaths = getInflatePath(newClipperPaths, inflateVal);
- for (i = 0; i < zdepth; i += zstep) {
- inflateGrp = drawClipperPaths(inflatedPaths, 0xff00ff, 0.8, -i, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
- inflateGrp.name = 'inflateGrp';
- if (inflateGrp.userData.color) {
- inflateGrp.userData.color = inflateGrp.material.color.getHex();
- }
- inflateGrp.position = infobject.position;
- console.log(i);
- inflateGrpZ.add(inflateGrp);
- }
- return inflateGrpZ;
- // }
+ for (i = 0; i < zdepth; i += zstep) {
+ inflateGrp = drawClipperPaths(inflatedPaths, 0xff00ff, 0.8, -i, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
+ inflateGrp.name = 'inflateGrp';
+ if (inflateGrp.userData.color) {
+ inflateGrp.userData.color = inflateGrp.material.color.getHex();
+ }
+ inflateGrp.position = infobject.position;
+ console.log(i);
+ inflateGrpZ.add(inflateGrp);
+ }
+ return inflateGrpZ;
+ // }
};
pocketPath = function(infobject, inflateVal, zstep, zdepth) {
- var zstep = parseFloat(zstep, 2);
- var zdepth = parseFloat(zdepth, 2);
- var pocketGrp = new THREE.Group();
- if (typeof(inflateGrp) != 'undefined') {
- scene.remove(inflateGrp);
- inflateGrp = null;
- }
- if (inflateVal != 0) {
- console.log("user wants to inflate. val:", inflateVal);
- infobject.updateMatrix();
- var grp = infobject;
- var clipperPaths = [];
- grp.traverse(function(child) {
- console.log('Traverse: ', child)
- if (child.name == "inflatedGroup") {
- console.log("this is the inflated path from a previous run. ignore.");
- return;
- } else if (child.type == "Line") {
- // let's inflate the path for this line. it may not be closed
- // so we need to check that.
- var clipperArr = [];
- // Fix world Coordinates
- for (i = 0; i < child.geometry.vertices.length; i++) {
- var localPt = child.geometry.vertices[i];
- var worldPt = grp.localToWorld(localPt.clone());
- var xpos = (parseFloat(worldPt.x.toFixed(3)));
- var ypos = (parseFloat(worldPt.y.toFixed(3)));
-
- var xpos_offset = (parseFloat(child.position.x.toFixed(3)));
- var ypos_offset = (parseFloat(child.position.y.toFixed(3)));
-
- if (child.geometry.type == "CircleGeometry") {
- xpos = (xpos + xpos_offset);
- ypos = (ypos + ypos_offset);
- }
-
-
-
- clipperArr.push({
- X: xpos,
- Y: ypos
- });
- }
- clipperPaths.push(clipperArr);
- } else if (child.type == "Points") {
- child.visible = false;
- } else {
- console.log("type of ", child.type, " being skipped");
- }
- });
+ var zstep = parseFloat(zstep, 2);
+ var zdepth = parseFloat(zdepth, 2);
+ var pocketGrp = new THREE.Group();
+ if (typeof(inflateGrp) != 'undefined') {
+ scene.remove(inflateGrp);
+ inflateGrp = null;
+ }
+ if (inflateVal != 0) {
+ console.log("user wants to inflate. val:", inflateVal);
+ infobject.updateMatrix();
+ var grp = infobject;
+ var clipperPaths = [];
+ grp.traverse(function(child) {
+ console.log('Traverse: ', child)
+ if (child.name == "inflatedGroup") {
+ console.log("this is the inflated path from a previous run. ignore.");
+ return;
+ } else if (child.type == "Line") {
+ // let's inflate the path for this line. it may not be closed
+ // so we need to check that.
+ var clipperArr = [];
+ // Fix world Coordinates
+ for (i = 0; i < child.geometry.vertices.length; i++) {
+ var localPt = child.geometry.vertices[i];
+ var worldPt = grp.localToWorld(localPt.clone());
+ var xpos = (parseFloat(worldPt.x.toFixed(3)));
+ var ypos = (parseFloat(worldPt.y.toFixed(3)));
+
+ var xpos_offset = (parseFloat(child.position.x.toFixed(3)));
+ var ypos_offset = (parseFloat(child.position.y.toFixed(3)));
+
+ if (child.geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
- console.log("clipperPaths:", clipperPaths);
- // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
- var newClipperPaths = simplifyPolygons(clipperPaths);
- if (newClipperPaths.length < 1) {
- console.error("Clipper Simplification Failed!:");
- printLog('Clipper Simplification Failed!', errorcolor, "viewer");
+ clipperArr.push({
+ X: xpos,
+ Y: ypos
+ });
}
+ clipperPaths.push(clipperArr);
+ } else if (child.type == "Points") {
+ child.visible = false;
+ } else {
+ console.log("type of ", child.type, " being skipped");
+ }
+ });
- for (j = 0; j < zdepth; j += zstep) {
- // get the inflated/deflated path
-
- for (i = 1; i < 100; i++) { // Rather 100 than a while loop, just in case
- inflateValUsed = inflateVal * i;
- var inflatedPaths = getInflatePath(newClipperPaths, -inflateValUsed);
- inflateGrp = drawClipperPaths(inflatedPaths, 0xff00ff, 0.8, -j, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
- if (inflateGrp.children.length) {
- inflateGrp.name = 'inflateGrp';
- inflateGrp.position = infobject.position;
- // pocketGrp.userData.color = pocketGrp.material.color.getHex();
- pocketGrp.add(inflateGrp);
- } else {
- console.log('Pocket already done after ' + i + ' iterations');
- break;
- }
- }
+ console.log("clipperPaths:", clipperPaths);
+
+ // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
+ var newClipperPaths = simplifyPolygons(clipperPaths);
+
+ if (newClipperPaths.length < 1) {
+ console.error("Clipper Simplification Failed!:");
+ printLog('Clipper Simplification Failed!', errorcolor, "viewer");
+ }
+
+ for (j = 0; j < zdepth; j += zstep) {
+ // get the inflated/deflated path
+
+ for (i = 1; i < 100; i++) { // Rather 100 than a while loop, just in case
+ inflateValUsed = inflateVal * i;
+ var inflatedPaths = getInflatePath(newClipperPaths, -inflateValUsed);
+ inflateGrp = drawClipperPaths(inflatedPaths, 0xff00ff, 0.8, -j, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
+ if (inflateGrp.children.length) {
+ inflateGrp.name = 'inflateGrp';
+ inflateGrp.position = infobject.position;
+ // pocketGrp.userData.color = pocketGrp.material.color.getHex();
+ pocketGrp.add(inflateGrp);
+ } else {
+ console.log('Pocket already done after ' + i + ' iterations');
+ break;
}
- return pocketGrp;
+ }
}
+ return pocketGrp;
+ }
};
dragknifePath = function(infobject, inflateVal, zstep, zdepth) {
- var zstep = parseFloat(zstep, 2);
- var zdepth = parseFloat(zdepth, 2);
- var dragknifeGrp = new THREE.Group();
- if (typeof(inflateGrp) != 'undefined') {
- scene.remove(inflateGrp);
- inflateGrp = null;
- }
+ var zstep = parseFloat(zstep, 2);
+ var zdepth = parseFloat(zdepth, 2);
+ var dragknifeGrp = new THREE.Group();
+ if (typeof(inflateGrp) != 'undefined') {
+ scene.remove(inflateGrp);
+ inflateGrp = null;
+ }
- // if (inflateVal != 0) {
- console.log("user wants to create Drag Knife Path. val:", inflateVal);
- infobject.updateMatrix();
- var grp = infobject;
- var clipperPaths = [];
- grp.traverse(function(child) {
- // console.log('Traverse: ', child)
- if (child.name == "inflatedGroup") {
- console.log("this is the inflated path from a previous run. ignore.");
- return;
- } else if (child.type == "Line") {
- // let's inflate the path for this line. it may not be closed
- // so we need to check that.
- var clipperArr = [];
- // Fix world Coordinates
- for (i = 0; i < child.geometry.vertices.length; i++) {
- var localPt = child.geometry.vertices[i];
- var worldPt = grp.localToWorld(localPt.clone());
- var xpos = worldPt.x;
- var ypos = worldPt.y;
-
- var xpos_offset = child.position.x;
- var ypos_offset = child.position.y;
-
- if (child.geometry.type == "CircleGeometry") {
- xpos = (xpos + xpos_offset);
- ypos = (ypos + ypos_offset);
- }
-
- clipperArr.push({
- X: xpos,
- Y: ypos
- });
- }
- clipperPaths.push(clipperArr);
- } else if (child.type == "Points") {
- child.visible = false;
- } else {
- console.log("type of ", child.type, " being skipped");
- }
+ // if (inflateVal != 0) {
+ console.log("user wants to create Drag Knife Path. val:", inflateVal);
+ infobject.updateMatrix();
+ var grp = infobject;
+ var clipperPaths = [];
+ grp.traverse(function(child) {
+ // console.log('Traverse: ', child)
+ if (child.name == "inflatedGroup") {
+ console.log("this is the inflated path from a previous run. ignore.");
+ return;
+ } else if (child.type == "Line") {
+ // let's inflate the path for this line. it may not be closed
+ // so we need to check that.
+ var clipperArr = [];
+ // Fix world Coordinates
+ for (i = 0; i < child.geometry.vertices.length; i++) {
+ var localPt = child.geometry.vertices[i];
+ var worldPt = grp.localToWorld(localPt.clone());
+ var xpos = worldPt.x;
+ var ypos = worldPt.y;
+
+ var xpos_offset = child.position.x;
+ var ypos_offset = child.position.y;
+
+ if (child.geometry.type == "CircleGeometry") {
+ xpos = (xpos + xpos_offset);
+ ypos = (ypos + ypos_offset);
+ }
+
+ clipperArr.push({
+ X: xpos,
+ Y: ypos
});
+ }
+ clipperPaths.push(clipperArr);
+ } else if (child.type == "Points") {
+ child.visible = false;
+ } else {
+ console.log("type of ", child.type, " being skipped");
+ }
+ });
- console.log("clipperPaths:", clipperPaths);
+ console.log("clipperPaths:", clipperPaths);
- // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
- var newClipperPaths = simplifyPolygons(clipperPaths);
+ // simplify this set of paths which is a very powerful Clipper call that figures out holes and path orientations
+ var newClipperPaths = simplifyPolygons(clipperPaths);
- if (newClipperPaths.length < 1) {
- console.error("Clipper Simplification Failed!:");
- printLog('Clipper Simplification Failed!', errorcolor, "viewer")
- }
+ if (newClipperPaths.length < 1) {
+ console.error("Clipper Simplification Failed!:");
+ printLog('Clipper Simplification Failed!', errorcolor, "viewer")
+ }
- for (j = 0; j < zdepth; j += zstep) {
- var polygons = newClipperPaths;
- polygons = polygons.map(function (poly) {
- // return addCornerActions(poly, Math.pow(2, 20) * 5, 20 / 180 * Math.PI);
- return addCornerActions(poly, inflateVal, 20 / 180 * Math.PI);
- });
- inflateGrp = drawClipperPaths(polygons, 0xff00ff, 0.8, -j, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
- if (inflateGrp.children.length) {
- inflateGrp.name = 'dragknifeGrp';
- inflateGrp.position = infobject.position;
- dragknifeGrp.userData.color = dragknifeGrp.material.color.getHex();
- dragknifeGrp.add(inflateGrp)
- } else {
- console.log('Dragknife Operation Failed')
- break;
- }
- }
- return dragknifeGrp
+ for (j = 0; j < zdepth; j += zstep) {
+ var polygons = newClipperPaths;
+ polygons = polygons.map(function (poly) {
+ // return addCornerActions(poly, Math.pow(2, 20) * 5, 20 / 180 * Math.PI);
+ return addCornerActions(poly, inflateVal, 20 / 180 * Math.PI);
+ });
+ inflateGrp = drawClipperPaths(polygons, 0xff00ff, 0.8, -j, true, "inflatedGroup"); // (paths, color, opacity, z, zstep, isClosed, isAddDirHelper, name, inflateVal)
+ if (inflateGrp.children.length) {
+ inflateGrp.name = 'dragknifeGrp';
+ inflateGrp.position = infobject.position;
+ dragknifeGrp.userData.color = dragknifeGrp.material.color.getHex();
+ dragknifeGrp.add(inflateGrp)
+ } else {
+ console.log('Dragknife Operation Failed')
+ break;
+ }
+ }
+ return dragknifeGrp
};
addCornerActions = function (clipperPolyline, clipperRadius, toleranceAngleRadians) {
// var previousPoint = null;
// var point = [];
- console.log("clipperPolyline Starting : ", clipperPolyline);
- if (clipperRadius == 0 || clipperPolyline.length == 0)
- return clipperPolyline;
- var result = [];
- result.push(clipperPolyline[0]);
- //previous point is not always at i-1, because repeated points in the polygon are skipped
- // var previousPoint = clipperPolyline[0];
- var previousPoint = new Point(clipperPolyline[0].X, clipperPolyline[0].Y, 0); //clipperPolyline[i - 1];
- for (var i = 1; i < clipperPolyline.length - 1; i++) {
- previousPoint = new Point(clipperPolyline[i - 1].X, clipperPolyline[i - 1].Y, 0); //clipperPolyline[i - 1];
- var point = new Point(clipperPolyline[i].X, clipperPolyline[i].Y, 0); //clipperPolyline[i];
- if (previousPoint.sqDistance(point) == 0)
- continue;
- // you don't want to play with atan2() if a point is repeated
- var incomingVector = point.sub(previousPoint);
- var nextPoint = new Point(clipperPolyline[i + 1].X, clipperPolyline[i + 1].Y, 0) //clipperPolyline[i + 1];
- var angle = point.angle(previousPoint, nextPoint);
- var overshoot = point.add(incomingVector.normalized().scale(clipperRadius));
- result.push(overshoot);
- if (Math.abs(angle) > toleranceAngleRadians) {
-
- var arcPoints = 100 / (2 * Math.PI) * Math.abs(angle);
- var incomingAngle = incomingVector.atan2();
- for (var j = 0; j <= arcPoints; j++) {
- var a = incomingAngle + angle / arcPoints * j;
- var pt = point.add(polarPoint(clipperRadius, a));
- result.push(pt);
- }
- }
- previousPoint = point;
+ console.log("clipperPolyline Starting : ", clipperPolyline);
+ if (clipperRadius == 0 || clipperPolyline.length == 0)
+ return clipperPolyline;
+ var result = [];
+ result.push(clipperPolyline[0]);
+ //previous point is not always at i-1, because repeated points in the polygon are skipped
+ // var previousPoint = clipperPolyline[0];
+ var previousPoint = new Point(clipperPolyline[0].X, clipperPolyline[0].Y, 0); //clipperPolyline[i - 1];
+ for (var i = 1; i < clipperPolyline.length - 1; i++) {
+ previousPoint = new Point(clipperPolyline[i - 1].X, clipperPolyline[i - 1].Y, 0); //clipperPolyline[i - 1];
+ var point = new Point(clipperPolyline[i].X, clipperPolyline[i].Y, 0); //clipperPolyline[i];
+ if (previousPoint.sqDistance(point) == 0)
+ continue;
+ // you don't want to play with atan2() if a point is repeated
+ var incomingVector = point.sub(previousPoint);
+ var nextPoint = new Point(clipperPolyline[i + 1].X, clipperPolyline[i + 1].Y, 0) //clipperPolyline[i + 1];
+ var angle = point.angle(previousPoint, nextPoint);
+ var overshoot = point.add(incomingVector.normalized().scale(clipperRadius));
+ result.push(overshoot);
+ if (Math.abs(angle) > toleranceAngleRadians) {
+
+ var arcPoints = 100 / (2 * Math.PI) * Math.abs(angle);
+ var incomingAngle = incomingVector.atan2();
+ for (var j = 0; j <= arcPoints; j++) {
+ var a = incomingAngle + angle / arcPoints * j;
+ var pt = point.add(polarPoint(clipperRadius, a));
+ result.push(pt);
+ }
}
- if (clipperPolyline.length > 1)
- result.push(clipperPolyline[clipperPolyline.length - 1]);
- return result;
- }
-
- function Point(X, Y, Z) {
- this.X = X;
- this.Y = Y;
- this.Z = Z === undefined ? 0 : Z;
- }
-
- Point.prototype = {
- sqDistance: function (p) {
+ previousPoint = point;
+ }
+ if (clipperPolyline.length > 1)
+ result.push(clipperPolyline[clipperPolyline.length - 1]);
+ return result;
+}
+
+function Point(X, Y, Z) {
+ this.X = X;
+ this.Y = Y;
+ this.Z = Z === undefined ? 0 : Z;
+}
+
+Point.prototype = {
+ sqDistance: function (p) {
var d = p == null ? this : this.sub(p);
return d.X * d.X + d.Y * d.Y + d.Z * d.Z;
},
sub: function (p) {
- // console.log("sub.x: ", this.x, " p.x ", p.x)
- return new Point(this.X - p.X, this.Y - p.Y, this.Z - p.Z);
+ // console.log("sub.x: ", this.x, " p.x ", p.x)
+ return new Point(this.X - p.X, this.Y - p.Y, this.Z - p.Z);
},
angle: function (fromPoint, toPoint) {
- var toPoint2 = new Point(toPoint.X, toPoint.Y, toPoint.Z);
- var v1 = this.sub(fromPoint);
- var v2 = toPoint2.sub(this);
- var dot = v1.X * v2.X + v1.Y * v2.Y;
- var cross = v1.X * v2.Y - v1.Y * v2.X;
- var res = Math.atan2(cross, dot);
- var twoPi = 2 * Math.PI;
- if (res < -twoPi)
- return res + twoPi;
- if (res > twoPi)
- return res - twoPi;
- return res;
+ var toPoint2 = new Point(toPoint.X, toPoint.Y, toPoint.Z);
+ var v1 = this.sub(fromPoint);
+ var v2 = toPoint2.sub(this);
+ var dot = v1.X * v2.X + v1.Y * v2.Y;
+ var cross = v1.X * v2.Y - v1.Y * v2.X;
+ var res = Math.atan2(cross, dot);
+ var twoPi = 2 * Math.PI;
+ if (res < -twoPi)
+ return res + twoPi;
+ if (res > twoPi)
+ return res - twoPi;
+ return res;
},
normalized: function () {
- // console.log("normalized.distance: ", this.distance())
- return this.scale(1 / this.distance());
- console.log("normalized: ", this.scale(1 / this.distance()))
+ // console.log("normalized.distance: ", this.distance())
+ return this.scale(1 / this.distance());
+ console.log("normalized: ", this.scale(1 / this.distance()))
},
scale: function (val) {
- return new Point(this.X * val, this.Y * val, this.Z * val);
+ return new Point(this.X * val, this.Y * val, this.Z * val);
},
distance: function (p) {
- return Math.sqrt(this.sqDistance(p));
+ return Math.sqrt(this.sqDistance(p));
},
add: function (p) {
- return new Point(this.X + p.X, this.Y + p.Y, this.Z + p.Z);
+ return new Point(this.X + p.X, this.Y + p.Y, this.Z + p.Z);
},
atan2: function () {
- return Math.atan2(this.Y, this.Y);
+ return Math.atan2(this.Y, this.Y);
},
};
@@ -683,66 +783,66 @@ polarPoint = function (r, theta) {
simplifyPolygons = function(paths) {
- console.log('Simplifying: ', paths);
- var scale = 10000;
- ClipperLib.JS.ScaleUpPaths(paths, scale);
- var newClipperPaths = ClipperLib.Clipper.SimplifyPolygons(paths, ClipperLib.PolyFillType.pftEvenOdd);
- console.log('Simplified: ', newClipperPaths);
- // scale back down
- ClipperLib.JS.ScaleDownPaths(newClipperPaths, scale);
- ClipperLib.JS.ScaleDownPaths(paths, scale);
- return newClipperPaths;
+ console.log('Simplifying: ', paths);
+ var scale = 10000;
+ ClipperLib.JS.ScaleUpPaths(paths, scale);
+ var newClipperPaths = ClipperLib.Clipper.SimplifyPolygons(paths, ClipperLib.PolyFillType.pftEvenOdd);
+ console.log('Simplified: ', newClipperPaths);
+ // scale back down
+ ClipperLib.JS.ScaleDownPaths(newClipperPaths, scale);
+ ClipperLib.JS.ScaleDownPaths(paths, scale);
+ return newClipperPaths;
};
getInflatePath = function(paths, delta, joinType) {
- var scale = 10000;
- ClipperLib.JS.ScaleUpPaths(paths, scale);
- var miterLimit = 2;
- var arcTolerance = 10;
- joinType = joinType ? joinType : ClipperLib.JoinType.jtRound;
- var co = new ClipperLib.ClipperOffset(miterLimit, arcTolerance);
- co.AddPaths(paths, joinType, ClipperLib.EndType.etClosedPolygon);
- //var delta = 0.0625; // 1/16 inch endmill
- var offsetted_paths = new ClipperLib.Paths();
- co.Execute(offsetted_paths, delta * scale);
- // scale back down
- ClipperLib.JS.ScaleDownPaths(offsetted_paths, scale);
- ClipperLib.JS.ScaleDownPaths(paths, scale);
- return offsetted_paths;
+ var scale = 10000;
+ ClipperLib.JS.ScaleUpPaths(paths, scale);
+ var miterLimit = 2;
+ var arcTolerance = 10;
+ joinType = joinType ? joinType : ClipperLib.JoinType.jtRound;
+ var co = new ClipperLib.ClipperOffset(miterLimit, arcTolerance);
+ co.AddPaths(paths, joinType, ClipperLib.EndType.etClosedPolygon);
+ //var delta = 0.0625; // 1/16 inch endmill
+ var offsetted_paths = new ClipperLib.Paths();
+ co.Execute(offsetted_paths, delta * scale);
+ // scale back down
+ ClipperLib.JS.ScaleDownPaths(offsetted_paths, scale);
+ ClipperLib.JS.ScaleDownPaths(paths, scale);
+ return offsetted_paths;
};
drawClipperPaths = function(paths, color, opacity, z, isClosed, name) {
- console.log("drawClipperPaths", paths);
+ console.log("drawClipperPaths", paths);
- var lineUnionMat = new THREE.LineBasicMaterial({
- color: color,
- transparent: true,
- opacity: opacity,
- });
+ var lineUnionMat = new THREE.LineBasicMaterial({
+ color: color,
+ transparent: true,
+ opacity: opacity,
+ });
- if (z === undefined || z == null)
- z = 0;
+ if (z === undefined || z == null)
+ z = 0;
- if (isClosed === undefined || isClosed == null)
- isClosed = true;
+ if (isClosed === undefined || isClosed == null)
+ isClosed = true;
- var group = new THREE.Object3D();
- if (name) group.name = name;
+ var group = new THREE.Object3D();
+ if (name) group.name = name;
- for (var i = 0; i < paths.length; i++) {
- var lineUnionGeo = new THREE.Geometry();
- for (var j = 0; j < paths[i].length; j++) {
- lineUnionGeo.vertices.push(new THREE.Vector3(paths[i][j].X, paths[i][j].Y, z));
- }
- // close it by connecting last point to 1st point
- if (isClosed) {
- lineUnionGeo.vertices.push(new THREE.Vector3(paths[i][0].X, paths[i][0].Y, z));
- }
- var lineUnion = new THREE.Line(lineUnionGeo, lineUnionMat);
- if (name) {
- lineUnion.name = name;
- }
- group.add(lineUnion);
+ for (var i = 0; i < paths.length; i++) {
+ var lineUnionGeo = new THREE.Geometry();
+ for (var j = 0; j < paths[i].length; j++) {
+ lineUnionGeo.vertices.push(new THREE.Vector3(paths[i][j].X, paths[i][j].Y, z));
+ }
+ // close it by connecting last point to 1st point
+ if (isClosed) {
+ lineUnionGeo.vertices.push(new THREE.Vector3(paths[i][0].X, paths[i][0].Y, z));
}
- return group;
+ var lineUnion = new THREE.Line(lineUnionGeo, lineUnionMat);
+ if (name) {
+ lineUnion.name = name;
+ }
+ group.add(lineUnion);
+ }
+ return group;
};