1
0
Fork 0

construction: Sleeve head

This commit is contained in:
Joost De Cock 2018-08-06 16:19:12 +02:00
parent b77c146a7e
commit 8379361e47
8 changed files with 381 additions and 145 deletions

View file

@ -27,13 +27,31 @@ export default {
{ id: "sleeveLengthBonus", val: 0, min: -40, max: 80 }, { id: "sleeveLengthBonus", val: 0, min: -40, max: 80 },
// Percentages // Percentages
{ id: "frontArmholeDeeper", val: 0.5, type: "%" }, { id: "frontArmholeDeeper", val: 0.5, type: "%", min: 0, max: 1.5 },
{ id: "chestEase", val: 8, type: "%", min: -4, max: 20 }, { id: "chestEase", val: 8, type: "%", min: -4, max: 20 },
{ id: "collarEase", val: 3.5, type: "%", min: 0, max: 10 }, { id: "collarEase", val: 3.5, type: "%", min: 0, max: 10 },
{ id: "bicepsEase", val: 15, type: "%", min: 0, max: 100 }, { id: "bicepsEase", val: 15, type: "%", min: 0, max: 100 },
{ id: "backNeckCutout", val: 5, type: "%", min: 2, max: 8 }, { id: "backNeckCutout", val: 5, type: "%", min: 2, max: 8 },
{ id: "acrossBackFactor", val: 97, type: "%", min: 93, max: 100 }, { id: "acrossBackFactor", val: 97, type: "%", min: 93, max: 100 },
{ id: "armholeDepthFactor", val: 50, type: "%", min: 35, max: 65 }, { id: "armholeDepthFactor", val: 50, type: "%", min: 35, max: 65 },
{ id: "sleevecapHeightFactor", val: 55, type: "%", min: 35, max: 75 } { id: "sleevecapHeightFactor", val: 55, type: "%", min: 35, max: 75 },
{ id: "sleevecapBackFactorX", val: 50, type: "%", min: 35, max: 65 },
{ id: "sleevecapBackFactorY", val: 33, type: "%", min: 35, max: 65 },
{ id: "sleevecapFrontFactorX", val: 50, type: "%", min: 35, max: 65 },
{ id: "sleevecapFrontFactorY", val: 33, type: "%", min: 35, max: 65 },
{ id: "sleevecapQ1Offset", val: 5, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ2Offset", val: 5.5, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ3Offset", val: 4.5, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ4Offset", val: 2, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ1Spread1", val: 6, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ1Spread2", val: 15, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ2Spread1", val: 15, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ2Spread2", val: 5, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ3Spread1", val: 5, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ3Spread2", val: 8, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ4Spread1", val: 7, type: "%", min: 0, max: 7 },
{ id: "sleevecapQ4Spread2", val: 7, type: "%", min: 0, max: 7 },
{ id: "sleevecapTopSpread1", val: 5, type: "%", min: 0, max: 7 },
{ id: "sleevecapTopSpread2", val: 5, type: "%", min: 0, max: 7 },
] ]
}; };

View file

@ -31,9 +31,23 @@
shoulderToWrist: 700, shoulderToWrist: 700,
wristCircumference: 190 wristCircumference: 190
}; };
//pattern.options.sleevecapQ1Offset = 0.05;
//pattern.options.sleevecapQ2Offset = 0.055;
//pattern.options.sleevecapQ3Offset = 0.045;
//pattern.options.sleevecapQ4Offset = 0.02;
//pattern.options.sleevecapQ1Spread1 = 0.06;
//pattern.options.sleevecapQ1Spread2 = 0.15;
//pattern.options.sleevecapQ2Spread1 = 0.15;
//pattern.options.sleevecapQ2Spread2 = 0.05;
//pattern.options.sleevecapQ3Spread1 = 0.05;
//pattern.options.sleevecapQ3Spread2 = 0.08;
//pattern.options.sleevecapQ4Spread1 = 0.07;
//pattern.options.sleevecapQ4Spread2 = 0.07;
//pattern.options.sleevecapTopSpread1 = 0.05;
//pattern.options.sleevecapTopSpread2 = 0.05;
pattern.settings.mode = 'draft'; pattern.settings.mode = 'draft';
pattern.settings.paperless = true; pattern.settings.paperless = true;
pattern.settings.sa = 10; //pattern.settings.sa = 10;
pattern.settings.units = 'metric'; pattern.settings.units = 'metric';
pattern.draft(); pattern.draft();
document.getElementById("svg").innerHTML = pattern.render(); document.getElementById("svg").innerHTML = pattern.render();

