2018-12-19 12:14:48 +01:00
|
|
|
import init from "./init";
|
2018-09-04 16:51:39 +02:00
|
|
|
|
|
|
|
function tuskDelta(part) {
|
2019-07-02 19:27:40 +02:00
|
|
|
let { Path, points, store } = part.shorthand();
|
2018-09-04 16:51:39 +02:00
|
|
|
let len = new Path()
|
|
|
|
.move(points.midRight)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(
|
|
|
|
points.curveRightCpTop,
|
|
|
|
points.curveRightCpBottom,
|
|
|
|
points.rightTuskRight
|
|
|
|
)
|
2018-09-04 16:51:39 +02:00
|
|
|
.length();
|
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
return len - store.get("curve");
|
2018-09-04 16:51:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function tweakTusk(delta, part) {
|
2019-05-10 13:14:31 +02:00
|
|
|
let { points } = part.shorthand();
|
2018-09-04 16:51:39 +02:00
|
|
|
|
|
|
|
let factor;
|
|
|
|
if (Math.abs(delta) > 2) factor = 3;
|
|
|
|
else factor = 5;
|
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
points.rightTuskRight = points.rightTuskRight.shift(90, delta / factor);
|
|
|
|
points.rightTuskLeft = points.rightTuskLeft.shift(90, delta / factor);
|
|
|
|
points.curveRightCpBottom = points.curveRightCpBottom.shift(
|
|
|
|
90,
|
|
|
|
delta / factor
|
|
|
|
);
|
2018-09-04 16:51:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-19 12:14:48 +01:00
|
|
|
export default function(part) {
|
2019-05-10 13:14:31 +02:00
|
|
|
let {
|
|
|
|
store,
|
|
|
|
sa,
|
|
|
|
Point,
|
|
|
|
points,
|
|
|
|
Path,
|
|
|
|
paths,
|
|
|
|
options,
|
|
|
|
complete,
|
|
|
|
paperless,
|
|
|
|
macro,
|
|
|
|
utils,
|
|
|
|
debug
|
|
|
|
} = part.shorthand();
|
2018-12-19 12:14:48 +01:00
|
|
|
|
|
|
|
// Initialize
|
|
|
|
init(part);
|
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
points.topRight = new Point(store.get("hipsFront") / 2, 0);
|
2018-12-19 12:14:48 +01:00
|
|
|
points.topLeft = points.topRight.flipX();
|
2019-05-10 13:14:31 +02:00
|
|
|
points.midMid = new Point(0, store.get("heightFront"));
|
|
|
|
points.midRight = new Point(
|
|
|
|
points.topRight.x + store.get("heightFront") * 0.05,
|
|
|
|
points.midMid.y
|
|
|
|
);
|
2018-12-19 12:14:48 +01:00
|
|
|
points.midLeft = points.midRight.flipX();
|
|
|
|
|
|
|
|
// Store this length for a notch on the side part
|
2019-05-10 13:14:31 +02:00
|
|
|
store.set("frontNotch", points.topRight.dist(points.midRight));
|
2018-12-19 12:14:48 +01:00
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
points.bottomMid = new Point(0, store.get("riseLength"));
|
2018-12-19 12:14:48 +01:00
|
|
|
points.rightTuskRight = new Point(
|
2019-05-10 13:14:31 +02:00
|
|
|
store.get("gusset") *
|
|
|
|
store.get("xScale") *
|
|
|
|
(1 - store.get("gussetInsetRatio")),
|
2018-12-19 12:14:48 +01:00
|
|
|
points.bottomMid.y
|
|
|
|
);
|
|
|
|
points.rightTuskLeft = points.bottomMid.clone();
|
2019-05-10 13:14:31 +02:00
|
|
|
points.curveRightCpTop = new Point(
|
|
|
|
points.midRight.x - store.get("gusset") * 1.3,
|
|
|
|
points.midRight.y
|
|
|
|
);
|
|
|
|
points.curveRightCpBottom = new Point(
|
|
|
|
points.rightTuskRight.x,
|
|
|
|
points.rightTuskRight.y - store.get("gusset") * 1.3
|
|
|
|
);
|
2018-12-19 12:14:48 +01:00
|
|
|
|
|
|
|
// Adjust tusk length to fit inset curve
|
|
|
|
let delta = tuskDelta(part);
|
|
|
|
let count = 0;
|
2019-05-10 13:14:31 +02:00
|
|
|
while (Math.abs(delta) > 1) {
|
|
|
|
// Below 1mm is good enough
|
2018-12-19 12:14:48 +01:00
|
|
|
tweakTusk(delta, part);
|
|
|
|
delta = tuskDelta(part);
|
|
|
|
count++;
|
2019-05-10 13:14:31 +02:00
|
|
|
if (count > 150)
|
|
|
|
throw "We got stuck trying to calculate an optimal tusk length. Please report this.";
|
2018-12-19 12:14:48 +01:00
|
|
|
}
|
2019-05-10 13:14:31 +02:00
|
|
|
debug(
|
|
|
|
`After ${count} iterations, tusk curve length is ${utils.round(
|
|
|
|
delta
|
|
|
|
)}mm off.`
|
|
|
|
);
|
2018-12-19 12:14:48 +01:00
|
|
|
|
|
|
|
// Adjust midMid to new length
|
|
|
|
points.bottomMid = new Point(0, points.rightTuskLeft.y);
|
2018-09-04 16:51:39 +02:00
|
|
|
|
2018-12-19 12:14:48 +01:00
|
|
|
// Front dart only if bulge > 0
|
2019-05-10 13:14:31 +02:00
|
|
|
if (options.bulge > 0) {
|
|
|
|
// Rotate tusk according to bulge option
|
|
|
|
for (let pid of [
|
|
|
|
"curveRightCpTop",
|
|
|
|
"curveRightCpBottom",
|
|
|
|
"rightTuskRight",
|
|
|
|
"rightTuskLeft"
|
|
|
|
]) {
|
|
|
|
points[pid] = points[pid].rotate(options.bulge, points.midRight);
|
|
|
|
}
|
2018-09-04 16:51:39 +02:00
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
// Dart join point
|
|
|
|
points.dartJoin = new Point(
|
|
|
|
0,
|
|
|
|
points.midMid.y + 0.65 * points.midMid.dist(points.bottomMid)
|
|
|
|
);
|
2018-09-04 16:51:39 +02:00
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
// Dart control point
|
|
|
|
points.dartCpRight = new Point(
|
|
|
|
0,
|
|
|
|
points.dartJoin.y +
|
|
|
|
points.dartJoin.dist(points.bottomMid) * (options.bulge / 30)
|
|
|
|
);
|
|
|
|
points.dartCpRight = points.dartCpRight.rotate(
|
|
|
|
options.bulge,
|
|
|
|
points.dartJoin
|
|
|
|
);
|
2018-09-04 16:51:39 +02:00
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
// Flip control point to left side
|
|
|
|
points.dartCpLeft = points.dartCpRight.flipX();
|
2018-12-19 12:14:48 +01:00
|
|
|
} else {
|
2019-05-10 13:14:31 +02:00
|
|
|
points.dartJoin = points.rightTuskLeft;
|
2018-12-19 12:14:48 +01:00
|
|
|
}
|
2018-09-04 16:51:39 +02:00
|
|
|
|
2018-12-19 12:14:48 +01:00
|
|
|
// Flip points to left side
|
|
|
|
points.leftTuskRight = points.rightTuskLeft.flipX();
|
|
|
|
points.leftTuskLeft = points.rightTuskRight.flipX();
|
|
|
|
points.curveLeftCpBottom = points.curveRightCpBottom.flipX();
|
|
|
|
points.curveLeftCpTop = points.curveRightCpTop.flipX();
|
|
|
|
|
|
|
|
// Handle back rise
|
|
|
|
points.topMid = new Point(0, points.topLeft.y);
|
2019-05-10 13:14:31 +02:00
|
|
|
points.topLeft = points.topLeft.shift(90, store.get("frontRise"));
|
|
|
|
points.topRight = points.topRight.shift(90, store.get("frontRise"));
|
2018-12-19 12:14:48 +01:00
|
|
|
points.topMidCpRight = new Point(points.topRight.x / 2, points.topMid.y);
|
|
|
|
points.topMidCpLeft = points.topMidCpRight.flipX();
|
|
|
|
|
2019-05-10 13:14:31 +02:00
|
|
|
if (options.bulge > 0) {
|
2018-12-19 12:14:48 +01:00
|
|
|
paths.trimBase = new Path()
|
|
|
|
.move(points.rightTuskLeft)
|
|
|
|
.curve(points.rightTuskLeft, points.dartCpRight, points.dartJoin)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(points.dartCpLeft, points.leftTuskRight, points.leftTuskRight);
|
2018-12-19 12:14:48 +01:00
|
|
|
paths.seamStart = new Path()
|
|
|
|
.move(points.midLeft)
|
|
|
|
.line(points.topLeft)
|
|
|
|
.curve(points.topLeft, points.topMidCpLeft, points.topMid)
|
|
|
|
.curve(points.topMidCpRight, points.topRight, points.topRight)
|
|
|
|
.line(points.midRight)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(
|
|
|
|
points.curveRightCpTop,
|
|
|
|
points.curveRightCpBottom,
|
|
|
|
points.rightTuskRight
|
|
|
|
)
|
2018-12-19 12:14:48 +01:00
|
|
|
.line(points.rightTuskLeft);
|
|
|
|
paths.seamEnd = new Path()
|
|
|
|
.move(points.leftTuskRight)
|
|
|
|
.line(points.leftTuskLeft)
|
|
|
|
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft);
|
|
|
|
paths.seamStart.render = false;
|
|
|
|
paths.trimBase.render = false;
|
|
|
|
paths.seamEnd.render = false;
|
|
|
|
paths.seam = paths.seamStart.join(paths.trimBase).join(paths.seamEnd);
|
|
|
|
} else {
|
|
|
|
paths.seam = new Path()
|
|
|
|
.move(points.midLeft)
|
|
|
|
.line(points.topLeft)
|
|
|
|
.curve(points.topLeft, points.topMidCpLeft, points.topMid)
|
|
|
|
.curve(points.topMidCpRight, points.topRight, points.topRight)
|
|
|
|
.line(points.midRight)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(
|
|
|
|
points.curveRightCpTop,
|
|
|
|
points.curveRightCpBottom,
|
|
|
|
points.rightTuskRight
|
|
|
|
)
|
2018-12-19 12:14:48 +01:00
|
|
|
.line(points.leftTuskLeft)
|
|
|
|
.curve(points.curveLeftCpBottom, points.curveLeftCpTop, points.midLeft);
|
|
|
|
}
|
2019-05-10 13:14:31 +02:00
|
|
|
paths.seam.close().attr("class", "fabric");
|
2018-12-19 12:14:48 +01:00
|
|
|
|
|
|
|
// Complete pattern?
|
|
|
|
if (complete) {
|
2019-05-10 13:14:31 +02:00
|
|
|
if (sa) {
|
|
|
|
if (options.bulge > 0) {
|
2018-12-19 12:14:48 +01:00
|
|
|
let saStart = paths.seamStart.offset(sa * -1);
|
|
|
|
let saTrim = paths.trimBase.offset(sa * -1).trim();
|
|
|
|
let saEnd = paths.seamEnd.offset(sa * -1);
|
|
|
|
paths.sa = saStart.join(saTrim).join(saEnd);
|
|
|
|
} else {
|
|
|
|
paths.sa = paths.seam.offset(sa * -1).trim();
|
|
|
|
}
|
2018-09-04 16:51:39 +02:00
|
|
|
}
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("title", {
|
2018-12-19 12:14:48 +01:00
|
|
|
at: points.midMid,
|
|
|
|
nr: 2,
|
2019-05-10 13:14:31 +02:00
|
|
|
title: "front"
|
2018-12-19 12:14:48 +01:00
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("grainline", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.dartJoin,
|
|
|
|
to: points.topMid
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Paperless?
|
|
|
|
if (paperless) {
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.topLeft,
|
|
|
|
to: points.topRight,
|
|
|
|
y: points.topLeft.y - 15 - sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.midLeft,
|
|
|
|
to: points.midRight,
|
|
|
|
y: points.topLeft.y - 30 - sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.midLeft,
|
|
|
|
to: points.topMid,
|
|
|
|
x: points.midLeft.x - 15 - sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.midLeft,
|
|
|
|
to: points.topLeft,
|
|
|
|
x: points.midLeft.x - 30 - sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
if (options.bulge === 0) {
|
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskLeft,
|
|
|
|
to: points.rightTuskRight,
|
|
|
|
y: points.leftTuskLeft.y + 15 + sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskLeft,
|
|
|
|
to: points.topLeft,
|
|
|
|
x: points.midLeft.x - 45 - sa
|
|
|
|
});
|
2018-09-07 16:35:37 +02:00
|
|
|
} else {
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskLeft,
|
|
|
|
to: points.topLeft,
|
|
|
|
x: points.midLeft.x - 45 - sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskRight,
|
|
|
|
to: points.topLeft,
|
|
|
|
x: points.midLeft.x - 60 - sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
2018-12-19 12:14:48 +01:00
|
|
|
points.narrowRight = new Path()
|
|
|
|
.move(points.midRight)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(
|
|
|
|
points.curveRightCpTop,
|
|
|
|
points.curveRightCpBottom,
|
|
|
|
points.rightTuskRight
|
|
|
|
)
|
|
|
|
.edge("left");
|
2018-12-19 12:14:48 +01:00
|
|
|
points.narrowLeft = new Path()
|
|
|
|
.move(points.midLeft)
|
2019-05-10 13:14:31 +02:00
|
|
|
.curve(
|
|
|
|
points.curveLeftCpTop,
|
|
|
|
points.curveLeftCpBottom,
|
|
|
|
points.leftTuskLeft
|
|
|
|
)
|
|
|
|
.attr("class", "various stroke-xl lashed")
|
|
|
|
.edge("right");
|
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.narrowLeft,
|
|
|
|
to: points.narrowRight,
|
|
|
|
y: points.narrowLeft.y
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskRight,
|
|
|
|
to: points.rightTuskLeft,
|
|
|
|
y: points.rightTuskLeft.y + 15 + sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("hd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.leftTuskLeft,
|
|
|
|
to: points.rightTuskRight,
|
|
|
|
y: points.rightTuskLeft.y + 30 + sa
|
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("ld", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.rightTuskLeft,
|
|
|
|
to: points.rightTuskRight,
|
|
|
|
d: -15 - sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.narrowRight,
|
|
|
|
to: points.topRight,
|
|
|
|
x: points.topRight.x + 15 + sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
2019-05-10 13:14:31 +02:00
|
|
|
macro("vd", {
|
2018-12-19 12:14:48 +01:00
|
|
|
from: points.dartJoin,
|
|
|
|
to: points.topRight,
|
|
|
|
x: points.topRight.x + 30 + sa
|
2018-09-04 16:51:39 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-19 12:14:48 +01:00
|
|
|
return part;
|
2019-05-10 13:14:31 +02:00
|
|
|
}
|