dazscript-framework 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/babel/babel.config.js +33 -0
  2. package/babel/trace-babel-plugin.js +243 -0
  3. package/babel/trace-log-babel-plugin.js +164 -0
  4. package/common/core.ts +2 -0
  5. package/common/log.ts +57 -0
  6. package/common/trace.ts +26 -0
  7. package/core/action-decorator.ts +16 -0
  8. package/dialog/basic-dialog.ts +32 -0
  9. package/dialog/builders/button-builder.ts +53 -0
  10. package/dialog/builders/checkbox-builder.ts +30 -0
  11. package/dialog/builders/combo-box-builder.ts +36 -0
  12. package/dialog/builders/combo-edit-builder.ts +36 -0
  13. package/dialog/builders/dialog-builder.ts +49 -0
  14. package/dialog/builders/groupbox-builder.ts +73 -0
  15. package/dialog/builders/label-builder.ts +18 -0
  16. package/dialog/builders/layout-builder.ts +46 -0
  17. package/dialog/builders/line-edit-builder.ts +118 -0
  18. package/dialog/builders/list-view-builder.ts +327 -0
  19. package/dialog/builders/node-selection-builder.ts +44 -0
  20. package/dialog/builders/popup-menu-builder.ts +47 -0
  21. package/dialog/builders/radio-builder.ts +43 -0
  22. package/dialog/builders/splitter-builder.ts +90 -0
  23. package/dialog/builders/tab-builder.ts +106 -0
  24. package/dialog/builders/widget-builder.ts +109 -0
  25. package/dialog/builders/widgets-builder.ts +119 -0
  26. package/dialog/input-dialog.ts +28 -0
  27. package/dialog/input-validator.ts +9 -0
  28. package/dialog/shared.ts +8 -0
  29. package/helpers/action-helper.ts +81 -0
  30. package/helpers/array-helper.ts +145 -0
  31. package/helpers/camera-helper.ts +14 -0
  32. package/helpers/custom-action-helper.ts +176 -0
  33. package/helpers/file-helper.ts +90 -0
  34. package/helpers/input-helper.ts +19 -0
  35. package/helpers/list-view-helper.ts +89 -0
  36. package/helpers/menu-helper.ts +29 -0
  37. package/helpers/message-box-helper.ts +16 -0
  38. package/helpers/node-helper.ts +216 -0
  39. package/helpers/number-helper.ts +11 -0
  40. package/helpers/numeric-property-helper.ts +92 -0
  41. package/helpers/object-helper.ts +3 -0
  42. package/helpers/pane-helper.ts +21 -0
  43. package/helpers/progress-helper.ts +34 -0
  44. package/helpers/property-helper.ts +53 -0
  45. package/helpers/record-helper.ts +16 -0
  46. package/helpers/scene-helper.ts +96 -0
  47. package/helpers/script-helper.ts +16 -0
  48. package/helpers/skeleton-helper.ts +27 -0
  49. package/helpers/splitter-helper.ts +9 -0
  50. package/helpers/string-helper.ts +28 -0
  51. package/helpers/surface-helper.ts +6 -0
  52. package/helpers/undo-helper.ts +7 -0
  53. package/helpers/viewport-helper.ts +9 -0
  54. package/lib/delayed.ts +39 -0
  55. package/lib/dz-dump.ts +121 -0
  56. package/lib/global.ts +5 -0
  57. package/lib/guid.ts +3 -0
  58. package/lib/observable.ts +94 -0
  59. package/lib/set.ts +25 -0
  60. package/lib/settings.ts +104 -0
  61. package/models/custom-action.ts +12 -0
  62. package/models/frame-keys.ts +68 -0
  63. package/package.json +48 -0
  64. package/shared/base-script.ts +30 -0
  65. package/shared/install-generator.js +185 -0
  66. package/shared/set-keyboard-shortcut.ts +103 -0
  67. package/webpack.config.js +48 -0
