diff --git a/config/software/designs.json b/config/software/designs.json index b8d1d736fc3..2f8f4978db3 100644 --- a/config/software/designs.json +++ b/config/software/designs.json @@ -434,6 +434,6 @@ "design": "Biou", "difficulty": 3, "tags": ["tops"], - "techniques": [] + "techniques": ["curvedSeam", "flatSleeve", "hem", "button"] } } diff --git a/designs/yuri/i18n/en.json b/designs/yuri/i18n/en.json index d1a56b7fbde..2f8190ec9b3 100644 --- a/designs/yuri/i18n/en.json +++ b/designs/yuri/i18n/en.json @@ -9,7 +9,10 @@ "hoodSide": "Hood side", "sleeve": "Sleeve" }, - "s": {}, + "s": { + "cutHoodCenter.t": "The hood center is not shown", + "cutHoodCenter.d": "The **Hood center** is a rectangular piece of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). The hood center not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part." + }, "o": { "hipsEase": { "t": "Hips ease", diff --git a/designs/yuri/src/back.mjs b/designs/yuri/src/back.mjs index 7c87626664a..3770acf2bb1 100644 --- a/designs/yuri/src/back.mjs +++ b/designs/yuri/src/back.mjs @@ -2,20 +2,7 @@ import { back as brianBack } from '@freesewing/brian' import { sharedDimensions } from './shared.mjs' import { hidePresets } from '@freesewing/core' -function yuriBack({ - store, - macro, - Path, - Point, - points, - paths, - complete, - paperless, - sa, - options, - measurements, - part, -}) { +function yuriBack({ store, macro, Path, Point, points, paths, sa, options, measurements, part }) { // Clear paths from Brian for (const i in paths) { if (['backArmhole', 'backCollar'].indexOf(i) === -1) delete paths[i] @@ -69,30 +56,45 @@ function yuriBack({ .close() .attr('class', 'fabric') - // Complete? - if (complete) { - macro('cutonfold', { - from: points.cbNeck, - to: points.cbBottom, - grainline: true, - }) - macro('scalebox', { at: new Point(points.armholePitch.x / 2, points.cbWaist.y) }) - if (sa) { - paths.sa = paths.hemBase - .offset(3 * sa) - .join(paths.gussetBase.offset(sa)) - .join(paths.saBase.offset(sa)) - paths.sa - .move(paths.sa.end()) - .line(points.cbNeck) - .move(paths.sa.start()) - .line(points.cbBottom) - .attr('class', 'fabric sa') - } + if (sa) { + paths.sa = paths.hemBase + .offset(3 * sa) + .join(paths.gussetBase.offset(sa)) + .join(paths.saBase.offset(sa)) + paths.sa + .move(paths.sa.end()) + .line(points.cbNeck) + .move(paths.sa.start()) + .line(points.cbBottom) + .attr('class', 'fabric sa') } - // Paperless? - if (paperless) sharedDimensions(part, 'back') + /* + * Annotations + */ + // Cutlist + store.cutlist.setCut({ cut: 1, from: 'fabric', onFold: true }) + + // Cut on fold + macro('cutonfold', { + from: points.cbNeck, + to: points.cbBottom, + grainline: true, + }) + + // Scalebox + macro('scalebox', { at: new Point(points.armholePitch.x / 2, points.cbWaist.y) }) + + // Title + macro('rmtitle') + macro('title', { + at: points.title, + nr: 2, + title: 'back', + }) + + // Dimensions + sharedDimensions(part, 'back') return part } diff --git a/designs/yuri/src/front.mjs b/designs/yuri/src/front.mjs index d1adcb1b6b8..3639614eb99 100644 --- a/designs/yuri/src/front.mjs +++ b/designs/yuri/src/front.mjs @@ -8,8 +8,6 @@ function yuriFront({ Path, points, paths, - complete, - paperless, sa, options, measurements, @@ -77,31 +75,37 @@ function yuriFront({ .close() .attr('class', 'fabric') - // Complete? - if (complete) { - macro('grainline', { - from: points.s3CollarSplit, - to: new Point(points.s3CollarSplit.x, points.bottom.y), - }) - snippets.buttonhole = new Snippet('buttonhole-start', points.button.shift(0, 25)) - .attr('data-rotate', '90') - .attr('data-scale', '2.5') - snippets.button = new Snippet( - 'button', - paths.buttonBase.shiftFractionAlong(0.146).shift(0, 30) - ).attr('data-scale', '3.3') - - if (sa) { - paths.sa = paths.hemBase - .offset(3 * sa) - .join(paths.saBase.offset(sa)) - .join(paths.buttonBase.offset(3 * sa)) - paths.sa = paths.sa.line(paths.sa.start()).close().attr('class', 'fabric sa') - } + if (sa) { + paths.sa = paths.hemBase + .offset(3 * sa) + .join(paths.saBase.offset(sa)) + .join(paths.buttonBase.offset(3 * sa)) + paths.sa = paths.sa.line(paths.sa.start()).close().attr('class', 'fabric sa') } - // Paperless? - if (paperless) sharedDimensions(part, 'front') + /* + * Annotations + */ + // Cutlist + store.cutlist.setCut({ cut: 2, from: 'fabric' }) + + // Grainline + macro('grainline', { + from: points.s3CollarSplit, + to: new Point(points.s3CollarSplit.x, points.bottom.y), + }) + + // Button(hole) + snippets.buttonhole = new Snippet('buttonhole-start', points.button.shift(0, 25)) + .attr('data-rotate', '90') + .attr('data-scale', '2.5') + snippets.button = new Snippet( + 'button', + paths.buttonBase.shiftFractionAlong(0.146).shift(0, 30) + ).attr('data-scale', '3.3') + + // Dimensions + sharedDimensions(part, 'front') return part } diff --git a/designs/yuri/src/gusset.mjs b/designs/yuri/src/gusset.mjs index b72abf1414e..4f837d5a9fa 100644 --- a/designs/yuri/src/gusset.mjs +++ b/designs/yuri/src/gusset.mjs @@ -1,19 +1,6 @@ import { back } from './back.mjs' -function yuriGusset({ - Point, - Path, - points, - paths, - Snippet, - snippets, - complete, - sa, - paperless, - macro, - store, - part, -}) { +function yuriGusset({ Point, Path, points, paths, Snippet, snippets, sa, macro, store, part }) { const w = store.get('gussetLength') points.top = new Point(0, 0) points.bottom = new Point(0, w) @@ -35,55 +22,65 @@ function yuriGusset({ paths.seam = paths.hat.join(paths.curve).close() - // Complete? - if (complete) { - macro('cutonfold', { - from: new Point(points.top.x, points.top.y + 50), - to: points.bottom, - grainline: true, - }) - macro('title', { - at: points.title, - nr: 4, - title: 'gusset', - }) - points.logo = points.title.shift(-75, 100) - snippets.logo = new Snippet('logo', points.logo) - if (sa) { - paths.saBase = new Path().move(points.right).line(points.top).hide() - paths.sa = paths.curve - .offset(3 * sa) - .join(paths.saBase.offset(sa)) - .line(points.top) - .close() - .attr('class', 'fabric sa') - } + if (sa) { + paths.saBase = new Path().move(points.right).line(points.top).hide() + paths.sa = paths.curve + .offset(3 * sa) + .join(paths.saBase.offset(sa)) + .line(points.top) + .close() + .attr('class', 'fabric sa') } - // Paperless? - if (paperless) { - macro('vd', { - from: points.top, - to: points.bottom, - x: points.top.x - sa - 15, - }) - macro('vd', { - from: new Point(0, points.right.y), - to: points.bottom, - x: 20, - }) + /* + * Annotations + */ + // Cutlist + store.cutlist.setCut({ cut: 2, from: 'fabric', onFold: true }) - macro('ld', { - from: points.top, - to: points.right, - d: sa + 15, - }) - macro('hd', { - from: new Point(0, points.right), - to: points.right, - y: points.right.y, - }) - } + // Cut on fold + macro('cutonfold', { + from: new Point(points.top.x, points.top.y + 50), + to: points.bottom, + grainline: true, + }) + + // Title + macro('title', { + at: points.title, + nr: 4, + title: 'gusset', + }) + + // Logo + points.logo = points.title.shift(-75, 100) + snippets.logo = new Snippet('logo', points.logo) + + // Dimensions + macro('vd', { + id: 'hFull', + from: points.top, + to: points.bottom, + x: points.top.x - sa - 15, + }) + macro('vd', { + id: 'hBottomToTipRight', + from: new Point(0, points.right.y), + to: points.bottom, + x: 20, + }) + macro('ld', { + id: 'lSide', + from: points.top, + to: points.right, + d: sa + 15, + }) + macro('hd', { + id: 'wFull', + from: new Point(0, points.right), + to: points.right, + y: points.right.y, + }) return part } diff --git a/designs/yuri/src/hoodcenter.mjs b/designs/yuri/src/hoodcenter.mjs index 4c9051525fb..2231b4f94c6 100644 --- a/designs/yuri/src/hoodcenter.mjs +++ b/designs/yuri/src/hoodcenter.mjs @@ -1,92 +1,79 @@ import { hoodSide } from './hoodside.mjs' -function yuriHoodCenter({ - store, - sa, - Point, - points, - Path, - paths, - complete, - paperless, - macro, - units, - part, -}) { +function yuriHoodCenter({ store, sa, Point, points, Path, paths, expand, macro, units, part }) { const width = store.get('hoodCenterWidth') - const length = complete ? width * 2.5 : store.get('hoodCenterLength') + const length = store.get('hoodCenterLength') + + if (expand) { + store.flag.preset('expandIsOn') + } else { + // Expand is off, do not draw the part but flag this to the user + store.flag.note({ + msg: `yuri:cutHoodCenter`, + replace: { + width: units(width + 2 * sa), + length: units(length + 2 * sa), + }, + suggest: { + text: 'flag:show', + icon: 'expand', + update: { + settings: ['expand', 1], + }, + }, + }) + // Also hint about expand + store.flag.preset('expandIsOff') + + return part.hide() + } + points.topLeft = new Point(0, 0) points.bottomLeft = new Point(0, width) - points.topMidLeft = new Point(width, 0) - points.bottomMidLeft = new Point(width, width) - points.topMidRight = new Point(width * 1.5, 0) - points.bottomMidRight = new Point(width * 1.5, width) points.topRight = new Point(length, 0) points.bottomRight = new Point(length, width) - if (complete) { - paths.seam = new Path() - .move(points.topMidLeft) - .line(points.topLeft) - .line(points.bottomLeft) - .line(points.bottomMidLeft) - .move(points.bottomMidRight) - .line(points.bottomRight) - .line(points.topRight) - .line(points.topMidRight) - .attr('class', 'fabric') - paths.hint = new Path() - .move(points.topMidLeft) - .line(points.topMidRight) - .move(points.bottomMidLeft) - .line(points.bottomMidRight) - .attr('class', 'fabric dashed') - } else { - paths.seam = new Path() - .move(points.topLeft) - .line(points.bottomLeft) - .line(points.bottomRight) - .line(points.topRight) - .close() - .attr('class', 'fabric') - } + paths.seam = new Path() + .move(points.topLeft) + .line(points.bottomLeft) + .line(points.bottomRight) + .line(points.topRight) + .line(points.topLeft) + .close() + .attr('class', 'fabric') - // Complete pattern? - if (complete) { - if (sa) - paths.sa = new Path() - .move(points.topLeft.shift(180, sa)) - .line(points.bottomLeft.shift(180, sa)) - .line(points.bottomLeft.shift(-90, sa)) - .line(points.bottomRight.shift(-90, sa)) - .line(points.bottomRight.shift(0, sa)) - .line(points.topRight.shift(0, sa)) - .line(points.topRight.shift(90, sa)) - .line(points.topLeft.shift(90, sa)) - .close() - .attr('class', 'fabric sa') - points.title = points.bottomLeft.shiftFractionTowards(points.topRight, 0.5) - macro('title', { at: points.title, nr: 6, title: 'hoodCenter' }) - macro('grainline', { - from: points.topLeft.shift(-90, width / 2), - to: points.topRight.shift(-90, width / 2), - }) - // Always include this dimension as we don't print the entire part - macro('hd', { - from: points.bottomLeft, - to: points.bottomRight, - y: points.bottomRight.y + sa + 15, - text: units(store.get('hoodCenterLength')), - }) - // Paperless? - if (paperless) { - macro('vd', { - from: points.bottomRight, - to: points.topRight, - x: points.topRight.x + sa + 15, - }) - } - } + if (sa) paths.sa = paths.seam.offset(sa).addClass('fabric sa') + + /* + * Annotations + */ + // Cutlist + store.cutlist.setCut({ cut: 2, from: 'fabric' }) + + // Title + points.title = points.bottomLeft.shiftFractionTowards(points.topRight, 0.5) + macro('title', { at: points.title, nr: 6, title: 'hoodCenter' }) + + // Grainline + macro('grainline', { + from: points.topLeft.shift(-90, width / 2), + to: points.topRight.shift(-90, width / 2), + }) + + // Dimensions + macro('hd', { + id: 'wFull', + from: points.bottomLeft, + to: points.bottomRight, + y: points.bottomRight.y + sa + 15, + text: units(store.get('hoodCenterLength')), + }) + macro('vd', { + id: 'hFull', + from: points.bottomRight, + to: points.topRight, + x: points.topRight.x + sa + 15, + }) return part } diff --git a/designs/yuri/src/hoodside.mjs b/designs/yuri/src/hoodside.mjs index 76f24256c68..ffc4a52104d 100644 --- a/designs/yuri/src/hoodside.mjs +++ b/designs/yuri/src/hoodside.mjs @@ -11,8 +11,6 @@ function yuriHoodSide({ Snippet, snippets, measurements, - complete, - paperless, macro, part, }) { @@ -73,79 +71,91 @@ function yuriHoodSide({ .length() ) - // Complete pattern? - if (complete) { - if (sa) { - // Reversing this curve sidesteps a bezierjs edge case - paths.sa = paths.seam - .reverse() - .offset(sa * -1) - .attr('class', 'fabric sa') - } - points.title = points.hoodTop.shift(-90, 50) - macro('title', { at: points.title, nr: 5, title: 'hoodSide' }) - points.logo = points.title.shift(-90, 60) - snippets.logo = new Snippet('logo', points.logo) - macro('grainline', { - from: points.shoulderNotch, - to: points.hoodTop, - }) - } + if (sa) + paths.sa = paths.seam + .reverse() // Reversing this curve sidesteps a bezierjs edge case + .offset(sa * -1) + .addClass('fabric sa') - // Paperless? - if (paperless) { - const neckSeam = new Path() - .move(points.neckEdge) - .curve(points.neckEdgeCp2, points.frontEdgeCp1, points.frontEdge) - .split(points.shoulderNotch) - const centralSeam = new Path() - .move(points.hoodRim) - .curve(points.hoodRim, points.hoodTopCp1, points.hoodTop) - .curve(points.hoodTopCp2, points.neckEdge, points.neckEdge) - .reverse() - const openingSeam = new Path() - .move(points.neckRoll) - .curve(points.neckRollCp2, points.hoodRimCp, points.hoodRim) + /* + * Annotations + */ + // Cutlist + store.cutlist.setCut({ cut: 4, from: 'fabric' }) - macro('pd', { - path: neckSeam[0], - d: sa + 15, - }) - macro('pd', { - path: neckSeam[1], - d: sa + 15, - }) - macro('pd', { - path: centralSeam, - d: sa * -1 - 15, - }) - macro('hd', { - from: points.neckEdge, - to: points.frontEdge, - y: points.frontEdge.y + sa + 30, - }) - macro('hd', { - from: centralSeam.edge('left'), - to: points.frontEdge, - y: points.frontEdge.y + sa + 45, - }) - const openingEdge = openingSeam.edge('left') - macro('hd', { - from: openingEdge, - to: points.frontEdge, - y: openingEdge.y, - }) - macro('vd', { - from: points.frontEdge, - to: points.hoodRim, - x: points.hoodRim.x + sa + 15, - }) - macro('vd', { - from: points.frontEdge, - to: points.hoodTop, - x: points.hoodRim.x + sa + 30, - }) - } + // TItle + points.title = points.hoodTop.shift(-90, 50) + macro('title', { at: points.title, nr: 5, title: 'hoodSide' }) + + // Logo + points.logo = points.title.shift(-90, 60) + snippets.logo = new Snippet('logo', points.logo) + + // Grainline + macro('grainline', { + from: points.shoulderNotch, + to: points.hoodTop, + }) + + // Dimensions + const neckSeam = new Path() + .move(points.neckEdge) + .curve(points.neckEdgeCp2, points.frontEdgeCp1, points.frontEdge) + .split(points.shoulderNotch) + const centralSeam = new Path() + .move(points.hoodRim) + .curve(points.hoodRim, points.hoodTopCp1, points.hoodTop) + .curve(points.hoodTopCp2, points.neckEdge, points.neckEdge) + .reverse() + const openingSeam = new Path() + .move(points.neckRoll) + .curve(points.neckRollCp2, points.hoodRimCp, points.hoodRim) + macro('pd', { + id: 'lNeckBackToNotch', + path: neckSeam[0], + d: sa + 15, + }) + macro('pd', { + id: 'lNotchToNeckFront', + path: neckSeam[1], + d: sa + 15, + }) + macro('pd', { + id: 'lCentralSeam', + path: centralSeam, + d: sa * -1 - 15, + }) + macro('hd', { + id: 'wAtNeck', + from: points.neckEdge, + to: points.frontEdge, + y: points.frontEdge.y + sa + 30, + }) + macro('hd', { + id: 'wFull', + from: centralSeam.edge('left'), + to: points.frontEdge, + y: points.frontEdge.y + sa + 45, + }) + const openingEdge = openingSeam.edge('left') + macro('hd', { + id: 'wOpeningDepth', + from: openingEdge, + to: points.frontEdge, + y: openingEdge.y, + }) + macro('vd', { + id: 'hToOpeningTop', + from: points.frontEdge, + to: points.hoodRim, + x: points.hoodRim.x + sa + 15, + }) + macro('vd', { + id: 'hFull', + from: points.frontEdge, + to: points.hoodTop, + x: points.hoodRim.x + sa + 30, + }) return part } diff --git a/designs/yuri/src/shared.mjs b/designs/yuri/src/shared.mjs index 0030df310c6..069a8998933 100644 --- a/designs/yuri/src/shared.mjs +++ b/designs/yuri/src/shared.mjs @@ -1,5 +1,5 @@ export const sharedDimensions = function (part, s) { - let { macro, Point, points, sa } = part.shorthand() + const { macro, Point, points, sa } = part.shorthand() if (s === 'front') { points.cHem = points.cfBottom @@ -10,17 +10,20 @@ export const sharedDimensions = function (part, s) { } macro('hd', { + id: 'wAtHem', from: points.cHem, to: points.bottom, y: points.cHem.y + 3 * sa + 15, }) macro('hd', { + id: 'wHemToArmhole', from: points.armhole, to: points.bottom, y: points.bottom.y + 10, }) if (s === 'front') { macro('ld', { + id: 'wCollarToArmholePitch', from: new Point(points.s3CollarSplit.x, points.armholePitch.y), to: points.armholePitch, }) @@ -32,16 +35,19 @@ export const sharedDimensions = function (part, s) { } if (s === 'back') { macro('hd', { + id: 'wCbNeckToHps', from: points.cNeck, to: points.neck, y: points.neck.y - sa - 15, }) macro('hd', { + id: 'wCbNeckToShoulder', from: points.cNeck, to: points.shoulder, y: points.neck.y - sa - 30, }) macro('hd', { + id: 'wFull', from: points.cNeck, to: points.armhole, y: points.neck.y - sa - 45, @@ -49,68 +55,81 @@ export const sharedDimensions = function (part, s) { } if (s === 'front') { macro('hd', { + id: 'wEdgeToCollar', from: points.button, to: points.s3CollarSplit, y: points.s3CollarSplit.y, }) macro('vd', { + id: 'hEdgeToCollar', from: points.button, to: points.s3CollarSplit, x: points.button.x, }) macro('vd', { + id: 'hShoulderToCollar', from: points.s3CollarSplit, to: points.s3ArmholeSplit, x: points.s3ArmholeSplit.x, }) } macro('ld', { + id: 'lShoulderSeam', from: points.neck, to: points.shoulder, d: -15, }) macro('vd', { + id: 'hHem', from: points.cHem, to: points.bottom, x: points.bottom.x + 10, }) macro('vd', { + id: 'hHemToArmhole', from: points.bottom, to: points.armhole, x: points.armhole.x + sa + 15, }) macro('vd', { + id: 'hArmholeToArmholePitch', from: points.armhole, to: points.armholePitch, x: points.armhole.x + sa + 15, }) macro('vd', { + id: 'hArmholePitchToShoulder', from: points.armholePitch, to: points.shoulder, x: points.armhole.x + sa + 15, }) macro('vd', { from: points.armhole, + id: 'hArmholeToShoulder', to: points.shoulder, x: points.armhole.x + sa + 30, }) macro('vd', { + id: 'hArmholeToHps', from: points.armhole, to: points.neck, x: points.armhole.x + sa + 45, }) if (s === 'back') { macro('vd', { + id: 'hCbNeckToHps', from: points.cNeck, to: points.neck, x: points.cNeck.x - 15, }) macro('vd', { + id: 'hHemToCbHeck', from: points.cHem, to: points.cNeck, x: points.cNeck.x - 15, }) macro('vd', { + id: 'hFull', from: points.cHem, to: points.neck, x: points.cNeck.x - 30, diff --git a/designs/yuri/src/sleeve.mjs b/designs/yuri/src/sleeve.mjs index e24f8723f88..03e4cb9b6ec 100644 --- a/designs/yuri/src/sleeve.mjs +++ b/designs/yuri/src/sleeve.mjs @@ -1,11 +1,9 @@ import { sleeve as brianSleeve } from '@freesewing/brian' import { hidePresets } from '@freesewing/core' -function yuriSleeve({ Point, Path, points, paths, complete, sa, paperless, macro, part }) { - // Clear paths from Brian, but keep sleevecap - for (let p of Object.keys(paths)) { - if (p !== 'sleevecap') delete paths[p] - } +function yuriSleeve({ Path, points, paths, sa, part }) { + // This sleeve is identical to Brian, but has more hem allowance + // Which is kinda hard to patch in so we re-create the paths // Paths paths.saBase = new Path() @@ -23,45 +21,13 @@ function yuriSleeve({ Point, Path, points, paths, complete, sa, paperless, macro paths.seam = paths.saBase.join(paths.hemBase).close().setClass('fabric') - // Complete? - if (complete) { - macro('grainline', { - from: new Point(0, points.wristLeft.y), - to: new Point(0, points.backPitch.y), - }) - if (sa) { - paths.sa = paths.saBase - .clone() - .offset(sa) - .join(paths.hemBase.offset(3 * sa)) - .close() - paths.sa.attr('class', 'fabric sa') - } - } - - // Paperless? - if (paperless) { - const hemSa = 3 * sa - macro('hd', { - from: points.wristLeft, - to: points.wristRight, - y: points.wristLeft.y + hemSa + 15, - }) - macro('hd', { - from: points.bicepsLeft, - to: points.bicepsRight, - y: points.sleeveTip.y - sa - 15, - }) - 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, - }) + if (sa) { + paths.sa = paths.saBase + .clone() + .offset(sa) + .join(paths.hemBase.offset(3 * sa)) + .close() + paths.sa.attr('class', 'fabric sa') } return part