View file

@ -1,31 +1,31 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
import * as shared from "./shared";
var back = { var back = {
draft: function(pattern) { draft: function(pattern) {
let part = new pattern.Part().copy(pattern.parts.base); let part = new pattern.Part().copy(pattern.parts.base);
// prettier-ignore // prettier-ignore
let {sa, Point, points, Path, paths, Snippet, snippets, final, paperless, macro} = freesewing.utils.shorthand(part); let {store, sa, Point, points, Path, paths, Snippet, snippets, final, paperless, macro} = freesewing.utils.shorthand(part);
paths.seam = new Path() // Seamline
.move(points.cbNeck) paths.seam = shared.seamLine("back", points, Path);
.line(points.cbHips)
.line(points.hips) // Store lengths to fit sleeve
.line(points.armhole) store.set("backArmholeLength", shared.armholeLength(points, Path));
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow) store.set(
.curve( "backShoulderToArmholePitch",
points.armholeHollowCp1, shared.shoulderToArmholePitch(points, Path)
points.armholeHollowCp2, );
points.armholePitch
)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder)
.line(points.neck)
.curve(points.neckCp1, points.cbNeck, points.cbNeck)
.close()
.attr("class", "fabric");
// Final? // Final?
if (final) { if (final) {
macro("cutonfold", {
from: points.cbNeck,
to: points.cbHips,
grainline: true
});
macro("title", { at: points.title, nr: 2, title: "back" }); macro("title", { at: points.title, nr: 2, title: "back" });
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch); snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa"); if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
@ -33,33 +33,26 @@ var back = {
// Paperless? // Paperless?
if (paperless) { if (paperless) {
macro("pd", { shared.dimensions(macro, points, Path, sa);
id: "armholeLengthDimension", macro("hd", {
path: new Path() from: points.cbHips,
.move(points.armhole) to: points.hips,
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow) y: points.hips.y + sa + 15
.curve(
points.armholeHollowCp1,
points.armholeHollowCp2,
points.armholePitch
)
.curve(
points.armholePitchCp1,
points.armholePitchCp2,
points.shoulder
),
d: sa + 15
}); });
macro("pd", { macro("vd", {
id: "armholePitchDimension", from: points.cbHips,
path: new Path() to: points.cbNeck,
.move(points.armholePitch) x: points.cbHips.x - sa - 15
.curve( });
points.armholePitchCp1, macro("hd", {
points.armholePitchCp2, from: points.cbNeck,
points.shoulder to: points.neck,
), y: points.neck.y - sa - 15
d: -15 });
macro("hd", {
from: points.cbNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
}); });
} }

View file

@ -105,12 +105,6 @@ var base = {
// Final? // Final?
if (final) { if (final) {
macro("cutonfold", {
from: points.cbNeck,
to: points.cbHips,
grainline: true
});
points.title = new Point( points.title = new Point(
points.armholePitch.x / 2, points.armholePitch.x / 2,
points.armholePitch.y points.armholePitch.y
@ -119,52 +113,6 @@ var base = {
snippets.logo = new Snippet("logo", points.logo); snippets.logo = new Snippet("logo", points.logo);
} }
// Paperless?
if (paperless) {
macro("hd", {
from: points.cbHips,
to: points.hips,
y: points.hips.y + sa + 15
});
macro("vd", {
from: points.hips,
to: points.armhole,
x: points.hips.x + sa + 15
});
macro("vd", {
from: points.hips,
to: points.armholePitch,
x: points.hips.x + sa + 30
});
macro("vd", {
from: points.hips,
to: points.shoulder,
x: points.hips.x + sa + 45
});
macro("vd", {
from: points.hips,
to: points.neck,
x: points.hips.x + sa + 60
});
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
});
macro("ld", { from: points.neck, to: points.shoulder, d: sa + 15 });
}
return part; return part;
} }
}; };

View file

@ -1,12 +1,13 @@
import freesewing from "freesewing"; import freesewing from "freesewing";
import base from "./base"; import base from "./base";
import * as shared from "./shared";
var front = { var front = {
draft: function(pattern) { draft: function(pattern) {
let part = new pattern.Part().copy(pattern.parts.back); let part = new pattern.Part().copy(pattern.parts.back);
// prettier-ignore // prettier-ignore
let {sa, Point, points, Path, paths, Snippet, snippets, options, measurements, final, paperless, macro} = freesewing.utils.shorthand(part); let {store, sa, Point, points, Path, paths, Snippet, snippets, options, measurements, final, paperless, macro} = freesewing.utils.shorthand(part);
// 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;
@ -16,7 +17,6 @@ var front = {
// 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 ["Neck", "Shoulder", "Armhole", "Waist", "Hips"]) {
console.log("key is", key);
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
@ -28,58 +28,49 @@ var front = {
points.cfNeck = points.cfNeck.shift(-90, points.neck.x); points.cfNeck = points.cfNeck.shift(-90, points.neck.x);
points.neckCp2 = points.cfNeck.shift(0, points.neck.x * 0.7); points.neckCp2 = points.cfNeck.shift(0, points.neck.x * 0.7);
paths.seam = new Path() paths.seam = shared.seamLine("front", points, Path);
.move(points.cfNeck)
.line(points.cfHips) // Store lengths to fit sleeve
.line(points.hips) store.set("frontArmholeLength", shared.armholeLength(points, Path));
.line(points.armhole) store.set(
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow) "frontShoulderToArmholePitch",
.curve( shared.shoulderToArmholePitch(points, Path)
points.armholeHollowCp1, );
points.armholeHollowCp2,
points.armholePitch
)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder)
.line(points.neck)
.curve(points.neckCp1, points.neckCp2, points.cfNeck)
.close()
.attr("class", "fabric");
// Final? // Final?
if (final) { if (final) {
macro("cutonfold", {
from: points.cfNeck,
to: points.cfHips,
grainline: true
});
macro("title", { at: points.title, nr: 1, title: "front" }); macro("title", { at: points.title, nr: 1, title: "front" });
snippets.armholePitchNotch = new Snippet("notch", points.armholePitch); snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa"); if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
} }
// Paperless? // Paperless?
if (paperless) { if (paperless) {
macro("pd", { shared.dimensions(macro, points, Path, sa);
path: new Path() macro("hd", {
.move(points.armhole) from: points.cfHips,
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow) to: points.hips,
.curve( y: points.hips.y + sa + 15
points.armholeHollowCp1,
points.armholeHollowCp2,
points.armholePitch
)
.curve(
points.armholePitchCp1,
points.armholePitchCp2,
points.shoulder
),
d: sa + 15
}); });
macro("pd", { macro("vd", {
path: new Path() from: points.cfHips,
.move(points.armholePitch) to: points.cfNeck,
.curve( x: points.cfHips.x - sa - 15
points.armholePitchCp1, });
points.armholePitchCp2, macro("hd", {
points.shoulder from: points.cfNeck,
), to: points.neck,
d: -15 y: points.neck.y - sa - 15
});
macro("hd", {
from: points.cfNeck,
to: points.shoulder,
y: points.neck.y - sa - 30
}); });
} }

View file

@ -10,6 +10,7 @@ import { version } from "../package.json";
import base from "./base"; import base from "./base";
import back from "./back"; import back from "./back";
import front from "./front"; import front from "./front";
import sleeve from "./sleeve";
var pattern = new freesewing.Pattern({ version: version, ...config }) var pattern = new freesewing.Pattern({ version: version, ...config })
.with(pluginCutonfold) .with(pluginCutonfold)
@ -21,10 +22,7 @@ pattern.draft = function() {
pattern.parts.base = base.draft(pattern); pattern.parts.base = base.draft(pattern);
pattern.parts.back = back.draft(pattern); pattern.parts.back = back.draft(pattern);
pattern.parts.front = front.draft(pattern); pattern.parts.front = front.draft(pattern);
// Clone back pattern.parts.sleeve = sleeve.draft(pattern);
//pattern.parts.front = pattern.parts.back.clone(pattern.parts.front.id);
// Draft front
//front.draft(pattern.parts.front);
return pattern; return pattern;
}; };

View file

@ -0,0 +1,91 @@
export function seamLine(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);
}
path
.line(points.hips)
.line(points.armhole)
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow)
.curve(
points.armholeHollowCp1,
points.armholeHollowCp2,
points.armholePitch
)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder)
.line(points.neck);
if (side === "back") {
path.curve(points.neckCp1, points.cbNeck, points.cbNeck);
} else {
path.curve(points.neckCp1, points.neckCp2, points.cfNeck);
}
path.close().attr("class", "fabric");
return path;
}
export function armholeLength(points, Path) {
return new Path()
.move(points.armhole)
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow)
.curve(
points.armholeHollowCp1,
points.armholeHollowCp2,
points.armholePitch
)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder)
.length();
}
export function shoulderToArmholePitch(points, Path) {
return new Path()
.move(points.armholePitch)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder)
.length();
}
export function dimensions(macro, points, Path, sa) {
macro("pd", {
path: new Path()
.move(points.armhole)
.curve(points.armholeCp1, points.armholeCp2, points.armholeHollow)
.curve(
points.armholeHollowCp1,
points.armholeHollowCp2,
points.armholePitch
)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder),
d: sa + 15
});
macro("pd", {
path: new Path()
.move(points.armholePitch)
.curve(points.armholePitchCp1, points.armholePitchCp2, points.shoulder),
d: -15
});
macro("vd", {
from: points.hips,
to: points.armhole,
x: points.hips.x + sa + 15
});
macro("vd", {
from: points.hips,
to: points.armholePitch,
x: points.hips.x + sa + 30
});
macro("vd", {
from: points.hips,
to: points.shoulder,
x: points.hips.x + sa + 45
});
macro("vd", {
from: points.hips,
to: points.neck,
x: points.hips.x + sa + 60
});
macro("ld", { from: points.neck, to: points.shoulder, d: sa + 15 });
}

