dazscript-framework 0.1.15 → 0.1.16
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/README.md +365 -93
- package/babel.config.js +33 -33
- package/dist/babel/trace-babel-plugin.js +243 -243
- package/dist/babel/trace-log-babel-plugin.js +164 -164
- package/dist/scripts/install-generator.js +185 -185
- package/package.json +72 -70
- package/src/common/dz-dump.ts +120 -120
- package/src/common/log.ts +56 -56
- package/src/common/trace.ts +26 -26
- package/src/core/action-decorator.ts +15 -15
- package/src/core/base-script.ts +30 -30
- package/src/core/custom-action.ts +11 -11
- package/src/core/global.ts +4 -4
- package/src/dialog/basic-dialog.ts +40 -32
- package/src/dialog/builders/button-builder.ts +52 -52
- package/src/dialog/builders/checkbox-builder.ts +29 -29
- package/src/dialog/builders/color-picker-builder.ts +35 -35
- package/src/dialog/builders/combo-box-builder.ts +38 -35
- package/src/dialog/builders/combo-edit-builder.ts +35 -35
- package/src/dialog/builders/dialog-builder.ts +49 -49
- package/src/dialog/builders/groupbox-builder.ts +121 -82
- package/src/dialog/builders/label-builder.ts +33 -28
- package/src/dialog/builders/layout-builder.ts +59 -59
- package/src/dialog/builders/line-edit-builder.ts +124 -119
- package/src/dialog/builders/list-box-builder.ts +103 -0
- package/src/dialog/builders/list-view-builder.ts +396 -328
- package/src/dialog/builders/node-selection-builder.ts +55 -55
- package/src/dialog/builders/path-combo-box-builder.ts +24 -24
- package/src/dialog/builders/popup-menu-builder.ts +46 -46
- package/src/dialog/builders/radio-builder.ts +42 -42
- package/src/dialog/builders/slider-builder.ts +39 -22
- package/src/dialog/builders/splitter-builder.ts +88 -88
- package/src/dialog/builders/tab-builder.ts +120 -106
- package/src/dialog/builders/widget-builder.ts +136 -124
- package/src/dialog/builders/widgets-builder.ts +140 -135
- package/src/dialog/input-dialog.ts +30 -27
- package/src/dialog/input-validator.ts +8 -8
- package/src/dialog/selection-dialog.ts +47 -0
- package/src/dialog/shared.ts +8 -8
- package/src/helpers/action-helper.ts +214 -81
- package/src/helpers/array-helper.ts +170 -145
- package/src/helpers/camera-helper.ts +12 -12
- package/src/helpers/custom-action-helper.ts +176 -176
- package/src/helpers/directory-helper.ts +14 -0
- package/src/helpers/file-helper.ts +90 -90
- package/src/helpers/http-helper.ts +186 -0
- package/src/helpers/input-helper.ts +18 -18
- package/src/helpers/list-view-helper.ts +105 -89
- package/src/helpers/menu-helper.ts +28 -28
- package/src/helpers/message-box-helper.ts +25 -15
- package/src/helpers/node-helper.ts +461 -236
- package/src/helpers/number-helper.ts +10 -10
- package/src/helpers/numeric-property-helper.ts +91 -91
- package/src/helpers/object-helper.ts +2 -2
- package/src/helpers/pane-helper.ts +28 -20
- package/src/helpers/progress-helper.ts +51 -33
- package/src/helpers/property-helper.ts +61 -52
- package/src/helpers/record-helper.ts +16 -16
- package/src/helpers/scene-helper.ts +144 -94
- package/src/helpers/script-helper.ts +15 -15
- package/src/helpers/skeleton-helper.ts +26 -26
- package/src/helpers/splitter-helper.ts +8 -8
- package/src/helpers/string-helper.ts +39 -31
- package/src/helpers/surface-helper.ts +5 -5
- package/src/helpers/undo-helper.ts +8 -8
- package/src/helpers/viewport-helper.ts +21 -8
- package/src/lib/delayed.ts +38 -38
- package/src/lib/dictionary.ts +3 -0
- package/src/lib/frame-keys.ts +67 -67
- package/src/lib/guid.ts +2 -2
- package/src/lib/menu-item.ts +10 -9
- package/src/lib/observable.ts +147 -94
- package/src/lib/set.ts +50 -25
- package/src/lib/settings.ts +112 -104
- package/src/lib/tree-node.ts +149 -145
- package/src/samples/config.ts +2 -2
- package/src/samples/hello-world.dsa.ts +12 -12
- package/src/samples/sample-dialog.dsa.ts +51 -51
- package/src/samples/sample-dialog.ts +48 -48
- package/src/shared/set-keyboard-shortcut.ts +146 -102
- package/tsconfig.json +116 -116
- package/webpack.config.js +70 -70
|
@@ -1,236 +1,461 @@
|
|
|
1
|
-
import { app, sceneHelper } from '@dsf/core/global';
|
|
2
|
-
import { TreeNode } from '@dsf/lib/tree-node';
|
|
3
|
-
import { group } from './array-helper';
|
|
4
|
-
import { entries } from './record-helper';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export const
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
* @param
|
|
44
|
-
* @
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Returns true if the specified node is
|
|
69
|
-
* @param node
|
|
70
|
-
* @param figure
|
|
71
|
-
* @returns
|
|
72
|
-
*/
|
|
73
|
-
export const
|
|
74
|
-
return node
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
*
|
|
79
|
-
* @param node
|
|
80
|
-
* @
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
*
|
|
89
|
-
* @param
|
|
90
|
-
* @returns
|
|
91
|
-
*/
|
|
92
|
-
export const
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
1
|
+
import { app, sceneHelper } from '@dsf/core/global';
|
|
2
|
+
import { TreeNode } from '@dsf/lib/tree-node';
|
|
3
|
+
import { find, group } from './array-helper';
|
|
4
|
+
import { entries } from './record-helper';
|
|
5
|
+
import { getSelectedPropertyGroups } from './scene-helper';
|
|
6
|
+
import { contains } from './string-helper';
|
|
7
|
+
|
|
8
|
+
export enum NamedAxis {
|
|
9
|
+
Bend = 'Bend',
|
|
10
|
+
Twist = 'Twist',
|
|
11
|
+
SideSide = 'Side-Side',
|
|
12
|
+
FrontBack = 'Front-Back',
|
|
13
|
+
UpDown = 'Up-Down',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const isBone = (node: DzNode): boolean => {
|
|
17
|
+
return node.iskindof('DzBone')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const isFigure = (node: DzNode): boolean => {
|
|
21
|
+
return node.iskindof('DzSkeleton')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns the root of a node
|
|
26
|
+
* @param node
|
|
27
|
+
* @returns The root of the node, if the node is part of a figure, return the figure (skeleton) otherwise return the node itself
|
|
28
|
+
*/
|
|
29
|
+
export const getRoot = (node: DzNode): DzNode => {
|
|
30
|
+
if (node && node.className() === "DzBone" && node.getSkeleton)
|
|
31
|
+
return node.getSkeleton();
|
|
32
|
+
else
|
|
33
|
+
return node;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const getFigure = (node: DzNode): DzSkeleton | null => {
|
|
37
|
+
return node.getSkeleton?.() ?? null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Find a property by the given name or internal name
|
|
42
|
+
* @param node the node to search on
|
|
43
|
+
* @param name the name or internal name of the property
|
|
44
|
+
* @returns The first property with the given name or internal name, or NULL.
|
|
45
|
+
*/
|
|
46
|
+
export const findProperty = <T extends DzProperty = DzProperty>(node: DzNode, name: string): T | null => {
|
|
47
|
+
return sceneHelper.findPropertyOnNode(name, node) as T
|
|
48
|
+
?? sceneHelper.findPropertyOnNodeByInternalName(name, node) as T
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get all properties associated with the node.
|
|
53
|
+
* @param node The node to get the properties from.
|
|
54
|
+
* @param includeModifiers Whether or not to include the properties of DzModifiers.
|
|
55
|
+
* @returns All properties associated with the node.
|
|
56
|
+
*/
|
|
57
|
+
export const getProperties = (node: DzNode, includeModifiers: boolean = false): DzProperty[] => {
|
|
58
|
+
return sceneHelper.getPropertiesOnNode(node, includeModifiers)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const getChildren = (node: DzNode, recursive: boolean, includeParented?: boolean, includeFittedTo?: boolean) => {
|
|
62
|
+
return node.getNodeChildren(recursive ?? false).filter(n =>
|
|
63
|
+
includeParented || isBodyPartOf(n, node.getSkeleton())
|
|
64
|
+
&& (includeFittedTo || !isFitting(getFigure(n), node)))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Returns true if the specified node is a body part of a figure
|
|
69
|
+
* @param node
|
|
70
|
+
* @param figure
|
|
71
|
+
* @returns
|
|
72
|
+
*/
|
|
73
|
+
export const isBodyPartOf = (node: DzNode, figure: DzSkeleton): boolean => {
|
|
74
|
+
return isBone(node) && isChildOf(node, figure) && node.getSkeleton()?.getLabel() == figure.getSkeleton()?.getLabel()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Returns true if the specified node is parented or a body part of a figure
|
|
79
|
+
* @param node
|
|
80
|
+
* @param figure
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
83
|
+
export const isChildOf = (node: DzNode, figure: DzNode): boolean => {
|
|
84
|
+
return node.isNodeDescendantOf(figure, true)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get the fitting target of the node
|
|
89
|
+
* @param node
|
|
90
|
+
* @returns the fitting target (skeleton) of the node or null
|
|
91
|
+
*/
|
|
92
|
+
export const getFittingTarget = (node: DzNode): DzSkeleton | null => {
|
|
93
|
+
return getRoot(node).getSkeleton()?.getFollowTarget()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns true if the node is fitted to another node (eg: it's a clothing item)
|
|
98
|
+
* @param figure
|
|
99
|
+
* @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
|
|
100
|
+
* @returns true if the node is fitted to another node
|
|
101
|
+
*/
|
|
102
|
+
export const isFitting = (figure: DzSkeleton, target?: DzNode): boolean => {
|
|
103
|
+
return target
|
|
104
|
+
? figure?.getFollowTarget() == target
|
|
105
|
+
: figure?.getFollowTarget() != null
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const isClothingType = (node: DzNode): boolean => {
|
|
109
|
+
if (!isFigure(node)) return false
|
|
110
|
+
const figure = getFigure(node)!
|
|
111
|
+
const assetMgr = app.getAssetMgr()
|
|
112
|
+
const type = assetMgr.getTypeForNode(figure)
|
|
113
|
+
return assetMgr.isClothingType(type) || type === 'Follower'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const isHairType = (node: DzNode): boolean => {
|
|
117
|
+
if (!isFigure(node)) {
|
|
118
|
+
return node.className() === 'DzStrandHairNode'
|
|
119
|
+
}
|
|
120
|
+
const figure = getFigure(node)!
|
|
121
|
+
const assetMgr = app.getAssetMgr()
|
|
122
|
+
const type = assetMgr.getTypeForNode(figure)
|
|
123
|
+
return assetMgr.isHairType(type) || contains(type.valueOf(), 'Hair')
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const isGeoShell = (node: DzNode): boolean => {
|
|
127
|
+
return node.inherits('DzGeometryShellNode')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const getTransforms = (node: DzNode, include: { rotations?: boolean, translations?: boolean, scale?: boolean }) => {
|
|
131
|
+
let transforms: DzFloatProperty[] = []
|
|
132
|
+
|
|
133
|
+
if (include.rotations === true) transforms = getRotations(node)
|
|
134
|
+
if (include.translations === true) transforms = transforms.concat(getTranslations(node))
|
|
135
|
+
if (include.scale === true) transforms = transforms.concat(getScales(node))
|
|
136
|
+
|
|
137
|
+
return transforms
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const getRotations = (node: DzNode, includeExtraRotations: boolean = true): DzFloatProperty[] => {
|
|
141
|
+
if (!node) return [];
|
|
142
|
+
|
|
143
|
+
const xRotate = sceneHelper.findPropertyOnNode('XRotate', node) as DzFloatProperty;
|
|
144
|
+
const xRotate2 = sceneHelper.findPropertyOnNode('XRotate2', node) as DzFloatProperty;
|
|
145
|
+
const yRotate = sceneHelper.findPropertyOnNode('YRotate', node) as DzFloatProperty;
|
|
146
|
+
const yRotate2 = sceneHelper.findPropertyOnNode('YRotate2', node) as DzFloatProperty;
|
|
147
|
+
const zRotate = sceneHelper.findPropertyOnNode('ZRotate', node) as DzFloatProperty;
|
|
148
|
+
const zRotate2 = sceneHelper.findPropertyOnNode('ZRotate2', node) as DzFloatProperty;
|
|
149
|
+
|
|
150
|
+
if (includeExtraRotations) {
|
|
151
|
+
return [xRotate, xRotate2, yRotate, yRotate2, zRotate, zRotate2].filter(Boolean);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Prefer Rotate2 if available, otherwise fallback to Rotate
|
|
155
|
+
return [
|
|
156
|
+
xRotate2 ?? xRotate,
|
|
157
|
+
yRotate2 ?? yRotate,
|
|
158
|
+
zRotate2 ?? zRotate
|
|
159
|
+
].filter(Boolean);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const getRotationsForAxis = (node: DzNode, axis: 'x' | 'y' | 'z'): DzFloatProperty => {
|
|
163
|
+
debug(`Getting rotation property for axis: ${axis} on node: ${node.getName()} - isBone: ${isBone(node)}`);
|
|
164
|
+
|
|
165
|
+
let prop: DzFloatProperty | undefined;
|
|
166
|
+
|
|
167
|
+
if (isBone(node)) {
|
|
168
|
+
prop = getNamedRotationForAxis(node, axis);
|
|
169
|
+
if (!prop) {
|
|
170
|
+
debug(`Named rotation not found for ${axis} on bone ${node.getName()}, falling back to generic search`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!prop) {
|
|
175
|
+
prop = find(
|
|
176
|
+
getRotations(node, false),
|
|
177
|
+
(rotation) => rotation.getName().valueOf()[0].toLowerCase() === axis
|
|
178
|
+
) as DzFloatProperty;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return prop;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const getNamedRotations = (node: DzNode): DzFloatProperty[] => {
|
|
185
|
+
const rotations: DzFloatProperty[] = []
|
|
186
|
+
|
|
187
|
+
for (let namedAxis in NamedAxis) {
|
|
188
|
+
let property = sceneHelper.findPropertyOnNodeByLabel(NamedAxis[namedAxis], node) as DzFloatProperty
|
|
189
|
+
if (property) rotations.push(property)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return rotations
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export const getRotationAxisFor = (node: DzNode, axis: NamedAxis): string => {
|
|
196
|
+
const rotations = getNamedRotations(node)
|
|
197
|
+
if (!rotations) return null
|
|
198
|
+
|
|
199
|
+
for (let rotation of rotations) {
|
|
200
|
+
if (rotation.getLabel() == axis) {
|
|
201
|
+
const axis = rotation.getName().valueOf()[0].toLowerCase()
|
|
202
|
+
return axis
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return null
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export const getNamedRotationForAxis = (node: DzNode, axis: 'x' | 'y' | 'z'): DzFloatProperty | null => {
|
|
210
|
+
const rotations = getNamedRotations(node)
|
|
211
|
+
if (!rotations) return null
|
|
212
|
+
|
|
213
|
+
for (let rotation of rotations) {
|
|
214
|
+
if (rotation.getName().valueOf()[0].toLowerCase() == axis) {
|
|
215
|
+
return rotation
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return null
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const getTranslations = (node: DzNode): DzFloatProperty[] => {
|
|
223
|
+
return !node ? [] : [node.getXPosControl(), node.getYPosControl(), node.getZPosControl()];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export const getScales = (node: DzNode): DzFloatProperty[] => {
|
|
227
|
+
return [node.getXScaleControl(), node.getYScaleControl(), node.getZScaleControl(), node.getScaleControl()];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export const getPropertiesFromSelectedGroup = (nodes: DzNode[], recursive: boolean = false, traverse: boolean = false, pane?: DzAbstractNodeEditorPane): DzProperty[] => {
|
|
231
|
+
var properties: DzProperty[] = [];
|
|
232
|
+
var propertyGroups = getSelectedPropertyGroups(pane);
|
|
233
|
+
|
|
234
|
+
nodes.forEach(node => {
|
|
235
|
+
propertyGroups.forEach(path => {
|
|
236
|
+
properties.push(...getPropertiesInPath(node, path, recursive, traverse));
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
return properties;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* A function for getting the list properties for an element
|
|
245
|
+
* @param node
|
|
246
|
+
* @param path
|
|
247
|
+
* @param recursive
|
|
248
|
+
* @returns
|
|
249
|
+
*/
|
|
250
|
+
export const getPropertiesInPath = (node: DzNode, path: string, recursive: boolean, traverse: boolean = false): DzProperty[] => {
|
|
251
|
+
if (!path) return getProperties(node);
|
|
252
|
+
|
|
253
|
+
var groupTree = node.getPropertyGroups();
|
|
254
|
+
var propertyGroup: DzPropertyGroup | null = null;
|
|
255
|
+
var name = "";
|
|
256
|
+
var index = -1;
|
|
257
|
+
var subPath = path;
|
|
258
|
+
|
|
259
|
+
while (!subPath.isEmpty()) {
|
|
260
|
+
index = subPath.indexOf("/");
|
|
261
|
+
if (index < 0) {
|
|
262
|
+
name = subPath;
|
|
263
|
+
subPath = "";
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
name = subPath.left(index);
|
|
267
|
+
subPath = subPath.right(subPath.length - index - 1);
|
|
268
|
+
}
|
|
269
|
+
propertyGroup = propertyGroup ? propertyGroup.findChild(name) : groupTree.findChild(name);
|
|
270
|
+
|
|
271
|
+
if (propertyGroup === null) break;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (!propertyGroup) return [];
|
|
275
|
+
|
|
276
|
+
return getPropertiesInGroup(propertyGroup, traverse, recursive);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const getPropertiesInGroup = (group: DzPropertyGroup, traverse: boolean, recursive: boolean): DzProperty[] => {
|
|
280
|
+
var properties: DzProperty[] = [];
|
|
281
|
+
|
|
282
|
+
if (!group) return properties;
|
|
283
|
+
|
|
284
|
+
var propertiesCount = group.getNumProperties();
|
|
285
|
+
|
|
286
|
+
properties = new Array(propertiesCount);
|
|
287
|
+
|
|
288
|
+
for (var i = 0; i < propertiesCount; i += 1) {
|
|
289
|
+
properties[i] = group.getProperty(i);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// If we are recursing
|
|
293
|
+
if (recursive) {
|
|
294
|
+
// Concatenate the properties array from child groups
|
|
295
|
+
properties = properties.concat(
|
|
296
|
+
getPropertiesInGroup(group.getFirstChild(), true, recursive));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// If we are traversing
|
|
300
|
+
if (traverse) {
|
|
301
|
+
// Concatenate the properties array from sibling groups
|
|
302
|
+
properties = properties.concat(
|
|
303
|
+
getPropertiesInGroup(group.getNextSibling(), traverse, recursive));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return properties;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Method for building a bounding box; optionally excluding a node and/or its children
|
|
311
|
+
* @param node
|
|
312
|
+
* @param excludeBase
|
|
313
|
+
* @param excludeChildren
|
|
314
|
+
* @param recursive
|
|
315
|
+
* @returns
|
|
316
|
+
* http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/core/frame_camera/start
|
|
317
|
+
*/
|
|
318
|
+
export const buildBoundingBox = (node: DzNode, excludeBase: boolean, excludeChildren: boolean, recursive: boolean): DzBox3 => {
|
|
319
|
+
var boxBounding = new DzBox3();
|
|
320
|
+
var g_oArrayHelper = new DzArrayHelper();
|
|
321
|
+
|
|
322
|
+
if (!node) return null;
|
|
323
|
+
|
|
324
|
+
// Define an array of nodes to exclude
|
|
325
|
+
var aExcludeNodes = (excludeChildren ? node.getNodeChildren(recursive) : []);
|
|
326
|
+
|
|
327
|
+
// If we're excluding the base node
|
|
328
|
+
if (excludeBase) {
|
|
329
|
+
// Add the base node to the front of the list
|
|
330
|
+
aExcludeNodes.unshift(node);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Declare working variable
|
|
334
|
+
var boxNode: DzBox3;
|
|
335
|
+
|
|
336
|
+
// Define a flag to indicate whether the box grows
|
|
337
|
+
var bHasGrown = false;
|
|
338
|
+
|
|
339
|
+
// Get whether a node is selected
|
|
340
|
+
var bSelectedNode = (Scene.getPrimarySelection() != undefined);
|
|
341
|
+
// Get the number of nodes to process
|
|
342
|
+
var nNodes = (bSelectedNode ? Scene.getNumSelectedNodes() : Scene.getNumNodes());
|
|
343
|
+
// Iterate over the nodes
|
|
344
|
+
for (var i = 0; i < nNodes; i += 1) {
|
|
345
|
+
// Get the 'current' node; based on selection
|
|
346
|
+
var oNode = (bSelectedNode ? Scene.getSelectedNode(i) : Scene.getNode(i));
|
|
347
|
+
// If we have a node and it is not in the exclude list
|
|
348
|
+
if (oNode && g_oArrayHelper.isInArray(aExcludeNodes, oNode) < 0) {
|
|
349
|
+
// Get the world space bounding box
|
|
350
|
+
boxNode = oNode.getWSBoundingBox();
|
|
351
|
+
// Grow our box to include the node box
|
|
352
|
+
boxBounding.include(boxNode.max);
|
|
353
|
+
boxBounding.include(boxNode.min);
|
|
354
|
+
// Update the flag
|
|
355
|
+
bHasGrown = true;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// If the box has not grown
|
|
360
|
+
if (!bHasGrown) {
|
|
361
|
+
// We're done here...
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Return the bounding box
|
|
366
|
+
return boxBounding;
|
|
367
|
+
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export const getPropertiesTree = <T = DzProperty>(node: DzNode, map?: (property: DzProperty) => T, filter?: (property: DzProperty) => boolean, showProgress: boolean = false): TreeNode<T>[] => {
|
|
371
|
+
if (showProgress) startProgress(`Collecting Properties`, 3)
|
|
372
|
+
let root: TreeNode<T>;
|
|
373
|
+
|
|
374
|
+
// Fetch properties and group them by their path
|
|
375
|
+
const properties = sceneHelper.getPropertiesOnNode(node);
|
|
376
|
+
if (showProgress) stepProgress()
|
|
377
|
+
|
|
378
|
+
const grouped = group(properties, (p) => p.getPath());
|
|
379
|
+
if (showProgress) stepProgress()
|
|
380
|
+
|
|
381
|
+
// Root TreeNode
|
|
382
|
+
root = new TreeNode<T>('root', '');
|
|
383
|
+
const pathMap: Record<string, TreeNode<T>> = { '': root };
|
|
384
|
+
|
|
385
|
+
// Process grouped entries
|
|
386
|
+
const groupedEntries = entries(grouped);
|
|
387
|
+
if (showProgress) stepProgress()
|
|
388
|
+
|
|
389
|
+
if (showProgress) startProgress(`Processing ${groupedEntries.length} properties`, groupedEntries.length)
|
|
390
|
+
for (const [path, props] of groupedEntries) {
|
|
391
|
+
const paths = path.split('/');
|
|
392
|
+
let currentPath = '';
|
|
393
|
+
|
|
394
|
+
// Create nodes for the path hierarchy
|
|
395
|
+
for (let i = 0; i < paths.length; i++) {
|
|
396
|
+
currentPath = paths.slice(0, i + 1).join('/');
|
|
397
|
+
if (!pathMap[currentPath]) {
|
|
398
|
+
const newNode = new TreeNode<T>(paths[i], currentPath);
|
|
399
|
+
pathMap[currentPath] = newNode;
|
|
400
|
+
|
|
401
|
+
if (i > 0) {
|
|
402
|
+
const parentPath = paths.slice(0, i).join('/');
|
|
403
|
+
const parentNode = pathMap[parentPath];
|
|
404
|
+
parentNode?.addChild(newNode);
|
|
405
|
+
newNode.parent = parentNode;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Add property nodes to the current path
|
|
411
|
+
const currentNode = pathMap[path];
|
|
412
|
+
if (currentNode) {
|
|
413
|
+
for (const property of props) {
|
|
414
|
+
if (filter && !filter(property)) continue
|
|
415
|
+
const newNode = new TreeNode<T>(
|
|
416
|
+
property.getLabel(),
|
|
417
|
+
property.getPath(),
|
|
418
|
+
map?.(property) ?? (property as T)
|
|
419
|
+
);
|
|
420
|
+
currentNode.addChild(newNode);
|
|
421
|
+
newNode.parent = currentNode;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (showProgress) stepProgress()
|
|
425
|
+
}
|
|
426
|
+
if (showProgress) finishProgress()
|
|
427
|
+
if (showProgress) finishProgress()
|
|
428
|
+
|
|
429
|
+
// Return root children or an empty array if none exist
|
|
430
|
+
return root.children.length > 0 ? root.children : [];
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
export const getPropertiesPathsTree = (node: DzNode): TreeNode<string>[] => {
|
|
434
|
+
let items = entries(group(sceneHelper.getPropertiesOnNode(node), (p) => p.getPath())).map(x => ({ path: x[0], properties: x[1] }))
|
|
435
|
+
|
|
436
|
+
const root = new TreeNode<string>('root', '')
|
|
437
|
+
const pathMap: { [key: string]: TreeNode<string> } = { '': root }
|
|
438
|
+
|
|
439
|
+
items.forEach(element => {
|
|
440
|
+
const paths = element.path.split('/')
|
|
441
|
+
let currentPath = ''
|
|
442
|
+
|
|
443
|
+
paths.forEach((path, index) => {
|
|
444
|
+
currentPath += `${index === 0 ? '' : '/'}${path}`
|
|
445
|
+
if (!pathMap[currentPath]) {
|
|
446
|
+
const newNode = new TreeNode<string>(path, currentPath)
|
|
447
|
+
pathMap[currentPath] = newNode
|
|
448
|
+
|
|
449
|
+
if (index !== 0) {
|
|
450
|
+
const parentPath = currentPath.substring(0, currentPath.lastIndexOf('/'))
|
|
451
|
+
const parentNode = pathMap[parentPath]
|
|
452
|
+
parentNode?.addChild(newNode)
|
|
453
|
+
newNode.parent = parentNode
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
})
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
const rootChildren = pathMap[''].children
|
|
460
|
+
return rootChildren && rootChildren.length > 0 ? rootChildren : root.children
|
|
461
|
+
}
|