1
0
Fork 0

sparkles: Refactored code after changes in freesewing

This commit is contained in:
Joost De Cock 2018-12-17 14:42:28 +01:00
parent e2c7d98169
commit 694a5742ee
9 changed files with 553 additions and 586 deletions

View file

@ -3,9 +3,18 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Brian</title> <title>Brian</title>
<style>
.two {
display: inline-block;
max-width: 45%;
margin: auto;
}
</style>
</head> </head>
<body> <body>
<div id="svg"></div> <div id="svg"></div>
<div id="svg1" class="two"></div>
<div id="svg2" class="two"></div>
<!-- <script type="text/javascript" src="node_modules/freesewing/dist/browser.js"></script> --> <!-- <script type="text/javascript" src="node_modules/freesewing/dist/browser.js"></script> -->
<script type="text/javascript" src="../../freesewing/dist/browser.js"></script> <script type="text/javascript" src="../../freesewing/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/plugin-bundle/dist/browser.js"></script> <script type="text/javascript" src="node_modules/@freesewing/plugin-bundle/dist/browser.js"></script>
@ -20,133 +29,126 @@
<script type="text/javascript" src="node_modules/@freesewing/models/dist/browser.js"></script> <script type="text/javascript" src="node_modules/@freesewing/models/dist/browser.js"></script>
<script type="text/javascript" src="node_modules/@freesewing/antman/dist/browser.js"></script> <script type="text/javascript" src="node_modules/@freesewing/antman/dist/browser.js"></script>
<script> <script>
//console.log('adding hooks to pattern'); let settings = {
let settings = { "complete": true,
"complete": true, "idPrefix": "fs-",
"idPrefix": "fs-", "locale": "en",
"locale": "en", "units": "imperial",
"units": "imperial", "margin": 2.38125,
"margin": 2.38125, "options": {
"options": { "brianFitSleeve": true,
"brianFitSleeve": true, "brianFitCollar": true,
"brianFitCollar": true, "collarFactor": 4.8,
"collarFactor": 4.8, "acrossBackFactor": 0.97,
"acrossBackFactor": 0.97, "armholeDepthFactor": 0.6,
"armholeDepthFactor": 0.6, "backNeckCutout": 0.05,
"backNeckCutout": 0.05, "bicepsEase": 0.15,
"bicepsEase": 0.15, "chestEase": 0.08,
"chestEase": 0.08, "collarEase": 0.035,
"collarEase": 0.035, "cuffEase": 0.2,
"cuffEase": 0.2, "frontArmholeDeeper": 0.005,
"frontArmholeDeeper": 0.005, "lengthBonus": 0,
"lengthBonus": 0, "shoulderEase": 0,
"shoulderEase": 0, "shoulderSlopeReduction": 0,
"shoulderSlopeReduction": 0, "sleevecapEase": 0.01,
"sleevecapEase": 0.01, "sleevecapBackFactorX": 0.6,
"sleevecapBackFactorX": 0.6, "sleevecapBackFactorY": 0.33,
"sleevecapBackFactorY": 0.33, "sleevecapFrontFactorX": 0.55,
"sleevecapFrontFactorX": 0.55, "sleevecapFrontFactorY": 0.33,
"sleevecapFrontFactorY": 0.33, "sleevecapQ1Offset": 0.03,
"sleevecapQ1Offset": 0.03, "sleevecapQ2Offset": 0.055,
"sleevecapQ2Offset": 0.055, "sleevecapQ3Offset": 0.045,
"sleevecapQ3Offset": 0.045, "sleevecapQ4Offset": 0.01,
"sleevecapQ4Offset": 0.01, "sleevecapQ1Spread1": 0.06,
"sleevecapQ1Spread1": 0.06, "sleevecapQ1Spread2": 0.15,
"sleevecapQ1Spread2": 0.15, "sleevecapQ2Spread1": 0.15,
"sleevecapQ2Spread1": 0.15, "sleevecapQ2Spread2": 0.1,
"sleevecapQ2Spread2": 0.1, "sleevecapQ3Spread1": 0.1,
"sleevecapQ3Spread1": 0.1, "sleevecapQ3Spread2": 0.08,
"sleevecapQ3Spread2": 0.08, "sleevecapQ4Spread1": 0.07,
"sleevecapQ4Spread1": 0.07, "sleevecapQ4Spread2": 0.07,
"sleevecapQ4Spread2": 0.07, "sleeveWidthGuarantee": 0.9,
"sleeveWidthGuarantee": 0.9, "sleeveLengthBonus": 0
"sleeveLengthBonus": 0 },
}, "embed": true,
"embed": true, "sa": 0,
"sa": 0, "paperless": false,
"paperless": false, "measurements": {
"only": [ "front", "back" ], "bicepsCircumference": 335,
"measurements": { "centerBackNeckToWaist": 520,
"bicepsCircumference": 335, "chestCircumference": 1080,
"centerBackNeckToWaist": 520, "hipsCircumference": 990,
"chestCircumference": 1080, "naturalWaist": 925,
"hipsCircumference": 990, "naturalWaistToHip": 145,
"naturalWaist": 925, "neckCircumference": 420,
"naturalWaistToHip": 145, "shoulderSlope": 55,
"neckCircumference": 420, "shoulderToElbow": 410,
"shoulderSlope": 55, "shoulderToShoulder": 465,
"shoulderToElbow": 410, "shoulderToWrist": 680,
"shoulderToShoulder": 465, "wristCircumference": 190,
"shoulderToWrist": 680, "seatCircumference": 1080,
"wristCircumference": 190, "inseam": 910,
"seatCircumference": 1080, "seatDepth": 200,
"inseam": 910, "hipsToUpperLeg": 220,
"seatDepth": 200, "upperLegCircumference": 630,
"hipsToUpperLeg": 220, "headCircumference": 590,
"upperLegCircumference": 630, "naturalWaistToFloor": 1310,
"headCircumference": 590, "naturalWaistToSeat": 280
"naturalWaistToFloor": 1310, }
"naturalWaistToSeat": 280 };
} let settings1 = { ...settings};
}; settings1.sample = {
var pattern = new freesewing.patterns.brian(settings); type: "models",
//console.log('pattern', pattern); models: {
pattern.with(freesewing.plugins.debug) a: {
//pattern.with(freesewing.plugins.validate) "bicepsCircumference": 335,
// pattern.with(freesewing.plugins.theme) "centerBackNeckToWaist": 520,
//pattern.with(freesewing.plugins.designer) "chestCircumference": 1080,
//pattern.with(freesewing.plugins.i18n) "hipsCircumference": 990,
// console.log('pattern after', pattern); "naturalWaist": 925,
"naturalWaistToHip": 145,
//pattern.on('postSample', function(next) { "neckCircumference": 420,
// console.log('postSample hook'); "shoulderSlope": 55,
// next(); "shoulderToElbow": 410,
//}); "shoulderToShoulder": 465,
//pattern.on('preSample', function(next) { "shoulderToWrist": 680,
// console.log('preSample hook'); "wristCircumference": 190,
// next(); "seatCircumference": 1080,
//}); "inseam": 910,
//pattern.on('preDraft', function(next) { "seatDepth": 200,
// console.log('preDraft hook'); "hipsToUpperLeg": 220,
// next(); "upperLegCircumference": 630,
//}); "headCircumference": 590,
//pattern.on('postDraft', function(next) { "naturalWaistToFloor": 1310,
// console.log('postDraft hook'); "naturalWaistToSeat": 280
// next(); },
//}); b: {
//pattern.settings.locale = 'nl'; "bicepsCircumference": 33.5,
//pattern.settings.paperless = true; "centerBackNeckToWaist": 52,
//pattern.settings.complete = false; "chestCircumference": 108,
// pattern.settings.measurements = freesewing.models.men.manSize38; "hipsCircumference": 99,
// pattern.settings.measurements = { "naturalWaist": 92,
// bicepsCircumference: 305, "naturalWaistToHip": 14,
// centerBackNeckToWaist: 495, "neckCircumference": 42,
// chestCircumference: 965, "shoulderSlope": 5,
// hipsCircumference: 838, "shoulderToElbow": 41,
// naturalWaistToHip: 110, "shoulderToShoulder": 46,
// neckCircumference: 391, "shoulderToWrist": 68,
// shoulderSlope: 49, "wristCircumference": 19,
// shoulderToShoulder: 444, "seatCircumference": 108,
// shoulderToWrist: 680, "inseam": 91,
// wristCircumference: 185, "seatDepth": 20,
// } "hipsToUpperLeg": 22,
//pattern.settings.sa = 10; "upperLegCircumference": 63,
//pattern.settings.units = 'metric'; "headCircumference": 59,
//pattern.settings.sample = { "naturalWaistToFloor": 131,
// type: 'models', "naturalWaistToSeat": 28
// focus: 'manSize34', }}
// models: freesewing.models.men }
//} var pattern1 = new freesewing.patterns.brian(settings1);
//pattern.mergeSettings({only: ["sleeve"]}); pattern1.sample();
//pattern.options.lengthBonus = 0.15; console.log(pattern1);
//pattern.options.brianFitCollar = false; document.getElementById("svg1").innerHTML = pattern1.render();
//pattern.sampleOption('shoulderSlopeReduction');
//pattern.sampleMeasurement('shoulderSlope');
//pattern.sampleModels(freesewing.models.men, 'manSize34');
//pattern.sample();
console.log('settings', pattern.settings);
console.log('draft return value', pattern.draft());
document.getElementById("svg").innerHTML = pattern.render();
function pointHover(evt) { function pointHover(evt) {
var point = evt.target; var point = evt.target;

View file

@ -2750,9 +2750,9 @@
} }
}, },
"freesewing": { "freesewing": {
"version": "0.22.3", "version": "0.23.0",
"resolved": "https://registry.npmjs.org/freesewing/-/freesewing-0.22.3.tgz", "resolved": "https://registry.npmjs.org/freesewing/-/freesewing-0.23.0.tgz",
"integrity": "sha512-1w2vIb8LKjaHmWXrqQfOiTRXtmVwzO2Gpcofx3DlcSwV8WssPf7DcavZpROJMqWWb6Od/Ycf5lHVkDjhW+2RnQ==", "integrity": "sha512-JPknXGAWeWmjejpygJjoEgsbwpPSR3/bJqb9ymXOm9/IJJqUI73ZdVW4MEDS/WLQQTdCTxRNPVeHcu8VzucuOw==",
"requires": { "requires": {
"bezier-js": "^2.2.15", "bezier-js": "^2.2.15",
"bin-pack": "1.0.2" "bin-pack": "1.0.2"

View file

@ -48,7 +48,7 @@
}, },
"dependencies": { "dependencies": {
"@freesewing/plugin-bundle": "0.5.1", "@freesewing/plugin-bundle": "0.5.1",
"freesewing": "^0.22.3" "freesewing": "^0.23"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.0.0-beta.56", "@babel/core": "7.0.0-beta.56",

View file

@ -1,73 +1,69 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
import * as shared from "./shared"; import * as shared from "./shared";
var back = { export default part => {
draft: function(part) { // prettier-ignore
// prettier-ignore let {store, sa, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
let {store, sa, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
// Seamline // Seamline
paths.saBase = shared.saBase("back", points, Path); paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path() paths.seam = new Path()
.move(points.cbNeck) .move(points.cbNeck)
.line(points.cbHips) .line(points.cbHips)
.join(paths.saBase) .join(paths.saBase)
.attr("class", "fabric"); .attr("class", "fabric");
// Store lengths to fit sleeve // Store lengths to fit sleeve
store.set("backArmholeLength", shared.armholeLength(points, Path)); store.set("backArmholeLength", shared.armholeLength(points, Path));
store.set( store.set(
"backShoulderToArmholePitch", "backShoulderToArmholePitch",
shared.shoulderToArmholePitch(points, Path) shared.shoulderToArmholePitch(points, Path)
); );
// Complete pattern? // Complete pattern?
if (complete) { if (complete) {
macro("cutonfold", { macro("cutonfold", {
from: points.cbNeck, from: points.cbNeck,
to: points.cbHips, to: points.cbHips,
grainline: true grainline: true
}); });
macro("title", { at: points.title, nr: 2, title: "back" }); macro("title", { at: points.title, nr: 2, title: "back" });
snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch); snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch);
if (sa) { if (sa) {
paths.sa = paths.saBase paths.sa = paths.saBase
.offset(sa) .offset(sa)
.attr("class", "fabric sa") .attr("class", "fabric sa")
.line(points.cbNeck) .line(points.cbNeck)
.move(points.cbHips); .move(points.cbHips);
paths.sa.line(paths.sa.start()); paths.sa.line(paths.sa.start());
}
} }
// Paperless?
if (paperless) {
shared.dimensions(macro, points, Path, sa);
macro("hd", {
from: points.cbHips,
to: points.hips,
y: points.hips.y + sa + 15
});
macro("vd", {
from: points.cbHips,
to: points.cbNeck,
x: points.cbHips.x - sa - 15
});
macro("hd", {
from: points.cbNeck,
to: points.neck,
y: points.neck.y - sa - 15
});
macro("hd", {
from: points.cbNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
});
}
return part;
} }
};
export default back; // Paperless?
if (paperless) {
shared.dimensions(macro, points, Path, sa);
macro("hd", {
from: points.cbHips,
to: points.hips,
y: points.hips.y + sa + 15
});
macro("vd", {
from: points.cbHips,
to: points.cbNeck,
x: points.cbHips.x - sa - 15
});
macro("hd", {
from: points.cbNeck,
to: points.neck,
y: points.neck.y - sa - 15
});
macro("hd", {
from: points.cbNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
});
}
return part;
};

View file

@ -1,176 +1,169 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
import * as shared from "./shared"; import * as shared from "./shared";
var base = { export default part => {
draft: function(part) { // prettier-ignore
// prettier-ignore let {units, debug, measurements, options, store, points, snippets, Point, Snippet, Path, paths, utils, complete } = part.shorthand();
let {units, debug, measurements, options, store, points, snippets, Point, Snippet, Path, paths, utils, complete } = part.shorthand();
store.set( store.set(
"shoulderEase", "shoulderEase",
(measurements.shoulderToShoulder * options.shoulderEase) / 2 (measurements.shoulderToShoulder * options.shoulderEase) / 2
); );
// Center back (cb) vertical axis // Center back (cb) vertical axis
points.cbNeck = new Point( points.cbNeck = new Point(
0, 0,
options.backNeckCutout * measurements.neckCircumference options.backNeckCutout * measurements.neckCircumference
); );
points.cbShoulder = new Point( points.cbShoulder = new Point(
0, 0,
(measurements.shoulderSlope - (measurements.shoulderSlope -
measurements.shoulderToShoulder * options.shoulderSlopeReduction) / measurements.shoulderToShoulder * options.shoulderSlopeReduction) /
2 2
); );
points.cbArmhole = new Point( points.cbArmhole = new Point(
0, 0,
points.cbShoulder.y + points.cbShoulder.y +
measurements.bicepsCircumference * measurements.bicepsCircumference *
(1 + options.bicepsEase) * (1 + options.bicepsEase) *
options.armholeDepthFactor options.armholeDepthFactor
); );
points.cbWaist = new Point( points.cbWaist = new Point(
0, 0,
points.cbNeck.y + measurements.centerBackNeckToWaist points.cbNeck.y + measurements.centerBackNeckToWaist
); );
points.cbHips = new Point( points.cbHips = new Point(
0, 0,
points.cbWaist.y + points.cbWaist.y +
measurements.naturalWaistToHip + measurements.naturalWaistToHip +
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) * (measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) *
options.lengthBonus options.lengthBonus
); );
// Side back (cb) vertical axis // Side back (cb) vertical axis
points.armhole = new Point( points.armhole = new Point(
(measurements.chestCircumference * (1 + options.chestEase)) / 4, (measurements.chestCircumference * (1 + options.chestEase)) / 4,
points.cbArmhole.y points.cbArmhole.y
); );
points.waist = new Point(points.armhole.x, points.cbWaist.y); points.waist = new Point(points.armhole.x, points.cbWaist.y);
points.hips = new Point(points.armhole.x, points.cbHips.y); points.hips = new Point(points.armhole.x, points.cbHips.y);
// Shoulder line // Shoulder line
points.neck = new Point( points.neck = new Point(
(measurements.neckCircumference * (1 + options.collarEase)) / (measurements.neckCircumference * (1 + options.collarEase)) /
options.collarFactor, options.collarFactor,
0 0
); );
points.shoulder = new Point( points.shoulder = new Point(
measurements.shoulderToShoulder / 2 + store.get("shoulderEase"), measurements.shoulderToShoulder / 2 + store.get("shoulderEase"),
points.cbShoulder.y points.cbShoulder.y
); );
// Armhhole // Armhhole
points.armholePitch = new Point( points.armholePitch = new Point(
(measurements.shoulderToShoulder * options.acrossBackFactor) / 2 + (measurements.shoulderToShoulder * options.acrossBackFactor) / 2 +
store.get("shoulderEase") / 2, store.get("shoulderEase") / 2,
points.shoulder.y + points.shoulder.dy(points.armhole) / 2 points.shoulder.y + points.shoulder.dy(points.armhole) / 2
); );
points._tmp1 = new Point(points.armholePitch.x, points.armhole.y); points._tmp1 = new Point(points.armholePitch.x, points.armhole.y);
points._tmp2 = points._tmp1.shift(45, 10); points._tmp2 = points._tmp1.shift(45, 10);
points._tmp3 = utils.beamsIntersect( points._tmp3 = utils.beamsIntersect(
points._tmp1, points._tmp1,
points._tmp2, points._tmp2,
points.armhole, points.armhole,
points.armholePitch points.armholePitch
); );
points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5); points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5);
points.armholeCp2 = points.armhole.shift( points.armholeCp2 = points.armhole.shift(
180, 180,
points._tmp1.dx(points.armhole) / 4 points._tmp1.dx(points.armhole) / 4
); );
points.armholeHollowCp1 = points.armholeHollow.shift( points.armholeHollowCp1 = points.armholeHollow.shift(
-45, -45,
points.armholeHollow.dy(points.armhole) / 2 points.armholeHollow.dy(points.armhole) / 2
); );
points.armholeHollowCp2 = points.armholeHollow.shift( points.armholeHollowCp2 = points.armholeHollow.shift(
135, 135,
points.armholePitch.dx(points.armholeHollow) points.armholePitch.dx(points.armholeHollow)
); );
points.armholePitchCp1 = points.armholePitch.shift( points.armholePitchCp1 = points.armholePitch.shift(
-90, -90,
points.armholePitch.dy(points.armholeHollow) / 2 points.armholePitch.dy(points.armholeHollow) / 2
); );
points.armholePitchCp2 = points.armholePitch.shift( points.armholePitchCp2 = points.armholePitch.shift(
90, 90,
points.shoulder.dy(points.armholePitch) / 2 points.shoulder.dy(points.armholePitch) / 2
); );
points.shoulderCp1 = points.shoulder points.shoulderCp1 = points.shoulder
.shiftTowards(points.neck, points.shoulder.dy(points.armholePitch) / 5) .shiftTowards(points.neck, points.shoulder.dy(points.armholePitch) / 5)
.rotate(90, points.shoulder); .rotate(90, points.shoulder);
// Neck opening (back) // Neck opening (back)
points._tmp4 = points.neck points._tmp4 = points.neck
.shiftTowards(points.shoulder, 10) .shiftTowards(points.shoulder, 10)
.rotate(-90, points.neck); .rotate(-90, points.neck);
points.neckCp2 = utils.beamIntersectsY( points.neckCp2 = utils.beamIntersectsY(
points.neck,
points._tmp4,
points.cbNeck.y
);
// Fit collar
points.cfNeck = points.neck.rotate(-90, new Point(0, 0));
let target = measurements.neckCircumference * (1 + options.collarEase);
let delta = 0;
let run = 0;
do {
run++;
points.cfNeck = points.cfNeck.shift(90, delta / 3);
points.frontNeckCpEdge = utils.beamsIntersect(
points.neck, points.neck,
points._tmp4, points.neckCp2,
points.cbNeck.y points.cfNeck,
new Point(20, points.cfNeck.y)
); );
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(
points.frontNeckCpEdge,
0.55
);
points.neckCp2Front = points.neck.shiftFractionTowards(
points.frontNeckCpEdge,
0.65
);
paths.neckOpening = new Path()
.move(points.cfNeck)
.curve(points.cfNeckCp1, points.neckCp2Front, points.neck)
.curve(points.neckCp2, points.cbNeck, points.cbNeck)
.attr("class", "dashed stroke-xl various");
delta = paths.neckOpening.length() * 2 - target;
} while (Math.abs(delta) > 1 && options.brianFitCollar && run < 10);
delete paths.neckOpening;
if (options.brianFitCollar) {
debug(
{ style: "success", label: "🏁 Collar fitted" },
// prettier-ignore
`Target was ${units(target)}, delta of ${units(delta)} reached in ${run} attempts.`
);
} else
debug({ style: "warning", label: "🚫 Not fitting collar" }, "(in Brian)");
// Fit collar // Anchor point for sampling
points.cfNeck = points.neck.rotate(-90, new Point(0, 0)); points.gridAnchor = points.cbHips;
let target = measurements.neckCircumference * (1 + options.collarEase);
let delta = 0;
let run = 0;
do {
run++;
points.cfNeck = points.cfNeck.shift(90, delta / 3);
points.frontNeckCpEdge = utils.beamsIntersect(
points.neck,
points.neckCp2,
points.cfNeck,
new Point(20, points.cfNeck.y)
);
points.cfNeckCp1 = points.cfNeck.shiftFractionTowards(
points.frontNeckCpEdge,
0.55
);
points.neckCp2Front = points.neck.shiftFractionTowards(
points.frontNeckCpEdge,
0.65
);
paths.neckOpening = new Path()
.move(points.cfNeck)
.curve(points.cfNeckCp1, points.neckCp2Front, points.neck)
.curve(points.neckCp2, points.cbNeck, points.cbNeck)
.attr("class", "dashed stroke-xl various");
delta = paths.neckOpening.length() * 2 - target;
} while (Math.abs(delta) > 1 && options.brianFitCollar && run < 10);
delete paths.neckOpening;
if (options.brianFitCollar) {
debug(
{ style: "success", label: "🏁 Collar fitted" },
// prettier-ignore
`Target was ${units(target)}, delta of ${units(delta)} reached in ${run} attempts.`
);
} else
debug({ style: "warning", label: "🚫 Not fitting collar" }, "(in Brian)");
// Anchor point for sampling // Seamline
points.gridAnchor = points.cbHips; paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path()
.move(points.cbNeck)
.line(points.cbHips)
.join(paths.saBase)
.attr("class", "fabric");
// Seamline // Complete pattern?
paths.saBase = shared.saBase("back", points, Path); if (complete) {
paths.seam = new Path() points.title = new Point(points.armholePitch.x / 2, points.armholePitch.y);
.move(points.cbNeck) points.logo = points.title.shift(-90, 100);
.line(points.cbHips) snippets.logo = new Snippet("logo", points.logo);
.join(paths.saBase)
.attr("class", "fabric");
// Complete pattern?
if (complete) {
points.title = new Point(
points.armholePitch.x / 2,
points.armholePitch.y
);
points.logo = points.title.shift(-90, 100);
snippets.logo = new Snippet("logo", points.logo);
}
return part;
} }
};
export default base; return part;
};