View file

@ -0,0 +1,183 @@
import freesewing from "freesewing";
var sleeve = {
draft: function(pattern) {
let part = new pattern.Part();
// prettier-ignore
let {store, sa, measurements, options, Point, points, Path, paths, Snippet, snippets, final, paperless, macro} = freesewing.utils.shorthand(part);
store.set("sleeveFactor", 1);
// Sleeve center axis
points.centerCap = new Point(0, 0);
points.centerWrist = new Point(
0,
measurements.shoulderToWrist * (1 + options.sleeveLengthBonus)
);
points.centerBiceps = new Point(
0,
points.centerWrist.y -
measurements.bicepsCircumference *
(1 + options.sleevecapHeightFactor) *
store.get("sleeveFactor")
);
// Sleeve half width, limit impact of sleeveTweakFactor to 25% to avoid a too narrow sleeve
let halfWidth =
(measurements.bicepsCircumference * (1 + options.bicepsEase)) / 2;
points.leftBiceps = points.centerBiceps.shift(
180,
halfWidth * 0.75 + halfWidth * 0.25 * store.get("sleeveFactor")
);
points.rightBiceps = points.leftBiceps.flipX(points.centerBiceps);
// Pitch points
points.backPitch = new Point(
points.leftBiceps.x * options.sleevecapBackFactorX,
points.leftBiceps.y * options.sleevecapBackFactorY
);
points.frontPitch = new Point(
points.rightBiceps.x * options.sleevecapFrontFactorX,
points.rightBiceps.y * options.sleevecapFrontFactorY
);
// 4 sleevecap quadrants
// Base points
points.capQ1Base = points.frontPitch.shiftFractionTowards(
points.rightBiceps,
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.leftBiceps,
0.5
);
// Offset points
let baseOffset =
measurements.bicepsCircumference * (1 + options.bicepsEase);
points.capQ1 = points.capQ1Base.shift(
points.rightBiceps.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.leftBiceps.angle(points.backPitch) - 90,
baseOffset * options.sleevecapQ4Offset
);
// Control points
points.capQ1Cp1 = points.capQ1.shift(
points.frontPitch.angle(points.rightBiceps),
baseOffset * options.sleevecapQ1Spread1
);
points.capQ1Cp2 = points.capQ1.shift(
points.frontPitch.angle(points.rightBiceps),
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.leftBiceps.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread1
);
points.capQ4Cp2 = points.capQ4.shift(
points.leftBiceps.angle(points.backPitch),
baseOffset * options.sleevecapQ4Spread2 * -1
);
// Center cap control points
points.centerCapCp1 = points.centerCap.shift(
points.capQ3.angle(points.capQ2),
baseOffset * options.sleevecapTopSpread1
);
points.centerCapCp2 = points.centerCap.shift(
points.capQ3.angle(points.capQ2),
baseOffset * options.sleevecapTopSpread2 * -1
);
paths.test = new Path()
.move(points.centerWrist)
.line(points.centerCap)
.move(points.leftBiceps)
.line(points.rightBiceps)
.curve(points.rightBiceps, points.capQ1Cp1, points.capQ1)
.curve(points.capQ1Cp2, points.capQ2Cp1, points.capQ2)
.curve(points.capQ2Cp2, points.centerCapCp1, points.centerCap)
.curve(points.centerCapCp2, points.capQ3Cp1, points.capQ3)
.curve(points.capQ3Cp2, points.capQ4Cp1, points.capQ4)
.curve(points.capQ4Cp2, points.leftBiceps, points.leftBiceps);
//// Wrist
//$wristWidth = $model->getMeasurement('wristCircumference') + $this->getOption('cuffEase');
//$p->newPoint(31, $wristWidth / -2, $p->y(3), 'Wrist point back');
//$p->newPoint(32, $wristWidth / 2, $p->y(3), 'Wrist point front');
//// Elbow location
//$p->newPoint(33, 0, $p->y(2) + $p->distance(2, 3) / 2 - 25, 'Elbow point');
//$p->addPoint('.help1', $p->shift(33, 0, 10));
//$p->addPoint(34, $p->beamsCross(-5, 31, 33, '.help1'), 'Elbow point back side');
//$p->addPoint(35, $p->beamsCross(5, 32, 33, 34), 'Elbow point front side');
//$path = 'M 31 L -5 C -5 20 16 C 21 10 10 C 10 22 17 C 23 28 30 C 29 25 18 C 24 11 11 C 11 27 19 C 26 5 5 L 32 z';
//$p->newPath('seamline', $path, ['class' => 'fabric']);
//// Mark path for sample service
//$p->paths['seamline']->setSample(true);
//
//// Store sleevehead length
//$this->setValue('sleeveheadLength',
// $p->curveLen(-5,-5,20,16) +
// $p->curveLen(16,21,10,10) +
// $p->curveLen(10,10,22,17) +
// $p->curveLen(17,23,28,30) +
// $p->curveLen(30,29,25,18) +
// $p->curveLen(18,24,11,11) +
// $p->curveLen(11,11,27,19) +
// $p->curveLen(19,26,5,5)
//);
// Anchor point for sampling
points.gridAnchor = points.origin;
points.test = new Point(10, 10);
console.log(part);
// Final?
if (final) {
//macro("title", { at: points.title, nr: 2, title: "back" });
//snippets.armholePitchNotch = new Snippet("notch", points.armholePitch);
//if (sa) paths.sa = paths.seam.offset(sa).attr("class", "fabric sa");
}
// Paperless?
if (paperless) {
//shared.dimensions(macro, points, Path, sa);
}
return part;
}
};
export default sleeve;