1
0
Fork 0

Add Bust-aligned buttons option to Simone.

This commit is contained in:
Benjamin F 2022-08-17 13:27:06 -07:00
parent c2ae5ba5d6
commit c36a151ced
13 changed files with 140 additions and 11 deletions

View file

@ -54,6 +54,11 @@
### simone
#### Added
- Added Bust-aligned buttons option and functionality. Closes [#2154] (https://github.com/freesewing/freesewing/issues/2154)
- Added a notch at the center front bustline.
#### Fixed
- Don't do a negative FBA from there's no need for an FBA Fixes [#2121](https://github.com/freesewing/freesewing/issues/2121)

View file

@ -8,6 +8,10 @@ Unreleased:
plugin-title:
- Added support for removing the title via a macro call
- Added a render timestamp to the title
simone:
- Added Bust-aligned buttons option and functionality.
Closes [#2154] (https://github.com/freesewing/freesewing/issues/2154)
- Added a notch at the center front bustline.
Changed:
charlie:

View file

@ -131,6 +131,10 @@ const config = {
extraTopButton: { bool: true },
seperateButtonPlacket: { bool: false },
seperateButtonholePlacket: { bool: false },
// Not used in Simon but needed for Simone
bustAlignedButtons: {
dflt: 'Disabled',
list: ['Even spacing', 'Split spacing', 'Disabled'], },
// Collar
collarEase: { pct: 2, min: 0, max: 10 },

View file

@ -25,7 +25,7 @@ export default (part) => {
}
for (const id in paths) delete part.paths[id]
for (const i of ['waist', 'armholePitch', 'hips', 'armhole']) {
for (const i of ['waist', 'armholePitch', 'hips', 'armhole', 'bust',]) {
delete snippets[i + '-notch']
}
const width = store.get('buttonholePlacketWidth')
@ -98,6 +98,12 @@ export default (part) => {
// Notches
snippets['cfArmhole-notch'].anchor.x = points.cfArmhole.x - fold * 2
snippets['cfWaist-notch'].anchor.x = points.cfArmhole.x - fold * 2
// Not available in Simon
if (typeof snippets['cfBust-notch'] !== 'undefined')
snippets['cfBust-notch'].anchor.x = points.cfArmhole - fold * 2
// Not available in Simon
if (typeof snippets['cfHem-notch'] !== 'undefined')
snippets['cfHem-notch'].anchor.x = points.cfArmhole.x - fold * 2
// This notch is not available in Simone
if (typeof snippets['cfHips-notch'] !== 'undefined')
snippets['cfHips-notch'].anchor.x = points.cfArmhole.x - fold * 2

View file

@ -27,8 +27,10 @@ export default (part) => {
for (const id in paths) {
if (id !== 'seam') delete part.paths[id]
}
for (const i in snippets) {
if (i.indexOf('notch')) delete snippets[i]
let notchesToKeep = ['cfBust-notch', 'cfArmhole-notch', 'cfWaist-notch',
'cfHem-notch']
for (const id in snippets) {
if (!notchesToKeep.includes(id)) delete snippets[id]
}
macro('flip')
const width = store.get('buttonPlacketWidth')

View file

@ -22,6 +22,8 @@ export default (part) => {
points.placketBottomOuterEdgeUnder = points.placketCfHem.shift(180, width / 2 + fold)
points.placketTopEdge = points.placketTopOuterEdgeFold.shift(180, width)
points.placketBottomEdge = points.placketBottomOuterEdgeFold.shift(180, width)
if (typeof points.cfBust !== 'undefined')
points.cfBust = points.cfBust.shift(180, fold * 2)
paths.seam.line(points.placketTopEdge).line(points.placketBottomEdge).close()
@ -63,6 +65,8 @@ export default (part) => {
points.placketEdgeWaist = new Point(points.placketBottomEdge.x, points.waist.y)
points.placketEdgeArmhole = new Point(points.placketBottomEdge.x, points.armhole.y)
points.placketEdgeHips = new Point(points.placketBottomEdge.x, points.hips.y)
// Delete old cfBust location notch, so we can re-add in new location.
delete snippets['cfBust-notch']
macro('sprinkle', {
snippet: 'notch',
on: [
@ -83,6 +87,7 @@ export default (part) => {
'placketBottomOuterEdgeFold',
'placketBottomOuterEdgeOver',
'placketBottomOuterEdgeUnder',
'cfBust'
],
})
delete snippets['cfWaist-notch']

View file

@ -25,6 +25,7 @@ export default (part) => {
delete snippets['cfWaist-notch']
delete snippets['cfHips-notch']
delete snippets['cfArmhole-notch']
delete snippets['cfBust-notch']
points.edgeArmhole = new Point(points.neckEdge.x, points.armhole.y)
points.edgeWaist = new Point(points.neckEdge.x, points.waist.y)
points.edgeHips = new Point(points.neckEdge.x, points.hips.y)

View file

@ -23,6 +23,7 @@ export default (part) => {
delete snippets['cfWaist-notch']
delete snippets['cfHips-notch']
delete snippets['cfArmhole-notch']
delete snippets['cfBust-notch']
points.edgeArmhole = new Point(points.placketTopIn.x, points.armhole.y)
points.edgeWaist = new Point(points.placketTopIn.x, points.waist.y)
points.edgeHips = new Point(points.placketTopIn.x, points.hips.y)

View file

@ -27,15 +27,82 @@ export const calculateReduction = function (part) {
export const addButtons = function (part, origin = 'cfNeck', snippet = 'button') {
const { points, options, snippets, Snippet } = part.shorthand()
const len = points.cfNeck.dist(points.cfHips) * (1 - options.buttonFreeLength)
for (let i = 1; i <= options.buttons; i++) {
points['button' + i] = points[origin].shift(-90, (len / options.buttons) * i)
const full_len = points.cfNeck.dist(points.cfHips)
const adjusted_len = full_len * (1 - options.buttonFreeLength)
const total_buttons = options.buttons
switch (options.bustAlignedButtons) {
case 'Even spacing': {
// Strategy: Even button spacing,
// - Determine the correct spacing above the bustline and use that
// spacing for all buttons.
// - The bottom button position is variable, and it ignores the "Button
// free length" setting.
const top_len = points.cfNeck.dist(points.cfBust)
const top_percentage = top_len / full_len
const top_number_buttons = Math.round(total_buttons * top_percentage)
const top_spacing = top_len / top_number_buttons
const even_spacing = top_spacing
for (let i = 1; i <= total_buttons; i++) {
points['button' + i] = points[origin].shift(-90, (even_spacing * i))
snippets[snippet + i] = new Snippet(snippet, points['button' + i])
}
break }
case 'Split spacing': {
// Strategy: Different spacings above and below.
// - Calculate the number of buttons that should be above and below
// the bustline by proportion.
// - Calculate the correct spacings to be used above and below the
// bustline, adhering to the "Button free length" setting.
// - For the first and last bottom buttons, slightly shift their
// positions to make the difference in spacings less noticeable
// at the bustline.
const top_len = points.cfNeck.dist(points.cfBust)
const bot_len = adjusted_len - top_len
const top_percentage = top_len / adjusted_len
const top_number_buttons = Math.round(total_buttons * top_percentage)
const bot_number_buttons = total_buttons - top_number_buttons
const top_spacing = top_len / top_number_buttons
const bot_spacing = bot_len / bot_number_buttons
// Top buttons
for (let i = 1; i <= top_number_buttons; i++) {
points['button' + i] = points[origin].shift(-90, top_spacing * i)
snippets[snippet + i] = new Snippet(snippet, points['button' + i])
}
// Bottom buttons
const adjustment = (top_spacing - bot_spacing) / 2
points.currentpoint = points['cfBust'].clone()
for (let i = top_number_buttons + 1; i <= total_buttons; i++) {
points.currentpoint = points.currentpoint.shift(-90, bot_spacing)
if (i == top_number_buttons + 1) {
// Adjust first button position
points.currentpoint = points.currentpoint.shift(-90, adjustment)
} else if (i == total_buttons) {
// Adjust last button position in opposite direction.
points.currentpoint = points.currentpoint.shift(90, adjustment)
}
points['button' + i] = points.currentpoint.clone()
snippets[snippet + i] = new Snippet(snippet, points['button' + i])
}
break }
case 'Disabled':
default: {
// Strategy: The default strategy.
// - Buttons are evenly spaced without regard to the bustline.
// - The "Button free length" setting is obeyed.
const default_spacing = adjusted_len / total_buttons
for (let i = 1; i <= total_buttons; i++) {
points['button' + i] = points[origin].shift(-90, default_spacing * i)
snippets[snippet + i] = new Snippet(snippet, points['button' + i])
}
}
}
// Add optional extra top button
if (options.extraTopButton)
snippets['top' + snippet] = new Snippet(
snippet,
points[origin].shift(-90, len / options.buttons / 2)
points[origin].shift(-90, adjusted_len / total_buttons / 2)
)
}

View file

@ -7,7 +7,12 @@ const config = {
name: 'simone',
optionGroups: {
...simonConfig.optionGroups,
style: [...simonConfig.optionGroups.style, 'frontDarts', 'contour'],
style: [
...simonConfig.optionGroups.style,
'frontDarts',
'contour',
'bustAlignedButtons',
],
advanced: [
...simonConfig.optionGroups.advanced,
'bustDartAngle',
@ -38,6 +43,9 @@ const config = {
frontDarts: { bool: false },
frontDartLength: { pct: 45, min: 30, max: 60 },
contour: { pct: 50, min: 30, max: 75 },
bustAlignedButtons: {
dflt: 'Disabled',
list: ['Even spacing', 'Split spacing', 'Disabled'], },
},
}

View file

@ -65,6 +65,11 @@ export default (part) => {
* it's based on the model's measurements. (bust span and high point shoulder (HPS) to bust).
* So we need to find the bust point that would end up in the right place AFTER we do the FBA
* For this, we'll just rotate it FBARot in the other direction
* In other words, we are pre-rotating points.bust now, so it gets rotated
* back to its original position during the FBA procedure.
* For convenience and clarity, we're defining points.realBustPoint here.
* However, points.bust will eventually be identical to points.realBustPoint
* after the FBA procedure.
*/
points.realBustPoint = points.bust.clone()
points.bust = points.bust.rotate(FBARot * -1, points.armholePitch)
@ -276,7 +281,7 @@ export default (part) => {
'armholePitchCp1',
]
for (let p of clone1) points[p] = points[`${p}_rot1`].clone()
let clone2 = ['hem', 'hips', 'hipsCp2', 'waistCp1', 'waist']
let clone2 = ['hem', 'hips', 'hipsCp2', 'waistCp1', 'waist', 'bust']
for (let p of clone2) points[p] = points[`${p}_rot2`].clone()
points.cfHem = new Point(points.cfHem.x, points.bustHem_rot2.y)
points.waistCp2 = points.belowDartCpBottom_rot2.clone()
@ -287,6 +292,7 @@ export default (part) => {
points.cfArmhole = new Point(0, points.armhole.y)
points.cfWaist = new Point(0, points.waist.y)
points.cfHips = new Point(0, points.hips.y)
points.cfBust = new Point(0, points.bust.y)
//
// Smooth out the armhole to avoid a kink where we rotated
@ -311,7 +317,8 @@ export default (part) => {
for (let s in snippets) delete snippets[s]
macro('sprinkle', {
snippet: 'notch',
on: ['armhole', 'armholePitch', 'cfArmhole', 'cfWaist', 'cfHem', 'hips', 'waist', 'bust_rot2'],
on: ['armhole', 'armholePitch', 'cfArmhole', 'cfWaist', 'cfHem', 'hips',
'waist', 'bust', 'cfBust',],
})
points.logo = new Point(points.armhole.x / 2, points.armhole.y)
snippets.logo = new Snippet('logo', points.logo)

View file

@ -0,0 +1,15 @@
---
title: "Bust-aligned buttons"
---
Select an optional bust-aligned button spacing strategy.
- Even spacing
- Split spacing
- Disabled
By default bust-aligned button spacing is "Disabled", and center front buttons are spaced without regard to the bustline. Choosing "Even spacing" or "Split spacing" will ensure that there is a button positioned on the bustline to prevent possible gaping.
- Even spacing: Button spacing is calculated for buttons above the bustline, and this spacing is used for all buttons. The `Button free length` setting is ignored for this option. This option might cause the bottommost button to be positioned in a non-optimal location. If this occurs, you may want to experiment with adding or subtracting a button to see if it produces a better design.
- Split spacing: Different button spacings are calculated and used for buttons above and below the bustline. Buttons above the bustline are spaced evenly. Buttons below the bustline are also spaced evenly, except for the topmost and bottommost buttons. The spacings for those buttons are shifted slightly to make the transition between the top and bottom spacings less noticeable. The `Button free length` setting is obeyed for this option. This option might cause non-optimal, visibly different spacings above and below the bustline. If this occurs, you may want to experiment with adding or subtracting a button to see if it produces a better design.
- Disabled: Even button spacing is calculated and used, without regard to the bustline. The `Button free length` setting is obeyed for this option.

View file

@ -1,3 +1,7 @@
bustAlignedButtons:
title: Bust-aligned buttons
description: Optional button spacing strategies to ensure a button at the bustline
bustDartAngle:
title: Bust dart angle
description: Controls the angle by which the (side) bust dart slopes downward