1
0
Fork 0

sparkles: Sleevecap part, small fixes and scalebox

This commit is contained in:
Joost De Cock 2018-08-20 14:33:29 +02:00
parent 22cf515068
commit 52f6e7e850
10 changed files with 277 additions and 197 deletions

View file

@ -7,7 +7,12 @@ var back = {
let {store, sa, points, Path, paths, Snippet, snippets, final, paperless, macro} = part.shorthand();
// Seamline
paths.seam = shared.seamLine("back", points, Path);
paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path()
.move(points.cbNeck)
.line(points.cbHips)
.join(paths.saBase)
.attr("class", "fabric");
// Store lengths to fit sleeve
store.set("backArmholeLength", shared.armholeLength(points, Path));
@ -26,7 +31,14 @@ var back = {
macro("title", { at: points.title, nr: 2, title: "back" });
snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch);
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
if (sa) {
paths.sa = paths.saBase
.offset(sa)
.attr("class", "fabric sa")
.line(points.cbNeck)
.move(points.cbHips);
paths.sa.line(paths.sa.start());
}
}
// Paperless?

View file

@ -26,7 +26,13 @@ var front = {
points.cfNeck = points.cfNeck.shift(-90, points.neck.x);
points.neckCp2 = points.cfNeck.shift(0, points.neck.x * 0.7);
paths.seam = shared.seamLine("front", points, Path);
// Seamline
paths.saBase = shared.saBase("front", points, Path);
paths.seam = new Path()
.move(points.cfNeck)
.line(points.cfHips)
.join(paths.saBase)
.attr("class", "fabric");
// Store lengths to fit sleeve
store.set("frontArmholeLength", shared.armholeLength(points, Path));
@ -44,7 +50,14 @@ var front = {
});
macro("title", { at: points.title, nr: 1, title: "front" });
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
if (sa) {
paths.sa = paths.saBase
.offset(sa)
.attr("class", "fabric sa")
.line(points.cfNeck)
.move(points.cfHips);
paths.sa.line(paths.sa.start());
}
}
// Paperless?

View file

