-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLSUtilLib.ms
479 lines (410 loc) · 13.7 KB
/
LSUtilLib.ms
1
2
3
4
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
37
38
39
40
41
42
43
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
/*
LSUtilLib.ms
Version: 1.52
Created On: December 05, 2002
Created By: Jeff Hanna
Modified On: January 03, 2018
Modified By: Jeff Hanna
tested using 3ds Max 2016
v1.52 - Removed RemoveDuplicates() and changed all append() calls to appendIfUnique()
v1.51 - Renamed variables to match programming guidelines.
Removed the strStartMapsFile and strFileToOpen variables. They weren't used in this script.
v1.5 - Added the GeometryFilter and GetSelectionBoundingBox functions.
Commented out the strStartMapsFile and strFileToOpen variable declarations. They are P4Lib.ms variables. Why are they being delcared here?
v1.4 - Reworked functions to standardized programming conventions.
Changed DOSTempPath function to take start and end character locations as input variables.
v1.3 - Added CompareFileDates function
v1.2 - Renamed the function "ConvertArrays" to "ConvertArray" since it only works on one array at a time.
v1.1 - Initial release.
*/
struct LSUtilLib_Base
(
strLSULVersion = "1.52",
-- Performs a simple alphabetic check on two file names. Returns a value indicating which one is
-- closer to A in the alphabet (e.g. A_File.text is higher than File.text)
fn NameCompare strName1 strName2 =
(
if strName1.name < strName2.name then
(
return -1
)
else if strName1.name > strName2.name then
(
return 1
)
else
(
return 0
)
),
-------------------------------------------------------------------------------------------------------------------------
--FILE MANIPULATION FUNCTIONS
---------------------------------
-- Takes an array of items and a file path name.
-- Writes the list of items in the array to the file on disk.
fn WriteFile aInput strFilePath =
(
local FileOut = createFile strFilePath
for i in aInput do
(
format "%\n" i to:FileOut
)
close FileOut
),
-------------------------------------------------------------------------------------------------------------------------
-- Takes two file paths and checks to see if they point to files of the same name.
-- If so, it checks the modification dates to see which is newer.
-- Returns 0 if the files aren't the same name and can't be compared.
-- Returns 1 if the files have the same modification dates/times.
-- Returns 2 if the first input file is newer.
-- Returns 3 if the second input file is newer.
fn CompareFileDates strFile1 strFile2 =
(
local iResult = 0
-- If the file names don't match the files can't be synchronized
if (getFilenameFile strFile1) != (getFilenameFile strFile2) then
(
iResult = 0
)
else
(
-- If the file mod dates are the same the files don't need to be synchronized
if getFileModDate strFile1 == getFileModDate strFile2 then
(
iResult = 1
)
else
(
-- Break File 1's mod date info up and put it in an array
-- The array items are always ordered; MM, DD, YYY, HH, MM, SS
aFile1ModInfo = filterString (getFileModDate strFile1) "//, ,:"
-- Break File 2's mod date info up and put it in an array
aFile2ModInfo = filterstring (getFileModDate strFile2) "//, ,:"
-- Pull the MM/DD/YYYY and HH:MM:SS out of the arrays and put them in integer variables for comparison.
-- Must be done since the values in the array are strings and won't compare properly as such.
iFile1Month = aFile1ModInfo[1] as integer
iFile2Month = aFile2ModInfo[1] as integer
iFile1Day = aFile1ModInfo[2] as integer
iFIle2Day = aFile2ModInfo[2] as integer
iFile1Year = aFile1ModInfo[3] as integer
iFile2Year = aFile2ModInfo[3] as integer
iFile1Hour = aFile1ModInfo[4] as integer
iFile2Hour = aFile2ModInfo[4] as integer
iFile1Minute = aFile1ModInfo[5] as integer
iFile2Minute = aFile2ModInfo[5] as integer
iFile1Second = aFile1ModInfo[6] as integer
iFile2Second = aFile2ModInfo[6] as integer
-- Check to see if File2's date is newer than File1's.
if iFile2Month > iFile1Month and iFile2Day > iFile1Day and iFile2Year > iFile1Year then
(
-- If the date is newer, then check the time to see if it is newer.
if iFile2Hour > iFile1Hour and iFile2Minute >= iFile1Minute and iFile2Second > iFile1Second then
(
iResult = 3
)
)
-- If file 1's mod date info is newer than File 2's it must be the newer file.
else
(
iResult = 2
)
)
)
return iResult
),
-------------------------------------------------------------------------------------------------------------------------
--PATH MANIPULATION FUNCTIONS
----------------------------------
-- Convert the array's elements from DOS based absolute pathing to Unix based relative pathing.
fn ConvertArrayDOS2Unix aInput =
(
local aReturn = #()
for i in aInput do
(
i = MakeRelativePath i
aPathPieces = filterString i "\\"
local UnixPath = stringStream ""
format "//" to:UnixPath
for j = 1 to aPathPieces.count do
(
format aPathPieces[j] to:UnixPath
if j != aPathPieces.count then
(
format "/" to:UnixPath
)
)
close UnixPath
strUnixPath = UnixPath as string
appendIfUnique aReturn strUnixPath
)
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
-- Changes C:\ absolute pathing to \\ relative pathing
fn MakeRelativePath strInputPath =
(
replace strInputPath 1 2 "\\"
),
-------------------------------------------------------------------------------------------------------------------------
-- DOS Commands don't understand the Max-centric relative Temp path of $temp.
-- Instead, they understand %temp%.
fn DOSTempPath strInputPath iStartCharacter iEndCharacter =
(
replace strInputPath iStartCharacter iEndCharacter "%temp%"
),
-------------------------------------------------------------------------------------------------------------------------
--MATERIAL TREE FUNCTIONS
----------------------------
--Scan the scene to find all Map assignments within it.
fn GetSceneMaps =
(
local aSceneMaterials = #()
local aReturn = #()
aTempMap = #()
aSceneMaterials = this.GetSceneMaterials()
for i in aSceneMaterials do
(
aTempMaps = #()
this.GetMapsFromMaterial i aTempMaps
join aReturn aTempMaps
)
qSort aReturn NameCompare
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
--Scan the scene to find all material assignments within it.
fn GetSceneMaterials =
(
local aReturn = #()
local iIndex = 0 as integer
for i in $* do
(
if i.material != undefined then
(
for i in (this.GetAllMaterials i.material) do
(
iIndex = findItem aReturn i
if iIndex == 0 then
(
appendIfUnique aReturn i
)
)
)
)
qSort aReturn NameCompare
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
-- Find all materials and multi-sub materials within a given assigned scene material.
fn GetAllMaterials InputMaterial =
(
aReturn = #()
aTempMaterials = #()
appendIfUnique aReturn InputMaterial
this.GetSubMaterials InputMaterial aTempMaterials
for i in aTempMaterials do
(
if findItem aReturn i == 0 then
(
appendIfUnique aReturn i
)
)
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
-- If the InputMaterial array has multi-sub materials then scan them for material entries.
fn GetSubMaterials InputMaterial aInput =
(
if InputMaterial.numsubs != 0 then
(
for i = 1 to InputMaterial.numsubs do
(
if InputMaterial[i] != undefined then
(
if isKindOf InputMaterial[i] material == true then
(
if classOf InputMaterial[i] == subAnim then
(
if superClassOf InputMaterial[i].object == material then
(
if findItem aInput (InputMaterial[i].object) == 0 then
(
appendIfUnique aInput (InputMaterial[i].object)
)
)
)
if superClassOf InputMaterial[i] == material then
(
if findItem aInput InputMaterial[i] == 0 then
(
appendIfUnique aInput InputMaterial[i]
)
)
)
GetSubMaterials InputMaterial[i] aInput
)
)
)
),
-------------------------------------------------------------------------------------------------------------------------
-- Find all maps in the inputted materials.
fn GetMapsFromMaterial InputMaterial aInput =
(
if InputMaterial.numsubs != 0 then
(
for i = 1 to InputMaterial.numsubs do
(
if InputMaterial[i] != undefined then
(
if classOf InputMaterial[i] == subAnim then
(
if superClassOf InputMaterial[i].object == textureMap then
(
if InputMaterial[i].object != undefined then
(
appendIfUnique aInput InputMaterial[i].object
)
)
)
GetMapsFromMaterial InputMaterial[i] aInput
)
)
)
),
-------------------------------------------------------------------------------------------------------------------------
-- Scan the lights in the scene for projector map bitmaps.
fn GetOtherMaps =
(
local aReturn = #()
for i in lights do
(
if superClassof i == light then
(
local bLightType = false
if classOf i == targetSpot or classOf i == Omnilight or classOf i == TargetDirectionallight or classOf i == Directionallight or classOf i == freeSpot then
(
bLightType = true
)
if bLightType == true then
(
if i.projectorMap != undefined then
(
appendIfUnique aReturn i.projetorMap
)
if i.shadowProjectorMap != undefined then
(
appendIfUnique aReturn i.shadowProjectorMap
)
)
)
)
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
-- From the input array of maps gather all of the bitmap filepaths.
fn GetBitmapsFromMaps aInput =
(
local aReturn = #()
for i in aInput do
(
if classOf i == Bitmaptexture then
(
appendIfUnique aReturn i.filename
)
)
return aReturn
),
-------------------------------------------------------------------------------------------------------------------------
--BITMAP PATH FUNCTIONS
--------------------------
-- Enumerate all bitmaps in the scene. If the gathered bitmap isn't in the array of stored bitmaps, add it.
-- DEPRECATED DUE TO THE FACT THAT IT DOESN'T ALWAYS GATHER ALL BITMAPS IN THE SCENE.
fn GetUsedMapPaths strMapPathname =
(
local iIndex = findItem StartMapPathnames strMapPathname
StartMapPathnames = #()
if iIndex == 0 do
(
appendIfUnique StartMapPathnames strMapPathname
)
),
-------------------------------------------------------------------------------------------------------------------------
-- Compare the list of current maps against the array of original maps to see if any new ones were added to the Max scene.
-- DEPRECATED DUE TO THE FACT THAT IT DOESN'T ALWAYS GATHER ALL BITMAPS IN THE SCENE.
fn GetNewMapPaths strNewPathname =
(
local iIndex = findItem StartMapPathnames strNewPathname
if iIndex == 0 do
(
appendIfUnique NewPathnames strNewPathname
)
),
-------------------------------------------------------------------------------------------------------------------------
--GEOMETRY FUNCTIONS
------------------------
-- Pickbutton filter that tests the potential pick object to ensure that it is valid geometry.
fn GeometryFilter InputObject =
(
superClassOf InputObject == GeometryClass
),
-------------------------------------------------------------------------------------------------------------------------
-- Takes the current selected objects, puts them into an array, then calculates the bounding volume for all of the objects.
fn GetSelectionBoundingBox =
(
-- Put the selected items into an array.
arraySelection = $*
local point3Min = [0,0,0]
local point3Max = [0,0,0]
-- If the array is empty, return null bounding volume coordinates.
if arraySelection.count == 0 then
(
return #(point3Min, point3Max)
)
else
(
-- Else, walk the array and compare each element's min and max values against the initial set.
for i in arraySelection do
(
-- Check each element to see if it is valid geometry. Skip objects that don't have a volume associated with them.
if superclassof i != light and superclassof i != camera and superclassof i != spacewarpObject then
(
-- If the element''s min coordinates are smaller than the initial set, replace the initial set with these coordinates.
if i.min.x < point3Min.x then
(
point3Min.x = i.min.x
)
if i.min.y < point3Min.y then
(
point3Min.y = i.min.y
)
if i.min.z < point3Min.z then
(
point3Min.z = i.min.z
)
-- If the element's max coordinates are larger then the initial set, replace the initial set with these coordinates.
if i.max.x > point3Max.x then
(
point3Max.x = i.max.x
)
if i.max.y > point3Max.y then
(
point3Max.y = i.max.y
)
if i.max.z > point3Max.z then
(
point3Max.z = i.max.z
)
)
)
return #(point3Min, point3Max)
)
),
-------------------------------------------------------------------------------------------------------------------------
fn init =
(
-- print version information to the listener. Useful if a bug-report needs to be sent.
format "LSUtilLib v% loaded.\n" strLSULVersion to:Listener
)
)
LSUtilLib = LSUtilLib_Base()
LSUtilLib.init()