diff --git a/src/part.js b/src/part.js index b4bd2cf4eee..7322e1354d5 100644 --- a/src/part.js +++ b/src/part.js @@ -4,6 +4,7 @@ import path from "./path"; import snippet from "./snippet"; import attributes from "./attributes"; import * as hooklib from "hooks"; +import { round, units } from "./utils"; function part(id) { this.attributes = new attributes(); @@ -11,6 +12,7 @@ function part(id) { this.paths = {}; this.snippets = {}; this.id = id; + this.freeId = 0; this.render = id.substr(0, 1) === "_" ? false : true; this.points.origin = new point(0, 0); for (let k in hooklib) this[k] = hooklib[k]; @@ -20,6 +22,9 @@ function part(id) { this.path = path; this.snippet = snippet; + // Expose round method to plugins + this.round = round; + return this; } @@ -38,4 +43,15 @@ part.prototype.macroRunner = function(args) { return method; }; +/** Returns an unused ID */ +part.prototype.getUid = function() { + this.freeId += 1; + + return "" + this.freeId; +}; + +part.prototype.units = function(value) { + return units(value, this.context.settings.units); +}; + export default part; diff --git a/src/path.js b/src/path.js index d502c5d32f1..d11b4c05d61 100644 --- a/src/path.js +++ b/src/path.js @@ -1,5 +1,6 @@ import attributes from "./attributes"; -import { pathOffset } from "./utils"; +import Bezier from "bezier-js"; +import { pathOffset, pathLength } from "./utils"; function path() { this.render = true; @@ -70,12 +71,47 @@ path.prototype.asPathstring = function() { return d; }; -/** Returns this path as a Bezier object */ -path.prototype.asBezier = function() {}; - /** Returns offset of this path as a new path */ path.prototype.offset = function(distance) { return pathOffset(this, distance); }; +/** Returns the length of this path */ +path.prototype.length = function() { + let current, start; + let length = 0; + for (let i in this.ops) { + let op = this.ops[i]; + if (op.type === "move") { + start = op.to; + } else if (op.type === "line") { + length += op.from.dist(op.to); + } else if (op.type === "curve") { + length += new Bezier( + { x: current.x, y: current.y }, + { x: op.cp1.x, y: op.cp1.y }, + { x: op.cp2.x, y: op.cp2.y }, + { x: op.to.x, y: op.to.y } + ).length(); + } else if (op.type === "close") { + length += current.dist(start); + } + if (op.to) current = op.to; + } + + return length; +}; + +/** Returns the startpoint of the path */ +path.prototype.start = function() { + return this.ops[0].to; +}; + +/** Returns the endpoint of the path */ +path.prototype.end = function() { + let op = this.ops[this.ops.length - 1]; + + if (op.type === "close") return this.start(); + else return op.to; +}; export default path; diff --git a/src/pattern.js b/src/pattern.js index 6df91bcb27a..bcdcb3ab947 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -12,7 +12,8 @@ export default function pattern(config = false) { this.config = { parts: ["part"], measurements: {}, - options: {} + options: {}, + units: "metric" }; } else { this.config = config; @@ -49,7 +50,7 @@ export default function pattern(config = false) { this.options = {}; if (typeof config.options !== "undefined" && config.options.length > 0) { for (let conf of config.options) { - if (conf.type === "percentage") this.options[conf.id] = conf.val / 100; + if (conf.type === "%") this.options[conf.id] = conf.val / 100; else this.options[conf.id] = conf.val; } } diff --git a/src/point.js b/src/point.js index a6a6e7d5826..395b0fe3a63 100644 --- a/src/point.js +++ b/src/point.js @@ -1,16 +1,12 @@ import attributes from "./attributes"; +import { round } from "./utils"; function point(x, y) { - this.x = this.round(x); - this.y = this.round(y); + this.x = round(x); + this.y = round(y); this.attributes = new attributes(); } -/** Rounds a value to PRECISION */ -point.prototype.round = function(value) { - return Math.round(value * 1e2) / 1e2; -}; - /** Radians to degrees */ point.prototype.rad2deg = function(radians) { return radians * 57.29577951308232; @@ -33,7 +29,7 @@ point.prototype.dist = function(that) { let dx = this.x - that.x; let dy = this.y - that.y; - return this.round(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2))); + return round(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2))); }; /** Returns slope of a line made by this point and that point */ diff --git a/src/utils.js b/src/utils.js index bba097c1006..106af9462d7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -70,6 +70,7 @@ export function shorthand(part) { let final = part.context.settings.mode === "draft" ? true : false; let paperless = part.context.settings.paperless === true ? true : false; return { + sa: part.context.settings.sa || 0, measurements: part.context.settings.measurements || {}, options: part.context.options || {}, values: part.context.values || {}, @@ -157,3 +158,14 @@ export function joinPaths(paths, closed = false) { return joint; } + +/** Convert value in mm to cm or imperial units */ +export function units(value, to = "metric") { + if (to === "imperial") return round(value / 25.4) + '"'; + else return round(value / 10) + "cm"; +} + +/** Rounds a value to 2 decimals */ +export function round(value) { + return Math.round(value * 1e2) / 1e2; +}