@ -7,6 +7,7 @@ import { version } from "../package.json";
import base from "./base";
import back from "./back";
import front from "./front";
import sleevecap from "./sleevecap";
import sleeve from "./sleeve";
var pattern = new freesewing.Pattern({ version: version, ...config }).with(
@ -15,9 +16,25 @@ var pattern = new freesewing.Pattern({ version: version, ...config }).with(
pattern.draft = function() {
this.parts.base = this.draftBase(new pattern.Part());
this.parts.back = this.draftBack(new pattern.Part().copy(this.parts.base));
this.parts.front = this.draftFront(new pattern.Part().copy(this.parts.back));
this.parts.sleeve = this.draftSleeve(new pattern.Part());
if (!this.needs("base", true)) this.parts.base.render = false;
if (this.needs(["back", "front", "sleeve", "sleevecap"])) {
this.parts.back = this.draftBack(new pattern.Part().copy(this.parts.base));
}
if (this.needs(["front", "sleeve", "sleevecap"])) {
this.parts.front = this.draftFront(
new pattern.Part().copy(this.parts.back)
);
}
if (this.needs(["sleeve", "sleevecap"])) {
this.parts.sleevecap = this.draftSleevecap(new pattern.Part());
// Don't render sleevecap unless specifically requested
if (!this.needs("sleevecap", true)) this.parts.sleevecap.render = false;
}
if (this.needs("sleeve")) {
this.parts.sleeve = this.draftSleeve(
new pattern.Part().copy(this.parts.sleevecap)
);
}
return pattern;
};
@ -25,6 +42,7 @@ pattern.draft = function() {
pattern.draftBase = part => base.draft(part);
pattern.draftBack = part => back.draft(part);
pattern.draftFront = part => front.draft(part);
pattern.draftSleevecap = part => sleevecap.draft(part);
pattern.draftSleeve = part => sleeve.draft(part);
export default pattern;

View file

@ -1,12 +1,7 @@
export function seamLine(side, points, Path) {
export function saBase(side, points, Path) {
let path = new Path();
if (side === "back") {
path.move(points.cbNeck);
path.line(points.cbHips);
} else {
path.move(points.cfNeck);
path.line(points.cfHips);
}
if (side === "back") path.move(points.cbHips);
else path.move(points.cfHips);
path
.line(points.hips)
.line(points.armhole)
@ -19,7 +14,6 @@ export function seamLine(side, points, Path) {
} else {
path.curve(points.neckCp2, points.cfNeck, points.cfNeck);
}
path.close().attr("class", "fabric");
return path;
}
@ -41,7 +35,6 @@ export function shoulderToArmholePitch(points, Path) {
}
export function dimensions(macro, points, Path, sa) {
console.log("points for dimensions", points);
macro("pd", {
path: new Path()
.move(points.armhole)

View file

@ -1,167 +1,10 @@
import freesewing from "freesewing";
/** Calculates the differece between actual and optimal sleevecap length
* Positive values mean sleevecap is longer than armhole
*/
function sleevecapDelta(store) {
return store.get("sleevecapLength") - store.get("sleevecapTarget");
}
function sleevecapAdjust(store) {
let delta = sleevecapDelta(store);
let factor = store.get("sleeveFactor");
if (delta > 0) factor = factor * 0.98;
else factor = factor * 1.02;
store.set("sleeveFactor", factor);
}
function draftSleevecap(part, run) {
// prettier-ignore
let {debug, units, store, measurements, options, Point, points, Path, paths} = part.shorthand();
// Sleeve center axis
points.centerBiceps = new Point(0, 0);
points.centerCap = points.centerBiceps.shift(
90,
measurements.bicepsCircumference *
(1 + options.bicepsEase) *
options.armholeDepthFactor *
store.get("sleeveFactor")
);
// Left and right biceps points, limit impact of sleeveFactor to 25%
let halfWidth =
(measurements.bicepsCircumference * (1 + options.bicepsEase)) / 2;
points.bicepsLeft = points.centerBiceps.shift(
180,
halfWidth * options.sleeveWidthGuarantee +
halfWidth * (1 - options.sleeveWidthGuarantee) * store.get("sleeveFactor")
);
points.bicepsRight = points.bicepsLeft.flipX(points.centerBiceps);
// Pitch points
let width = points.bicepsRight.x;
let height = points.centerCap.y;
points.backPitch = new Point(
-1 * width * options.sleevecapBackFactorX,
height * options.sleevecapBackFactorY
);
points.frontPitch = new Point(
width * options.sleevecapFrontFactorX,
height * options.sleevecapFrontFactorY
);
// 4 sleevecap quadrants
// Base points
points.capQ1Base = points.frontPitch.shiftFractionTowards(
points.bicepsRight,
0.5
);
points.capQ2Base = points.frontPitch.shiftFractionTowards(
points.centerCap,
0.5
);
points.capQ3Base = points.backPitch.shiftFractionTowards(
points.centerCap,
0.5
);
points.capQ4Base = points.backPitch.shiftFractionTowards(
points.bicepsLeft,
0.5
);
// Offset points
let baseOffset = measurements.bicepsCircumference * (1 + options.bicepsEase);
points.capQ1 = points.capQ1Base.shift(
points.bicepsRight.angle(points.frontPitch) + 90,
baseOffset * options.sleevecapQ1Offset
);
points.capQ2 = points.capQ2Base.shift(
points.centerCap.angle(points.frontPitch) + 90,
baseOffset * options.sleevecapQ2Offset
);
points.capQ3 = points.capQ3Base.shift(
points.centerCap.angle(points.backPitch) - 90,
baseOffset * options.sleevecapQ3Offset
);
points.capQ4 = points.capQ4Base.shift(
points.bicepsLeft.angle(points.backPitch) - 90,
baseOffset * options.sleevecapQ4Offset
);
// Control points
points.capQ1Cp1 = points.capQ1.shift(
points.frontPitch.angle(points.bicepsRight),
baseOffset * options.sleevecapQ1Spread1
);
points.capQ1Cp2 = points.capQ1.shift(
points.frontPitch.angle(points.bicepsRight),
baseOffset * options.sleevecapQ1Spread2 * -1
);
points.capQ2Cp1 = points.capQ2.shift(
points.centerCap.angle(points.frontPitch),
baseOffset * options.sleevecapQ2Spread1
);
points.capQ2Cp2 = points.capQ2.shift(
points.centerCap.angle(points.frontPitch),
baseOffset * options.sleevecapQ2Spread2 * -1
);
points.capQ3Cp1 = points.capQ3.shift(
points.backPitch.angle(points.centerCap),
baseOffset * options.sleevecapQ3Spread1
);
points.capQ3Cp2 = points.capQ3.shift(
points.backPitch.angle(points.centerCap),
baseOffset * options.sleevecapQ3Spread2 * -1
);
points.capQ4Cp1 = points.capQ4.shift(
points.bicepsLeft.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread1
);
points.capQ4Cp2 = points.capQ4.shift(
points.bicepsLeft.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread2 * -1
);
// Sleevecap seamline
paths.sleevecap = new Path()
.move(points.bicepsRight)
.curve(points.bicepsRight, points.capQ1Cp1, points.capQ1)
.curve(points.capQ1Cp2, points.capQ2Cp1, points.capQ2)
.curve(points.capQ2Cp2, points.capQ3Cp1, points.capQ3)
.curve(points.capQ3Cp2, points.capQ4Cp1, points.capQ4)
.curve(points.capQ4Cp2, points.bicepsLeft, points.bicepsLeft);
// Store sleevecap length
store.set("sleevecapLength", paths.sleevecap.length());
if (run === 1) {
let armholeLength =
store.get("frontArmholeLength") + store.get("backArmholeLength");
let sleevecapEase = armholeLength * options.sleevecapEase;
store.set("sleevecapEase", sleevecapEase);
store.set("sleevecapTarget", armholeLength + sleevecapEase);
debug("Sleevecap ease is", units(sleevecapEase));
// Uncomment this line to see all sleevecap iterations
//paths[run] = paths.sleevecap;
}
}
var sleeve = {
draft: function(part) {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, final, paperless, macro} = part.shorthand();
store.set("sleeveFactor", 1);
let run = 1;
do {
draftSleevecap(part, run);
debug(
`Sleevecap draft ${run}, sleevecap delta is ${units(
sleevecapDelta(store)
)}`
);
sleevecapAdjust(store);
run++;
} while (Math.abs(sleevecapDelta(store)) > 2 && run < 100);
// Wrist
let top = paths.sleevecap.bbox().topLeft.y;
debug("Sleevecap height is ", units(Math.abs(top)));
@ -200,6 +43,11 @@ var sleeve = {
snippets.logo = new Snippet("logo", points.logo);
macro("title", { at: points.centerBiceps, nr: 3, title: "sleeve" });
macro("grainline", { from: points.centerWrist, to: points.centerBiceps });
points.scaleboxAnchor = points.scalebox = points.centerBiceps.shiftFractionTowards(
points.centerWrist,
0.5
);
macro("scalebox", { at: points.scalebox });
points.sleeveTip = paths.sleevecap.shiftFractionAlong(0.5);
points.frontNotch = paths.sleevecap.shiftAlong(

View file

@ -0,0 +1,176 @@
import freesewing from "freesewing";
/** Calculates the differece between actual and optimal sleevecap length
* Positive values mean sleevecap is longer than armhole
*/
function sleevecapDelta(store) {
return store.get("sleevecapLength") - store.get("sleevecapTarget");
}
function sleevecapAdjust(store) {
let delta = sleevecapDelta(store);
let factor = store.get("sleeveFactor");
if (delta > 0) factor = factor * 0.98;
else factor = factor * 1.02;
store.set("sleeveFactor", factor);
}
function draftSleevecap(part, run) {
// prettier-ignore
let {debug, units, store, measurements, options, Point, points, Path, paths} = part.shorthand();
// Sleeve center axis
points.centerBiceps = new Point(0, 0);
points.centerCap = points.centerBiceps.shift(
90,
measurements.bicepsCircumference *
(1 + options.bicepsEase) *
options.armholeDepthFactor *
store.get("sleeveFactor")
);
// Left and right biceps points, limit impact of sleeveFactor to 25%
let halfWidth =
(measurements.bicepsCircumference * (1 + options.bicepsEase)) / 2;
points.bicepsLeft = points.centerBiceps.shift(
180,
halfWidth * options.sleeveWidthGuarantee +
halfWidth * (1 - options.sleeveWidthGuarantee) * store.get("sleeveFactor")
);
points.bicepsRight = points.bicepsLeft.flipX(points.centerBiceps);
// Pitch points
let width = points.bicepsRight.x;
let height = points.centerCap.y;
points.backPitch = new Point(
-1 * width * options.sleevecapBackFactorX,
height * options.sleevecapBackFactorY
);
points.frontPitch = new Point(
width * options.sleevecapFrontFactorX,
height * options.sleevecapFrontFactorY
);
// 4 sleevecap quadrants
// Base points
points.capQ1Base = points.frontPitch.shiftFractionTowards(
points.bicepsRight,
0.5
);
points.capQ2Base = points.frontPitch.shiftFractionTowards(
points.centerCap,
0.5
);
points.capQ3Base = points.backPitch.shiftFractionTowards(
points.centerCap,
0.5
);
points.capQ4Base = points.backPitch.shiftFractionTowards(
points.bicepsLeft,
0.5
);
// Offset points
let baseOffset = measurements.bicepsCircumference * (1 + options.bicepsEase);
points.capQ1 = points.capQ1Base.shift(
points.bicepsRight.angle(points.frontPitch) + 90,
baseOffset * options.sleevecapQ1Offset
);
points.capQ2 = points.capQ2Base.shift(
points.centerCap.angle(points.frontPitch) + 90,
baseOffset * options.sleevecapQ2Offset
);
points.capQ3 = points.capQ3Base.shift(
points.centerCap.angle(points.backPitch) - 90,
baseOffset * options.sleevecapQ3Offset
);
points.capQ4 = points.capQ4Base.shift(
points.bicepsLeft.angle(points.backPitch) - 90,
baseOffset * options.sleevecapQ4Offset
);
// Control points
points.capQ1Cp1 = points.capQ1.shift(
points.frontPitch.angle(points.bicepsRight),
baseOffset * options.sleevecapQ1Spread1
);
points.capQ1Cp2 = points.capQ1.shift(
points.frontPitch.angle(points.bicepsRight),
baseOffset * options.sleevecapQ1Spread2 * -1
);
points.capQ2Cp1 = points.capQ2.shift(
points.centerCap.angle(points.frontPitch),
baseOffset * options.sleevecapQ2Spread1
);
points.capQ2Cp2 = points.capQ2.shift(
points.centerCap.angle(points.frontPitch),
baseOffset * options.sleevecapQ2Spread2 * -1
);
points.capQ3Cp1 = points.capQ3.shift(
points.backPitch.angle(points.centerCap),
baseOffset * options.sleevecapQ3Spread1
);
points.capQ3Cp2 = points.capQ3.shift(
points.backPitch.angle(points.centerCap),
baseOffset * options.sleevecapQ3Spread2 * -1
);
points.capQ4Cp1 = points.capQ4.shift(
points.bicepsLeft.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread1
);
points.capQ4Cp2 = points.capQ4.shift(
points.bicepsLeft.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread2 * -1
);
// Sleevecap seamline
paths.sleevecap = new Path()
.move(points.bicepsRight)
.curve(points.bicepsRight, points.capQ1Cp1, points.capQ1)
.curve(points.capQ1Cp2, points.capQ2Cp1, points.capQ2)
.curve(points.capQ2Cp2, points.capQ3Cp1, points.capQ3)
.curve(points.capQ3Cp2, points.capQ4Cp1, points.capQ4)
.curve(points.capQ4Cp2, points.bicepsLeft, points.bicepsLeft);
// Store sleevecap length
store.set("sleevecapLength", paths.sleevecap.length());
if (run === 1) {
let armholeLength =
store.get("frontArmholeLength") + store.get("backArmholeLength");
let sleevecapEase = armholeLength * options.sleevecapEase;
store.set("sleevecapEase", sleevecapEase);
store.set("sleevecapTarget", armholeLength + sleevecapEase);
debug("Sleevecap ease is", units(sleevecapEase));
// Uncomment this line to see all sleevecap iterations
//paths[run] = paths.sleevecap;
}
}
var sleevecap = {
draft: function(part) {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, final, paperless, macro} = part.shorthand();
store.set("sleeveFactor", 1);
let run = 1;
do {
draftSleevecap(part, run);
debug(
`Sleevecap draft ${run}, sleevecap delta is ${units(
sleevecapDelta(store)
)}`
);
sleevecapAdjust(store);
run++;
} while (Math.abs(sleevecapDelta(store)) > 2 && run < 100);
// Paths
paths.sleevecap.attr("class", "fabric");
// Anchor point for sampling
points.gridAnchor = points.origin;
points.test = new Point(10, 10);
return part;
}
};
export default sleevecap;