View file

@ -2,89 +2,82 @@ import freesewing from "freesewing";
import base from "./base"; import base from "./base";
import * as shared from "./shared"; import * as shared from "./shared";
var front = { export default part => {
draft: function(part) { // prettier-ignore
// prettier-ignore let {store, sa, Point, points, Path, paths, Snippet, snippets, options, measurements, complete, paperless, macro} = part.shorthand();
let {store, sa, Point, points, Path, paths, Snippet, snippets, options, measurements, complete, paperless, macro} = part.shorthand();
// Cut arm a bit deeper at the front // Cut arm a bit deeper at the front
let deeper = measurements.chestCircumference * options.frontArmholeDeeper; let deeper = measurements.chestCircumference * options.frontArmholeDeeper;
points.armholePitchCp1.x -= deeper; points.armholePitchCp1.x -= deeper;
points.armholePitch.x -= deeper; points.armholePitch.x -= deeper;
points.armholePitchCp2.x -= deeper; points.armholePitchCp2.x -= deeper;
// Rename cb (center back) to cf (center front) // Rename cb (center back) to cf (center front)
for (let key of ["Shoulder", "Armhole", "Waist", "Hips"]) { for (let key of ["Shoulder", "Armhole", "Waist", "Hips"]) {
points[`cf${key}`] = new Point( points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y);
points[`cb${key}`].x, delete points[`cb${key}`];
points[`cb${key}`].y
);
delete points[`cb${key}`];
}
// Front neckline points
points.neckCp2 = new Point(points.neckCp2Front.x, points.neckCp2Front.y);
// 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));
store.set(
"frontShoulderToArmholePitch",
shared.shoulderToArmholePitch(points, Path)
);
// Complete pattern?
if (complete) {
macro("cutonfold", {
from: points.cfNeck,
to: points.cfHips,
grainline: true
});
macro("title", { at: points.title, nr: 1, title: "front" });
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
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?
if (paperless) {
shared.dimensions(macro, points, Path, sa);
macro("hd", {
from: points.cfHips,
to: points.hips,
y: points.hips.y + sa + 15
});
macro("vd", {
from: points.cfHips,
to: points.cfNeck,
x: points.cfHips.x - sa - 15
});
macro("hd", {
from: points.cfNeck,
to: points.neck,
y: points.neck.y - sa - 15
});
macro("hd", {
from: points.cfNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
});
}
return part;
} }
}; // Front neckline points
points.neckCp2 = new Point(points.neckCp2Front.x, points.neckCp2Front.y);
export default front; // 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));
store.set(
"frontShoulderToArmholePitch",
shared.shoulderToArmholePitch(points, Path)
);
// Complete pattern?
if (complete) {
macro("cutonfold", {
from: points.cfNeck,
to: points.cfHips,
grainline: true
});
macro("title", { at: points.title, nr: 1, title: "front" });
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
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?
if (paperless) {
shared.dimensions(macro, points, Path, sa);
macro("hd", {
from: points.cfHips,
to: points.hips,
y: points.hips.y + sa + 15
});
macro("vd", {
from: points.cfHips,
to: points.cfNeck,
x: points.cfHips.x - sa - 15
});
macro("hd", {
from: points.cfNeck,
to: points.neck,
y: points.neck.y - sa - 15
});
macro("hd", {
from: points.cfNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
});
}
return part;
};

View file

@ -2,11 +2,12 @@ import freesewing from "freesewing";
import pluginBundle from "@freesewing/plugin-bundle"; import pluginBundle from "@freesewing/plugin-bundle";
import config from "../config/config"; import config from "../config/config";
import { version } from "../package.json"; import { version } from "../package.json";
import base from "./base"; // Parts
import back from "./back"; import draftBase from "./base";
import front from "./front"; import draftBack from "./back";
import sleevecap from "./sleevecap"; import draftFront from "./front";
import sleeve from "./sleeve"; import draftSleevecap from "./sleevecap";
import draftSleeve from "./sleeve";
// Constructor boilerplate // Constructor boilerplate
const Brian = function(settings = false) { const Brian = function(settings = false) {
@ -21,21 +22,11 @@ const Brian = function(settings = false) {
Brian.prototype = Object.create(freesewing.Pattern.prototype); Brian.prototype = Object.create(freesewing.Pattern.prototype);
Brian.prototype.constructor = Brian; Brian.prototype.constructor = Brian;
// Per-part draft methods // Attach per-part draft methods to prototype
Brian.prototype.draftBase = function(part) { Brian.prototype.draftBase = draftBase;
return base.draft(part); Brian.prototype.draftBack = draftBack;
}; Brian.prototype.draftFront = draftFront;
Brian.prototype.draftBack = function(part) { Brian.prototype.draftSleevecap = draftSleevecap;
return back.draft(part); Brian.prototype.draftSleeve = draftSleeve;
};
Brian.prototype.draftFront = function(part) {
return front.draft(part);
};
Brian.prototype.draftSleevecap = function(part) {
return sleevecap.draft(part);
};
Brian.prototype.draftSleeve = function(part) {
return sleeve.draft(part);
};
export default Brian; export default Brian;

View file

@ -1,101 +1,97 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
var sleeve = { export default part => {
draft: function(part) { // prettier-ignore
// prettier-ignore let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
// Wrist // Wrist
let top = paths.sleevecap.bbox().topLeft.y; let top = paths.sleevecap.bbox().topLeft.y;
debug({ style: "info", label: "🗸 Sleevecap height" }, units(Math.abs(top))); debug({ style: "info", label: "🗸 Sleevecap height" }, units(Math.abs(top)));
debug( debug(
{ style: "info", label: "🗸 Sleevecap width" }, { style: "info", label: "🗸 Sleevecap width" },
units(points.bicepsRight.x * 2) units(points.bicepsRight.x * 2)
);
points.centerWrist = new Point(
0,
top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus)
);
points.wristRight = points.centerWrist.shift(
0,
(measurements.wristCircumference * (1 + options.cuffEase)) / 2
);
points.wristLeft = points.wristRight.rotate(180, points.centerWrist);
points.sleeveTip = paths.sleevecap.shiftFractionAlong(0.5);
// Paths
paths.sleevecap.render = false;
paths.seam = new Path()
.move(points.bicepsLeft)
.move(points.wristLeft)
.move(points.wristRight)
.line(points.bicepsRight)
.join(paths.sleevecap)
.close()
.attr("class", "fabric");
// Anchor point for sampling
points.gridAnchor = new Point(0, 0);
// Complete pattern?
if (complete) {
points.logo = points.centerBiceps.shiftFractionTowards(
points.centerWrist,
0.3
); );
points.centerWrist = new Point( snippets.logo = new Snippet("logo", points.logo);
0, macro("title", { at: points.centerBiceps, nr: 3, title: "sleeve" });
top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus) macro("grainline", { from: points.centerWrist, to: points.centerBiceps });
points.scaleboxAnchor = points.scalebox = points.centerBiceps.shiftFractionTowards(
points.centerWrist,
0.5
); );
points.wristRight = points.centerWrist.shift( macro("scalebox", { at: points.scalebox });
0,
(measurements.wristCircumference * (1 + options.cuffEase)) / 2 points.frontNotch = paths.sleevecap.shiftAlong(
paths.sleevecap.length() / 2 -
store.get("frontShoulderToArmholePitch") -
store.get("sleevecapEase") / 2
); );
points.wristLeft = points.wristRight.rotate(180, points.centerWrist); points.backNotch = paths.sleevecap.shiftAlong(
points.sleeveTip = paths.sleevecap.shiftFractionAlong(0.5); paths.sleevecap.length() / 2 +
store.get("backShoulderToArmholePitch") +
// Paths store.get("sleevecapEase") / 2
paths.sleevecap.render = false; );
paths.seam = new Path() snippets.frontNotch = new Snippet("notch", points.frontNotch);
.move(points.bicepsLeft) snippets.backNotch = new Snippet("bnotch", points.backNotch);
.move(points.wristLeft) if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
.move(points.wristRight)
.line(points.bicepsRight)
.join(paths.sleevecap)
.close()
.attr("class", "fabric");
// Anchor point for sampling
points.gridAnchor = new Point(0, 0);
// Complete pattern?
if (complete) {
points.logo = points.centerBiceps.shiftFractionTowards(
points.centerWrist,
0.3
);
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.frontNotch = paths.sleevecap.shiftAlong(
paths.sleevecap.length() / 2 -
store.get("frontShoulderToArmholePitch") -
store.get("sleevecapEase") / 2
);
points.backNotch = paths.sleevecap.shiftAlong(
paths.sleevecap.length() / 2 +
store.get("backShoulderToArmholePitch") +
store.get("sleevecapEase") / 2
);
snippets.frontNotch = new Snippet("notch", points.frontNotch);
snippets.backNotch = new Snippet("bnotch", points.backNotch);
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
}
// Paperless?
if (paperless) {
macro("vd", {
from: points.wristLeft,
to: points.bicepsLeft,
x: points.bicepsLeft.x - sa - 15
});
macro("vd", {
from: points.wristLeft,
to: points.sleeveTip,
x: points.bicepsLeft.x - sa - 30
});
macro("hd", {
from: points.bicepsLeft,
to: points.bicepsRight,
y: points.sleeveTip.y - sa - 30
});
macro("hd", {
from: points.wristLeft,
to: points.wristRight,
y: points.wristLeft.y + sa + 30
});
macro("pd", {
path: paths.sleevecap.reverse(),
d: -1 * sa - 15
});
}
return part;
} }
};
export default sleeve; // Paperless?
if (paperless) {
macro("vd", {
from: points.wristLeft,
to: points.bicepsLeft,
x: points.bicepsLeft.x - sa - 15
});
macro("vd", {
from: points.wristLeft,
to: points.sleeveTip,
x: points.bicepsLeft.x - sa - 30
});
macro("hd", {
from: points.bicepsLeft,
to: points.bicepsRight,
y: points.sleeveTip.y - sa - 30
});
macro("hd", {
from: points.wristLeft,
to: points.wristRight,
y: points.wristLeft.y + sa + 30
});
macro("pd", {
path: paths.sleevecap.reverse(),
d: -1 * sa - 15
});
}
return part;
};

View file

@ -144,45 +144,41 @@ function draftSleevecap(part, run) {
} }
} }
var sleevecap = { export default part => {
draft: function(part) { // prettier-ignore
// prettier-ignore let {debug, store, units, sa, measurements, options, Point, points, Path, paths } = part.shorthand();
let {debug, store, units, sa, measurements, options, Point, points, Path, paths } = part.shorthand();
store.set("sleeveFactor", 1); store.set("sleeveFactor", 1);
let run = 0; let run = 0;
let delta = 0; let delta = 0;
do { do {
draftSleevecap(part, run); draftSleevecap(part, run);
delta = sleevecapDelta(store); delta = sleevecapDelta(store);
sleevecapAdjust(store); sleevecapAdjust(store);
run++; run++;
} while ( } while (
options.brianFitSleeve === true && options.brianFitSleeve === true &&
run < 30 && run < 30 &&
Math.abs(sleevecapDelta(store)) > 2 Math.abs(sleevecapDelta(store)) > 2
);
if (options.brianFitSleeve) {
debug(
{ style: "success", label: "🏁 Sleevecap fitted" },
`Target was ${units(store.get("sleevecapTarget"))}, delta of ${units(
delta
)} reached in ${run} attempts.`
);
} else
debug(
{ style: "warning", label: "🚫 Not fitting sleevecap" },
"(in Brian)"
); );
if (options.brianFitSleeve) {
debug(
{ style: "success", label: "🏁 Sleevecap fitted" },
`Target was ${units(store.get("sleevecapTarget"))}, delta of ${units(
delta
)} reached in ${run} attempts.`
);
} else
debug(
{ style: "warning", label: "🚫 Not fitting sleevecap" },
"(in Brian)"
);
// Paths // Paths
paths.sleevecap.attr("class", "fabric"); paths.sleevecap.attr("class", "fabric");
// Anchor point for sampling // Anchor point for sampling
points.gridAnchor = new Point(0, 0); points.gridAnchor = new Point(0, 0);
return part; return part;
}
}; };
export default sleevecap;