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.
- package/babel/babel.config.js +33 -0
- package/babel/trace-babel-plugin.js +243 -0
- package/babel/trace-log-babel-plugin.js +164 -0
- package/common/core.ts +2 -0
- package/common/log.ts +57 -0
- package/common/trace.ts +26 -0
- package/core/action-decorator.ts +16 -0
- package/dialog/basic-dialog.ts +32 -0
- package/dialog/builders/button-builder.ts +53 -0
- package/dialog/builders/checkbox-builder.ts +30 -0
- package/dialog/builders/combo-box-builder.ts +36 -0
- package/dialog/builders/combo-edit-builder.ts +36 -0
- package/dialog/builders/dialog-builder.ts +49 -0
- package/dialog/builders/groupbox-builder.ts +73 -0
- package/dialog/builders/label-builder.ts +18 -0
- package/dialog/builders/layout-builder.ts +46 -0
- package/dialog/builders/line-edit-builder.ts +118 -0
- package/dialog/builders/list-view-builder.ts +327 -0
- package/dialog/builders/node-selection-builder.ts +44 -0
- package/dialog/builders/popup-menu-builder.ts +47 -0
- package/dialog/builders/radio-builder.ts +43 -0
- package/dialog/builders/splitter-builder.ts +90 -0
- package/dialog/builders/tab-builder.ts +106 -0
- package/dialog/builders/widget-builder.ts +109 -0
- package/dialog/builders/widgets-builder.ts +119 -0
- package/dialog/input-dialog.ts +28 -0
- package/dialog/input-validator.ts +9 -0
- package/dialog/shared.ts +8 -0
- package/helpers/action-helper.ts +81 -0
- package/helpers/array-helper.ts +145 -0
- package/helpers/camera-helper.ts +14 -0
- package/helpers/custom-action-helper.ts +176 -0
- package/helpers/file-helper.ts +90 -0
- package/helpers/input-helper.ts +19 -0
- package/helpers/list-view-helper.ts +89 -0
- package/helpers/menu-helper.ts +29 -0
- package/helpers/message-box-helper.ts +16 -0
- package/helpers/node-helper.ts +216 -0
- package/helpers/number-helper.ts +11 -0
- package/helpers/numeric-property-helper.ts +92 -0
- package/helpers/object-helper.ts +3 -0
- package/helpers/pane-helper.ts +21 -0
- package/helpers/progress-helper.ts +34 -0
- package/helpers/property-helper.ts +53 -0
- package/helpers/record-helper.ts +16 -0
- package/helpers/scene-helper.ts +96 -0
- package/helpers/script-helper.ts +16 -0
- package/helpers/skeleton-helper.ts +27 -0
- package/helpers/splitter-helper.ts +9 -0
- package/helpers/string-helper.ts +28 -0
- package/helpers/surface-helper.ts +6 -0
- package/helpers/undo-helper.ts +7 -0
- package/helpers/viewport-helper.ts +9 -0
- package/lib/delayed.ts +39 -0
- package/lib/dz-dump.ts +121 -0
- package/lib/global.ts +5 -0
- package/lib/guid.ts +3 -0
- package/lib/observable.ts +94 -0
- package/lib/set.ts +25 -0
- package/lib/settings.ts +104 -0
- package/models/custom-action.ts +12 -0
- package/models/frame-keys.ts +68 -0
- package/package.json +48 -0
- package/shared/base-script.ts +30 -0
- package/shared/install-generator.js +185 -0
- package/shared/set-keyboard-shortcut.ts +103 -0
- 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,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,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
|
+
}
|