@@ -0,0 +1,216 @@
1
+ import { app, sceneHelper } from '@dsf/lib/global';
2
+ import { TreeNode } from 'shared/models/tree-node';
3
+ import { group } from './array-helper';
4
+ import { entries } from './record-helper';
5
+
6
+ export const isBone = (node: DzNode): boolean => {
7
+ return node.iskindof('DzBone')
8
+ }
9
+
10
+ export const isFigure = (node: DzNode): boolean => {
11
+ return node.iskindof('DzSkeleton')
12
+ }
13
+
14
+ /**
15
+ * Returns the root of a node
16
+ * @param node
17
+ * @returns The root of the node, if the node is part of a figure, return the figure (skeleton) otherwise return the node itself
18
+ */
19
+ export const getRoot = (node: DzNode): DzNode => {
20
+ if (node && node.className() === "DzBone" && node.getSkeleton)
21
+ return node.getSkeleton();
22
+ else
23
+ return node;
24
+ }
25
+
26
+ export const getFigure = (node: DzNode): DzSkeleton | null => {
27
+ return node.getSkeleton?.() ?? null
28
+ }
29
+
30
+ /**
31
+ * Find a property by the given name or internal name
32
+ * @param node the node to search on
33
+ * @param name the name or internal name of the property
34
+ * @returns The first property with the given name or internal name, or NULL.
35
+ */
36
+ export const findProperty = <T extends DzProperty = DzProperty>(node: DzNode, name: string): T | null => {
37
+ return sceneHelper.findPropertyOnNode(name, node) as T
38
+ ?? sceneHelper.findPropertyOnNodeByInternalName(name, node) as T
39
+ }
40
+
41
+ /**
42
+ * Get all properties associated with the node.
43
+ * @param node The node to get the properties from.
44
+ * @param includeModifiers Whether or not to include the properties of DzModifiers.
45
+ * @returns All properties associated with the node.
46
+ */
47
+ export const getProperties = (node: DzNode, includeModifiers: boolean = false): DzProperty[] => {
48
+ return sceneHelper.getPropertiesOnNode(node, includeModifiers)
49
+ }
50
+
51
+ export const getChildren = (node: DzNode, recursive: boolean, includeParented?: boolean, includeFittedTo?: boolean) => {
52
+ return node.getNodeChildren(recursive ?? false).filter(n =>
53
+ includeParented || isBodyPartOf(n, node.getSkeleton())
54
+ && (includeFittedTo || !isFitting(getFigure(n), node)))
55
+ }
56
+
57
+ /**
58
+ * Returns true if the specified node is a body part of a figure
59
+ * @param node
60
+ * @param figure
61
+ * @returns
62
+ */
63
+ export const isBodyPartOf = (node: DzNode, figure: DzSkeleton): boolean => {
64
+ return isBone(node) && isChildOf(node, figure) && node.getSkeleton()?.getLabel() == figure.getSkeleton()?.getLabel()
65
+ }
66
+
67
+ /**
68
+ * Returns true if the specified node is parented or a body part of a figure
69
+ * @param node
70
+ * @param figure
71
+ * @returns
72
+ */
73
+ export const isChildOf = (node: DzNode, figure: DzNode): boolean => {
74
+ return node.isNodeDescendantOf(figure, true)
75
+ }
76
+
77
+ /**
78
+ * Get the fitting target of the node
79
+ * @param node
80
+ * @returns the fitting target (skeleton) of the node or null
81
+ */
82
+ export const getFittingTarget = (node: DzNode): DzSkeleton | null => {
83
+ return getRoot(node).getSkeleton()?.getFollowTarget()
84
+ }
85
+
86
+ /**
87
+ * Returns true if the node is fitted to another node (eg: it's a clothing item)
88
+ * @param figure
89
+ * @param target if specified, check if the node is fitted to the target node, otherwise check if the node is fitted to any other node
90
+ * @returns true if the node is fitted to another node
91
+ */
92
+ export const isFitting = (figure: DzSkeleton, target?: DzNode): boolean => {
93
+ return target
94
+ ? figure?.getFollowTarget() == target
95
+ : figure?.getFollowTarget() != null
96
+ }
97
+
98
+ export const isClothingType = (node: DzNode): boolean => {
99
+ if (!isFigure(node)) return false
100
+ const figure = getFigure(node)!
101
+ const assetMgr = app.getAssetMgr()
102
+ const type = assetMgr.getTypeForNode(figure)
103
+ return assetMgr.isClothingType(type) || type === 'Follower'
104
+ }
105
+
106
+ export const isHairType = (node: DzNode): boolean => {
107
+ if (!isFigure(node)) return false
108
+ const figure = getFigure(node)!
109
+ const assetMgr = app.getAssetMgr()
110
+ const type = assetMgr.getTypeForNode(figure)
111
+ return assetMgr.isHairType(type)
112
+ }
113
+
114
+ export const isGeoShell = (node: DzNode): boolean => {
115
+ return node.inherits('DzGeometryShellNode')
116
+ }
117
+
118
+ export const getTransforms = (node: DzNode, include: { rotations?: boolean, translations?: boolean, scale?: boolean }) => {
119
+ let transforms: DzFloatProperty[] = []
120
+
121
+ if (include.rotations === true) transforms = getRotations(node)
122
+ if (include.translations === true) transforms = transforms.concat(getTranslations(node))
123
+ if (include.scale === true) transforms = transforms.concat(getScales(node))
124
+
125
+ return transforms
126
+ }
127
+
128
+ export const getRotations = (node: DzNode): DzFloatProperty[] => {
129
+ if (!node) return [];
130
+
131
+ const xRotate = sceneHelper.findPropertyOnNode('XRotate', node) as DzFloatProperty
132
+ const yRotate = sceneHelper.findPropertyOnNode('YRotate', node) as DzFloatProperty
133
+ const zRotate = sceneHelper.findPropertyOnNode('ZRotate', node) as DzFloatProperty
134
+
135
+ return [xRotate, yRotate, zRotate];
136
+ }
137
+
138
+ export const getTranslations = (node: DzNode): DzFloatProperty[] => {
139
+ return !node ? [] : [node.getXPosControl(), node.getYPosControl(), node.getZPosControl()];
140
+ }
141
+
142
+ export const getScales = (node: DzNode): DzFloatProperty[] => {
143
+ return [node.getXScaleControl(), node.getYScaleControl(), node.getZScaleControl(), node.getScaleControl()];
144
+ }
145
+
146
+ export const getPropertiesTree = <T = DzProperty>(node: DzNode, map?: (property: DzProperty) => T, filter?: (property: DzProperty) => boolean): TreeNode<T>[] => {
147
+ let items = entries(group(sceneHelper.getPropertiesOnNode(node), (p) => p.getPath())).map(x => ({ path: x[0], properties: x[1] }))
148
+
149
+ const root = new TreeNode<T>('root', '')
150
+ const pathMap: { [key: string]: TreeNode<T> } = { '': root }
151
+
152
+ items.forEach(element => {
153
+ const paths = element.path.split('/')
154
+ let currentPath = ''
155
+
156
+ paths.forEach((path, index) => {
157
+ currentPath += `${index === 0 ? '' : '/'}${path}`
158
+ if (!pathMap[currentPath]) {
159
+ const newNode = new TreeNode<T>(path, currentPath)
160
+ pathMap[currentPath] = newNode
161
+
162
+ if (index !== 0) {
163
+ const parentPath = currentPath.substring(0, currentPath.lastIndexOf('/'))
164
+ const parentNode = pathMap[parentPath]
165
+ parentNode?.addChild(newNode)
166
+ newNode.parent = parentNode
167
+ }
168
+ }
169
+ })
170
+
171
+ element.properties.forEach(property => {
172
+ const currentNode = pathMap[property.getPath()]
173
+ const newNode = new TreeNode<T>(
174
+ property.getLabel(),
175
+ property.getPath(),
176
+ map?.(property) ?? property as T
177
+ )
178
+
179
+ currentNode?.addChild(newNode)
180
+ newNode.parent = currentNode
181
+ })
182
+ })
183
+
184
+ const rootChildren = pathMap[''].children
185
+ return rootChildren && rootChildren.length > 0 ? rootChildren : root.children
186
+ }
187
+
188
+ export const getPropertiesPathsTree = (node: DzNode): TreeNode<string>[] => {
189
+ let items = entries(group(sceneHelper.getPropertiesOnNode(node), (p) => p.getPath())).map(x => ({ path: x[0], properties: x[1] }))
190
+
191
+ const root = new TreeNode<string>('root', '')
192
+ const pathMap: { [key: string]: TreeNode<string> } = { '': root }
193
+
194
+ items.forEach(element => {
195
+ const paths = element.path.split('/')
196
+ let currentPath = ''
197
+
198
+ paths.forEach((path, index) => {
199
+ currentPath += `${index === 0 ? '' : '/'}${path}`
200
+ if (!pathMap[currentPath]) {
201
+ const newNode = new TreeNode<string>(path, currentPath)
202
+ pathMap[currentPath] = newNode
203
+
204
+ if (index !== 0) {
205
+ const parentPath = currentPath.substring(0, currentPath.lastIndexOf('/'))
206
+ const parentNode = pathMap[parentPath]
207
+ parentNode?.addChild(newNode)
208
+ newNode.parent = parentNode
209
+ }
210
+ }
211
+ })
212
+ })
213
+
214
+ const rootChildren = pathMap[''].children
215
+ return rootChildren && rootChildren.length > 0 ? rootChildren : root.children
216
+ }
@@ -0,0 +1,11 @@
1
+ export const tryParse = (input: string): { valid: boolean, value: number } => {
2
+ const parsedValue = Number(input);
3
+ if (isNaN(parsedValue)) {
4
+ return { valid: false, value: 0 }
5
+ }
6
+ return { valid: true, value: parsedValue }
7
+ }
8
+
9
+ export const clamp = (value: number, min: number, max: number): number => {
10
+ return Math.min(Math.max(value, min), max);
11
+ }
@@ -0,0 +1,92 @@
1
+ import { scene } from '@dsf/lib/global';
2
+ import { PropertyKey, PropertyKeys } from '@dsf/models/frame-keys';
3
+ import { isNumeric, toFloat } from './property-helper';
4
+ import { timeToFrame } from './scene-helper';
5
+
6
+ /**
7
+ * Adjust the value of the property based on the contribution of property controllers.
8
+ * @param property the property to adjust
9
+ * @param value the 'final' value desired for the property
10
+ * @param time the animation time to adjust the property at or current time if not specified
11
+ * @param interpolation the animation interpolation of DzProperty
12
+ * @deprecated use adjust instead
13
+ */
14
+ export const adjustFn = (property: DzFloatProperty | DzIntProperty, value: number, interpolation?: number, time?: DzTime) => {
15
+ return () => {
16
+ interpolation = interpolation ?? DzProperty.InterpConstant
17
+ time = time ?? scene.getTime()
18
+ property.setValue(time, property.adjustValue(time, value), interpolation)
19
+ };
20
+ }
21
+
22
+ /**
23
+ * Adjust the value of the property based on the contribution of property controllers.
24
+ * @param property the property to adjust
25
+ * @param value the 'final' value desired for the property
26
+ * @param time the animation time to adjust the property at or current time if not specified
27
+ * @param interpolation the animation interpolation of DzProperty
28
+ */
29
+ export const adjust = (property: DzFloatProperty | DzIntProperty, value: number, interpolation?: number, time?: DzTime) => {
30
+ interpolation = interpolation ?? DzProperty.InterpConstant
31
+ time = time ?? scene.getTime()
32
+
33
+ adjustFn(property, value, interpolation, time)()
34
+ }
35
+
36
+ export const nudge = (property: DzFloatProperty | DzIntProperty, value: number, interpolation?: number, time?: DzTime) => {
37
+ interpolation = interpolation ?? DzProperty.InterpConstant
38
+ time = time ?? scene.getTime()
39
+
40
+ const sensitivity = property.getSensitivity()
41
+ adjust(property, property.getValue() + value * sensitivity, interpolation, time)
42
+ //property.setValue(time, property.getValue() + value * sensitivity, interpolation)
43
+ }
44
+
45
+ export const clamp = (property: DzFloatProperty | DzIntProperty, interpolation?: number, time?: DzTime) => {
46
+ interpolation = interpolation ?? DzProperty.InterpConstant
47
+ time = time ?? scene.getTime()
48
+
49
+ property.setIsClamped(true)
50
+
51
+ if (property.getRawValue() > property.getMax()) {
52
+ property.setValue(time, property.getMax(), interpolation)
53
+ }
54
+ else if (property.getRawValue() < property.getMin()) {
55
+ property.setValue(time, property.getMin(), interpolation)
56
+ }
57
+
58
+ }
59
+
60
+ export const setInterpolation = (property: DzProperty, keyIndex: number, interpolationType: number) => {
61
+ toFloat(property)?.setKeyInterpolation(keyIndex, interpolationType)
62
+ }
63
+
64
+ /**
65
+ * Gets a collection of numeric property keys
66
+ * @param property the property to get the keys from
67
+ * @returns an array of keys
68
+ */
69
+ export const getKeys = (property: DzNumericProperty): PropertyKeys => {
70
+ if (!isNumeric(property)) throw Error(`The property "${property.getLabel()}" is not numeric`)
71
+
72
+ const keys: PropertyKey[] = []
73
+
74
+ for (let i = 0; i < property.getNumKeys(); i++) {
75
+ const key = new PropertyKey()
76
+ key.index = i
77
+ key.time = property.getKeyTime(i)
78
+ key.value = property.getDoubleValue(key.time)
79
+ key.frame = timeToFrame(key.time)
80
+ keys.push(key)
81
+ }
82
+
83
+ const keyCollection = new PropertyKeys(keys);
84
+
85
+ // This would make frame the index, but it would not be zero based and
86
+ // could lead to trouble
87
+ // keys.forEach((key) => {
88
+ // keyCollection[key.frame] = key
89
+ // })
90
+
91
+ return keyCollection
92
+ }
@@ -0,0 +1,3 @@
1
+ export const keys = (o: {}): string[] => {
2
+ return Object.keys(o)
3
+ }
@@ -0,0 +1,21 @@
1
+ import { mainWindow } from '@dsf/lib/global'
2
+
3
+ const findPane = <T extends DzPane>(className: string): T => {
4
+ return mainWindow.getPaneMgr().findPane(className) as T
5
+ }
6
+
7
+ export const getSmartContentPane = (): DzSmartContentPane => {
8
+ return <DzSmartContentPane>findPane("DzSmartContentPane")
9
+ }
10
+
11
+ export const getSurfacesPane = (): DzSurfacesPane => {
12
+ return findPane<DzSurfacesPane>("DzSurfacesPane")
13
+ }
14
+
15
+ export const getAuxViewPort = (): DzAuxViewportPane => {
16
+ return findPane<DzAuxViewportPane>("DzAuxViewportPane")
17
+ }
18
+
19
+ export const getParametersPane = (): DzParametersPane => {
20
+ return findPane<DzParametersPane>("DzParametersPane")
21
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Displays a progress dialog to the user if one is not already being displayed and starts a progress tracking operation.
3
+ * @param info The string to display in the progress dialog as the current description of the operation.
4
+ * @param items The items to process
5
+ * @param callback The function to run for every item
6
+ * @param isCancellable If true, the user is given the option to cancel the operation.
7
+ * @param showTimeElapsed If true, the amount of time since the progress operation was started will be displayed in the dialog.
8
+ * @param totalSteps The number of progress steps for the operation to be complete.
9
+ */
10
+ export const progress = <T>(info: string, items: T[], callback: (item: T) => boolean | void, isCancellable: boolean = true, showTimeElapsed: boolean = true, totalSteps?: number) => {
11
+ totalSteps = totalSteps ?? items.length;
12
+
13
+ startProgress(info, totalSteps, isCancellable, showTimeElapsed);
14
+
15
+ for (let item of items) {
16
+ if (isCancellable) {
17
+ if (progressIsCancelled()) {
18
+ break;
19
+ } else {
20
+ // This is too slow
21
+ //if(progress) processEvents();
22
+ }
23
+ }
24
+
25
+ //============
26
+ if (callback && callback(item) === false)
27
+ return
28
+ //============
29
+
30
+ stepProgress(1);
31
+ }
32
+
33
+ finishProgress();
34
+ }
@@ -0,0 +1,53 @@
1
+ import { sceneHelper } from '@dsf/lib/global'
2
+
3
+ /**
4
+ * Sets the DzPropertyGroup path (and appropriate geometryregion_dz) for the given property.
5
+ * @param property The property to change the path of.
6
+ * @param path The new path for the given property.
7
+ */
8
+ export const setPath = (property: DzProperty, path: string) => {
9
+ sceneHelper.setPropertyPath(property, path)
10
+ }
11
+
12
+ /**
13
+ * Get the internal name of property (or its alias target), or “Unknown”.
14
+ * @param property
15
+ * @returns The internal name of property (or its alias target), or “Unknown”.
16
+ */
17
+ export const getName = (property: DzProperty): string => {
18
+ return sceneHelper.getInternalName(property)
19
+ }
20
+
21
+ /**
22
+ * Unlocks a property temporarily and executes the specified callback while it's unlocked
23
+ * @param property the property to unlock
24
+ * @param then the callback to exectue while the property is unlocked
25
+ */
26
+ export const unlock = (property: DzProperty, then: (property: DzProperty) => void) => {
27
+ let locked = property.isLocked()
28
+ if (locked) property.lock(true)
29
+ then(property)
30
+ if (locked) property.lock(false)
31
+ }
32
+
33
+ export const isNumeric = (property: DzProperty): boolean => {
34
+ return property.inherits('DzNumericProperty')
35
+ }
36
+
37
+ export const cast = <T extends DzProperty>(property: DzProperty, type: 'DzNumericProperty' | 'DzFloatProperty' | 'DzIntProperty'): T | null => {
38
+ return property.inherits(type)
39
+ ? property as T
40
+ : null
41
+ }
42
+
43
+ export const toNumeric = (property: DzProperty): DzFloatProperty | DzIntProperty | null => {
44
+ return toFloat(property) ?? toInt(property)
45
+ }
46
+
47
+ export const toFloat = (property: DzProperty): DzFloatProperty | null => {
48
+ return cast<DzFloatProperty>(property, 'DzFloatProperty')
49
+ }
50
+
51
+ export const toInt = (property: DzProperty): DzIntProperty | null => {
52
+ return cast<DzIntProperty>(property, 'DzIntProperty')
53
+ }
@@ -0,0 +1,16 @@
1
+ function objectEntries(obj: any) {
2
+ const ownProps = Object.keys(obj);
3
+ let i = ownProps.length;
4
+ const result = new Array(i); // preallocate the Array
5
+ while (i--) {
6
+ result[i] = [ownProps[i], obj[ownProps[i]]];
7
+ }
8
+ return result;
9
+ };
10
+
11
+ export function entries<K extends string, T>(
12
+ record: Record<K, T[]>
13
+ ): Array<[K, T[]]> {
14
+ return (objectEntries(record) as Array<[K, T[]]>);
15
+ }
16
+
@@ -0,0 +1,96 @@
1
+ import { scene } from '@dsf/lib/global'
2
+ import { contains, distinct } from './array-helper'
3
+ import { getRoot } from './node-helper'
4
+ import { getParametersPane } from './pane-helper'
5
+
6
+ export const getSelectedOf = <T>(typeName: string): DzNode[] => {
7
+ let nodes = []
8
+ for (let node of scene.getSelectedNodeList()) {
9
+ if (!node.inherits(typeName)) continue
10
+ nodes.push(node)
11
+ }
12
+ return nodes
13
+ }
14
+
15
+ export const getSelectedNode = (): DzNode | null => {
16
+ if (scene.getNumSelectedNodes() === 0) return null
17
+ return scene.getPrimarySelection()
18
+ }
19
+
20
+ export const getTopParent = (node: DzNode): DzNode => {
21
+ var parent = node.getNodeParent();
22
+ return parent ? getTopParent(parent) : node;
23
+ }
24
+
25
+ export const getNodes = (): DzNode[] => {
26
+ return scene.getNodeList()
27
+ }
28
+
29
+ export const getFigures = (): DzSkeleton[] => {
30
+ return distinct(getNodes().map(n => n.getSkeleton?.()), (n => n?.getLabel().valueOf())).filter(n => n !== null)
31
+ }
32
+
33
+ /**
34
+ * Get the selected figure
35
+ * @returns the figure skeleton, or null if there is no current selection or the selected node is not part of a figure
36
+ */
37
+ export const getSelectedFigure = (): DzSkeleton | null => {
38
+ return getSelectedNode()?.getSkeleton?.()
39
+ }
40
+
41
+ /**
42
+ * Given the selected nodes in the scene, return the figures they are part of
43
+ * @returns the selected figures
44
+ */
45
+ export const getSelectedFigures = (callback: (figure: DzSkeleton) => void | boolean = () => true): DzSkeleton[] => {
46
+ let nodes: DzSkeleton[] = []
47
+ for (let node of scene.getSelectedNodeList()) {
48
+ let skeleton = node.getSkeleton?.()
49
+ if (!skeleton || contains(nodes, node)) continue
50
+ nodes.push(skeleton)
51
+ if (!!callback?.(skeleton)) break
52
+ }
53
+ return nodes
54
+ }
55
+
56
+ export const getSelectedNodes = (): DzNode[] => {
57
+ return scene.getSelectedNodeList()
58
+ }
59
+
60
+ export const getSelectedRoot = (): DzNode => {
61
+ return getRoot(getSelectedNode())
62
+ }
63
+
64
+ export const getSelectedRoots = (): DzNode[] => {
65
+ return distinct(getSelectedNodes().map(n => getRoot(n)))
66
+ }
67
+
68
+ export const getSelectedProperties = (): DzProperty[] => {
69
+ return getParametersPane()?.getNodeEditor()?.getPropertySelections(true) ?? []
70
+ }
71
+
72
+ export const getSelectedPropertiesOfType = <TProperty extends DzProperty>(type: string): TProperty[] => {
73
+ return getSelectedProperties().filter(p => p.inherits(type)) as TProperty[]
74
+ }
75
+
76
+ export const clearSelection = () => {
77
+ for (let node of scene.getSelectedNodeList()) {
78
+ node.select(false)
79
+ }
80
+ }
81
+
82
+ export const currentTime = (): DzTime => {
83
+ return scene.getTime()
84
+ }
85
+
86
+ export const getCurrentFrame = (): number => {
87
+ return scene.getTime().valueOf() / scene.getTimeStep().valueOf()
88
+ }
89
+
90
+ export const getLastFrame = (): number => {
91
+ return scene.getAnimRange().end / scene.getTimeStep().valueOf()
92
+ }
93
+
94
+ export const timeToFrame = (time: DzTime): number => {
95
+ return time.valueOf() / scene.getTimeStep().valueOf()
96
+ }
@@ -0,0 +1,16 @@
1
+ export const getScriptPath = (): string => {
2
+ var fileName = getScriptFileName();
3
+ var fileInfo = new DzFileInfo(fileName);
4
+
5
+ let path: string;
6
+
7
+ if (typeof (fileInfo.canonicalPath) == "function") {
8
+ path = fileInfo.canonicalPath();
9
+ } else {
10
+ path = fileInfo.path();
11
+ }
12
+
13
+ fileInfo.deleteLater();
14
+
15
+ return path;
16
+ }
@@ -0,0 +1,27 @@
1
+
2
+ export const getModifiers = (figure: DzSkeleton): DzModifier[] => {
3
+ let modifiers: DzModifier[] = []
4
+ let obj = figure.getObject()
5
+
6
+ for (let i = 0; i < obj.getNumModifiers(); i++) {
7
+ modifiers.push(obj.getModifier(i))
8
+ }
9
+
10
+ return modifiers
11
+ }
12
+
13
+ export const getMirrorNodes = (figure: DzSkeleton, nodes: DzNode[]): DzNode[] => {
14
+ let mirrorNodes: DzNode[] = []
15
+
16
+ nodes.forEach((node) => {
17
+ const name = node.getName().valueOf()
18
+ let prefix = name[0]
19
+ if (prefix !== 'r' && prefix !== 'l') return
20
+ prefix = prefix === 'r' ? 'l' : 'r'
21
+ const mirrorName = `${prefix}${name.substring(1)}`
22
+ const mirrorNode = figure.findNodeChild(mirrorName, true)
23
+ if (mirrorNode) mirrorNodes.push(mirrorNode)
24
+ })
25
+
26
+ return mirrorNodes
27
+ }
@@ -0,0 +1,9 @@
1
+ export const restoreState = (splitter: DzSplitter, state: string) => {
2
+ if (!state) return
3
+ let base64Array = new ByteArray(state)
4
+ splitter.restoreState(base64Array.fromBase64(base64Array))
5
+ }
6
+
7
+ export const getState = (splitter: DzSplitter): string => {
8
+ return splitter.saveState().toBase64().convertToString()
9
+ }
@@ -0,0 +1,28 @@
1
+ export const isNumeric = (value: string | number): boolean => {
2
+ return ((value != null) &&
3
+ (value !== '') &&
4
+ !isNaN(Number(value.toString())))
5
+ }
6
+
7
+ export const contains = (source: string, search: string | string[]): boolean => {
8
+ if (Array.isArray(search)) {
9
+ for (const s of search) {
10
+ if (source.indexOf(s) >= 0) return true
11
+ }
12
+ return false
13
+ }
14
+ return source.indexOf(search) >= 0
15
+ }
16
+
17
+ export const remove = (source: string, search: string): string => {
18
+ return source.replace(search, "")
19
+ }
20
+
21
+ export const count = (source: string, search: string): number => {
22
+ return source.split(search).length - 1
23
+ }
24
+
25
+ export const isGUID = (str: string): boolean => {
26
+ const GUIDPattern = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
27
+ return GUIDPattern.test(str);
28
+ }
@@ -0,0 +1,6 @@
1
+ import { getSurfacesPane } from './pane-helper'
2
+
3
+ export const getSelectedSurfacePropertiesOfType = <TProperty extends DzProperty>(className: string): TProperty[] => {
4
+ return getSurfacesPane().getNodeEditor().getPropertySelections(true)
5
+ .filter(p => p.inherits(className)) as TProperty[]
6
+ }
@@ -0,0 +1,7 @@
1
+ const acceptUndoFor = (caption: string, callback: () => void) => {
2
+ beginUndo()
3
+ callback?.()
4
+ acceptUndo(caption)
5
+ }
6
+
7
+ export { acceptUndoFor as acceptUndo }
@@ -0,0 +1,9 @@
1
+ import { mainWindow } from '@dsf/lib/global'
2
+
3
+ export const selectUniversalRotateTool = (coordinateSpace?: number): DzUniversalRotateTool => {
4
+ const viewportMgr = mainWindow.getViewportMgr()
5
+ const tool = viewportMgr.findTool('DzUniversalRotateTool') as DzUniversalRotateTool
6
+ viewportMgr.setActiveTool(tool)
7
+ if (coordinateSpace) tool.setCoordinateSpace(coordinateSpace)
8
+ return tool
9
+ }