1
0
Fork 0

sparkles: Auto-fitting of collar via brianFitCollar option

This commit is contained in:
Joost De Cock 2018-09-23 13:14:25 +02:00
parent bb81f44678
commit ebb29cd5c5
9 changed files with 982 additions and 923 deletions

View file

@ -14,6 +14,7 @@ export default {
options: { options: {
// Constants // Constants
brianFitSleeve: true, brianFitSleeve: true,
brianFitCollar: true,
collarFactor: 4.8, collarFactor: 4.8,
// Percentages // Percentages

View file

@ -35,7 +35,9 @@
focus: 'manSize34', focus: 'manSize34',
models: freesewing.models.men models: freesewing.models.men
} }
pattern.settings.onl='base'; pattern.settings.nly= ['base'];
//pattern.options.brianFitSleeve = false;
//pattern.options.brianFitCollar = false;
//pattern.sampleOption('shoulderSlopeReduction'); //pattern.sampleOption('shoulderSlopeReduction');
//pattern.sampleMeasurement('shoulderSlope'); //pattern.sampleMeasurement('shoulderSlope');
//pattern.sampleModels(freesewing.models.men, 'manSize34'); //pattern.sampleModels(freesewing.models.men, 'manSize34');

File diff suppressed because it is too large Load diff

View file

@ -59,8 +59,8 @@
"babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-object-rest-spread": "^6.26.0",
"@freesewing/antman": "0.2.0", "@freesewing/antman": "0.2.0",
"@freesewing/models": "0.4.0", "@freesewing/models": "0.4.0",
"@freesewing/plugin-debug": "0.1.0", "@freesewing/plugin-debug": "0.3.0",
"@freesewing/plugin-designer": "0.7.2", "@freesewing/plugin-designer": "0.8.0",
"@freesewing/plugin-theme": "0.13.2", "@freesewing/plugin-theme": "0.13.2",
"@freesewing/plugin-validate": "0.2.0", "@freesewing/plugin-validate": "0.2.0",
"@freesewing/plugin-i18n": "0.0.1", "@freesewing/plugin-i18n": "0.0.1",

View file

@ -1,11 +1,10 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
import * as shared from "./shared";
var base = { var base = {
draft: function(part) { draft: function(part) {
part.render = false;
// prettier-ignore // prettier-ignore
let {measurements, options, store, points, snippets, Point, Snippet, 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",
@ -100,7 +99,7 @@ var base = {
.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 // 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);
@ -110,9 +109,56 @@ var base = {
points.cbNeck.y 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.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 // Anchor point for sampling
points.gridAnchor = points.cbHips; 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");
// Complete pattern? // Complete pattern?
if (complete) { if (complete) {
points.title = new Point( points.title = new Point(

View file

@ -14,17 +14,15 @@ var front = {
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 ["Neck", "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}`].x,
points[`cb${key}`].y points[`cb${key}`].y
); );
delete points[`cb${key}`]; delete points[`cb${key}`];
} }
// Front neckline points
// Adapt neck opening points.neckCp2 = new Point(points.neckCp2Front.x, points.neckCp2Front.y);
points.cfNeck = points.cfNeck.shift(-90, points.neck.x);
points.neckCp2 = points.cfNeck.shift(0, points.neck.x * 0.7);
// Seamline // Seamline
paths.saBase = shared.saBase("front", points, Path); paths.saBase = shared.saBase("front", points, Path);

View file

@ -12,7 +12,7 @@ export function saBase(side, points, Path) {
if (side === "back") { if (side === "back") {
path.curve(points.neckCp2, points.cbNeck, points.cbNeck); path.curve(points.neckCp2, points.cbNeck, points.cbNeck);
} else { } else {
path.curve(points.neckCp2, points.cfNeck, points.cfNeck); path.curve(points.neckCp2, points.cfNeckCp1, points.cfNeck);
} }
return path; return path;

View file

@ -7,8 +7,11 @@ var sleeve = {
// Wrist // Wrist
let top = paths.sleevecap.bbox().topLeft.y; let top = paths.sleevecap.bbox().topLeft.y;
debug("Sleevecap height is ", units(Math.abs(top))); debug({ style: "info", label: "🗸 Sleevecap height" }, units(Math.abs(top)));
debug("Sleeve width is ", units(points.bicepsRight.x * 2)); debug(
{ style: "info", label: "🗸 Sleevecap width" },
units(points.bicepsRight.x * 2)
);
points.centerWrist = new Point( points.centerWrist = new Point(
0, 0,
top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus) top + measurements.shoulderToWrist * (1 + options.sleeveLengthBonus)

View file

@ -131,13 +131,13 @@ function draftSleevecap(part, run) {
// Store sleevecap length // Store sleevecap length
store.set("sleevecapLength", paths.sleevecap.length()); store.set("sleevecapLength", paths.sleevecap.length());
if (run === 1) { if (run === 0) {
let armholeLength = let armholeLength =
store.get("frontArmholeLength") + store.get("backArmholeLength"); store.get("frontArmholeLength") + store.get("backArmholeLength");
let sleevecapEase = armholeLength * options.sleevecapEase; let sleevecapEase = armholeLength * options.sleevecapEase;
store.set("sleevecapEase", sleevecapEase); store.set("sleevecapEase", sleevecapEase);
store.set("sleevecapTarget", armholeLength + sleevecapEase); store.set("sleevecapTarget", armholeLength + sleevecapEase);
debug("Sleevecap ease is", units(sleevecapEase)); debug({ style: "info", label: "🗸 Sleevecap ease" }, units(sleevecapEase));
// Uncomment this line to see all sleevecap iterations // Uncomment this line to see all sleevecap iterations
//paths[run] = paths.sleevecap; //paths[run] = paths.sleevecap;
@ -150,21 +150,30 @@ var sleevecap = {
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 = 1; let run = 0;
let delta = 0;
do { do {
draftSleevecap(part, run); draftSleevecap(part, run);
debug( delta = sleevecapDelta(store);
`Sleevecap draft ${run}, sleevecap delta is ${units(
sleevecapDelta(store)
)}`
);
sleevecapAdjust(store); sleevecapAdjust(store);
run++; run++;
} while ( } while (
options.brianFitSleeve === true && options.brianFitSleeve === true &&
run < 100 && 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)"
);
// Paths // Paths
paths.sleevecap.attr("class", "fabric"); paths.sleevecap.attr("class", "fabric");