2022-09-03 15:41:48 +02:00
|
|
|
import { constructMainDart, shapeSideSeam, dartPath } from './shared.mjs'
|
|
|
|
import { front as brianFront } from '@freesewing/brian'
|
2023-03-08 12:12:13 -06:00
|
|
|
import { hidePresets } from '@freesewing/core'
|
2022-09-03 15:41:48 +02:00
|
|
|
import {
|
|
|
|
frontOverlap,
|
|
|
|
necklineDrop,
|
|
|
|
frontStyle,
|
|
|
|
frontInset,
|
|
|
|
shoulderInset,
|
|
|
|
neckInset,
|
|
|
|
hemStyle,
|
|
|
|
hemRadius,
|
|
|
|
pocketWidth,
|
|
|
|
pocketAngle,
|
|
|
|
pocketLocation,
|
|
|
|
frontScyeDart,
|
|
|
|
buttons,
|
|
|
|
waistEase,
|
|
|
|
hipsEase,
|
2022-09-28 22:50:22 +02:00
|
|
|
armholeDepthFactor,
|
|
|
|
chestEase,
|
|
|
|
lengthBonus,
|
|
|
|
acrossBackFactor,
|
|
|
|
frontArmholeDeeper,
|
2023-04-30 08:16:49 -07:00
|
|
|
bicepsEase,
|
|
|
|
collarEase,
|
|
|
|
cuffEase,
|
|
|
|
shoulderEase,
|
|
|
|
s3Collar,
|
|
|
|
s3Armhole,
|
|
|
|
shoulderSlopeReduction,
|
|
|
|
backNeckCutout,
|
2025-05-18 09:43:40 +00:00
|
|
|
legacyWaistHips,
|
2022-09-03 15:41:48 +02:00
|
|
|
} from './options.mjs'
|
|
|
|
|
2022-09-11 08:14:04 -07:00
|
|
|
function wahidFront({
|
|
|
|
points,
|
|
|
|
Point,
|
|
|
|
paths,
|
|
|
|
Path,
|
|
|
|
measurements,
|
|
|
|
options,
|
|
|
|
utils,
|
|
|
|
macro,
|
|
|
|
snippets,
|
|
|
|
Snippet,
|
|
|
|
complete,
|
|
|
|
sa,
|
|
|
|
store,
|
|
|
|
part,
|
|
|
|
}) {
|
2019-02-17 17:21:39 +01:00
|
|
|
// Cleanup from Brian
|
2019-08-03 15:03:33 +02:00
|
|
|
for (let i of Object.keys(paths)) delete paths[i]
|
|
|
|
delete snippets.armholePitchNotch
|
2025-05-18 09:43:40 +00:00
|
|
|
|
|
|
|
if (!options.legacyWaistHips) {
|
|
|
|
// Use actual measurements to set waist and hips points
|
|
|
|
points.waist = new Point((measurements.waist * (1 + options.waistEase)) / 4, points.cfWaist.y)
|
|
|
|
points.hips = new Point((measurements.hips * (1 + options.hipsEase)) / 4, points.cfHips.y)
|
|
|
|
points.hem = new Point(points.hips.x, points.cfHem.y)
|
|
|
|
}
|
|
|
|
|
2019-02-17 17:21:39 +01:00
|
|
|
// Neck cutout
|
|
|
|
points.closureTop = new Point(
|
2020-06-28 12:26:05 +02:00
|
|
|
measurements.chest * options.frontOverlap * -1,
|
2019-02-17 20:42:05 +01:00
|
|
|
points.waist.y * options.necklineDrop
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
|
|
|
if (options.frontStyle === 'classic')
|
|
|
|
points.closureTopCp1 = new Point(points.neck.x, (points.waist.y * options.necklineDrop) / 2)
|
2019-02-17 20:42:05 +01:00
|
|
|
else {
|
2019-08-03 15:03:33 +02:00
|
|
|
points.closureTopCp1 = new Point(points.neck.x, points.closureTop.y)
|
2019-02-17 20:42:05 +01:00
|
|
|
}
|
2019-02-17 17:21:39 +01:00
|
|
|
// Front inset
|
2019-08-03 15:03:33 +02:00
|
|
|
let shoulderLen = points.shoulder.dist(points.neck)
|
|
|
|
let frontInset = shoulderLen * options.frontInset
|
|
|
|
points.armholePitch = points.armholePitch.shift(180, frontInset)
|
|
|
|
points.armholePitchCp1 = points.armholePitchCp1.shift(180, frontInset)
|
|
|
|
points.armholePitchCp2 = points.armholePitchCp2.shift(180, frontInset)
|
|
|
|
points.armholeHollow = points.armholeHollow.shift(180, frontInset / 2)
|
|
|
|
points.armholeHollowCp2 = points.armholeHollowCp2.shift(180, frontInset / 2)
|
|
|
|
points.armholeHollowCp1 = points.armholeHollowCp1.shift(180, frontInset / 2)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Shoulder inset
|
2019-08-03 15:03:33 +02:00
|
|
|
points.shoulder = points.shoulder.shiftTowards(points.neck, shoulderLen * options.shoulderInset)
|
2019-02-17 17:21:39 +01:00
|
|
|
points.shoulderCp1 = points.shoulderCp1.shift(
|
|
|
|
points.shoulder.angle(points.neck),
|
|
|
|
shoulderLen * options.shoulderInset
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Neck inset
|
2019-08-03 15:03:33 +02:00
|
|
|
points.neck = points.neck.shiftTowards(points.shoulder, shoulderLen * options.neckInset)
|
|
|
|
points.neckCp2 = points.neck.shift(points.shoulder.angle(points.neck) + 90, shoulderLen * 0.2)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Construct main dart
|
2019-08-03 15:03:33 +02:00
|
|
|
constructMainDart(part)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Shape side seam
|
2019-08-03 15:03:33 +02:00
|
|
|
shapeSideSeam(part)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Hem
|
2019-08-03 15:03:33 +02:00
|
|
|
if (options.hemStyle === 'classic') {
|
2019-02-17 17:21:39 +01:00
|
|
|
// Construct cutaway
|
2019-08-03 15:03:33 +02:00
|
|
|
let cutaway = points.closureTop.dx(points.hem) / 4
|
|
|
|
points.closureBottom = new Point(points.closureTop.x, points.hem.y - cutaway / 2)
|
|
|
|
points.hemTip = new Point(points.closureBottom.x + cutaway, points.closureBottom.y + cutaway)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Shifting hem point to have a continious hem curve to work from
|
2019-08-03 15:03:33 +02:00
|
|
|
let shift = points.dartHemLeft.dx(points.dartHemRight)
|
|
|
|
points.splitHem = points.hem.shift(180, shift)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Split hem curve on left side of dart
|
|
|
|
points.hemSplit = utils.curveIntersectsX(
|
|
|
|
points.hemTip,
|
|
|
|
points.hemTip,
|
|
|
|
points.dartHemLeft,
|
|
|
|
points.splitHem,
|
|
|
|
points.dartHemLeft.x
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Split the hem curve
|
|
|
|
let [c1, c2] = utils.splitCurve(
|
|
|
|
points.hemTip,
|
|
|
|
points.hemTip,
|
|
|
|
points.dartHemLeft,
|
|
|
|
points.splitHem,
|
|
|
|
points.hemSplit
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
|
|
|
points.splitDartHemLeftCp1 = c1.cp2
|
|
|
|
points.splitDartHemRightCp2 = c2.cp1.shift(0, shift)
|
|
|
|
points.splitHemCp1 = c2.cp2.shift(0, shift)
|
2019-02-17 17:21:39 +01:00
|
|
|
points.splitDartHemLeft = utils.curveIntersectsX(
|
|
|
|
points.hemTip,
|
|
|
|
points.hemTip,
|
|
|
|
points.dartHemLeft,
|
|
|
|
points.splitHem,
|
|
|
|
points.dartHemLeft.x
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
|
|
|
points.splitDartHemRight = points.splitDartHemLeft.shift(0, shift)
|
|
|
|
points.lastButton = new Point(0, points.closureBottom.y)
|
2020-07-23 12:30:26 +02:00
|
|
|
} else if (options.hemStyle === 'rounded') {
|
2019-08-03 15:03:33 +02:00
|
|
|
points.closureBottom = new Point(points.closureTop.x, points.hem.y)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Draw rounded hem
|
2020-06-28 12:26:05 +02:00
|
|
|
let radius = measurements.hips * options.hemRadius
|
2019-02-17 17:21:39 +01:00
|
|
|
// Avoid radius extending beyond the dart
|
|
|
|
if (radius > points.closureTop.dx(points.dartHemLeft))
|
2019-08-03 15:03:33 +02:00
|
|
|
radius = points.closureTop.dx(points.dartHemLeft)
|
2023-09-28 13:27:00 +02:00
|
|
|
// Macro will return the auto-generated IDs
|
|
|
|
const ids = macro('round', {
|
|
|
|
id: 'hem',
|
2019-02-17 17:21:39 +01:00
|
|
|
from: points.closureTop,
|
|
|
|
to: points.hem,
|
|
|
|
via: points.closureBottom,
|
|
|
|
radius,
|
2019-08-03 15:03:33 +02:00
|
|
|
})
|
2023-09-28 13:27:00 +02:00
|
|
|
// Create points from them with easy names
|
|
|
|
for (const id of ['start', 'cp1', 'cp2', 'end']) {
|
|
|
|
points[`round${utils.capitalize(id)}`] = points[ids.points[id]].copy()
|
|
|
|
}
|
2019-08-03 15:03:33 +02:00
|
|
|
points.lastButton = new Point(0, points.roundStart.y)
|
2023-09-21 09:07:26 +02:00
|
|
|
points.hemTip = points.roundEnd.copy()
|
2020-07-23 12:30:26 +02:00
|
|
|
} else {
|
|
|
|
points.closureBottom = new Point(points.closureTop.x, points.hem.y)
|
2023-09-21 09:07:26 +02:00
|
|
|
points.lastButton = new Point(0, points.hem.y * 0.96)
|
|
|
|
points.hemTip = points.hem.copy()
|
2019-02-17 17:21:39 +01:00
|
|
|
}
|
2021-02-07 10:12:44 +01:00
|
|
|
// We use the roundEnd and roundStart points later on
|
|
|
|
// let's make sure they exist even if the hem is not rounded
|
|
|
|
// (essentially a rounded hem with radius zero
|
|
|
|
if (!points.roundStart) points.roundStart = points.closureBottom.clone()
|
|
|
|
if (!points.roundEnd) points.roundEnd = points.closureBottom.clone()
|
2019-02-17 20:42:05 +01:00
|
|
|
// Add dart start and end point regardless of style or front or back
|
2019-08-03 15:03:33 +02:00
|
|
|
points.dartStart = options.hemStyle === 'classic' ? points.splitDartHemLeft : points.dartHemLeft
|
|
|
|
points.dartEnd = options.hemStyle === 'classic' ? points.splitDartHemRight : points.dartHemRight
|
2019-02-17 17:21:39 +01:00
|
|
|
// Pockets
|
2020-06-28 12:26:05 +02:00
|
|
|
let pw = measurements.hips * options.pocketWidth // Pocket width
|
2019-08-03 15:03:33 +02:00
|
|
|
let pwh = pw * options.weltHeight // Pocket welt height
|
|
|
|
let pwvh = pwh / Math.cos(utils.deg2rad(options.pocketAngle)) // Pocket welt vertical height
|
2019-02-17 17:21:39 +01:00
|
|
|
points.pocketTopMid = points.dartWaistCenter.shiftFractionTowards(
|
|
|
|
points.dartHipCenter,
|
|
|
|
options.pocketLocation
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
2019-02-17 17:21:39 +01:00
|
|
|
points.pocketTopMidLeft = utils.curveIntersectsY(
|
|
|
|
points.dartWaistLeft,
|
|
|
|
points.dartWaistLeftCpBottom,
|
|
|
|
points.dartHipLeftCpTop,
|
|
|
|
points.dartHipLeft,
|
|
|
|
points.pocketTopMid.y
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
2019-02-17 17:21:39 +01:00
|
|
|
points.pocketBottomMidLeft = utils.curveIntersectsY(
|
|
|
|
points.dartWaistLeft,
|
|
|
|
points.dartWaistLeftCpBottom,
|
|
|
|
points.dartHipLeftCpTop,
|
|
|
|
points.dartHipLeft,
|
|
|
|
points.pocketTopMid.y + pwvh
|
2019-08-03 15:03:33 +02:00
|
|
|
)
|
2025-05-18 09:43:40 +00:00
|
|
|
// The pocket can start out offset from the horizontal/vertical.
|
|
|
|
const startingAngleOffset = points.pocketBottomMidLeft.angle(points.pocketTopMidLeft) - 90
|
|
|
|
points.pocketTopLeft = points.pocketTopMidLeft.shift(
|
|
|
|
180 + options.pocketAngle + startingAngleOffset,
|
|
|
|
pw / 2
|
|
|
|
)
|
|
|
|
points.pocketBottomLeft = points.pocketTopLeft.shift(
|
|
|
|
options.pocketAngle - 90 + startingAngleOffset,
|
|
|
|
pwh
|
|
|
|
)
|
2019-08-03 15:03:33 +02:00
|
|
|
points.pocketTopMidRight = points.pocketTopMidLeft.flipX(points.pocketTopMid)
|
|
|
|
points.pocketBottomMidRight = points.pocketBottomMidLeft.flipX(points.pocketTopMid)
|
2025-05-18 09:43:40 +00:00
|
|
|
points.pocketTopRight = points.pocketTopMidRight.shift(
|
|
|
|
options.pocketAngle - startingAngleOffset,
|
|
|
|
pw / 2
|
|
|
|
)
|
|
|
|
points.pocketBottomRight = points.pocketTopRight.shift(
|
|
|
|
options.pocketAngle - 90 - startingAngleOffset,
|
|
|
|
pwh
|
|
|
|
)
|
2019-02-18 17:52:34 +01:00
|
|
|
// Store pocket bag length
|
2019-08-03 15:03:33 +02:00
|
|
|
store.set('pocketBagLength', points.pocketTopMid.dy(points.cfHem) * 0.75)
|
2020-03-16 11:08:28 +01:00
|
|
|
if (options.frontScyeDart) {
|
2025-05-18 09:43:40 +00:00
|
|
|
// Save original armhole width so we can restore it later
|
|
|
|
const original_chest_width = points.cfArmhole.dist(points.armhole)
|
2020-03-16 11:08:28 +01:00
|
|
|
// Front scye dart
|
|
|
|
points._dartWidth = points.dartTop.shiftFractionTowards(
|
|
|
|
points.armholeHollow.rotate(options.frontScyeDart, points.dartTop),
|
|
|
|
1.5
|
|
|
|
)
|
|
|
|
points.armholeHollowTop = new Path()
|
|
|
|
.move(points.armholeHollow)
|
|
|
|
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
|
|
|
.intersects(new Path().move(points.dartTop).line(points._dartWidth))
|
|
|
|
.pop()
|
|
|
|
// Adjust control point
|
|
|
|
points.armholeHollowCp2 = points.armholeHollowCp2.shift(
|
|
|
|
points.armholeHollow.angle(points.armholeHollowTop),
|
|
|
|
points.armholeHollow.dist(points.armholeHollowTop)
|
|
|
|
)
|
|
|
|
// Rotate front scye dart into front dart
|
|
|
|
let toRotate = [
|
|
|
|
'dartWaistRightCpTop',
|
|
|
|
'dartWaistRight',
|
|
|
|
'dartWaistRightCpBottom',
|
|
|
|
'dartHipRightCpTop',
|
|
|
|
'dartHipRight',
|
|
|
|
'dartHemRight',
|
|
|
|
'splitDartHemRight',
|
|
|
|
'splitDartHemRightCp2',
|
|
|
|
'splitHemCp1',
|
|
|
|
'hem',
|
|
|
|
'hips',
|
|
|
|
'hipsCp2',
|
|
|
|
'waistCp1',
|
|
|
|
'waist',
|
|
|
|
'waistCp2',
|
|
|
|
'armhole',
|
|
|
|
'armholeCp2',
|
|
|
|
'armholeHollow',
|
|
|
|
'pocketTopMidRight',
|
|
|
|
'pocketBottomMidRight',
|
|
|
|
'pocketTopRight',
|
|
|
|
'pocketBottomRight',
|
2021-04-24 10:16:31 +02:00
|
|
|
'dartEnd',
|
2020-03-16 11:08:28 +01:00
|
|
|
]
|
|
|
|
for (let p of toRotate) {
|
|
|
|
if (typeof points[p] !== 'undefined')
|
|
|
|
points[p] = points[p].rotate(options.frontScyeDart, points.dartTop)
|
|
|
|
}
|
2025-05-18 09:43:40 +00:00
|
|
|
if (!options.legacyWaistHips) {
|
|
|
|
// Set armhole back to original width
|
|
|
|
points.armhole = points.cfArmhole.shiftTowards(points.armhole, original_chest_width)
|
|
|
|
}
|
2020-03-16 11:08:28 +01:00
|
|
|
points.armholeHollowCp1 = points.armholeHollowCp2.rotate(180, points.armholeHollow)
|
2019-02-17 17:21:39 +01:00
|
|
|
}
|
2020-04-18 17:35:25 +02:00
|
|
|
// Facing/Lining boundary (flb)
|
|
|
|
points.flbTop = points.neck.shiftFractionTowards(points.shoulder, 0.5)
|
2022-07-09 16:49:30 +02:00
|
|
|
points.flbCp = points.dartTop.shift(-90, points.armholePitch.dy(points.flbTop) / 2)
|
2022-08-13 21:09:23 +00:00
|
|
|
points.flbCpTop = points.flbTop
|
|
|
|
.shiftTowards(points.neck, points.flbTop.dy(points.armholePitch))
|
|
|
|
.rotate(90, points.flbTop)
|
2019-02-17 17:21:39 +01:00
|
|
|
// Seam line
|
2019-08-03 15:03:33 +02:00
|
|
|
delete paths.cutonfold
|
|
|
|
delete paths.saBase
|
|
|
|
delete paths.sa
|
2019-02-17 20:42:05 +01:00
|
|
|
paths.saBase = new Path()
|
|
|
|
.move(points.hem)
|
2019-02-17 17:21:39 +01:00
|
|
|
.line(points.hips)
|
|
|
|
.curve(points.hipsCp2, points.waistCp1, points.waist)
|
|
|
|
.curve_(points.waistCp2, points.armhole)
|
|
|
|
.curve(points.armholeCp2, points.armholeHollowCp1, points.armholeHollow)
|
|
|
|
.curve(points.armholeHollowCp2, points.armholePitchCp1, points.armholePitch)
|
|
|
|
.curve(points.armholePitchCp2, points.shoulderCp1, points.shoulder)
|
|
|
|
.line(points.neck)
|
2019-08-03 15:03:33 +02:00
|
|
|
.curve(points.neckCp2, points.closureTopCp1, points.closureTop)
|
|
|
|
if (options.hemStyle === 'classic') {
|
2019-02-17 17:21:39 +01:00
|
|
|
paths.saBase
|
|
|
|
.line(points.closureBottom)
|
|
|
|
.line(points.hemTip)
|
2019-08-03 15:03:33 +02:00
|
|
|
._curve(points.splitDartHemLeftCp1, points.splitDartHemLeft)
|
2019-02-17 20:42:05 +01:00
|
|
|
paths.hemBase = new Path()
|
|
|
|
.move(points.dartEnd)
|
2019-08-03 15:03:33 +02:00
|
|
|
.curve(points.splitDartHemRightCp2, points.splitHemCp1, points.hem)
|
2020-07-23 12:30:26 +02:00
|
|
|
} else if (options.hemStyle === 'rounded') {
|
2019-02-17 17:21:39 +01:00
|
|
|
paths.saBase
|
|
|
|
.line(points.roundStart)
|
|
|
|
.curve(points.roundCp1, points.roundCp2, points.roundEnd)
|
2019-08-03 15:03:33 +02:00
|
|
|
.line(points.dartHemLeft)
|
|
|
|
paths.hemBase = new Path().move(points.dartEnd).line(points.hem)
|
2020-07-23 12:30:26 +02:00
|
|
|
} else {
|
|
|
|
paths.saBase.line(points.closureBottom).line(points.dartHemLeft)
|
|
|
|
paths.hemBase = new Path().move(points.dartEnd).line(points.hem)
|
2019-02-17 17:21:39 +01:00
|
|
|
}
|
2019-08-03 15:03:33 +02:00
|
|
|
paths.dart = dartPath(part)
|
2020-04-18 17:35:25 +02:00
|
|
|
paths.seam = paths.saBase.join(paths.dart).join(paths.hemBase).close().attr('class', 'fabric')
|
2023-09-21 09:07:26 +02:00
|
|
|
if (sa)
|
|
|
|
paths.sa = paths.saBase.offset(sa).join(paths.hemBase.offset(sa)).close().addClass('fabric sa')
|
2022-09-18 17:01:19 +02:00
|
|
|
paths.saBase.hide()
|
|
|
|
paths.hemBase.hide()
|
|
|
|
paths.dart.hide()
|
2023-09-21 09:07:26 +02:00
|
|
|
|
2019-02-17 17:21:39 +01:00
|
|
|
if (complete) {
|
2020-04-18 16:18:11 +02:00
|
|
|
paths.pocket = new Path()
|
|
|
|
.move(points.pocketTopMidLeft)
|
|
|
|
.line(points.pocketTopLeft)
|
|
|
|
.line(points.pocketBottomLeft)
|
|
|
|
.line(points.pocketBottomMidLeft)
|
|
|
|
.move(points.pocketBottomMidRight)
|
|
|
|
.line(points.pocketBottomRight)
|
|
|
|
.line(points.pocketTopRight)
|
|
|
|
.line(points.pocketTopMidRight)
|
2023-09-21 09:07:26 +02:00
|
|
|
.addClass('fabric dashed')
|
2019-02-17 17:21:39 +01:00
|
|
|
// Facing/Lining boundary (flb)
|
2023-09-21 09:07:26 +02:00
|
|
|
paths.flb = new Path()
|
2019-02-17 17:21:39 +01:00
|
|
|
.move(points.dartTop)
|
2022-07-09 16:49:30 +02:00
|
|
|
.curve(points.flbCp, points.flbCpTop, points.flbTop)
|
2023-09-21 09:07:26 +02:00
|
|
|
.addClass('lining help')
|
|
|
|
macro('banner', {
|
|
|
|
id: 'flbFacing',
|
|
|
|
path: paths.flb,
|
|
|
|
text: 'wahid:flbFacingSide',
|
|
|
|
classes: 'text-sm fill-fabric center',
|
|
|
|
})
|
|
|
|
macro('banner', {
|
|
|
|
id: 'flbLining',
|
|
|
|
path: paths.flb,
|
|
|
|
text: 'wahid:flbLiningSide',
|
|
|
|
dy: 7,
|
|
|
|
classes: 'text-sm fill-lining center',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Annotations
|
|
|
|
*/
|
|
|
|
// Cutlist
|
|
|
|
store.cutlist.setCut({ cut: 2, from: 'fabric' })
|
2025-05-18 13:34:06 +00:00
|
|
|
store.cutlist.addCut({ cut: 2, from: 'interfacing' })
|
2023-09-21 09:07:26 +02:00
|
|
|
|
|
|
|
// Buttons
|
|
|
|
points.button1 = new Point(0, points.closureTop.y + 10)
|
|
|
|
let delta = points.button1.dist(points.lastButton) / (options.buttons - 1)
|
|
|
|
for (let i = 1; i <= options.buttons; i++) {
|
|
|
|
points['button' + i] = points.button1.shift(-90, delta * (i - 1))
|
|
|
|
snippets['button' + i] = new Snippet('button', points['button' + i])
|
|
|
|
snippets['buttonhole' + i] = new Snippet('buttonhole', points['button' + i]).attr(
|
|
|
|
'data-rotate',
|
|
|
|
90
|
|
|
|
)
|
|
|
|
}
|
2022-08-13 21:09:23 +00:00
|
|
|
|
2023-09-21 09:07:26 +02:00
|
|
|
// Grainline
|
|
|
|
macro('grainline', {
|
|
|
|
to: points.neck,
|
|
|
|
from: new Point(points.neck.x, points.cfHem.y),
|
|
|
|
})
|
2022-08-16 16:11:47 +00:00
|
|
|
|
2023-09-21 09:07:26 +02:00
|
|
|
// Title
|
|
|
|
macro('title', {
|
|
|
|
at: points.flbCpTop,
|
2024-03-12 13:58:38 +01:00
|
|
|
title: 'front',
|
2023-09-21 09:07:26 +02:00
|
|
|
nr: 1,
|
|
|
|
align: 'center',
|
|
|
|
})
|
|
|
|
|
|
|
|
// Dimensions
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wFrontEdgeToHps',
|
|
|
|
from: points.closureTop,
|
|
|
|
to: points.neck,
|
|
|
|
y: points.neck.y - 15 - sa,
|
|
|
|
})
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wFrontEdgeToShoulder',
|
|
|
|
from: points.closureTop,
|
|
|
|
to: points.shoulder,
|
|
|
|
y: points.neck.y - 30 - sa,
|
|
|
|
})
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wFrontEdgeToArmhole',
|
|
|
|
from: points.closureTop,
|
|
|
|
to: points.armhole,
|
|
|
|
y: points.neck.y - 45 - sa,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lShoulderSeam',
|
|
|
|
from: points.neck,
|
|
|
|
to: points.shoulder,
|
|
|
|
d: 15 + sa,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lHpsToFlb',
|
|
|
|
from: points.neck,
|
|
|
|
to: points.flbTop,
|
|
|
|
d: -15,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hArmholeToShoulder',
|
|
|
|
from: points.armhole,
|
|
|
|
to: points.shoulder,
|
|
|
|
x: points.armhole.x + 15 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hArmholeToHps',
|
|
|
|
from: points.armhole,
|
|
|
|
to: points.neck,
|
|
|
|
x: points.armhole.x + 30 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemToArmhole',
|
|
|
|
from: points.hem,
|
|
|
|
to: points.armhole,
|
|
|
|
x: (points.armhole.x > points.hem.x ? points.armhole.x : points.hem.x) + 15 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hDartRightToArmhole',
|
|
|
|
from: options.hemStyle === 'classic' ? points.splitDartHemRight : points.dartHemRight,
|
|
|
|
to: points.armhole,
|
|
|
|
x: (points.armhole.x > points.hem.x ? points.armhole.x : points.hem.x) + 30 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hDartLeftToArmhole',
|
|
|
|
from: options.hemStyle === 'classic' ? points.splitDartHemLeft : points.dartHemLeft,
|
|
|
|
to: points.armhole,
|
|
|
|
x: (points.armhole.x > points.hem.x ? points.armhole.x : points.hem.x) + 45 + sa,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'wDartToSide',
|
|
|
|
from: points.dartHemRight,
|
|
|
|
to: points.hem,
|
|
|
|
d: 15,
|
|
|
|
})
|
|
|
|
if (options.hemStyle === 'classic') {
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wHemChamfer',
|
|
|
|
from: points.closureBottom,
|
|
|
|
to: points.hemTip,
|
|
|
|
y: points.hemTip.y + 15 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemChamfer',
|
|
|
|
from: points.hemTip,
|
|
|
|
to: points.closureBottom,
|
|
|
|
x: points.closureBottom.x - 15 - sa,
|
|
|
|
})
|
|
|
|
} else if (options.hemStyle === 'rounded') {
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wHemFinish',
|
|
|
|
from: points.roundStart,
|
|
|
|
to: points.roundEnd,
|
|
|
|
y: points.roundEnd.y + 15 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemToButton',
|
|
|
|
from: points.roundEnd,
|
|
|
|
to: points.roundStart,
|
|
|
|
x: points.roundStart.x - 15 - sa,
|
2022-08-13 21:09:23 +00:00
|
|
|
})
|
2019-02-17 17:21:39 +01:00
|
|
|
}
|
2023-09-21 09:07:26 +02:00
|
|
|
macro('hd', {
|
|
|
|
id: 'wFrontEdgeToDartStart',
|
|
|
|
from: points.roundStart,
|
|
|
|
to: points.dartHemLeft,
|
|
|
|
y: points.hemTip.y + 30 + sa,
|
|
|
|
})
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wFrontEdgeToDartEnd',
|
|
|
|
from: points.roundStart,
|
|
|
|
to: points.dartHemRight,
|
|
|
|
y: points.hemTip.y + 45 + sa,
|
|
|
|
})
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wFull',
|
|
|
|
from: points.roundStart,
|
|
|
|
to: points.hem,
|
|
|
|
y: points.hemTip.y + 60 + sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemToPocketTopAtDart',
|
|
|
|
from: points.roundEnd,
|
|
|
|
to: points.pocketTopMidLeft,
|
|
|
|
x: points.roundStart.x - 30 - sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemToWaist',
|
|
|
|
from: points.roundEnd,
|
|
|
|
to: points.dartWaistLeft,
|
|
|
|
x: points.roundStart.x - 45 - sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hHemToClosureTop',
|
|
|
|
from: points.roundEnd,
|
|
|
|
to: points.closureTop,
|
|
|
|
x: points.roundStart.x - 60 - sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hClosureTopToHps',
|
|
|
|
from: points.closureTop,
|
|
|
|
to: points.neck,
|
|
|
|
x: points.closureTop.x - 15 - sa,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'hBetweenButtons',
|
|
|
|
from: points.button2,
|
|
|
|
to: points.button1,
|
|
|
|
x: points.button1.x + 15,
|
|
|
|
})
|
|
|
|
macro('hd', {
|
|
|
|
id: 'wButtonFromEdge',
|
|
|
|
from: points.closureTop,
|
|
|
|
to: points.button2,
|
|
|
|
y: points.button2.y + 15,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lDartAtWaist',
|
|
|
|
from: points.dartWaistLeft,
|
|
|
|
to: points.dartWaistRight,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lDartAtHip',
|
|
|
|
from: points.dartHipLeft,
|
|
|
|
to: points.dartHipRight,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lPocketTopLeft',
|
|
|
|
from: points.pocketTopLeft,
|
|
|
|
to: points.pocketTopMidLeft,
|
|
|
|
d: 15,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lPocketTopRight',
|
|
|
|
from: points.pocketTopMidRight,
|
|
|
|
to: points.pocketTopRight,
|
|
|
|
d: 15,
|
|
|
|
})
|
|
|
|
macro('ld', {
|
|
|
|
id: 'lPocketHeight',
|
|
|
|
from: points.pocketBottomRight,
|
|
|
|
to: points.pocketTopRight,
|
|
|
|
d: -15,
|
|
|
|
})
|
|
|
|
macro('vd', {
|
|
|
|
id: 'wPocketMidToDartTip',
|
|
|
|
from: points.pocketTopMidLeft,
|
|
|
|
to: points.dartTop,
|
|
|
|
x: points.closureTop.x - 30 - sa,
|
|
|
|
})
|
|
|
|
|
2019-08-03 15:03:33 +02:00
|
|
|
return part
|
|
|
|
}
|
2022-09-03 15:41:48 +02:00
|
|
|
|
|
|
|
export const front = {
|
|
|
|
name: 'wahid.front',
|
|
|
|
from: brianFront,
|
2023-03-08 12:12:13 -06:00
|
|
|
hide: hidePresets.HIDE_TREE,
|
2022-09-03 15:41:48 +02:00
|
|
|
measurements: ['hips', 'waist'],
|
|
|
|
options: {
|
|
|
|
frontOverlap,
|
|
|
|
necklineDrop,
|
|
|
|
frontStyle,
|
|
|
|
frontInset,
|
|
|
|
shoulderInset,
|
|
|
|
neckInset,
|
|
|
|
hemStyle,
|
|
|
|
hemRadius,
|
|
|
|
pocketWidth,
|
|
|
|
pocketAngle,
|
|
|
|
pocketLocation,
|
|
|
|
frontScyeDart,
|
|
|
|
buttons,
|
|
|
|
waistEase,
|
|
|
|
hipsEase,
|
2022-09-28 22:50:22 +02:00
|
|
|
armholeDepthFactor,
|
|
|
|
chestEase,
|
|
|
|
lengthBonus,
|
|
|
|
acrossBackFactor,
|
|
|
|
frontArmholeDeeper,
|
2023-04-30 08:16:49 -07:00
|
|
|
bicepsEase,
|
|
|
|
collarEase,
|
|
|
|
cuffEase,
|
|
|
|
shoulderEase,
|
|
|
|
s3Collar,
|
|
|
|
s3Armhole,
|
|
|
|
shoulderSlopeReduction,
|
|
|
|
backNeckCutout,
|
2025-05-18 09:43:40 +00:00
|
|
|
legacyWaistHips,
|
2022-09-03 15:41:48 +02:00
|
|
|
},
|
|
|
|
draft: wahidFront,
|
|
|
|
}
|