2023-10-19 15:24:06 +00:00
|
|
|
import { frontPoints as nobleFrontPoints } from '@freesewing/noble'
|
2023-10-30 23:55:00 +00:00
|
|
|
import { pctBasedOn, hidePresets } from '@freesewing/core'
|
2023-10-19 15:24:06 +00:00
|
|
|
|
2023-11-11 22:00:08 +00:00
|
|
|
function stringify(obj) {
|
|
|
|
let cache = []
|
|
|
|
let str = JSON.stringify(obj, function (key, value) {
|
|
|
|
if (typeof value === 'object' && value !== null) {
|
|
|
|
if (cache.indexOf(value) !== -1) {
|
|
|
|
// Circular reference found, discard key
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Store value in our collection
|
|
|
|
cache.push(value)
|
|
|
|
}
|
|
|
|
return value
|
|
|
|
})
|
|
|
|
cache = null // reset the cache
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
2023-10-19 15:24:06 +00:00
|
|
|
export const frontPoints = {
|
|
|
|
name: 'tristan.frontPoints',
|
|
|
|
from: nobleFrontPoints,
|
|
|
|
hide: hidePresets.HIDE_ALL,
|
2023-10-30 23:55:00 +00:00
|
|
|
options: {
|
|
|
|
// Static
|
|
|
|
armholeBackDepth: 0.6,
|
|
|
|
armholeBackIn: 0.6,
|
|
|
|
armholeDartPosition: 0.5,
|
|
|
|
armholeFrontDepth: 0.65,
|
|
|
|
armholeFrontIn: 0.2,
|
|
|
|
backArmholeCurvature: 0.63,
|
|
|
|
backArmholePitchDepth: 0.035,
|
|
|
|
backArmholeSlant: 5,
|
|
|
|
backDartHeight: 0.46,
|
|
|
|
backHemSlope: 2.5,
|
|
|
|
backNeckCutout: 0.06,
|
|
|
|
bustDartCurve: 1,
|
|
|
|
bustDartLength: 0.9,
|
|
|
|
dartPosition: 'shoulder',
|
|
|
|
frontArmholeCurvature: 0.63,
|
|
|
|
frontArmholePitchDepth: 0.29,
|
|
|
|
shoulderToShoulderCorrection: 0.995,
|
|
|
|
|
|
|
|
// Percentages
|
|
|
|
bustSpanEase: { pct: 0, min: -5, max: 20, ...pctBasedOn('bustSpan'), menu: 'fit' },
|
|
|
|
armholeDepth: { pct: 44, min: 38, max: 55, menu: 'style' },
|
|
|
|
cutDepthBack: { pct: 40, min: 5, max: 90, menu: 'style' },
|
|
|
|
cutDepthFront: { pct: 80, min: 0, max: 125, menu: 'style' },
|
|
|
|
cutRoundnessBack: { pct: 20, min: 0, max: 100, menu: 'style' },
|
|
|
|
cutRoundnessFront: { pct: 10, min: 0, max: 100, menu: 'style' },
|
|
|
|
shoulderDartPosition: { pct: 50, min: 10, max: 90, menu: 'style' },
|
|
|
|
strapWidth: { pct: 45, min: 5, max: 90, menu: 'style' },
|
2023-11-11 22:00:08 +00:00
|
|
|
hemSize: {
|
|
|
|
pct: 5.62,
|
|
|
|
min: 1,
|
|
|
|
max: 25,
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
|
menu: (settings, mergedOptions) =>
|
|
|
|
mergedOptions.hem === false || mergedOptions.peplum === true ? false : 'options',
|
|
|
|
},
|
2023-10-30 23:55:00 +00:00
|
|
|
upperDartLength: { pct: 90, min: 80, max: 95, menu: 'advanced' },
|
|
|
|
waistDartLength: { pct: 90, min: 75, max: 95, menu: 'advanced' },
|
|
|
|
|
|
|
|
// Options
|
2023-10-31 04:39:49 +00:00
|
|
|
zipperLocation: { dflt: 'side', list: ['front', 'side', 'back'], menu: 'options' },
|
2023-11-11 22:00:08 +00:00
|
|
|
hem: {
|
|
|
|
bool: false,
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
|
menu: (settings, mergedOptions) => (mergedOptions.peplum === true ? false : 'options'),
|
|
|
|
},
|
2023-11-01 02:25:39 +00:00
|
|
|
lacing: { bool: false, menu: 'options' },
|
|
|
|
lacingLocation: {
|
2023-10-31 04:39:49 +00:00
|
|
|
dflt: 'back',
|
|
|
|
list: ['front', 'back'],
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
2023-11-01 02:25:39 +00:00
|
|
|
menu: (settings, mergedOptions) => (mergedOptions.lacing === false ? false : 'options'),
|
2023-10-31 04:39:49 +00:00
|
|
|
},
|
2023-11-01 02:25:39 +00:00
|
|
|
lacingWidth: {
|
|
|
|
pct: 20,
|
2023-10-31 04:39:49 +00:00
|
|
|
min: 0,
|
|
|
|
max: 50,
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
2023-11-01 02:25:39 +00:00
|
|
|
menu: (settings, mergedOptions) => (mergedOptions.lacing === false ? false : 'options'),
|
2023-10-31 04:39:49 +00:00
|
|
|
},
|
2023-10-30 23:55:00 +00:00
|
|
|
},
|
2023-12-10 02:04:07 +00:00
|
|
|
draft: ({ points, Path, paths, snippets, options, macro, store, utils, units, part }) => {
|
2023-11-01 02:25:39 +00:00
|
|
|
const lacing = true == options.lacing && 'front' == options.lacingLocation
|
2023-10-19 15:24:06 +00:00
|
|
|
|
2023-10-22 18:58:54 +00:00
|
|
|
// Hide Noble paths
|
2023-10-19 15:24:06 +00:00
|
|
|
for (const key of Object.keys(paths)) paths[key].hide()
|
|
|
|
for (const i in snippets) delete snippets[i]
|
|
|
|
|
2023-10-22 18:58:54 +00:00
|
|
|
// Remove macros from Noble
|
2023-10-19 15:24:06 +00:00
|
|
|
macro('rmtitle')
|
|
|
|
macro('rmscalebox')
|
2023-11-10 04:58:16 +00:00
|
|
|
macro('rmcutonfold')
|
|
|
|
|
2023-11-11 22:00:08 +00:00
|
|
|
points.sideWaist = points.sideHem.clone()
|
|
|
|
points.sideWaistInitial = points.sideHemInitial.clone()
|
|
|
|
points.cfWaist = points.cfHem.clone()
|
|
|
|
|
2023-11-10 04:58:16 +00:00
|
|
|
store.cutlist.removeCut()
|
2023-10-19 15:24:06 +00:00
|
|
|
|
2023-10-19 23:02:21 +00:00
|
|
|
const shoulderWidthInside = points.shoulderDartInside.dist(points.hps)
|
|
|
|
const shoulderWidthOutside = points.shoulderDartOutside.dist(points.shoulder)
|
|
|
|
let strapWidth = (shoulderWidthInside + shoulderWidthOutside) * options.strapWidth
|
|
|
|
|
|
|
|
if (strapWidth / 2 > shoulderWidthInside) {
|
|
|
|
strapWidth = shoulderWidthInside * 2
|
|
|
|
}
|
|
|
|
if (strapWidth / 2 > shoulderWidthOutside) {
|
|
|
|
strapWidth = shoulderWidthOutside * 2
|
|
|
|
}
|
2023-10-22 18:58:54 +00:00
|
|
|
store.set('strapWidth', strapWidth)
|
2023-10-19 15:24:06 +00:00
|
|
|
|
2023-11-09 05:57:21 +00:00
|
|
|
if (strapWidth != (shoulderWidthInside + shoulderWidthOutside) * options.strapWidth) {
|
|
|
|
store.flag.info({
|
|
|
|
msg: 'tristan:strapWidthAdjusted',
|
|
|
|
replace: {
|
|
|
|
width: units(strapWidth),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-10-19 23:02:21 +00:00
|
|
|
points.strapInside = points.shoulderDartInside.shiftTowards(points.hps, strapWidth / 2)
|
|
|
|
points.strapOutside = points.shoulderDartOutside.shiftTowards(points.shoulder, strapWidth / 2)
|
|
|
|
|
|
|
|
points.cfCut = points.cfNeck.shiftFractionTowards(points.cfBust, options.cutDepthFront)
|
|
|
|
|
2023-11-11 22:00:08 +00:00
|
|
|
paths.cutSeamInside = new Path()
|
2023-10-19 15:24:06 +00:00
|
|
|
.move(points.waistDartLeft)
|
|
|
|
.curve(points.waistDartLeftCp, points.shoulderDartTipCpDownInside, points.shoulderDartTip)
|
|
|
|
.line(points.shoulderDartInside)
|
2023-11-11 22:00:08 +00:00
|
|
|
.hide()
|
|
|
|
points.cutSeamInside = paths.cutSeamInside.intersectsY(points.cfCut.y)[0]
|
2023-10-19 15:24:06 +00:00
|
|
|
|
2023-10-19 23:02:21 +00:00
|
|
|
points.cutSeamOutside = new Path()
|
|
|
|
.move(points.waistDartRight)
|
|
|
|
.curve(points.waistCpUp, points.waistUpDartRightCpDown, points.waistUpDartRight)
|
|
|
|
.curve(
|
|
|
|
points.waistUpDartRightCpUp,
|
|
|
|
points.shoulderDartTipCpDownOutside,
|
|
|
|
points.shoulderDartOutside
|
2023-10-19 15:24:06 +00:00
|
|
|
)
|
2023-10-19 23:02:21 +00:00
|
|
|
.intersectsY(points.cfCut.y)[0]
|
|
|
|
|
|
|
|
points.cfCutCp = points.cfCut.shiftFractionTowards(
|
|
|
|
points.cutSeamInside,
|
|
|
|
1 - options.cutRoundnessFront
|
|
|
|
)
|
|
|
|
points.strapInsideCp = points.strapInside.shiftFractionTowards(
|
|
|
|
points.cutSeamInside.shift(
|
|
|
|
points.cutSeamInside.angle(points.shoulderDartInside) + 90,
|
|
|
|
strapWidth / 2
|
|
|
|
),
|
|
|
|
1 - options.cutRoundnessFront
|
|
|
|
)
|
|
|
|
|
2023-10-30 23:55:00 +00:00
|
|
|
points.armholeCutCp = points.armhole.shiftFractionTowards(
|
|
|
|
points.bustDartTip,
|
|
|
|
options.armholeFrontIn
|
|
|
|
)
|
2023-10-19 23:02:21 +00:00
|
|
|
|
|
|
|
points.strapOutsideCp = points.strapOutside.shiftFractionTowards(
|
2023-10-27 04:43:09 +00:00
|
|
|
points.bustDartTip.shift(
|
2023-10-19 23:02:21 +00:00
|
|
|
points.cutSeamOutside.angle(points.shoulderDartOutside) - 90,
|
|
|
|
strapWidth / 2
|
|
|
|
),
|
2023-10-27 04:43:09 +00:00
|
|
|
options.armholeFrontDepth
|
2023-10-19 23:02:21 +00:00
|
|
|
)
|
|
|
|
|
2023-10-30 23:55:00 +00:00
|
|
|
if (points.strapOutsideCp.x > points.armholeDartCpBottom.x) {
|
|
|
|
points.strapOutsideCp.x = points.armholeDartCpBottom.x
|
|
|
|
}
|
|
|
|
if (points.strapOutsideCp.y > points.armholeDartCpBottom.y) {
|
|
|
|
points.strapOutsideCp.y = points.armholeDartCpBottom.y
|
|
|
|
}
|
2023-10-27 04:43:09 +00:00
|
|
|
|
|
|
|
// armhole adjustment
|
2023-12-10 02:04:07 +00:00
|
|
|
// if (points.sideWaist.y < points.waistDartRight.y) {
|
|
|
|
// points.sideWaist.y = points.waistDartRight.y
|
|
|
|
// }
|
2023-10-30 23:55:00 +00:00
|
|
|
|
2023-11-01 02:25:39 +00:00
|
|
|
if (lacing) {
|
|
|
|
points.lacingCut = points.cfCut.shift(
|
|
|
|
0,
|
|
|
|
(points.strapInsideCp.x - points.cfCut.x) * options.lacingWidth
|
|
|
|
)
|
2023-11-11 22:00:08 +00:00
|
|
|
points.lacingWaist = points.cfWaist.shiftTowards(
|
2023-11-01 02:25:39 +00:00
|
|
|
points.waistDartLeft,
|
|
|
|
(points.strapInsideCp.x - points.cfCut.x) * options.lacingWidth
|
|
|
|
)
|
|
|
|
}
|
2023-11-07 02:22:52 +00:00
|
|
|
|
2023-11-11 22:00:08 +00:00
|
|
|
if (options.hem && !options.peplum) {
|
|
|
|
const hemSize = points.cfWaist.dist(points.cfNeck) * options.hemSize
|
|
|
|
store.set('hemSize', hemSize)
|
|
|
|
|
|
|
|
points.cfHem = (lacing ? points.lacingCut : points.cfCut).shiftOutwards(
|
|
|
|
lacing ? points.lacingWaist : points.cfWaist,
|
|
|
|
hemSize
|
|
|
|
)
|
|
|
|
points.cfHemIn = (lacing ? points.lacingWaist : points.cfWaist).shiftTowards(
|
|
|
|
lacing ? points.lacingCut : points.cfCut,
|
|
|
|
hemSize
|
|
|
|
)
|
|
|
|
const waistDartLeftHemInTemp = points.cfHemIn.shift(
|
|
|
|
points.cfWaist.angle(points.waistDartLeft),
|
|
|
|
points.cfWaist.dist(points.waistDartLeft) * 1.5
|
|
|
|
)
|
|
|
|
points.waistDartLeftHem = utils.beamIntersectsCurve(
|
|
|
|
points.cfHemIn,
|
|
|
|
waistDartLeftHemInTemp,
|
|
|
|
points.waistDartLeft,
|
|
|
|
points.waistDartLeftCp,
|
|
|
|
points.shoulderDartTipCpDownInside,
|
|
|
|
points.shoulderDartTip
|
|
|
|
)
|
|
|
|
|
|
|
|
points.sideWaistHem = points.armhole.shiftOutwards(points.sideWaist, hemSize)
|
|
|
|
points.sideWaistHemIn = points.sideWaist.shiftTowards(points.armhole, hemSize)
|
|
|
|
const waistDartRightHemInTemp = points.sideWaistHemIn.shift(
|
|
|
|
points.sideWaist.angle(points.waistDartRight),
|
|
|
|
points.sideWaist.dist(points.waistDartRight) * 1.5
|
|
|
|
)
|
|
|
|
points.waistDartRightHem = utils.beamIntersectsCurve(
|
|
|
|
points.sideWaistHemIn,
|
|
|
|
waistDartRightHemInTemp,
|
|
|
|
points.waistDartRight,
|
|
|
|
points.waistDartRightCp,
|
|
|
|
points.waistUpDartRightCpDown,
|
|
|
|
points.waistUpDartRight
|
|
|
|
)
|
|
|
|
macro('mirror', {
|
|
|
|
clone: false,
|
|
|
|
mirror: [points.cfWaist, points.waistDartLeft],
|
|
|
|
points: ['waistDartLeftHem'],
|
|
|
|
})
|
|
|
|
macro('mirror', {
|
|
|
|
clone: false,
|
|
|
|
mirror: [points.sideWaist, points.waistDartRight],
|
|
|
|
points: ['waistDartRightHem'],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
store.set('frontOutsideWaistLength', points.waistDartRight.dist(points.sideWaist))
|
2023-11-01 02:25:39 +00:00
|
|
|
store.set(
|
|
|
|
'frontInsideWaistLength',
|
2023-11-11 22:00:08 +00:00
|
|
|
points.waistDartLeft.dist(lacing ? points.lacingWaist : points.cfWaist)
|
2023-11-01 02:25:39 +00:00
|
|
|
)
|
2023-11-11 22:00:08 +00:00
|
|
|
store.set('frontLength', points.cfNeck.dist(points.cfWaist))
|
2023-12-10 02:04:07 +00:00
|
|
|
store.set('sideSeamLength', points.armhole.dist(points.sideWaist))
|
2023-10-30 23:55:00 +00:00
|
|
|
|
2023-10-19 15:24:06 +00:00
|
|
|
return part
|
|
|
|
},
|
|
|
|
}
|