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

View file

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

View file

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

View file

@ -1,73 +1,69 @@
import freesewing from "freesewing";
import * as shared from "./shared";
var back = {
draft: function(part) {
// prettier-ignore
let {store, sa, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
export default part => {
// prettier-ignore
let {store, sa, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
// Seamline
paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path()
.move(points.cbNeck)
.line(points.cbHips)
.join(paths.saBase)
.attr("class", "fabric");
// Seamline
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));
store.set(
"backShoulderToArmholePitch",
shared.shoulderToArmholePitch(points, Path)
);
// Store lengths to fit sleeve
store.set("backArmholeLength", shared.armholeLength(points, Path));
store.set(
"backShoulderToArmholePitch",
shared.shoulderToArmholePitch(points, Path)
);
// Complete pattern?
if (complete) {
macro("cutonfold", {
from: points.cbNeck,
to: points.cbHips,
grainline: true
});
// Complete pattern?
if (complete) {
macro("cutonfold", {
from: points.cbNeck,
to: points.cbHips,
grainline: true
});
macro("title", { at: points.title, nr: 2, title: "back" });
snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch);
if (sa) {
paths.sa = paths.saBase
.offset(sa)
.attr("class", "fabric sa")
.line(points.cbNeck)
.move(points.cbHips);
paths.sa.line(paths.sa.start());
}
macro("title", { at: points.title, nr: 2, title: "back" });
snippets.armholePitchNotch = new Snippet("bnotch", points.armholePitch);
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?
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 * as shared from "./shared";
var base = {
draft: function(part) {
// prettier-ignore
let {units, debug, measurements, options, store, points, snippets, Point, Snippet, Path, paths, utils, complete } = part.shorthand();
export default part => {
// prettier-ignore
let {units, debug, measurements, options, store, points, snippets, Point, Snippet, Path, paths, utils, complete } = part.shorthand();
store.set(
"shoulderEase",
(measurements.shoulderToShoulder * options.shoulderEase) / 2
);
store.set(
"shoulderEase",
(measurements.shoulderToShoulder * options.shoulderEase) / 2
);
// Center back (cb) vertical axis
points.cbNeck = new Point(
0,
options.backNeckCutout * measurements.neckCircumference
);
points.cbShoulder = new Point(
0,
(measurements.shoulderSlope -
measurements.shoulderToShoulder * options.shoulderSlopeReduction) /
2
);
points.cbArmhole = new Point(
0,
points.cbShoulder.y +
measurements.bicepsCircumference *
(1 + options.bicepsEase) *
options.armholeDepthFactor
);
points.cbWaist = new Point(
0,
points.cbNeck.y + measurements.centerBackNeckToWaist
);
points.cbHips = new Point(
0,
points.cbWaist.y +
measurements.naturalWaistToHip +
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) *
options.lengthBonus
);
// Center back (cb) vertical axis
points.cbNeck = new Point(
0,
options.backNeckCutout * measurements.neckCircumference
);
points.cbShoulder = new Point(
0,
(measurements.shoulderSlope -
measurements.shoulderToShoulder * options.shoulderSlopeReduction) /
2
);
points.cbArmhole = new Point(
0,
points.cbShoulder.y +
measurements.bicepsCircumference *
(1 + options.bicepsEase) *
options.armholeDepthFactor
);
points.cbWaist = new Point(
0,
points.cbNeck.y + measurements.centerBackNeckToWaist
);
points.cbHips = new Point(
0,
points.cbWaist.y +
measurements.naturalWaistToHip +
(measurements.centerBackNeckToWaist + measurements.naturalWaistToHip) *
options.lengthBonus
);
// Side back (cb) vertical axis
points.armhole = new Point(
(measurements.chestCircumference * (1 + options.chestEase)) / 4,
points.cbArmhole.y
);
points.waist = new Point(points.armhole.x, points.cbWaist.y);
points.hips = new Point(points.armhole.x, points.cbHips.y);
// Side back (cb) vertical axis
points.armhole = new Point(
(measurements.chestCircumference * (1 + options.chestEase)) / 4,
points.cbArmhole.y
);
points.waist = new Point(points.armhole.x, points.cbWaist.y);
points.hips = new Point(points.armhole.x, points.cbHips.y);
// Shoulder line
points.neck = new Point(
(measurements.neckCircumference * (1 + options.collarEase)) /
options.collarFactor,
0
);
points.shoulder = new Point(
measurements.shoulderToShoulder / 2 + store.get("shoulderEase"),
points.cbShoulder.y
);
// Shoulder line
points.neck = new Point(
(measurements.neckCircumference * (1 + options.collarEase)) /
options.collarFactor,
0
);
points.shoulder = new Point(
measurements.shoulderToShoulder / 2 + store.get("shoulderEase"),
points.cbShoulder.y
);
// Armhhole
points.armholePitch = new Point(
(measurements.shoulderToShoulder * options.acrossBackFactor) / 2 +
store.get("shoulderEase") / 2,
points.shoulder.y + points.shoulder.dy(points.armhole) / 2
);
points._tmp1 = new Point(points.armholePitch.x, points.armhole.y);
points._tmp2 = points._tmp1.shift(45, 10);
points._tmp3 = utils.beamsIntersect(
points._tmp1,
points._tmp2,
points.armhole,
points.armholePitch
);
points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5);
points.armholeCp2 = points.armhole.shift(
180,
points._tmp1.dx(points.armhole) / 4
);
points.armholeHollowCp1 = points.armholeHollow.shift(
-45,
points.armholeHollow.dy(points.armhole) / 2
);
points.armholeHollowCp2 = points.armholeHollow.shift(
135,
points.armholePitch.dx(points.armholeHollow)
);
points.armholePitchCp1 = points.armholePitch.shift(
-90,
points.armholePitch.dy(points.armholeHollow) / 2
);
points.armholePitchCp2 = points.armholePitch.shift(
90,
points.shoulder.dy(points.armholePitch) / 2
);
points.shoulderCp1 = points.shoulder
.shiftTowards(points.neck, points.shoulder.dy(points.armholePitch) / 5)
.rotate(90, points.shoulder);
// Armhhole
points.armholePitch = new Point(
(measurements.shoulderToShoulder * options.acrossBackFactor) / 2 +
store.get("shoulderEase") / 2,
points.shoulder.y + points.shoulder.dy(points.armhole) / 2
);
points._tmp1 = new Point(points.armholePitch.x, points.armhole.y);
points._tmp2 = points._tmp1.shift(45, 10);
points._tmp3 = utils.beamsIntersect(
points._tmp1,
points._tmp2,
points.armhole,
points.armholePitch
);
points.armholeHollow = points._tmp1.shiftFractionTowards(points._tmp3, 0.5);
points.armholeCp2 = points.armhole.shift(
180,
points._tmp1.dx(points.armhole) / 4
);
points.armholeHollowCp1 = points.armholeHollow.shift(
-45,
points.armholeHollow.dy(points.armhole) / 2
);
points.armholeHollowCp2 = points.armholeHollow.shift(
135,
points.armholePitch.dx(points.armholeHollow)
);
points.armholePitchCp1 = points.armholePitch.shift(
-90,
points.armholePitch.dy(points.armholeHollow) / 2
);
points.armholePitchCp2 = points.armholePitch.shift(
90,
points.shoulder.dy(points.armholePitch) / 2
);
points.shoulderCp1 = points.shoulder
.shiftTowards(points.neck, points.shoulder.dy(points.armholePitch) / 5)
.rotate(90, points.shoulder);
// Neck opening (back)
points._tmp4 = points.neck
.shiftTowards(points.shoulder, 10)
.rotate(-90, points.neck);
points.neckCp2 = utils.beamIntersectsY(
// Neck opening (back)
points._tmp4 = points.neck
.shiftTowards(points.shoulder, 10)
.rotate(-90, points.neck);
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._tmp4,
points.cbNeck.y
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)");
// 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.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
points.gridAnchor = points.cbHips;
// Anchor point for sampling
points.gridAnchor = points.cbHips;
// Seamline
paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path()
.move(points.cbNeck)
.line(points.cbHips)
.join(paths.saBase)
.attr("class", "fabric");
// Seamline
paths.saBase = shared.saBase("back", points, Path);
paths.seam = new Path()
.move(points.cbNeck)
.line(points.cbHips)
.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;
// 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);
}
};
export default base;
return part;
};

View file

@ -2,89 +2,82 @@ import freesewing from "freesewing";
import base from "./base";
import * as shared from "./shared";
var front = {
draft: function(part) {
// prettier-ignore
let {store, sa, Point, points, Path, paths, Snippet, snippets, options, measurements, complete, paperless, macro} = part.shorthand();
export default part => {
// prettier-ignore
let {store, sa, Point, points, Path, paths, Snippet, snippets, options, measurements, complete, paperless, macro} = part.shorthand();
// Cut arm a bit deeper at the front
let deeper = measurements.chestCircumference * options.frontArmholeDeeper;
points.armholePitchCp1.x -= deeper;
points.armholePitch.x -= deeper;
points.armholePitchCp2.x -= deeper;
// Cut arm a bit deeper at the front
let deeper = measurements.chestCircumference * options.frontArmholeDeeper;
points.armholePitchCp1.x -= deeper;
points.armholePitch.x -= deeper;
points.armholePitchCp2.x -= deeper;
// Rename cb (center back) to cf (center front)
for (let key of ["Shoulder", "Armhole", "Waist", "Hips"]) {
points[`cf${key}`] = new Point(
points[`cb${key}`].x,
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;
// Rename cb (center back) to cf (center front)
for (let key of ["Shoulder", "Armhole", "Waist", "Hips"]) {
points[`cf${key}`] = new Point(points[`cb${key}`].x, points[`cb${key}`].y);
delete points[`cb${key}`];
}
};
// 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 config from "../config/config";
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";
// Parts
import draftBase from "./base";
import draftBack from "./back";
import draftFront from "./front";
import draftSleevecap from "./sleevecap";
import draftSleeve from "./sleeve";
// Constructor boilerplate
const Brian = function(settings = false) {
@ -21,21 +22,11 @@ const Brian = function(settings = false) {
Brian.prototype = Object.create(freesewing.Pattern.prototype);
Brian.prototype.constructor = Brian;
// Per-part draft methods
Brian.prototype.draftBase = function(part) {
return base.draft(part);
};
Brian.prototype.draftBack = function(part) {
return back.draft(part);
};
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);
};
// Attach per-part draft methods to prototype
Brian.prototype.draftBase = draftBase;
Brian.prototype.draftBack = draftBack;
Brian.prototype.draftFront = draftFront;
Brian.prototype.draftSleevecap = draftSleevecap;
Brian.prototype.draftSleeve = draftSleeve;
export default Brian;

View file

@ -1,101 +1,97 @@
import freesewing from "freesewing";
var sleeve = {
draft: function(part) {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
export default part => {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, complete, paperless, macro} = part.shorthand();
// Wrist
let top = paths.sleevecap.bbox().topLeft.y;
debug({ style: "info", label: "🗸 Sleevecap height" }, units(Math.abs(top)));
debug(
{ style: "info", label: "🗸 Sleevecap width" },
units(points.bicepsRight.x * 2)
// Wrist
let top = paths.sleevecap.bbox().topLeft.y;
debug({ style: "info", label: "🗸 Sleevecap height" }, units(Math.abs(top)));
debug(
{ style: "info", label: "🗸 Sleevecap width" },
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(
0,
top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus)
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
);
points.wristRight = points.centerWrist.shift(
0,
(measurements.wristCircumference * (1 + options.cuffEase)) / 2
macro("scalebox", { at: points.scalebox });
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.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
);
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;
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");
}
};
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 = {
draft: function(part) {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths } = part.shorthand();
export default part => {
// prettier-ignore
let {debug, store, units, sa, measurements, options, Point, points, Path, paths } = part.shorthand();
store.set("sleeveFactor", 1);
let run = 0;
let delta = 0;
do {
draftSleevecap(part, run);
delta = sleevecapDelta(store);
sleevecapAdjust(store);
run++;
} while (
options.brianFitSleeve === true &&
run < 30 &&
Math.abs(sleevecapDelta(store)) > 2
store.set("sleeveFactor", 1);
let run = 0;
let delta = 0;
do {
draftSleevecap(part, run);
delta = sleevecapDelta(store);
sleevecapAdjust(store);
run++;
} while (
options.brianFitSleeve === true &&
run < 30 &&
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.sleevecap.attr("class", "fabric");
// Paths
paths.sleevecap.attr("class", "fabric");
// Anchor point for sampling
points.gridAnchor = new Point(0, 0);
// Anchor point for sampling
points.gridAnchor = new Point(0, 0);
return part;
}
return part;
};
export default sleevecap;