fix(wahid): Add new waist, hips, and pocket calculations (#352)
This PR changes how the Wahid pattern is generated to improve widths at the waist and hips. It does so by using the actual waist and hips measurements to generate the waist and hips points, as opposed to the old method which used the chest circumference as the base to approximate the waist and hips points. The new method results in a pattern where the chest/waist/hips widths of the garment are exactly the values of chest/waist/hips measurements plus ease. The changes are controlled by a new Legacy Waist and Hips option. The option is disabled by default, but when it is enabled the Wahid pattern is generated the old way. So, users will be able to generate the same Wahid patterns as before, if desired. The PR also contains a fix for the front pocket angle. The waist and hips changes were tested by someone who reported that it fixed their sway back issue: https://discord.com/channels/698854858052075530/757631205804998759/1367899207553388556 discord://discord.com/channels/698854858052075530/757631205804998759/1367899207553388556 Fixes #302 Fixes #328 Co-authored-by: Benjamin Fan <ben-git@swinglonga.com> Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/352 Reviewed-by: Joost De Cock <joostdecock@noreply.codeberg.org> Co-authored-by: Benjamin Fan <benjamesben@noreply.codeberg.org> Co-committed-by: Benjamin Fan <benjamesben@noreply.codeberg.org>
This commit is contained in:
parent
3390def67c
commit
1896eba914
6 changed files with 100 additions and 5 deletions
|
@ -117,6 +117,18 @@
|
|||
"centerBackDart": {
|
||||
"t": "Center back dart",
|
||||
"d": "Whether or not to include a center back dart to fit a rounded back."
|
||||
},
|
||||
"legacyWaistHips": {
|
||||
"t": "Legacy waist and hips widths",
|
||||
"d": "Enable this option to use the legacy (v3) way to calculate the waist and hips widths (using chest circumference) rather than the new way (using the waist and hips measurements)."
|
||||
},
|
||||
"legacyWaistHipsNo": {
|
||||
"t": "Calculate waist and hips widths the new way",
|
||||
"d": "Uses the waist and hips measurements to calculate the waist and hips widths"
|
||||
},
|
||||
"legacyWaistHipsYes": {
|
||||
"t": "Calculate waist and hips widths the legacy (v3) way",
|
||||
"d": "Uses the chest measurement to approximate the waist and hips widths"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import { constructMainDart, shapeSideSeam, dartPath } from './shared.mjs'
|
||||
import { back as brianBack } from '@freesewing/brian'
|
||||
import { backInset, shoulderInset, neckInset, centerBackDart, backScyeDart } from './options.mjs'
|
||||
import {
|
||||
backInset,
|
||||
shoulderInset,
|
||||
neckInset,
|
||||
centerBackDart,
|
||||
backScyeDart,
|
||||
legacyWaistHips,
|
||||
} from './options.mjs'
|
||||
import { hidePresets } from '@freesewing/core'
|
||||
|
||||
function wahidBack({
|
||||
|
@ -20,6 +27,13 @@ function wahidBack({
|
|||
for (let i of Object.keys(paths)) delete paths[i]
|
||||
delete snippets.armholePitchNotch
|
||||
|
||||
if (!options.legacyWaistHips) {
|
||||
// Use actual measurements to set waist and hips points
|
||||
points.waist = new Point((measurements.waist * (1 + options.waistEase)) / 4, points.cbWaist.y)
|
||||
points.hips = new Point((measurements.hips * (1 + options.hipsEase)) / 4, points.cbHips.y)
|
||||
points.hem = new Point(points.hips.x, points.cbHem.y)
|
||||
}
|
||||
|
||||
// Back inset
|
||||
let shoulderLen = points.shoulder.dist(points.neck)
|
||||
let backInset = shoulderLen * options.backInset
|
||||
|
@ -279,6 +293,7 @@ export const back = {
|
|||
neckInset,
|
||||
centerBackDart,
|
||||
backScyeDart,
|
||||
legacyWaistHips,
|
||||
},
|
||||
draft: wahidBack,
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
s3Armhole,
|
||||
shoulderSlopeReduction,
|
||||
backNeckCutout,
|
||||
legacyWaistHips,
|
||||
} from './options.mjs'
|
||||
|
||||
function wahidFront({
|
||||
|
@ -51,6 +52,14 @@ function wahidFront({
|
|||
// Cleanup from Brian
|
||||
for (let i of Object.keys(paths)) delete paths[i]
|
||||
delete snippets.armholePitchNotch
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// Neck cutout
|
||||
points.closureTop = new Point(
|
||||
measurements.chest * options.frontOverlap * -1,
|
||||
|
@ -176,15 +185,31 @@ function wahidFront({
|
|||
points.dartHipLeft,
|
||||
points.pocketTopMid.y + pwvh
|
||||
)
|
||||
points.pocketTopLeft = points.pocketTopMidLeft.shift(180 + options.pocketAngle, pw / 2)
|
||||
points.pocketBottomLeft = points.pocketTopLeft.shift(options.pocketAngle - 90, pwh)
|
||||
// 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
|
||||
)
|
||||
points.pocketTopMidRight = points.pocketTopMidLeft.flipX(points.pocketTopMid)
|
||||
points.pocketBottomMidRight = points.pocketBottomMidLeft.flipX(points.pocketTopMid)
|
||||
points.pocketTopRight = points.pocketTopMidRight.shift(options.pocketAngle, pw / 2)
|
||||
points.pocketBottomRight = points.pocketTopRight.shift(options.pocketAngle - 90, pwh)
|
||||
points.pocketTopRight = points.pocketTopMidRight.shift(
|
||||
options.pocketAngle - startingAngleOffset,
|
||||
pw / 2
|
||||
)
|
||||
points.pocketBottomRight = points.pocketTopRight.shift(
|
||||
options.pocketAngle - 90 - startingAngleOffset,
|
||||
pwh
|
||||
)
|
||||
// Store pocket bag length
|
||||
store.set('pocketBagLength', points.pocketTopMid.dy(points.cfHem) * 0.75)
|
||||
if (options.frontScyeDart) {
|
||||
// Save original armhole width so we can restore it later
|
||||
const original_chest_width = points.cfArmhole.dist(points.armhole)
|
||||
// Front scye dart
|
||||
points._dartWidth = points.dartTop.shiftFractionTowards(
|
||||
points.armholeHollow.rotate(options.frontScyeDart, points.dartTop),
|
||||
|
@ -230,6 +255,10 @@ function wahidFront({
|
|||
if (typeof points[p] !== 'undefined')
|
||||
points[p] = points[p].rotate(options.frontScyeDart, points.dartTop)
|
||||
}
|
||||
if (!options.legacyWaistHips) {
|
||||
// Set armhole back to original width
|
||||
points.armhole = points.cfArmhole.shiftTowards(points.armhole, original_chest_width)
|
||||
}
|
||||
points.armholeHollowCp1 = points.armholeHollowCp2.rotate(180, points.armholeHollow)
|
||||
}
|
||||
// Facing/Lining boundary (flb)
|
||||
|
@ -561,6 +590,7 @@ export const front = {
|
|||
s3Armhole,
|
||||
shoulderSlopeReduction,
|
||||
backNeckCutout,
|
||||
legacyWaistHips,
|
||||
},
|
||||
draft: wahidFront,
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ export const shoulderInset = { pct: 10, min: 0, max: 20, menu: 'advanced' }
|
|||
export const neckInset = { pct: 5, min: 0, max: 10, menu: 'advanced' }
|
||||
export const pocketAngle = { deg: 5, min: 0, max: 5, menu: 'advanced' }
|
||||
export const shoulderSlopeReduction = { pct: 0, min: 0, max: 80, menu: 'advanced' }
|
||||
export const legacyWaistHips = { bool: false, menu: 'advanced' }
|
||||
|
||||
// Hide inherited options
|
||||
export const bicepsEase = 0.15
|
||||
|
|
|
@ -16,6 +16,22 @@ export const constructMainDart = (part) => {
|
|||
store.set('wr12', wr12)
|
||||
store.set('hr12', hr12)
|
||||
|
||||
if (!options.legacyWaistHips) {
|
||||
// Use largest chest-or-hips measurement to determine reduction
|
||||
const largest_measurement = chest >= hips ? chest : hips
|
||||
reduce.waist = largest_measurement - waist
|
||||
reduce.hips = largest_measurement - hips
|
||||
if (reduce.hips < 0) reduce.hips = 0
|
||||
if (reduce.waist < 0) reduce.waist = 0
|
||||
// Use a different reduction factor
|
||||
const reduction_factor = 15
|
||||
wr12 = reduce.waist / reduction_factor
|
||||
hr12 = reduce.hips / reduction_factor
|
||||
// Shift side seam to other direction by total amount added to dart
|
||||
store.set('wr12', wr12 * -2)
|
||||
store.set('hr12', hr12 * -2)
|
||||
}
|
||||
|
||||
points.dartWaistCenter = new Point(points.armhole.x / 2, points.waist.y)
|
||||
points.dartWaistRight = points.dartWaistCenter.shift(0, wr12)
|
||||
points.dartWaistLeft = points.dartWaistCenter.shift(180, wr12)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
title: 'Legacy waist and hips calculations'
|
||||
---
|
||||
|
||||
This option allows you to use the legacy way of calculating the waist
|
||||
and hips.
|
||||
|
||||
The legacy (v3) way used the chest circumference to set the intial waist
|
||||
and hips points.
|
||||
It then used waist and hips measurements to attempt to move the waist
|
||||
and hips points towards the actual measurement values.
|
||||
|
||||
The new, v4 way instead uses the actual waist and hips measurements to
|
||||
set the waist and hips points.
|
||||
It also contains corrections to the front waist dart and side seam
|
||||
adjustments to maintain the correct width and ease at the waist and hips.
|
||||
It also adjusts the armhole point after the dart rotation to maintain
|
||||
the correct width and ease at the armhole.
|
||||
|
||||
If you enable this option, Wahid will revert to the v3 way of calculating
|
||||
waist and hips points.
|
Loading…
Add table
Add a link
Reference in a new issue