Skip to content
Snippets Groups Projects
Commit 4461715f authored by Jakob Yanagibashi's avatar Jakob Yanagibashi
Browse files

Initial commit

parents
Branches
Tags
No related merge requests found
:root {
--header-height: 4rem;
}
/* TEMP */
#list-commands {
display: none;
}
body {
display: flex;
flex-flow: column wrap;
font-family: ui-sans-serif, sans-serif;
}
header {
height: var(--header-height);
}
h1 {
display: inline-block;
margin: 0 1rem;
padding-top: 0.5rem;
}
menu {
display: inline-block;
list-style-type: none;
padding: 0;
margin: 0;
}
menu > li {
display: inline-block;
}
menu button {
border: none;
border-radius: 0.5rem;
background-color: #ddd;
padding: 0.5rem 1rem;
margin: 0 0.5rem;
border: 1px solid black;
transition: 0.3s;
cursor: pointer;
}
menu button:hover {
background-color: #bbb;
}
main {
display: flex;
flex-direction: row;
}
section {
border-top: 2px solid black;
display: flex;
flex-direction: column;
height: calc(100vh - var(--header-height) - 2px);
}
section#viewer {
flex: 2;
border-right: 2px solid black;
}
article#viewer-settings {
background-color: #eff;
padding: 1rem 0 0 1rem;
border-top: 2px solid black;
}
section#tools {
background-color: #ddd;
flex: 1;
}
article#viewer-main {
flex: 1;
}
article#viewer-settings {
height: 3rem;
}
article#tools-edit {
flex: 1;
}
article#tools-list {
flex: 1;
}
article#tools-list-buttons {
height: 3rem;
}
/*ul {
padding-left: 0;
margin-bottom: 0;
}
#command-area {
height: 400px;
}
#list-commands-wrapper {
margin: 1rem 0;
width: 300px;
float: left;
background-color: slategray;
border-radius: 10px;
}
#list-commands {
height: 300px;
overflow-y: auto;
list-style: none;
padding: 2rem 0;
}
#list-commands > li {
width: 200px;
margin: 1rem auto;
padding: 0.5rem 1rem;
background-color: lightgray;
border-radius: 10px;
}
#list-commands .command-active {
background-color: white;
}
#popup-edit {
margin: 1rem 0;
width: 300px;
display: none;
float: right;
background-color: white;
padding: 2rem 3rem;
height: 300px;
border-radius: 10px;
}
#popup-edit-parameters {
list-style: none;
}*/
index.htm 0 → 100644
<!DOCTYPE html>
<html>
<head>
<title>3p</title>
<link
rel="stylesheet"
href="https://unpkg.com/normalize.css/normalize.css"
type="text/css"
/>
<!-- <link
rel="stylesheet"
href="https://unpkg.com/sakura.css/css/sakura.css"
type="text/css"
/> -->
<link rel="stylesheet" href="css/main.css" type="text/css" />
<script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script>
<script type="module" src="js/main.js"></script>
</head>
<body>
<header>
<h1>GPather</h1>
<menu>
<li><button id="saveProjectMenuButton">Save project</button></li>
<li><button id="loadProjectMenuButton">Load project</button></li>
<li><button id="loadPresetMenuButton">Load preset</button></li>
<li><button id="importProjectMenuButton">Import project</button></li>
<li><button id="exportProjectMenuButton">Export project</button></li>
</menu>
</header>
<main>
<section id="viewer">
<article id="viewer-main">
<canvas class="zdog-canvas" width="600" height="600"></canvas>
</article>
<article id="viewer-settings">
<menu>
<li><button>+ Zoom</button></li>
<li><button>- Zoom</button></li>
<li><button>Side</button></li>
<li><button>Top</button></li>
<li><button>Bottom</button></li>
</menu>
</article>
</section>
<section id="tools">
<article id="tools-edit">Tools Edit</article>
<article id="tools-list">
Tools List
<ul id="list-commands"></ul>
</article>
<article id="tools-list-buttons">Tools List Buttons</article>
</section>
</main>
<dialog id="loadPresetDialog">
<form method="dialog">
<input type="text" id="loadPresetInput" />
<menu>
<button value="load">Load</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
<!--
<div id="command-area">
<button id="button-loadProject">Load</button>
<input
type="text"
value="1101"
id="project-input"
onfocus="this.value = '';"
/>
<div>
<div id="list-commands-wrapper">
<ul id="list-commands"></ul>
</div>
<div id="popup-edit">
<h3 id="popup-edit-command">Command</h3>
<ul id="popup-edit-parameters"></ul>
<button id="button-update-command">Update</button>
<button id="button-delete-command">Delete</button>
</div>
</div>
</div>
<div id="canvas-area">
<canvas
style="display: inline-block; /*max-width: 49%*/"
class="zdog-canvas"
width="800"
height="600"
></canvas>
<canvas
style="display: inline-block; /*max-width: 49%*/"
class="zdog-canvas2"
width="800"
height="600"
></canvas>
<canvas
style="display: none"
class="zdog-canvas3"
width="800"
height="600"
></canvas>
<div id="model-stats">Kein Modell geladen.</div>
</div>
<div>
<button id="button-generate">Generate</button>
<button id="button-save">Save as...</button>
<textarea id="textarea-output" rows="20"></textarea>
</div>
-->
</body>
</html>
class Command {
constructor() {}
toString() {
return "";
}
}
// G0
class RapidMove extends Command {
constructor(x, y, z, speed) {
super();
this.goalx = x;
this.goaly = y;
this.goalz = z;
this.speed = speed;
}
getParameters() {
return [this.goalx, this.goaly, this.goalz, this.speed];
}
toString() {
return "G0" + this.goalx + this.goaly + this.goalz + this.speed;
}
getDescription() {
return "Rapid Move";
}
}
// G1
class Move extends Command {
// speed: Feed rate - F
// flow: Extrusion rate - E
constructor(x = null, y = null, z = null, flow = null, speed = null) {
super();
this.goalx = x;
this.goaly = y;
this.goalz = z;
this.speed = speed;
this.flow = flow;
}
getParameters() {
return [this.goalx, this.goaly, this.goalz, this.speed, this.flow];
}
setParameter(paramName, value) {
const myParams = [
this.goalx,
this.goaly,
this.goalz,
this.speed,
this.flow,
];
myParams.forEach((param) => {
if (param.constructor.name == paramName) param.setValue(value);
});
}
toString() {
return "G1" + this.flow + this.speed + this.goalx + this.goaly + this.goalz;
}
getDescription() {
return "Move";
}
}
class Extrude extends Command {
constructor(flow) {
super();
this.flow = flow;
}
getParameters() {
return [this.flow];
}
toString() {
return "G1" + this.flow;
}
getDescription() {
return "Extrude";
}
}
// G2/G3
class Circle extends Command {
constructor(orientation, radius, flow, x = null, y = null, z = null) {
super();
if (orientation == "right") {
this.circleCode = "G2";
} else if (orientation == "left") {
this.circleCode = "G3";
}
if (x == null && y != null && z != null) {
// YZ - G19
this.planeCode = "G19 ";
} else if (x != null && y == null && z != null) {
// XZ - G18
this.planeCode = "G18 ";
} else if (x != null && y != null && z == null) {
// XY - G17
this.planeCode = "G17 ";
}
this.x = x;
this.y = y;
this.z = z;
this.radius = radius;
this.flow = flow;
}
toString() {
if (this.x == null && this.y != null && this.z != null) {
// YZ - G19
return (
this.planeCode +
this.circleCode +
this.flow +
this.y +
this.z +
"R " +
this.radius
);
} else if (this.x != null && this.y == null && this.z != null) {
// XZ - G18
return (
this.planeCode +
this.circleCode +
this.flow +
this.x +
this.z +
" R" +
this.radius
);
} else if (this.x != null && this.y != null && this.z == null) {
// XY - G17
return (
this.planeCode +
this.circleCode +
this.flow +
this.x +
this.y +
" R" +
this.radius
);
}
}
getDescription() {
return "Arc";
}
}
// G4
class Pause extends Command {
constructor(time) {
super();
this.time = time;
}
getParameters() {
return [this.time];
}
toString() {
return "G4 S" + this.time;
}
getDescription() {
return "Pause";
}
}
export { RapidMove, Move, Pause, Extrude, Circle };
This diff is collapsed.
class Parameter {
constructor(value) {
this.value = value;
}
getValue() {
return this.value;
}
setValue(value) {
this.value = value;
}
}
class XCoord extends Parameter {
toString() {
var gcode = "";
if (this.value !== null) gcode = " X" + this.value.toFixed(8);
return gcode;
}
getDescription() {
return "X";
}
}
class YCoord extends Parameter {
toString() {
var gcode = "";
if (this.value !== null) gcode = " Y" + this.value.toFixed(8);
return gcode;
}
getDescription() {
return "Y";
}
}
class ZCoord extends Parameter {
toString() {
var gcode = "";
if (this.value !== null) gcode = " Z" + this.value.toFixed(8);
return gcode;
}
getDescription() {
return "Z";
}
}
class Speed extends Parameter {
toString() {
var gcode = "";
if (this.value !== null) gcode = " F" + this.value;
return gcode;
}
getDescription() {
return "Speed";
}
}
class Flow extends Parameter {
toString() {
var gcode = "";
if (this.value !== null) gcode = " E" + this.value.toFixed(8);
return gcode;
}
getDescription() {
return "Flow";
}
}
class TimeMillisec extends Parameter {
toString() {
var gcode = " P" + this.value;
return gcode;
}
getDescription() {
return "Duration (ms)";
}
}
export { XCoord, YCoord, ZCoord, Speed, Flow, TimeMillisec };
import { RapidMove, Move, Pause, Extrude, Circle } from "./command.js";
import { XCoord, YCoord, ZCoord, Speed, Flow } from "./parameter.js";
class Project {
/*
G90: absolute positioning
M82: Extruder, absolute positioning
G28: Auto home
G92: Set position (here: E to 0)
G1: Move
*/
static initAbsolute = {
startCode: `; -- START GCODE --
G90
M82
G28
G92 E0.0000
G1 E-4.0000 F60000
; -- end of START GCODE --
`,
endCode: `; -- END GCODE --
G92 E0.0000
G1 E-4.0000 F60000
G28
; -- end of END GCODE --
`,
};
coordModifier = {
axisX: 0.0,
axisY: 0.0,
axisZ: 0.0,
};
currentCoordinates = {
axisX: 0.0,
axisY: 0.0,
axisZ: 0.0,
axisExtruder: 0.0,
};
extrudeMulti = 1.0;
statOutput = "Kein Modell geladen";
constructor(extrudeMulti = 1.0, xMod = 0.0, yMod = 0.0, zMod = 0.0) {
this.extrudeMulti = extrudeMulti;
this.commands = [];
this.statOutput = "Kein Modell geladen";
this.coordModifier.axisX = xMod;
this.coordModifier.axisY = yMod;
this.coordModifier.axisZ = zMod;
this.currentCoordinates.axisX += this.coordModifier.axisX;
this.currentCoordinates.axisY += this.coordModifier.axisY;
this.currentCoordinates.axisZ += this.coordModifier.axisZ;
}
getCommands() {
return this.commands;
}
getCommand(id) {
// TODO: check if exists
return this.commands[id - 1];
}
deleteCommand(id) {
delete this.commands[id - 1];
}
updateParameter(commandId, param, value) {
this.commands[commandId - 1].setParameter(param, value);
}
appendArcTest(relX = 0.0, relY = 0.0, radius = 0.0, relE = 0.0) {
let newX = this.currentCoordinates.axisX + relX;
let newY = this.currentCoordinates.axisY + relY;
var length = Math.hypot(relX, relY); // calculate E proportionally from length
var newE;
if (relE > 0) {
newE =
this.currentCoordinates.axisExtruder +
relE * length * this.extrudeMulti;
} else {
newE = this.currentCoordinates.axisExtruder + relE * length;
}
const newCommand = new Circle(
"right",
radius,
new Flow(newE),
new XCoord(newX),
new YCoord(newY)
);
let id = this.commands.push(newCommand);
this.addCommandToList(newCommand, id);
//this.addCommandToCanvas(newCommand);
this.saveNewCoordinates(newX, newY, this.currentCoordinates.axisZ, newE); // always do this last
}
appendMoveAbsolute(
absX = 0.0,
absY = 0.0,
absZ = 0.0,
relE = 0.0,
speed = null
) {
if (absX == null) absX = this.currentCoordinates.axisX;
if (absY == null) absY = this.currentCoordinates.axisY;
if (absZ == null) absZ = this.currentCoordinates.axisZ;
var length = Math.hypot(
Math.abs(this.currentCoordinates.axisX - absX),
Math.abs(this.currentCoordinates.axisY - absY),
Math.abs(this.currentCoordinates.axisZ - absZ)
); // calculate E proportionally from length
var newE;
if (relE > 0) {
newE =
this.currentCoordinates.axisExtruder +
relE * length * this.extrudeMulti;
} else {
newE = this.currentCoordinates.axisExtruder + relE * length;
}
const newCommand = new Move(
new XCoord(absX + this.coordModifier.axisX),
new YCoord(absY + this.coordModifier.axisY),
new ZCoord(absZ + this.coordModifier.axisZ),
new Flow(newE),
new Speed(speed)
);
let id = this.commands.push(newCommand);
this.addCommandToList(newCommand, id);
//this.addCommandToCanvas(newCommand);
this.saveNewCoordinates(
absX + this.coordModifier.axisX,
absY + this.coordModifier.axisY,
absZ + this.coordModifier.axisZ,
newE
);
}
appendMoveRelative(
relX = 0.0,
relY = 0.0,
relZ = 0.0,
relE = 0.0,
speed = null
) {
let newX = this.currentCoordinates.axisX + relX;
let newY = this.currentCoordinates.axisY + relY;
let newZ = this.currentCoordinates.axisZ + relZ;
var length = Math.hypot(relX, relY, relZ); // calculate E proportionally from length
var newE;
if (relE > 0) {
newE =
this.currentCoordinates.axisExtruder +
relE * length * this.extrudeMulti;
} else {
newE = this.currentCoordinates.axisExtruder + relE * length;
}
const newCommand = new Move(
new XCoord(newX),
new YCoord(newY),
new ZCoord(newZ),
new Flow(newE),
new Speed(speed)
);
let id = this.commands.push(newCommand);
this.addCommandToList(newCommand, id);
//this.addCommandToCanvas(newCommand);
this.saveNewCoordinates(newX, newY, newZ, newE); // always do this last
}
extrude(mm = 1) {
const newE = this.currentCoordinates.axisExtruder + mm * this.extrudeMulti;
const newCommand = new Extrude(new Flow(newE));
let id = this.commands.push(newCommand);
this.addCommandToList(newCommand, id);
this.saveNewCoordinates(
this.currentCoordinates.axisX,
this.currentCoordinates.axisY,
this.currentCoordinates.axisZ,
newE
);
}
wait(seconds = 1) {
const newCommand = new Pause(seconds);
let id = this.commands.push(newCommand);
this.addCommandToList(newCommand, id);
}
saveNewCoordinates(newX = null, newY = null, newZ = null, newE = null) {
this.currentCoordinates.axisX = newX;
this.currentCoordinates.axisY = newY;
this.currentCoordinates.axisZ = newZ;
this.currentCoordinates.axisExtruder = newE;
}
addCommandToList(command, id) {
const li = document.createElement("li");
const commandList = document.getElementById("list-commands");
li.dataset.id = id;
li.textContent = command.getDescription();
//li.addEventListener('click', editCommand);
commandList.appendChild(li);
li.scrollIntoView(false);
}
/*
addCommandToCanvas(command) {
if (command instanceof Move) {
// Draw on canvas
const parameters = command.getParameters();
const c = document.getElementById("draw-canvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(this.currentCoordinates.axisX + 150, -this.currentCoordinates.axisZ + 300);
ctx.lineTo(parameters[0].getValue() + 150, -parameters[2].getValue() + 300);
if (parameters[4].getValue() !== null) { ctx.strokeStyle = 'red'; }
else { ctx.strokeStyle = 'black'; }
ctx.stroke();
const c2 = document.getElementById("draw-canvas-2");
var ctx2 = c2.getContext("2d");
ctx2.beginPath();
ctx2.moveTo(this.currentCoordinates.axisX + 150, -this.currentCoordinates.axisY + 300);
ctx2.lineTo(parameters[0].getValue() + 150, -parameters[1].getValue() + 300);
if (parameters[4].getValue() !== null) { ctx2.strokeStyle = 'red'; }
else { ctx2.strokeStyle = 'black'; }
ctx2.stroke();
// Draw on illo
if (parameters[4].getValue() > this.currentCoordinates.axisExtruder) {
new Zdog.Shape({
addTo: illo2,
path: [
{
y: this.currentCoordinates.axisX,
x: this.currentCoordinates.axisY,
z: this.currentCoordinates.axisZ,
},
{
y: parameters[0].getValue(),
x: parameters[1].getValue(),
z: parameters[2].getValue(),
},
],
stroke: illoStrokeWidth,
color: illoColor,
});
} else {
new Zdog.Shape({
addTo: illo3,
path: [
{
y: this.currentCoordinates.axisX,
x: this.currentCoordinates.axisY,
z: this.currentCoordinates.axisZ,
},
{
y: parameters[0].getValue(),
x: parameters[1].getValue(),
z: parameters[2].getValue(),
},
],
stroke: illoStrokeWidth,
color: illoColor,
});
}
}
}
*/
draw() {
this.commands.forEach((c) => {
if (c instanceof Move) {
const parameters = c.getParameters();
const illoColor = "#800";
const illoStrokeWidth = 0.9;
new Zdog.Shape({
addTo: window.illo,
path: [
{
y: this.currentCoordinates.axisX,
x: this.currentCoordinates.axisY,
z: this.currentCoordinates.axisZ,
},
{
y: parameters[0].getValue(),
x: parameters[1].getValue(),
z: parameters[2].getValue(),
},
],
stroke: illoStrokeWidth,
color: "black",
});
}
});
}
addStatOutput(text) {
this.statOutput += text + "<br>";
}
getModelStats() {
return this.statOutput;
}
getGCode() {
var gcode = Project.initAbsolute.startCode;
gcode += this.generateGCode();
gcode += Project.initAbsolute.endCode;
return gcode;
}
generateGCode() {
this.statOutput = "";
this.commands = this.commands.flat(); // de-sparse commands array
var gcode = "";
var maxVals = { x: 0, y: 0, z: 0, e: 0 };
var minVals = { x: 0, y: 0, z: 0 };
this.commands.forEach((command) => {
gcode += command + "\n";
if (command instanceof Move) {
const parameters = command.getParameters();
const vals = {
x: parameters[0].getValue(),
y: parameters[1].getValue(),
z: parameters[2].getValue(),
e: parameters[4].getValue(),
};
if (vals.z < 0.0) {
this.addStatOutput("CAUTION: Z-Axis below ground: " + command);
}
if (vals.e > maxVals.e) {
if (vals.x > maxVals.x) maxVals.x = vals.x;
if (vals.y > maxVals.y) maxVals.y = vals.y;
if (vals.z > maxVals.z) maxVals.z = vals.z;
if (vals.x < minVals.x) minVals.x = vals.x;
if (vals.y < minVals.y) minVals.y = vals.y;
if (vals.z < minVals.z) minVals.z = vals.z;
}
maxVals.e = vals.e;
}
});
this.addStatOutput(
"Max X: " +
maxVals.x +
", Max Y: " +
maxVals.y +
", Max Z: " +
maxVals.z +
", Max E: " +
maxVals.e
);
this.addStatOutput(
"Min X: " + minVals.x + ", Min Y: " + minVals.y + ", Min Z: " + minVals.z
);
this.addStatOutput("G-Code generation successful.");
return gcode;
}
}
export { Project };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment