Public
Edited
Apr 20, 2023
Fork of Drawing API
Insert cell
Insert cell
Insert cell
drawingPad = makeDrawingPad()
Insert cell
drawingPad.ps.project.layers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectedItemNewParams
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mutable test = 0
Insert cell
mutable clearDrawingIndicator = Date.now()
Insert cell
mutable toolUseIndicator = Date.now()
Insert cell
function generateCodeFromCanvas(ps) {
let cps = ps.project.activeLayer.children.map((c) => c.callParams);
let replace = (cp) => {
let obj = cp.obj;
if (cp.op === "circle") {
return `.circle({ x: ${obj.position.x}, y: ${obj.position.y}, r: ${obj.bounds.width}})`;
}
if (cp.op === "rectangle") {
return `.circle({ x: ${obj.position.x}, y: ${obj.position.y}, width: ${obj.bounds.width}, height: ${obj.bounds.width} })`;
} else {
return null;
}
};
return cps.map(replace);
}
Insert cell
generateCodeFromCanvas(drawingPad.ps)
Insert cell
Insert cell
travelHeight = 0.25
Insert cell
thickness = 0.75
Insert cell
stepdown = toolDiameter / 2
Insert cell
Insert cell
sampleShape = drawingPad.ps.project.activeLayer.children[0]
Insert cell
function supersample(path) {
if (path.callParams) {
return path.callParams;
if (path.callParams.op === "circle") {
return
}
}
return path.segments;
}
Insert cell
SAMPLING_RESOLUTION = 0.125
Insert cell
function offsetPathForCutSide(path) {
// TODO - inside outside
if (path.callParams.cutSide === "inside") {
return path.offset(-(toolDiameter / 2) * UPSCALE, { insert: false });
} else if (path.callParams.cutSide === "outside") {
return path.offset((toolDiameter / 2) * UPSCALE, { insert: false });
} else {
return path;
}
}
Insert cell
function instsFromDrawingPad(ps) {
// TODO: either super-sample non-rectangle shapes, or in the case of circles use the SBP CC command.
let paths = ps.project.activeLayer.children.filter(
(shape) => shape.callParams.staged
);
paths = paths.reverse();
return paths.map((path) => {
let truncate = (num) => {
return Math.round(num * 1000) / 1000;
};
if (!path.curves) {
return [];
}
path = offsetPathForCutSide(path);
let points = path.curves
.map((curve) => {
// NOTE: do NOT attempt to optimize for straight lines, we need supersampled
// points to generate tabs
let numCurveSamples = Math.floor(
curve.length / UPSCALE / SAMPLING_RESOLUTION
);
let times = [...Array(numCurveSamples).keys()].map(
(i) => i / numCurveSamples
);
let samplePoints = times.map((t) => curve.getPointAtTime(t));
let points = samplePoints.map((pt) => [pt.x, pt.y]);
return [...points, [curve.segment2.point.x, curve.segment2.point.y]];
})
.flat();
points = points.map((pt) => [
truncate(pt[0] / UPSCALE),
truncate(pt[1] / UPSCALE)
]);
let prologue = [`JZ,`];
let insts = points.map((point) => `M2,${point[0]},${point[1]}`);
if (points.length > 0 && path.closed) {
insts.push(`M2,${points[0][0]},${points[0][1]}`);
}
return insts;
});
}
Insert cell
Insert cell
Insert cell
Insert cell
mostInsts = [`JZ, 1`, ...extrudedInsts.flat()]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
populateVizSpace(vizSpace, [completeInstructions])
Insert cell
Insert cell
Insert cell
import {
viewof materialType,
viewof toolDiameter,
viewof toolNumFlutes,
surfaceSpeeds,
chiploadRangesFoam,
chiploadRangesPlywood,
chipload,
feed,
speed,
fsRationale
} from "@machine-agency/quickdraw-sketch-based-milling"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
surfaceSpeeds
Insert cell
adjustedSpeed = speed * 2 - 0
Insert cell
adjustedFeed = 1.2
Insert cell
fsRationale
Insert cell
completeInstructions = {
const setFeed = `MS,${adjustedFeed},${adjustedFeed / 2},,,`;
const setSpeed = `TR,${adjustedSpeed}`;
const spindleOn = `C6`;
const spindleOff = `C7`;
return [
setFeed,
setSpeed,
spindleOn,
...mostInsts,
`JZ,${travelHeight}`,
spindleOff
];
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function sendInstsToOverlay(sbpCodes) {
// Reference the dummy value to ensure that the socket.send below doesn't reference a stale socket,
// FIXME — cannot import
// socketResetDummy;
if (socket.readyState === socket.CLOSED) {
return html`🚫 <i>Did not send instructions to overlay at ${new Date().toLocaleString()} because the socket is closed.</i>`;
}
let packet = {
name: "drawing",
type: "tssInstructions",
data: sbpCodes
};
socket.send(JSON.stringify(packet));
return html`🎨 <i>Instructions sent to overlay at ${new Date().toLocaleString()}</i>.`;
}
Insert cell
sendInstsToOverlay(completeInstructions)
Insert cell
Insert cell
class CM {
constructor() {
this.thunks = [];
}

clear() {
this.thunks = [];
}

render(ps) {
__clearCanvas(ps);
this.thunks.forEach((thunk) => thunk(ps));
return this;
}
circle(x, y, r) {
let thisCall = `.circle(${x}, ${y}, ${r})`;
let callParams = {
op: "circle",
x,
y,
r
};
let thunk = (ps) => {
let center = new ps.Point(x, y);
let radius = r;
let path = new ps.Path.Circle(center, radius);
// path.applyMatrix = false;
path.strokeColor = "white";
callParams.obj = path;
path.callParams = callParams;
};
this.thunks.push(thunk);
return this;
}

point(x, y) {}

/* Do I need these? */
select() {}

deselect() {}
}
Insert cell
circle = (x, y, r) => {
return (ps) => {
let center = new ps.Point(x, y);
let radius = r;
let path = new ps.Path.Circle(center, radius);
path.strokeColor = "white";
}
}
Insert cell
renderCM = (drawingPad) => {}
Insert cell
mutable miniCadProgram = (ps) => {
// circle(50, 50, 20)(ps);
// circle(100, 100, 20)(ps);
// return ps.project.activeLayer.children;
updateMiniCadProgramIndicator;
// return new CM()
// .circle(50, 50, 20)
// .circle(100, 100, 20)
// .circle(200, 200, 40)
// .render(ps);
}
Insert cell
miniCadProgram(drawingPad.ps)
Insert cell
Inputs.button("Sabotage", {
reduce: () => {
mutable miniCadProgram = (x) => 42;
}
})
Insert cell
mutable updateMiniCadProgramIndicator = Date.now()
Insert cell
Insert cell
function __clearCanvas(ps) {
ps.project.activeLayer.removeChildren();
}
Insert cell
function __getSelected(ps) {
return ps.project.activeLayer.children.filter(c => c.selected);
}
Insert cell
function __clearSelects(ps) {
ps.project.activeLayer.children.forEach((c) => (c.selected = false));
}
Insert cell
Insert cell
fusionSbpRaw = FileAttachment("octi3.sbp").text()
Insert cell
fusionSbp = fusionSbpRaw.split("\r\n").filter((line) => !!line)
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more