✨ feat: update readme & scripts
Browse files- README.md +24 -0
- animation_frames.json +0 -0
- character_bones.txt +162 -0
- character_old_fbx.txt +51 -0
- character_refine.py +160 -0
- character_unposed.txt +20 -0
- character_verts.json +92 -0
- mixamo_download_script.js +649 -0
- requirements.txt +3 -0
- try_import_blender.py +40 -0
README.md
CHANGED
@@ -1,3 +1,27 @@
|
|
1 |
---
|
2 |
license: apache-2.0
|
3 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
license: apache-2.0
|
3 |
---
|
4 |
+
|
5 |
+
## Data
|
6 |
+
|
7 |
+
- `character`: 95 characters (T-pose with bones and texture) downloaded from [Mixamo](https://www.mixamo.com/#/?page=1&type=Character)
|
8 |
+
|
9 |
+
- `character_fbx_upgraded`: 51 (among 95) characters with FBX version upgraded by [FBX Converter](https://aps.autodesk.com/developer/overview/fbx-converter-archives) (so that they can be imported into [Blender](https://www.blender.org/))
|
10 |
+
|
11 |
+
- **`character_refined`**: all 95 characters (triangle mesh without texture, animatable by any one from `animation`) processed with `character_refine.py`
|
12 |
+
- vertices: 2374 ~ 35128 (average: 15482; details in `character_verts.json`)
|
13 |
+
- bones: 42 ~ 112 (mostly standard 65 *mixamorig* bones; details in `character_bones.txt`)
|
14 |
+
|
15 |
+
- **`animation`**: 2453 animations (only bones) downloaded from [Mixamo](https://www.mixamo.com/#/?page=1&type=Motion)
|
16 |
+
- frames: 2 ~ 2801 (average: 212; details in `animation_frames.json`)
|
17 |
+
|
18 |
+
## Reproduction
|
19 |
+
|
20 |
+
1. Download characters and animations [Mixamo](https://www.mixamo.com/).
|
21 |
+
|
22 |
+
2. Convert old-version FBX (`try_import_blender.py` > `character_old_fbx.txt`) with [FBX Converter](https://aps.autodesk.com/developer/overview/fbx-converter-archives).
|
23 |
+
|
24 |
+
3. ~~Re-target unposed characters with [Auto-Rig Pro](https://blendermarket.com/products/auto-rig-pro) (bind-only) in Blender.~~
|
25 |
+
Rename corrupted bone names in unposed characters (`character_unposed.txt`).
|
26 |
+
|
27 |
+
4. Convert all characters into **triangle mesh without texture** with [Blender](https://docs.blender.org/api/current/info_advanced_blender_as_bpy.html).
|
animation_frames.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
character_bones.txt
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
./character/0510032b674ce33343c2e058ef52e8c5.fbx: 65
|
2 |
+
./character/06caf212ded22a78500c06ebf372c9bb.fbx: 65
|
3 |
+
./character/079f3ee7c8d748481707ca78c95750ac.fbx: 65
|
4 |
+
./character/08ed9e6576433de9fb72baae34d482b6.fbx: 65
|
5 |
+
./character/08f7e724f32af241e56a9244c2f37b43.fbx: 65
|
6 |
+
./character/098424150eb08fb107185646afaeee83.fbx: 64
|
7 |
+
./character/0a29fafad2ca23eba1787e20894ea8f6.fbx: 65
|
8 |
+
./character/0b69ca9d9cd64f4c061659f29956e297.fbx: 81
|
9 |
+
./character/0eb7402a9104734d873599c7f9f01c3d.fbx: 99
|
10 |
+
./character/0fa8427ca1b7b2f410e893daa42df16c.fbx: 67
|
11 |
+
./character/123d7c7f828741681ffed14eacaf606d.fbx: 69
|
12 |
+
./character/19b740666ef33a06abf265235d8281a0.fbx: 65
|
13 |
+
./character/1c679b4220a9b78133db6c49f59ca65c.fbx: 83
|
14 |
+
./character/1f6a7214d5f9eee30f4da837ad0db9a9.fbx: 65
|
15 |
+
./character/216f6676c0df33582682a270735a0bda.fbx: 65
|
16 |
+
./character/222261b7a837ccdf5db5ea086430d4c7.fbx: 112
|
17 |
+
./character/258580e0c4983768c0233dca33157732.fbx: 57
|
18 |
+
./character/27de3b0b89d27fa7e654955765e40d3b.fbx: 79
|
19 |
+
./character/28069e1e9f570cc90128fe1241343875.fbx: 47
|
20 |
+
./character/2d925ffeafc887cf96d22d272e6a87cd.fbx: 69
|
21 |
+
./character/32db57cc0f9c3ee01c22924512d56283.fbx: 73
|
22 |
+
./character/39967d464dd297954f89d06fb587045f.fbx: 99
|
23 |
+
./character/3c21546cb958a3daba75704b232b7e4b.fbx: 65
|
24 |
+
./character/3e911fa9c30c9a00a9de31409095cd57.fbx: 67
|
25 |
+
./character/3ec1224ed7c692d1e83a4cdfc2f5340b.fbx: 65
|
26 |
+
./character/4c989f8d4d0b9c1e6e096f21719fd09d.fbx: 66
|
27 |
+
./character/4cd9c2951759527d10bb7916baa80ca2.fbx: 99
|
28 |
+
./character/4fd247797b4f3653d5c2a8b335b03d29.fbx: 69
|
29 |
+
./character/51b67149e52d48e2442f1db223f59ba9.fbx: 65
|
30 |
+
./character/51d19d5e4cd1c8c8d75a97f078ff9476.fbx: 65
|
31 |
+
./character/51e1e51887023725371b27fd0cb3dca1.fbx: 65
|
32 |
+
./character/525795a33ca1026996b5ca009d61e263.fbx: 65
|
33 |
+
./character/57f74ab8c6de76c82d53e3257a6778e4.fbx: 65
|
34 |
+
./character/5bf474106308ccb071045e9579ca95e5.fbx: 65
|
35 |
+
./character/5cd6b5bf8b921a2cb0e4ce71d685ff90.fbx: 69
|
36 |
+
./character/6987df4026a93126ed745db3b5f2fbcf.fbx: 67
|
37 |
+
./character/69c3f460dcf1f1f97942d5dafaac572d.fbx: 65
|
38 |
+
./character/73cd22e7123f4c8e78ffc11ad5fbbc29.fbx: 65
|
39 |
+
./character/75a7bced986dc088580ecbe09e1c8590.fbx: 65
|
40 |
+
./character/761718127eb6d283b7bf7076bca62b78.fbx: 65
|
41 |
+
./character/761b5a0cf1945d0089f00686beb41f49.fbx: 65
|
42 |
+
./character/7dcd7c3eb5f2fb50caf6ae6896e9464c.fbx: 65
|
43 |
+
./character/7dd7bf41bda834a9500b2ff93705ad02.fbx: 65
|
44 |
+
./character/7faa53355e944ba38be5a4b7de179290.fbx: 65
|
45 |
+
./character/7fd6d88afe76663358a61901be3c6c15.fbx: 65
|
46 |
+
./character/8044e1503d3549a144741dc1878d414a.fbx: 43
|
47 |
+
./character/81f41f90717b8383b3d2fffb18f95d07.fbx: 65
|
48 |
+
./character/831a835d6cca7f50fee848116a1e0a6b.fbx: 88
|
49 |
+
./character/83828f0fe01d389df691a0b8f2e19b95.fbx: 72
|
50 |
+
./character/840c84726b0f55c9fa7235074394fd6a.fbx: 67
|
51 |
+
./character/85bc8db2b257cf836c186593aa8a1fce.fbx: 43
|
52 |
+
./character/893b3e8f4a0cea4255ccee36633756e7.fbx: 65
|
53 |
+
./character/8b6cd9d3a78bdf860d3d06b58715b310.fbx: 65
|
54 |
+
./character/8dfaf7ace7778cd25a6b181d98cd7e77.fbx: 67
|
55 |
+
./character/93025f9cd069b342a20217702a522b54.fbx: 65
|
56 |
+
./character/932216e3a518b0468f18bbb824ee6fa5.fbx: 65
|
57 |
+
./character/9882611aba55c935f071e41769da7b99.fbx: 65
|
58 |
+
./character/9a24bbb67c6dac80b1e83238982fc9bd.fbx: 65
|
59 |
+
./character/9a3c048709538dfbe0be943c9fae3d62.fbx: 65
|
60 |
+
./character/9e33cfb2c5443136600e393a4aa2e7f1.fbx: 43
|
61 |
+
./character/a0641e810f7d000c8ca59e7224c9d796.fbx: 72
|
62 |
+
./character/a3d6df0a1670bd02cc732c8137427dbe.fbx: 67
|
63 |
+
./character/a4ce3af02c103b2e9b78b9b14e7a01a3.fbx: 65
|
64 |
+
./character/a688cfa656103db0d2acb62c8d2d9144.fbx: 69
|
65 |
+
./character/aa03d7c7297f3864ce77600f5f940606.fbx: 69
|
66 |
+
./character/aed9922313c4b66e9b3ec1bc6dec06a8.fbx: 65
|
67 |
+
./character/b0ce097858de7591269ef24996ad0808.fbx: 67
|
68 |
+
./character/b1bf836b9d040760b79534e30a8cba76.fbx: 86
|
69 |
+
./character/b1ca6a6e9f48e9a7e4c2a92eb1837e37.fbx: 69
|
70 |
+
./character/b1eea1f10e0a85ad8f6b8c8cc5882cf8.fbx: 65
|
71 |
+
./character/b45062da94f349e53a67b0028539deac.fbx: 63
|
72 |
+
./character/b6e2f4dbb404550f7c05e5158c45f979.fbx: 65
|
73 |
+
./character/b78413c2dc7908bf952a609b24569807.fbx: 65
|
74 |
+
./character/b9ae94869ab838ee63cf92990211e525.fbx: 49
|
75 |
+
./character/bad88bdd65811e64a724b49cb0e505a5.fbx: 65
|
76 |
+
./character/bc9c26c1c3653c81d3d35261cd696839.fbx: 67
|
77 |
+
./character/bd0a2e2cc4da1a2e566e6dd98402edfb.fbx: 65
|
78 |
+
./character/bd5584dc8872126d57d969aa07ec09a6.fbx: 37
|
79 |
+
./character/c3b24f5c406ef4c09c2c07ae65dba0e0.fbx: 65
|
80 |
+
./character/c4d054e07d59a8b2224e07ab2fbf505b.fbx: 75
|
81 |
+
./character/c92d8db4a32b4606fb6258a385f5fcd1.fbx: 65
|
82 |
+
./character/cb8b934b054940623581dfaf5d9fd468.fbx: 68
|
83 |
+
./character/cdf89c5c4430cbc672e0f61c78797d39.fbx: 65
|
84 |
+
./character/cf65a1c8be43a9c90570b99a0b702aff.fbx: 76
|
85 |
+
./character/cf7e9c498421b75e2df678adc5284783.fbx: 65
|
86 |
+
./character/d2f2e35da6c1fcca872fccf83fef9a5a.fbx: 72
|
87 |
+
./character/e000b51a0c9526a75f155bc925722db3.fbx: 65
|
88 |
+
./character/e426198d78eaf096bf1e38ffdaa9af17.fbx: 73
|
89 |
+
./character/e4280b007901ef1c87a68be75323ab39.fbx: 87
|
90 |
+
./character/e5e1eccee079207473fafb1c163e2272.fbx: 65
|
91 |
+
./character/eb5e61abbf1fd39f3e73212723d5f580.fbx: 66
|
92 |
+
./character/eceb1dd6a739c6523c4208394e95a659.fbx: 69
|
93 |
+
./character/ed5953ef8156aee8bbe329c3e6ff39a0.fbx: 68
|
94 |
+
./character/f24b568cf5d54dca7fbe5dd328e49632.fbx: 59
|
95 |
+
./character/fdad443d5251b547f75d6578a6447c7c.fbx: 65
|
96 |
+
mixamorig:Hips: 95/95
|
97 |
+
mixamorig:Spine: 95/95
|
98 |
+
mixamorig:Spine1: 95/95
|
99 |
+
mixamorig:Spine2: 95/95
|
100 |
+
mixamorig:Neck: 95/95
|
101 |
+
mixamorig:Head: 95/95
|
102 |
+
mixamorig:HeadTop_End: 95/95
|
103 |
+
LeftEye: 3/95
|
104 |
+
RightEye: 3/95
|
105 |
+
mixamorig:LeftShoulder: 95/95
|
106 |
+
mixamorig:LeftArm: 95/95
|
107 |
+
mixamorig:LeftForeArm: 95/95
|
108 |
+
mixamorig:LeftHand: 95/95
|
109 |
+
mixamorig:LeftHandThumb1: 94/95
|
110 |
+
mixamorig:LeftHandThumb2: 94/95
|
111 |
+
mixamorig:LeftHandThumb3: 94/95
|
112 |
+
mixamorig:LeftHandThumb4: 94/95
|
113 |
+
mixamorig:LeftHandIndex1: 94/95
|
114 |
+
mixamorig:LeftHandIndex2: 94/95
|
115 |
+
mixamorig:LeftHandIndex3: 94/95
|
116 |
+
mixamorig:LeftHandIndex4: 93/95
|
117 |
+
mixamorig:LeftHandMiddle1: 91/95
|
118 |
+
mixamorig:LeftHandMiddle2: 91/95
|
119 |
+
mixamorig:LeftHandMiddle3: 91/95
|
120 |
+
mixamorig:LeftHandMiddle4: 90/95
|
121 |
+
mixamorig:LeftHandRing1: 90/95
|
122 |
+
mixamorig:LeftHandRing2: 90/95
|
123 |
+
mixamorig:LeftHandRing3: 90/95
|
124 |
+
mixamorig:LeftHandRing4: 89/95
|
125 |
+
mixamorig:LeftHandPinky1: 88/95
|
126 |
+
mixamorig:LeftHandPinky2: 88/95
|
127 |
+
mixamorig:LeftHandPinky3: 88/95
|
128 |
+
mixamorig:LeftHandPinky4: 87/95
|
129 |
+
mixamorig:RightShoulder: 95/95
|
130 |
+
mixamorig:RightArm: 95/95
|
131 |
+
mixamorig:RightForeArm: 95/95
|
132 |
+
mixamorig:RightHand: 95/95
|
133 |
+
mixamorig:RightHandThumb1: 94/95
|
134 |
+
mixamorig:RightHandThumb2: 94/95
|
135 |
+
mixamorig:RightHandThumb3: 94/95
|
136 |
+
mixamorig:RightHandThumb4: 94/95
|
137 |
+
mixamorig:RightHandIndex1: 94/95
|
138 |
+
mixamorig:RightHandIndex2: 94/95
|
139 |
+
mixamorig:RightHandIndex3: 94/95
|
140 |
+
mixamorig:RightHandIndex4: 93/95
|
141 |
+
mixamorig:RightHandMiddle1: 89/95
|
142 |
+
mixamorig:RightHandMiddle2: 89/95
|
143 |
+
mixamorig:RightHandMiddle3: 89/95
|
144 |
+
mixamorig:RightHandMiddle4: 88/95
|
145 |
+
mixamorig:RightHandRing1: 89/95
|
146 |
+
mixamorig:RightHandRing2: 89/95
|
147 |
+
mixamorig:RightHandRing3: 89/95
|
148 |
+
mixamorig:RightHandRing4: 88/95
|
149 |
+
mixamorig:RightHandPinky1: 88/95
|
150 |
+
mixamorig:RightHandPinky2: 88/95
|
151 |
+
mixamorig:RightHandPinky3: 88/95
|
152 |
+
mixamorig:RightHandPinky4: 87/95
|
153 |
+
mixamorig:LeftUpLeg: 95/95
|
154 |
+
mixamorig:LeftLeg: 95/95
|
155 |
+
mixamorig:LeftFoot: 95/95
|
156 |
+
mixamorig:LeftToeBase: 95/95
|
157 |
+
mixamorig:LeftToe_End: 95/95
|
158 |
+
mixamorig:RightUpLeg: 95/95
|
159 |
+
mixamorig:RightLeg: 95/95
|
160 |
+
mixamorig:RightFoot: 95/95
|
161 |
+
mixamorig:RightToeBase: 95/95
|
162 |
+
mixamorig:RightToe_End: 95/95
|
character_old_fbx.txt
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
./character/098424150eb08fb107185646afaeee83.fbx
|
2 |
+
./character/0b69ca9d9cd64f4c061659f29956e297.fbx
|
3 |
+
./character/0eb7402a9104734d873599c7f9f01c3d.fbx
|
4 |
+
./character/0fa8427ca1b7b2f410e893daa42df16c.fbx
|
5 |
+
./character/123d7c7f828741681ffed14eacaf606d.fbx
|
6 |
+
./character/19b740666ef33a06abf265235d8281a0.fbx
|
7 |
+
./character/1c679b4220a9b78133db6c49f59ca65c.fbx
|
8 |
+
./character/222261b7a837ccdf5db5ea086430d4c7.fbx
|
9 |
+
./character/27de3b0b89d27fa7e654955765e40d3b.fbx
|
10 |
+
./character/28069e1e9f570cc90128fe1241343875.fbx
|
11 |
+
./character/2d925ffeafc887cf96d22d272e6a87cd.fbx
|
12 |
+
./character/32db57cc0f9c3ee01c22924512d56283.fbx
|
13 |
+
./character/39967d464dd297954f89d06fb587045f.fbx
|
14 |
+
./character/3e911fa9c30c9a00a9de31409095cd57.fbx
|
15 |
+
./character/4c989f8d4d0b9c1e6e096f21719fd09d.fbx
|
16 |
+
./character/4cd9c2951759527d10bb7916baa80ca2.fbx
|
17 |
+
./character/4fd247797b4f3653d5c2a8b335b03d29.fbx
|
18 |
+
./character/51e1e51887023725371b27fd0cb3dca1.fbx
|
19 |
+
./character/5cd6b5bf8b921a2cb0e4ce71d685ff90.fbx
|
20 |
+
./character/6987df4026a93126ed745db3b5f2fbcf.fbx
|
21 |
+
./character/761b5a0cf1945d0089f00686beb41f49.fbx
|
22 |
+
./character/8044e1503d3549a144741dc1878d414a.fbx
|
23 |
+
./character/840c84726b0f55c9fa7235074394fd6a.fbx
|
24 |
+
./character/85bc8db2b257cf836c186593aa8a1fce.fbx
|
25 |
+
./character/8dfaf7ace7778cd25a6b181d98cd7e77.fbx
|
26 |
+
./character/9e33cfb2c5443136600e393a4aa2e7f1.fbx
|
27 |
+
./character/a0641e810f7d000c8ca59e7224c9d796.fbx
|
28 |
+
./character/a3d6df0a1670bd02cc732c8137427dbe.fbx
|
29 |
+
./character/a688cfa656103db0d2acb62c8d2d9144.fbx
|
30 |
+
./character/aa03d7c7297f3864ce77600f5f940606.fbx
|
31 |
+
./character/aed9922313c4b66e9b3ec1bc6dec06a8.fbx
|
32 |
+
./character/b0ce097858de7591269ef24996ad0808.fbx
|
33 |
+
./character/b1bf836b9d040760b79534e30a8cba76.fbx
|
34 |
+
./character/b1ca6a6e9f48e9a7e4c2a92eb1837e37.fbx
|
35 |
+
./character/b45062da94f349e53a67b0028539deac.fbx
|
36 |
+
./character/bad88bdd65811e64a724b49cb0e505a5.fbx
|
37 |
+
./character/bc9c26c1c3653c81d3d35261cd696839.fbx
|
38 |
+
./character/bd0a2e2cc4da1a2e566e6dd98402edfb.fbx
|
39 |
+
./character/bd5584dc8872126d57d969aa07ec09a6.fbx
|
40 |
+
./character/c3b24f5c406ef4c09c2c07ae65dba0e0.fbx
|
41 |
+
./character/c4d054e07d59a8b2224e07ab2fbf505b.fbx
|
42 |
+
./character/c92d8db4a32b4606fb6258a385f5fcd1.fbx
|
43 |
+
./character/cb8b934b054940623581dfaf5d9fd468.fbx
|
44 |
+
./character/cf65a1c8be43a9c90570b99a0b702aff.fbx
|
45 |
+
./character/cf7e9c498421b75e2df678adc5284783.fbx
|
46 |
+
./character/d2f2e35da6c1fcca872fccf83fef9a5a.fbx
|
47 |
+
./character/e426198d78eaf096bf1e38ffdaa9af17.fbx
|
48 |
+
./character/eb5e61abbf1fd39f3e73212723d5f580.fbx
|
49 |
+
./character/eceb1dd6a739c6523c4208394e95a659.fbx
|
50 |
+
./character/ed5953ef8156aee8bbe329c3e6ff39a0.fbx
|
51 |
+
./character/f24b568cf5d54dca7fbe5dd328e49632.fbx
|
character_refine.py
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from glob import glob
|
4 |
+
|
5 |
+
import bpy
|
6 |
+
import numpy as np
|
7 |
+
from tqdm import tqdm
|
8 |
+
|
9 |
+
|
10 |
+
class HiddenPrints:
|
11 |
+
def __init__(self, disable=False):
|
12 |
+
self.disable = disable
|
13 |
+
|
14 |
+
def __enter__(self):
|
15 |
+
if self.disable:
|
16 |
+
return
|
17 |
+
self._original_stdout = sys.stdout
|
18 |
+
sys.stdout = open(os.devnull, "w")
|
19 |
+
|
20 |
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
21 |
+
if self.disable:
|
22 |
+
return
|
23 |
+
sys.stdout.close()
|
24 |
+
sys.stdout = self._original_stdout
|
25 |
+
|
26 |
+
|
27 |
+
def remove_all(delete_actions=True):
|
28 |
+
for obj in bpy.data.objects.values():
|
29 |
+
bpy.data.objects.remove(obj, do_unlink=True)
|
30 |
+
bpy.ops.outliner.orphans_purge(do_recursive=True)
|
31 |
+
if delete_actions:
|
32 |
+
for action in bpy.data.actions:
|
33 |
+
bpy.data.actions.remove(action, do_unlink=True)
|
34 |
+
|
35 |
+
|
36 |
+
def load_file(filepath: str):
|
37 |
+
old_objs = set(bpy.context.scene.objects)
|
38 |
+
if filepath.endswith(".glb"):
|
39 |
+
bpy.ops.import_scene.gltf(filepath=filepath)
|
40 |
+
elif filepath.endswith(".fbx"):
|
41 |
+
bpy.ops.import_scene.fbx(filepath=filepath)
|
42 |
+
else:
|
43 |
+
raise RuntimeError(f"Invalid input file: {filepath}")
|
44 |
+
imported_objs = set(bpy.context.scene.objects) - old_objs
|
45 |
+
print("Imported:", imported_objs)
|
46 |
+
return imported_objs
|
47 |
+
|
48 |
+
|
49 |
+
def get_type_objs(obj_list=None, type="MESH"):
|
50 |
+
if not obj_list:
|
51 |
+
obj_list = bpy.context.scene.objects
|
52 |
+
type_obj_list = []
|
53 |
+
for obj in obj_list:
|
54 |
+
if obj.type == type:
|
55 |
+
type_obj_list.append(obj)
|
56 |
+
return type_obj_list
|
57 |
+
|
58 |
+
|
59 |
+
def get_all_mesh_obj(obj_list=None):
|
60 |
+
return get_type_objs(obj_list, "MESH")
|
61 |
+
|
62 |
+
|
63 |
+
def get_all_armature_obj(obj_list=None):
|
64 |
+
return get_type_objs(obj_list, "ARMATURE")
|
65 |
+
|
66 |
+
|
67 |
+
def get_rest_bones(armature_obj):
|
68 |
+
if armature_obj is None:
|
69 |
+
return None, None
|
70 |
+
else:
|
71 |
+
rest_bones = []
|
72 |
+
bones_idx_dict: "dict[str,int]" = {}
|
73 |
+
for i, bone in enumerate(armature_obj.data.bones):
|
74 |
+
rest_bones.append(armature_obj.matrix_world @ bone.head_local)
|
75 |
+
bones_idx_dict[bone.name] = i
|
76 |
+
rest_bones = np.stack(rest_bones, axis=0)
|
77 |
+
# print(bones_idx_dict)
|
78 |
+
return rest_bones, bones_idx_dict
|
79 |
+
|
80 |
+
|
81 |
+
def rename_maxiamo_bone(armature_obj):
|
82 |
+
"""Replace name like 'mixamorig10:xxx' to 'mixamorig:xxx, so that character can be correctly animated.'"""
|
83 |
+
import re
|
84 |
+
|
85 |
+
pattern = re.compile(r"mixamorig[0-9]+:")
|
86 |
+
for bone in armature_obj.data.bones:
|
87 |
+
bone.name = re.sub(pattern, "mixamorig:", bone.name)
|
88 |
+
return armature_obj
|
89 |
+
|
90 |
+
|
91 |
+
def mesh_quads2tris(obj_list=None):
|
92 |
+
if not obj_list:
|
93 |
+
obj_list = bpy.context.scene.objects
|
94 |
+
for obj in obj_list:
|
95 |
+
if obj.type == "MESH":
|
96 |
+
# obj.select_set(True)
|
97 |
+
bpy.context.view_layer.objects.active = obj
|
98 |
+
bpy.ops.object.mode_set(mode="EDIT")
|
99 |
+
bpy.ops.mesh.quads_convert_to_tris(quad_method="BEAUTY", ngon_method="BEAUTY")
|
100 |
+
bpy.ops.object.mode_set(mode="OBJECT")
|
101 |
+
|
102 |
+
|
103 |
+
if __name__ == "__main__":
|
104 |
+
input_dir = "."
|
105 |
+
output_dir = os.path.join(input_dir, "character_refined")
|
106 |
+
os.makedirs(output_dir, exist_ok=True)
|
107 |
+
character_list = sorted(glob(os.path.join(input_dir, "character", "*.fbx")))
|
108 |
+
animation_list = sorted(glob(os.path.join(input_dir, "animation", "*.fbx")))
|
109 |
+
unposed_list_file = "character_unposed.txt"
|
110 |
+
if os.path.isfile(unposed_list_file):
|
111 |
+
with open(unposed_list_file, "r") as f:
|
112 |
+
unposed_list = f.readlines()
|
113 |
+
unposed_list = [x.strip() for x in unposed_list if x.strip() != ""]
|
114 |
+
else:
|
115 |
+
unposed_list = None
|
116 |
+
logfile = "character_bones.txt"
|
117 |
+
|
118 |
+
bones_name_list = []
|
119 |
+
for file in tqdm(character_list, dynamic_ncols=True):
|
120 |
+
try:
|
121 |
+
with HiddenPrints():
|
122 |
+
remove_all()
|
123 |
+
obj_list = load_file(file)
|
124 |
+
armature_obj = get_all_armature_obj(obj_list)
|
125 |
+
assert len(armature_obj) == 1, "Armature number is not 1"
|
126 |
+
armature_obj = armature_obj[0]
|
127 |
+
if unposed_list is None or file in unposed_list:
|
128 |
+
rename_maxiamo_bone(armature_obj)
|
129 |
+
rest_bones, bones_idx_dict = get_rest_bones(armature_obj)
|
130 |
+
|
131 |
+
# mesh_quads2tris(get_all_mesh_obj(obj_list))
|
132 |
+
bpy.ops.object.select_all(action="DESELECT")
|
133 |
+
for obj in obj_list:
|
134 |
+
obj.select_set(True)
|
135 |
+
bpy.ops.export_scene.fbx(
|
136 |
+
filepath=os.path.join(output_dir, os.path.basename(file)),
|
137 |
+
check_existing=False,
|
138 |
+
use_selection=True,
|
139 |
+
use_triangles=True, #!
|
140 |
+
add_leaf_bones=False,
|
141 |
+
bake_anim=False,
|
142 |
+
embed_textures=False,
|
143 |
+
)
|
144 |
+
bones_name_list += list(bones_idx_dict.keys())
|
145 |
+
with open(logfile, "a") as f:
|
146 |
+
f.write(f"{file}: {len(bones_idx_dict)}\n")
|
147 |
+
except Exception as e:
|
148 |
+
# raise
|
149 |
+
tqdm.write(f"{file}: {e}")
|
150 |
+
with open(logfile, "a") as f:
|
151 |
+
f.write(f"{file}: {e}\n")
|
152 |
+
|
153 |
+
# Calculate the coverage of each bone among all characters
|
154 |
+
print(sorted(set(bones_name_list)))
|
155 |
+
with HiddenPrints():
|
156 |
+
remove_all()
|
157 |
+
rest_bones, bones_idx_dict = get_rest_bones(get_all_armature_obj(load_file(animation_list[0]))[0])
|
158 |
+
with open(logfile, "a") as f:
|
159 |
+
for v in bones_idx_dict.keys():
|
160 |
+
f.write(f"{v}: {bones_name_list.count(v)}/{len(character_list)}\n")
|
character_unposed.txt
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
./character/06caf212ded22a78500c06ebf372c9bb.fbx
|
2 |
+
./character/08f7e724f32af241e56a9244c2f37b43.fbx
|
3 |
+
./character/0a29fafad2ca23eba1787e20894ea8f6.fbx
|
4 |
+
./character/1f6a7214d5f9eee30f4da837ad0db9a9.fbx
|
5 |
+
./character/216f6676c0df33582682a270735a0bda.fbx
|
6 |
+
./character/3c21546cb958a3daba75704b232b7e4b.fbx
|
7 |
+
./character/3ec1224ed7c692d1e83a4cdfc2f5340b.fbx
|
8 |
+
./character/525795a33ca1026996b5ca009d61e263.fbx
|
9 |
+
./character/5bf474106308ccb071045e9579ca95e5.fbx
|
10 |
+
./character/69c3f460dcf1f1f97942d5dafaac572d.fbx
|
11 |
+
./character/73cd22e7123f4c8e78ffc11ad5fbbc29.fbx
|
12 |
+
./character/75a7bced986dc088580ecbe09e1c8590.fbx
|
13 |
+
./character/932216e3a518b0468f18bbb824ee6fa5.fbx
|
14 |
+
./character/9882611aba55c935f071e41769da7b99.fbx
|
15 |
+
./character/9a3c048709538dfbe0be943c9fae3d62.fbx
|
16 |
+
./character/a4ce3af02c103b2e9b78b9b14e7a01a3.fbx
|
17 |
+
./character/b6e2f4dbb404550f7c05e5158c45f979.fbx
|
18 |
+
./character/b9ae94869ab838ee63cf92990211e525.fbx
|
19 |
+
./character/cdf89c5c4430cbc672e0f61c78797d39.fbx
|
20 |
+
./character/e5e1eccee079207473fafb1c163e2272.fbx
|
character_verts.json
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"0510032b674ce33343c2e058ef52e8c5": 26790,
|
3 |
+
"06caf212ded22a78500c06ebf372c9bb": 21796,
|
4 |
+
"079f3ee7c8d748481707ca78c95750ac": 14267,
|
5 |
+
"08ed9e6576433de9fb72baae34d482b6": 25340,
|
6 |
+
"08f7e724f32af241e56a9244c2f37b43": 27341,
|
7 |
+
"098424150eb08fb107185646afaeee83": 7482,
|
8 |
+
"0a29fafad2ca23eba1787e20894ea8f6": 18922,
|
9 |
+
"0b69ca9d9cd64f4c061659f29956e297": 6557,
|
10 |
+
"0eb7402a9104734d873599c7f9f01c3d": 7865,
|
11 |
+
"0fa8427ca1b7b2f410e893daa42df16c": 7825,
|
12 |
+
"123d7c7f828741681ffed14eacaf606d": 8014,
|
13 |
+
"19b740666ef33a06abf265235d8281a0": 8136,
|
14 |
+
"1c679b4220a9b78133db6c49f59ca65c": 4194,
|
15 |
+
"1f6a7214d5f9eee30f4da837ad0db9a9": 35128,
|
16 |
+
"216f6676c0df33582682a270735a0bda": 14442,
|
17 |
+
"222261b7a837ccdf5db5ea086430d4c7": 17272,
|
18 |
+
"258580e0c4983768c0233dca33157732": 6109,
|
19 |
+
"27de3b0b89d27fa7e654955765e40d3b": 8574,
|
20 |
+
"28069e1e9f570cc90128fe1241343875": 6234,
|
21 |
+
"2d925ffeafc887cf96d22d272e6a87cd": 5703,
|
22 |
+
"32db57cc0f9c3ee01c22924512d56283": 6294,
|
23 |
+
"39967d464dd297954f89d06fb587045f": 7870,
|
24 |
+
"3c21546cb958a3daba75704b232b7e4b": 31440,
|
25 |
+
"3e911fa9c30c9a00a9de31409095cd57": 5006,
|
26 |
+
"3ec1224ed7c692d1e83a4cdfc2f5340b": 29352,
|
27 |
+
"4c989f8d4d0b9c1e6e096f21719fd09d": 4858,
|
28 |
+
"4cd9c2951759527d10bb7916baa80ca2": 5750,
|
29 |
+
"4fd247797b4f3653d5c2a8b335b03d29": 6112,
|
30 |
+
"51b67149e52d48e2442f1db223f59ba9": 22183,
|
31 |
+
"51d19d5e4cd1c8c8d75a97f078ff9476": 33977,
|
32 |
+
"51e1e51887023725371b27fd0cb3dca1": 8094,
|
33 |
+
"525795a33ca1026996b5ca009d61e263": 25251,
|
34 |
+
"57f74ab8c6de76c82d53e3257a6778e4": 29379,
|
35 |
+
"5bf474106308ccb071045e9579ca95e5": 31515,
|
36 |
+
"5cd6b5bf8b921a2cb0e4ce71d685ff90": 2654,
|
37 |
+
"6987df4026a93126ed745db3b5f2fbcf": 7919,
|
38 |
+
"69c3f460dcf1f1f97942d5dafaac572d": 14634,
|
39 |
+
"73cd22e7123f4c8e78ffc11ad5fbbc29": 29056,
|
40 |
+
"75a7bced986dc088580ecbe09e1c8590": 30736,
|
41 |
+
"761718127eb6d283b7bf7076bca62b78": 23243,
|
42 |
+
"761b5a0cf1945d0089f00686beb41f49": 5550,
|
43 |
+
"7dcd7c3eb5f2fb50caf6ae6896e9464c": 24481,
|
44 |
+
"7dd7bf41bda834a9500b2ff93705ad02": 18453,
|
45 |
+
"7faa53355e944ba38be5a4b7de179290": 24850,
|
46 |
+
"7fd6d88afe76663358a61901be3c6c15": 12456,
|
47 |
+
"8044e1503d3549a144741dc1878d414a": 2374,
|
48 |
+
"81f41f90717b8383b3d2fffb18f95d07": 29192,
|
49 |
+
"831a835d6cca7f50fee848116a1e0a6b": 4260,
|
50 |
+
"83828f0fe01d389df691a0b8f2e19b95": 17879,
|
51 |
+
"840c84726b0f55c9fa7235074394fd6a": 10754,
|
52 |
+
"85bc8db2b257cf836c186593aa8a1fce": 2410,
|
53 |
+
"893b3e8f4a0cea4255ccee36633756e7": 29038,
|
54 |
+
"8b6cd9d3a78bdf860d3d06b58715b310": 32697,
|
55 |
+
"8dfaf7ace7778cd25a6b181d98cd7e77": 19404,
|
56 |
+
"93025f9cd069b342a20217702a522b54": 12465,
|
57 |
+
"932216e3a518b0468f18bbb824ee6fa5": 34437,
|
58 |
+
"9882611aba55c935f071e41769da7b99": 27963,
|
59 |
+
"9a24bbb67c6dac80b1e83238982fc9bd": 30535,
|
60 |
+
"9a3c048709538dfbe0be943c9fae3d62": 30724,
|
61 |
+
"9e33cfb2c5443136600e393a4aa2e7f1": 2414,
|
62 |
+
"a0641e810f7d000c8ca59e7224c9d796": 5837,
|
63 |
+
"a3d6df0a1670bd02cc732c8137427dbe": 7397,
|
64 |
+
"a4ce3af02c103b2e9b78b9b14e7a01a3": 31611,
|
65 |
+
"a688cfa656103db0d2acb62c8d2d9144": 7171,
|
66 |
+
"aa03d7c7297f3864ce77600f5f940606": 2931,
|
67 |
+
"aed9922313c4b66e9b3ec1bc6dec06a8": 24746,
|
68 |
+
"b0ce097858de7591269ef24996ad0808": 7512,
|
69 |
+
"b1bf836b9d040760b79534e30a8cba76": 3711,
|
70 |
+
"b1ca6a6e9f48e9a7e4c2a92eb1837e37": 10273,
|
71 |
+
"b1eea1f10e0a85ad8f6b8c8cc5882cf8": 30840,
|
72 |
+
"b45062da94f349e53a67b0028539deac": 3985,
|
73 |
+
"b6e2f4dbb404550f7c05e5158c45f979": 28745,
|
74 |
+
"b78413c2dc7908bf952a609b24569807": 28511,
|
75 |
+
"b9ae94869ab838ee63cf92990211e525": 17986,
|
76 |
+
"bad88bdd65811e64a724b49cb0e505a5": 5890,
|
77 |
+
"bc9c26c1c3653c81d3d35261cd696839": 5209,
|
78 |
+
"bd0a2e2cc4da1a2e566e6dd98402edfb": 9285,
|
79 |
+
"bd5584dc8872126d57d969aa07ec09a6": 5851,
|
80 |
+
"c3b24f5c406ef4c09c2c07ae65dba0e0": 27850,
|
81 |
+
"c4d054e07d59a8b2224e07ab2fbf505b": 6675,
|
82 |
+
"c92d8db4a32b4606fb6258a385f5fcd1": 6596,
|
83 |
+
"cb8b934b054940623581dfaf5d9fd468": 5330,
|
84 |
+
"cdf89c5c4430cbc672e0f61c78797d39": 18705,
|
85 |
+
"cf65a1c8be43a9c90570b99a0b702aff": 12430,
|
86 |
+
"cf7e9c498421b75e2df678adc5284783": 14241,
|
87 |
+
"d2f2e35da6c1fcca872fccf83fef9a5a": 7882,
|
88 |
+
"e000b51a0c9526a75f155bc925722db3": 16211,
|
89 |
+
"e426198d78eaf096bf1e38ffdaa9af17": 4887,
|
90 |
+
"e4280b007901ef1c87a68be75323ab39": 4224,
|
91 |
+
"e5e1eccee079207473fafb1c163e2272": 25240
|
92 |
+
}
|
mixamo_download_script.js
ADDED
@@ -0,0 +1,649 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
INSTRUCTIONS:
|
3 |
+
1. Set your browser NOT to ask where to save files on each download (else you will be bombarded with "Save As" prompts!)
|
4 |
+
2. Navigate to https://www.mixamo.com/#/?page=1&type=Motion%2CMotionPack&limit=96
|
5 |
+
3. For best results, set on-page thumbnails to "small" and "non-animated" (click the little gear icon)
|
6 |
+
4. Set to display 96 items per page (you can also enter 100 in the url, but it makes not much of a difference)
|
7 |
+
5. IMPORTANT: Before you run the script, make sure to manually download one sample animation - the page will remember your settings (if you don't do this, it will use defaults, i.e. it will download the character with each anim)
|
8 |
+
6. Set one (and only 1) of the first 6 variables to TRUE, in order to select the variant you want to download (regular, in place, root) by default it will download only the regular version (without inplace option).
|
9 |
+
7. Open the browser console (Shift+Ctrl+J in Chrome) and paste the entirety of the code
|
10 |
+
8. Hit Enter and wait for it to finish (can take some time)
|
11 |
+
|
12 |
+
NOTE: the script skips all of mixamos animation "packs", as those are duplicates (their content is available as seperate animations), but mostly because it messed up point no. 5
|
13 |
+
|
14 |
+
It is RECOMMENDED to use the variables below in the following WORKFLOW:
|
15 |
+
(1) set the first variable (Setup_DownloadAllExceptInPlace) from false to true,
|
16 |
+
(2) run the script, (3) move all downloaded animations to folder named "\regular",
|
17 |
+
(4) set the first variable back to false and the second to true,
|
18 |
+
(5) run the script again (make sure to open in a fresh tab and don't forget to repeat 5.),
|
19 |
+
(6) move all downloaded animations to folder named "\inplace",
|
20 |
+
(7) repeat for 3rd variable to have the entire set, or all 6 to have also a mirrored version.
|
21 |
+
|
22 |
+
You should end up with 2061 regular animations and 384 in root and inplace each.
|
23 |
+
|
24 |
+
TROUBLESHOOTING
|
25 |
+
With slower connections it is possible that your download queue will start to choke and leave downloads unfinished.
|
26 |
+
If that happens, reduce the per page amount of animations from 96 to 24, or manually enter 10 in the URL (like this) - on each page turn the script waits for a couple of seconds to help with the above.
|
27 |
+
|
28 |
+
For offline browsing purposes, here's a download with all thumbnail:
|
29 |
+
Here are the Thumbnails:
|
30 |
+
MixamoThumbnails.7z (523.28 MB)
|
31 |
+
(I've been made aware that the host uses pesky popup ads and such, keep that in mind or use an adblocker or better yet, a download manager, I highly recommend JDownloader2).
|
32 |
+
|
33 |
+
Have fun!
|
34 |
+
*/
|
35 |
+
|
36 |
+
/* these variables are there to allow running the script in multiple passes so the animations can then be grouped manually into organized folders */
|
37 |
+
var Setup_DownloadAllExceptInPlace = true; // example folder: \regular
|
38 |
+
var Setup_DownloadOnlyInPlace = false; // example folder: \inplace
|
39 |
+
var Setup_DownloadOnlyRoot = false; // example folder: \root
|
40 |
+
|
41 |
+
var Setup_DownloadOnlyInPlace_Mirrored = false; // example folder: \mirrored\inplace
|
42 |
+
var Setup_DownloadAllExceptInPlace_Mirrored = false; // example folder: \mirrored\regular
|
43 |
+
var Setup_DownloadOnlyRoot_Mirrored = false; // example folder: \mirrored\root
|
44 |
+
|
45 |
+
|
46 |
+
/* Debug Settings */
|
47 |
+
|
48 |
+
var debugVerbose = true; // write messages to console
|
49 |
+
var debugMaxIndex = 0; // will stop after x anims, 0 = unlimited
|
50 |
+
var debugStopAfterPage = 999;
|
51 |
+
var debugNoPageTurn = false; // will finish on current page
|
52 |
+
var setupGlobalTimeOffset = 0; // all timers will be increased by x (increase if script has to retry often)
|
53 |
+
var setupTimeModifier = 2; // all timers will multiply by x (increase if script has to retry often)
|
54 |
+
var setupDefaultDelay = 500; // default time step when adding anims to assets (increase when encountering problems)
|
55 |
+
var setupPlaySounds = true; // play sound notifications
|
56 |
+
var setupBeepOnAdd = false; // notification when an animation has been added to assets
|
57 |
+
var setupBeepOnPage = true; // notification when changing page
|
58 |
+
var TimeToReloadPage = 10000;
|
59 |
+
|
60 |
+
/* Do NOT change values below unless you know what you are doing - internal vars and setup constants*/
|
61 |
+
|
62 |
+
var pageURL = "https://www.mixamo.com/#/?type=Motion%2CMotionPack"; // base url without page and limit data
|
63 |
+
var setupElementID_Products = "product";
|
64 |
+
var setupElementID_Download = "btn-block btn btn-primary";
|
65 |
+
var setupElementID_DownloadConfirm = "btn btn-primary";
|
66 |
+
var setupElementID_InPlace = "inplace";
|
67 |
+
var setupElementID_Mirror = "mirror";
|
68 |
+
var setupElementID_Products = "product";
|
69 |
+
var setupElementID_Pagination = ".pagination li:nth-last-child(2) a";
|
70 |
+
var setupElementID_DownloadCaption = "Download";
|
71 |
+
var DownloadPending_Regular = downloadRegularVariant;
|
72 |
+
var DownloadPending_Mirror = downloadMirrorVariant;
|
73 |
+
var DownloadPending_InPlace = downloadInPlaceVariant;
|
74 |
+
var DownloadPending_InPlaceMirror = downloadInPlaceMirrorVariant;
|
75 |
+
var timeEnd = 0, timeStart = 0;
|
76 |
+
var scriptPaused = true;
|
77 |
+
var index = -1;
|
78 |
+
var debugFailedStart = 0;
|
79 |
+
var pageNum = geUrlPageNum();
|
80 |
+
var itemsPerPage = geUrlLimit();
|
81 |
+
var NumOfFilesProcessed = 0;
|
82 |
+
var buttonClicked = 0;
|
83 |
+
var retryCounter = 0;
|
84 |
+
var button = document.querySelector( "setupElementID_AddToAssets" );
|
85 |
+
var items = document.getElementsByClassName( setupElementID_Products );
|
86 |
+
|
87 |
+
var pageMax = 5; // limit pages
|
88 |
+
var downloadRegularVariant = true; // no checkboxes set, regular version, i.e. root or default
|
89 |
+
var download_RootExclude = false; // affects "downloadRegularVariant" only, ignores anims with "in place" option
|
90 |
+
var download_RootExclussive = false; // affects "downloadRegularVariant" only, ignores anims without "in place" option
|
91 |
+
var download_RootMirrored = false; // affects "downloadRegularVariant" only, forces mirror, meant to be used with "download_RootExclu[de|ssive]"
|
92 |
+
var downloadMirrorVariant = true; // will check only "mirror" and download a separate version
|
93 |
+
var downloadInPlaceVariant = true; // set In Place to true
|
94 |
+
var downloadInPlaceMirrorVariant = true; // In Place and mirrored to true
|
95 |
+
|
96 |
+
function DownloadAllExceptInPlace(){
|
97 |
+
//A. downloadRegularVariant + download_RootExclude // download all animations that have no INPLACE checkbox \regular
|
98 |
+
downloadRegularVariant = true;
|
99 |
+
download_RootExclude = true;
|
100 |
+
download_RootExclussive = false;
|
101 |
+
download_RootMirrored = false;
|
102 |
+
downloadMirrorVariant = false;
|
103 |
+
downloadInPlaceVariant = true;
|
104 |
+
downloadInPlaceMirrorVariant = false;
|
105 |
+
}
|
106 |
+
|
107 |
+
function DownloadAllExceptInPlace_Mirrored(){
|
108 |
+
//B. A. + download_RootMirrored // downloads A., but mirrored \regular_mirrored
|
109 |
+
downloadRegularVariant = true;
|
110 |
+
download_RootExclude = true;
|
111 |
+
download_RootExclussive = false;
|
112 |
+
download_RootMirrored = true;
|
113 |
+
downloadMirrorVariant = false;
|
114 |
+
downloadInPlaceVariant = false;
|
115 |
+
downloadInPlaceMirrorVariant = false;
|
116 |
+
}
|
117 |
+
|
118 |
+
function DownloadOnlyInPlace(){
|
119 |
+
//C. downloadInPlaceVariant // all anims w/ a INPLACE checkbox (set true) \inplace
|
120 |
+
downloadRegularVariant = false;
|
121 |
+
download_RootExclude = false;
|
122 |
+
download_RootExclussive = false;
|
123 |
+
download_RootMirrored = false;
|
124 |
+
downloadMirrorVariant = false;
|
125 |
+
downloadInPlaceVariant = true;
|
126 |
+
downloadInPlaceMirrorVariant = false;
|
127 |
+
}
|
128 |
+
|
129 |
+
function DownloadOnlyInPlace_Mirrored(){
|
130 |
+
// D. downloadInPlaceMirrorVariant // same as C., but morrored \inplace_mirrored
|
131 |
+
downloadRegularVariant = false;
|
132 |
+
download_RootExclude = false;
|
133 |
+
download_RootExclussive = false;
|
134 |
+
download_RootMirrored = false;
|
135 |
+
downloadMirrorVariant = false;
|
136 |
+
downloadInPlaceVariant = false;
|
137 |
+
downloadInPlaceMirrorVariant = true;
|
138 |
+
}
|
139 |
+
|
140 |
+
function DownloadOnlyRoot(){
|
141 |
+
//E. downloadRegularVariant + download_RootExclussive // download only anims with INPLACE checkbox (left to false) \root
|
142 |
+
downloadRegularVariant = true;
|
143 |
+
download_RootExclude = false;
|
144 |
+
download_RootExclussive = true;
|
145 |
+
download_RootMirrored = false;
|
146 |
+
downloadMirrorVariant = false;
|
147 |
+
downloadInPlaceVariant = false;
|
148 |
+
downloadInPlaceMirrorVariant = false;
|
149 |
+
}
|
150 |
+
|
151 |
+
function DownloadOnlyRoot_Mirrored(){
|
152 |
+
//F. E. + download_RootMirrored // E. mirrored \root_mirrored
|
153 |
+
downloadRegularVariant = true;
|
154 |
+
download_RootExclude = false;
|
155 |
+
download_RootExclussive = true;
|
156 |
+
download_RootMirrored = true;
|
157 |
+
downloadMirrorVariant = false;
|
158 |
+
downloadInPlaceVariant = false;
|
159 |
+
downloadInPlaceMirrorVariant = false;
|
160 |
+
}
|
161 |
+
|
162 |
+
function geUrlLimit(){
|
163 |
+
var result = getUrlVars()["limit"];
|
164 |
+
if (result && debugVerbose) console.log(result);
|
165 |
+
else {
|
166 |
+
if (debugVerbose) console.log("[DEBUG] geUrlLimit :: param LIMIT not found.");
|
167 |
+
result = "96";
|
168 |
+
}
|
169 |
+
return result;
|
170 |
+
}
|
171 |
+
|
172 |
+
function isAnimPack(){
|
173 |
+
var str = getAnimName();
|
174 |
+
str = str.toLowerCase();
|
175 |
+
var n = str.search(" pack");
|
176 |
+
return ( n > -1 );
|
177 |
+
}
|
178 |
+
|
179 |
+
var DownloadPending_Any = true;
|
180 |
+
function incIndex(){
|
181 |
+
if (debugVerbose) console.log("[DEBUG] incIndex :: Start; index:",index);
|
182 |
+
++index;
|
183 |
+
++NumOfFilesProcessed;
|
184 |
+
buttonClicked = 0;
|
185 |
+
|
186 |
+
DownloadPending_Regular = downloadRegularVariant;
|
187 |
+
DownloadPending_Mirror = downloadMirrorVariant;
|
188 |
+
DownloadPending_InPlace = downloadInPlaceVariant;
|
189 |
+
DownloadPending_InPlaceMirror = downloadInPlaceMirrorVariant;
|
190 |
+
DownloadPending_Any = true;
|
191 |
+
|
192 |
+
if (debugVerbose) console.log("[DEBUG] incIndex :: End; index:",index);
|
193 |
+
|
194 |
+
if (onProcessElement())
|
195 |
+
setTimeout(processElement, 2000 );
|
196 |
+
}
|
197 |
+
|
198 |
+
function getUrlVars() {
|
199 |
+
var vars = {};
|
200 |
+
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
|
201 |
+
function(m,key,value) {
|
202 |
+
vars[key] = value;
|
203 |
+
});
|
204 |
+
return vars;
|
205 |
+
}
|
206 |
+
|
207 |
+
function geUrlPageNum(){
|
208 |
+
var result = getUrlVars()["page"];
|
209 |
+
if (result && debugVerbose) console.log(result);
|
210 |
+
else {
|
211 |
+
if (debugVerbose) console.log("[DEBUG]param PAGE not found.");
|
212 |
+
result = 1;
|
213 |
+
}
|
214 |
+
return result;
|
215 |
+
}
|
216 |
+
|
217 |
+
function timeMod( time1 ){
|
218 |
+
var baseTime = time1 * setupDefaultDelay;
|
219 |
+
var t = ((baseTime)*setupTimeModifier) + setupGlobalTimeOffset;
|
220 |
+
if (t < baseTime*0.1) t = baseTime*0.1;
|
221 |
+
if (t > baseTime*10) t = baseTime*10;
|
222 |
+
return t;
|
223 |
+
}
|
224 |
+
|
225 |
+
function reloadPage() {
|
226 |
+
if (debugVerbose) console.log("[DEBUG] reloadPage :: Start; index:",index);
|
227 |
+
scriptPaused = true;
|
228 |
+
|
229 |
+
if (pageNum >= debugStopAfterPage) {
|
230 |
+
return;
|
231 |
+
}
|
232 |
+
|
233 |
+
|
234 |
+
var newUrl = "";
|
235 |
+
newUrl = pageURL + "&limit=" + itemsPerPage + "&page=" + pageNum.toString();
|
236 |
+
|
237 |
+
if (debugVerbose) console.log("[DEBUG] reloadPage :: ",newUrl);
|
238 |
+
document.location.href = newUrl;
|
239 |
+
|
240 |
+
setTimeout( mixamoScript, 2000 );
|
241 |
+
}
|
242 |
+
|
243 |
+
function onFinish(){
|
244 |
+
/*
|
245 |
+
timeEnd = Date.now();
|
246 |
+
scriptPaused = true;
|
247 |
+
if (debugVerbose) console.log("[DEBUG]MixamoScript: Added (", numAssetsAdded, ")" );
|
248 |
+
|
249 |
+
if (setupBeepOnFinish) {
|
250 |
+
soundOnFinish();
|
251 |
+
setTimeout(promptOnEnd, 2000);
|
252 |
+
} else setTimeout(promptOnEnd, 0);
|
253 |
+
*/
|
254 |
+
}
|
255 |
+
|
256 |
+
if (!audioCtx) var audioCtx = new (window.AudioContext || window.webkitAudioContext || window.audioContext);
|
257 |
+
function beep(duration, frequency, volume, type, callback) {
|
258 |
+
if (!setupPlaySounds) return;
|
259 |
+
|
260 |
+
var oscillator = audioCtx.createOscillator();
|
261 |
+
var gainNode = audioCtx.createGain();
|
262 |
+
|
263 |
+
oscillator.connect(gainNode);
|
264 |
+
gainNode.connect(audioCtx.destination);
|
265 |
+
|
266 |
+
if (volume){gainNode.gain.value = volume;};
|
267 |
+
if (frequency){oscillator.frequency.value = frequency;}
|
268 |
+
if (type){oscillator.type = type;}
|
269 |
+
if (callback){oscillator.onended = callback;}
|
270 |
+
|
271 |
+
oscillator.start();
|
272 |
+
setTimeout(function(){oscillator.stop()}, (duration ? duration : 500));
|
273 |
+
}
|
274 |
+
|
275 |
+
function soundOnPageEnd(){
|
276 |
+
|
277 |
+
setTimeout(function(){ beep(500, 500, 0.060, "triangle") }, 0);
|
278 |
+
setTimeout(function(){ beep(500, 550, 0.035, "triangle") }, 600);
|
279 |
+
setTimeout(function(){ beep(500, 600, 0.020, "triangle") }, 1200);
|
280 |
+
setTimeout(function(){ beep(500, 650, 0.005, "triangle") }, 1800);
|
281 |
+
}
|
282 |
+
|
283 |
+
function beepOnAdd(){
|
284 |
+
if (debugVerbose) console.log("[DEBUG] beepOnAdd :: Start; index:",index);
|
285 |
+
beep(225, 200, 0.3, "triangle");
|
286 |
+
}
|
287 |
+
|
288 |
+
|
289 |
+
/**/
|
290 |
+
function printToLogCurrItems(){
|
291 |
+
|
292 |
+
}
|
293 |
+
|
294 |
+
function onEndOfPage() {
|
295 |
+
if (debugVerbose) console.log("[DEBUG] onEndOfPage :: Start; index:",index);
|
296 |
+
scriptPaused = true;
|
297 |
+
|
298 |
+
var t = 0;
|
299 |
+
if (setupBeepOnPage) {
|
300 |
+
t = 1000;
|
301 |
+
setTimeout(soundOnPageEnd, 0);
|
302 |
+
}
|
303 |
+
|
304 |
+
//printToLogCurrItems();
|
305 |
+
if (pageNum >= debugStopAfterPage) {
|
306 |
+
setTimeout( onFinish, 2000 );
|
307 |
+
if (debugVerbose) console.log("[DEBUG] onEndOfPage_Assets :: Start; pageNum:",pageNum,"; debugStopAfterPage:",debugStopAfterPage);
|
308 |
+
return;
|
309 |
+
} else {
|
310 |
+
if (!debugNoPageTurn) {
|
311 |
+
index = 0;
|
312 |
+
++pageNum;
|
313 |
+
setTimeout(reloadPage, TimeToReloadPage);
|
314 |
+
}
|
315 |
+
}
|
316 |
+
|
317 |
+
}
|
318 |
+
|
319 |
+
function isDownloadInProgress(){
|
320 |
+
var elements = document.getElementsByClassName( "progress-bar" );
|
321 |
+
if (elements && elements.length>0)
|
322 |
+
{
|
323 |
+
console.log("[DEBUG] Download In Progress");
|
324 |
+
return true;
|
325 |
+
} else {
|
326 |
+
console.log("[DEBUG] Download Not In Progress");
|
327 |
+
return false;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
function onProcessElement() {
|
332 |
+
if (debugVerbose) console.log("[DEBUG] onProcessElement :: start; index:",index);
|
333 |
+
|
334 |
+
if (!items || items.length == 0) {
|
335 |
+
if (debugVerbose) console.log("[DEBUG] onProcessElement :: items; index:",index);
|
336 |
+
items = document.getElementsByClassName( setupElementID_Products );
|
337 |
+
}
|
338 |
+
if (!button) {
|
339 |
+
if (debugVerbose) console.log("[DEBUG] onProcessElement :: button; index:",index);
|
340 |
+
//button = document.querySelector( setupElementID_AddToAssets );
|
341 |
+
var buttons = document.getElementsByClassName( setupElementID_Download );
|
342 |
+
if (buttons && buttons.length>0)
|
343 |
+
button = buttons[0];
|
344 |
+
}
|
345 |
+
if (items.length != 0) {
|
346 |
+
// Next Page
|
347 |
+
if(index >= items.length) {
|
348 |
+
// end of page
|
349 |
+
onEndOfPage();
|
350 |
+
return true;
|
351 |
+
}
|
352 |
+
items[index].click();
|
353 |
+
|
354 |
+
if (debugVerbose) console.log("[DEBUG] onProcessElement :: Clicked");
|
355 |
+
return true;
|
356 |
+
}
|
357 |
+
|
358 |
+
return false;
|
359 |
+
}
|
360 |
+
|
361 |
+
function getAnimName(){
|
362 |
+
if (debugVerbose) console.log("[DEBUG] getAnimName :: Start; index:",index);
|
363 |
+
var element = document.getElementsByClassName( "text-center h5" );
|
364 |
+
if (element && element.length>0) {
|
365 |
+
if (debugVerbose) console.log("[DEBUG] getAnimName :: name:",element[0].textContent,"; Start; index:",index);
|
366 |
+
return element[0].textContent;
|
367 |
+
}
|
368 |
+
if (debugVerbose) console.log("[DEBUG] getAnimName :: Failed; Start; index:",index);
|
369 |
+
return "[]";
|
370 |
+
}
|
371 |
+
|
372 |
+
function confirmDownload(){
|
373 |
+
if (debugVerbose) console.log("[DEBUG] confirmDownload :: start; index:",index);
|
374 |
+
var buttons = document.getElementsByClassName( setupElementID_DownloadConfirm );
|
375 |
+
if (buttons && buttons.length>1) {
|
376 |
+
buttons[1].click();
|
377 |
+
|
378 |
+
if (debugVerbose) console.log("[DEBUG] confirmDownload :: Button Clicked");
|
379 |
+
|
380 |
+
setTimeout( processElementEx, 1000 );
|
381 |
+
} else if (debugVerbose) console.log("[DEBUG] confirmDownload :: Button Not Found");
|
382 |
+
}
|
383 |
+
|
384 |
+
function initAnimDownload() {
|
385 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload :: Start; Index:",index);
|
386 |
+
|
387 |
+
var currAnim = getAnimName();
|
388 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload :: Anim: ",currAnim,"; index:",index);
|
389 |
+
|
390 |
+
// main button is ready to add asset)
|
391 |
+
if (button.textContent == setupElementID_DownloadCaption) {
|
392 |
+
if (buttonClicked == 0) {
|
393 |
+
button.click();
|
394 |
+
|
395 |
+
//++buttonClicked;
|
396 |
+
//++numAssetsAddedCurrPage;
|
397 |
+
if (setupBeepOnAdd) beepOnAdd();
|
398 |
+
|
399 |
+
setTimeout( confirmDownload, 1000);
|
400 |
+
|
401 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload :: Added To Assets; buttonClicked:",buttonClicked);
|
402 |
+
return true;
|
403 |
+
}
|
404 |
+
} else { // main button caption is something unexpected
|
405 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload :: button.textContent:",button.textContent);
|
406 |
+
return false;
|
407 |
+
|
408 |
+
}
|
409 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload :: end");
|
410 |
+
}
|
411 |
+
|
412 |
+
function checkElement(elementName, desiredState) {
|
413 |
+
var element = document.getElementsByName(elementName);
|
414 |
+
if (element.length != 0) {
|
415 |
+
if (element[0].checked != desiredState) {
|
416 |
+
if (debugVerbose) console.log("[DEBUG] checkElement :: Clicked; previous state:",element[0].checked,"; elementName:",elementName,"; desiredState:",desiredState);
|
417 |
+
element[0].click();
|
418 |
+
} else if (debugVerbose) console.log("[DEBUG] checkElement :: Element already has desired state; elementName:",elementName,"; desiredState:",desiredState);
|
419 |
+
|
420 |
+
return true;
|
421 |
+
}
|
422 |
+
if (debugVerbose) console.log("[DEBUG] checkElement :: Element not found; elementName:",elementName,"; desiredState:",desiredState);
|
423 |
+
|
424 |
+
return false;
|
425 |
+
}
|
426 |
+
|
427 |
+
function isElementChecked(elementName, desiredState) {
|
428 |
+
var element = document.getElementsByName(elementName);
|
429 |
+
if (element.length != 0) {
|
430 |
+
if (debugVerbose) console.log("[DEBUG] isElementChecked :: elementName: ",elementName,"; desiredState: ",desiredState,"; current state:",element[0].checked,"; items found: ",element.length);
|
431 |
+
if (element[0].checked != desiredState) {
|
432 |
+
if (debugVerbose) console.log("[DEBUG] isElementChecked :: return: 0");
|
433 |
+
return 0;
|
434 |
+
} else {
|
435 |
+
if (debugVerbose) console.log("[DEBUG] isElementChecked :: return: 1");
|
436 |
+
return 1;
|
437 |
+
}
|
438 |
+
}
|
439 |
+
if (debugVerbose) console.log("[DEBUG] isElementChecked :: Element not found; elementName:",elementName,"; desiredState:",desiredState);
|
440 |
+
return -1;
|
441 |
+
}
|
442 |
+
|
443 |
+
var waitingForDownloadToComplete = false;
|
444 |
+
function processElement() {
|
445 |
+
if (debugVerbose) console.log("[DEBUG] processElement :: start; index:",index);
|
446 |
+
|
447 |
+
if (isDownloadInProgress()) {
|
448 |
+
// give page time to prepare current download
|
449 |
+
waitingForDownloadToComplete = true;
|
450 |
+
setTimeout(processElement, 500 );
|
451 |
+
return;
|
452 |
+
}
|
453 |
+
|
454 |
+
if (waitingForDownloadToComplete === true){
|
455 |
+
// some extra time to complete downloading
|
456 |
+
waitingForDownloadToComplete = false;
|
457 |
+
setTimeout(processElement, 1000 );
|
458 |
+
return;
|
459 |
+
}
|
460 |
+
|
461 |
+
if (debugMaxIndex > 0 && NumOfFilesProcessed >= debugMaxIndex) {
|
462 |
+
if (debugVerbose) console.log("[DEBUG] processElement :: debugMaxIndex:",debugMaxIndex,"; onFinish");
|
463 |
+
onFinish();
|
464 |
+
return;
|
465 |
+
}
|
466 |
+
|
467 |
+
if ( scriptPaused ) return;
|
468 |
+
|
469 |
+
retryCounter = 0;
|
470 |
+
|
471 |
+
setTimeout(processElementEx, timeMod( 1 ));
|
472 |
+
|
473 |
+
if (debugVerbose) console.log("[DEBUG] processElement :: End");
|
474 |
+
}
|
475 |
+
|
476 |
+
function processElementEx(){
|
477 |
+
if (debugVerbose) {
|
478 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_Regular: ",DownloadPending_Regular);
|
479 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_Mirror: ",DownloadPending_Mirror);
|
480 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_InPlace: ",DownloadPending_InPlace);
|
481 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_InPlaceMirror: ",DownloadPending_InPlaceMirror);
|
482 |
+
}
|
483 |
+
|
484 |
+
if (!isAnimPack()) {
|
485 |
+
// download variants
|
486 |
+
if (DownloadPending_Regular) {
|
487 |
+
if (initAnimDownload_Regular() ) {
|
488 |
+
setTimeout(initAnimDownload, timeMod( 2 ) );
|
489 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: call initAnimDownload");
|
490 |
+
} else {
|
491 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
492 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: call processElementEx");
|
493 |
+
}
|
494 |
+
DownloadPending_Regular = false;
|
495 |
+
return;
|
496 |
+
} else if (DownloadPending_Mirror){
|
497 |
+
setTimeout(initAnimDownload_Mirror, timeMod( 1 ) );
|
498 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: call initAnimDownload_Mirror");
|
499 |
+
return;
|
500 |
+
} else if (DownloadPending_InPlace){
|
501 |
+
setTimeout(initAnimDownload_InPlace, timeMod( 1 ) );
|
502 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: call initAnimDownload_InPlace");
|
503 |
+
return;
|
504 |
+
} else if (DownloadPending_InPlaceMirror){
|
505 |
+
setTimeout(initAnimDownload_InPlaceMirror, timeMod( 1 ) );
|
506 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: call initAnimDownload_InPlaceMirror");
|
507 |
+
return;
|
508 |
+
}
|
509 |
+
} else {
|
510 |
+
if (debugVerbose) console.log("[DEBUG] processElementEx :: skipping Pack");
|
511 |
+
}
|
512 |
+
|
513 |
+
if (debugVerbose) {
|
514 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_Regular: ",DownloadPending_Regular);
|
515 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_Mirror: ",DownloadPending_Mirror);
|
516 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_InPlace: ",DownloadPending_InPlace);
|
517 |
+
console.log("[DEBUG] processElementEx :: DownloadPending_InPlaceMirror: ",DownloadPending_InPlaceMirror);
|
518 |
+
}
|
519 |
+
|
520 |
+
//DownloadPending_Any = false;
|
521 |
+
setTimeout(incIndex, timeMod(2) );
|
522 |
+
}
|
523 |
+
|
524 |
+
function initAnimDownload_Regular(){
|
525 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_Regular :: Start");
|
526 |
+
r1 = isElementChecked(setupElementID_Mirror, false);
|
527 |
+
r2 = isElementChecked(setupElementID_InPlace, false);
|
528 |
+
|
529 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_Regular :: R1: ",r1,", R2: ",r2);
|
530 |
+
|
531 |
+
if ((download_RootExclude===true && r2>-1) || (download_RootExclussive===true && r2<0)) {
|
532 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_Regular :: download_RootExclude: ",download_RootExclude);
|
533 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_Regular :: download_RootExclussive: ",download_RootExclussive);
|
534 |
+
return false;
|
535 |
+
}
|
536 |
+
if (download_RootMirrored===true) {
|
537 |
+
DownloadPending_Mirror = true;
|
538 |
+
return false;
|
539 |
+
} else {
|
540 |
+
return true;
|
541 |
+
}
|
542 |
+
}
|
543 |
+
|
544 |
+
function initAnimDownload_Mirror(){
|
545 |
+
r1 = isElementChecked(setupElementID_Mirror, true);
|
546 |
+
r2 = isElementChecked(setupElementID_InPlace, false);
|
547 |
+
|
548 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_Mirror :: R1: ",r1,", R2: ",r2);
|
549 |
+
|
550 |
+
if (r1 === -1) {
|
551 |
+
// option n/a
|
552 |
+
DownloadPending_Mirror = false;
|
553 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
554 |
+
} else if (r1===0 || r2===0) {
|
555 |
+
// req options not yet not checked
|
556 |
+
if (r1===0) checkElement(setupElementID_Mirror, true);
|
557 |
+
if (r2===0) checkElement(setupElementID_InPlace, false);
|
558 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
559 |
+
} else {
|
560 |
+
// req met
|
561 |
+
setTimeout(initAnimDownload, timeMod( 2 ) );
|
562 |
+
DownloadPending_Mirror = false;
|
563 |
+
}
|
564 |
+
}
|
565 |
+
|
566 |
+
function initAnimDownload_InPlace(){
|
567 |
+
//r1 = isElementChecked(setupElementID_InPlace, true);
|
568 |
+
r1 = isElementChecked(setupElementID_InPlace, false);
|
569 |
+
r2 = isElementChecked(setupElementID_Mirror, false);
|
570 |
+
|
571 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_InPlace :: R1: ",r1,", R2: ",r2);
|
572 |
+
|
573 |
+
if (r1 === -1) {
|
574 |
+
// option n/a
|
575 |
+
DownloadPending_InPlace = false;
|
576 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
577 |
+
} else if (r1===0 || r2===0) {
|
578 |
+
// req options not yet not checked
|
579 |
+
//if (r1===0) checkElement(setupElementID_InPlace, true);
|
580 |
+
if (r1===0) checkElement(setupElementID_InPlace, false);
|
581 |
+
if (r2===0) checkElement(setupElementID_Mirror, false);
|
582 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
583 |
+
} else {
|
584 |
+
// req met
|
585 |
+
setTimeout(initAnimDownload, timeMod( 2 ) );
|
586 |
+
DownloadPending_InPlace = false;
|
587 |
+
}
|
588 |
+
}
|
589 |
+
|
590 |
+
function initAnimDownload_InPlaceMirror(){
|
591 |
+
r1 = isElementChecked(setupElementID_InPlace, true);
|
592 |
+
r2 = isElementChecked(setupElementID_Mirror, true);
|
593 |
+
|
594 |
+
if (debugVerbose) console.log("[DEBUG] initAnimDownload_InPlaceMirror :: R1: ",r1,", R2: ",r2);
|
595 |
+
|
596 |
+
if (r1 === -1 || r2 === -1) {
|
597 |
+
// option n/a
|
598 |
+
DownloadPending_InPlaceMirror = false;
|
599 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
600 |
+
} else if (r1===0 || r2===0) {
|
601 |
+
// req options not yet not checked
|
602 |
+
if (r1===0) checkElement(setupElementID_InPlace, true);
|
603 |
+
if (r2===0) checkElement(setupElementID_Mirror, true);
|
604 |
+
setTimeout(processElementEx, timeMod( 1 ) );
|
605 |
+
} else {
|
606 |
+
// req met
|
607 |
+
setTimeout(initAnimDownload, timeMod( 2 ) );
|
608 |
+
DownloadPending_InPlaceMirror = false;
|
609 |
+
}
|
610 |
+
}
|
611 |
+
|
612 |
+
function mixamoScript(){
|
613 |
+
timeStart = Date.now();
|
614 |
+
|
615 |
+
if (debugVerbose) console.log("[DEBUG] mixamoScript :: Start; index:",index);
|
616 |
+
var pagination = document.querySelector(setupElementID_Pagination);
|
617 |
+
if (pagination) pageMax = parseInt(pagination.textContent, 10);
|
618 |
+
else pageMax = 1;
|
619 |
+
|
620 |
+
scriptPaused = false;
|
621 |
+
items = document.getElementsByClassName( setupElementID_Products );
|
622 |
+
|
623 |
+
index = -1;
|
624 |
+
|
625 |
+
// get products or retry later
|
626 |
+
if (items.length == 0) {
|
627 |
+
++debugFailedStart;
|
628 |
+
if (debugFailedStart > 2) {
|
629 |
+
reloadPage();
|
630 |
+
return;
|
631 |
+
}
|
632 |
+
setTimeout(mixamoScript, 2000 );
|
633 |
+
return;
|
634 |
+
}
|
635 |
+
debugFailedStart = 0;
|
636 |
+
|
637 |
+
// process first element
|
638 |
+
incIndex();
|
639 |
+
//processElement();
|
640 |
+
}
|
641 |
+
|
642 |
+
if (Setup_DownloadAllExceptInPlace===true) DownloadAllExceptInPlace();
|
643 |
+
else if (Setup_DownloadAllExceptInPlace_Mirrored===true) DownloadAllExceptInPlace_Mirrored();
|
644 |
+
else if (Setup_DownloadOnlyInPlace===true) DownloadOnlyInPlace();
|
645 |
+
else if (Setup_DownloadOnlyInPlace_Mirrored===true) DownloadOnlyInPlace_Mirrored();
|
646 |
+
else if (Setup_DownloadOnlyRoot===true) DownloadOnlyRoot();
|
647 |
+
else if (Setup_DownloadOnlyRoot_Mirrored===true) DownloadOnlyRoot_Mirrored();
|
648 |
+
|
649 |
+
mixamoScript();
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
bpy
|
2 |
+
numpy
|
3 |
+
tqdm
|
try_import_blender.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from glob import glob
|
4 |
+
|
5 |
+
import bpy
|
6 |
+
from tqdm import tqdm
|
7 |
+
|
8 |
+
|
9 |
+
class HiddenPrints:
|
10 |
+
def __init__(self, disable=False):
|
11 |
+
self.disable = disable
|
12 |
+
|
13 |
+
def __enter__(self):
|
14 |
+
if self.disable:
|
15 |
+
return
|
16 |
+
self._original_stdout = sys.stdout
|
17 |
+
sys.stdout = open(os.devnull, "w")
|
18 |
+
|
19 |
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
20 |
+
if self.disable:
|
21 |
+
return
|
22 |
+
sys.stdout.close()
|
23 |
+
sys.stdout = self._original_stdout
|
24 |
+
|
25 |
+
|
26 |
+
if __name__ == "__main__":
|
27 |
+
input_dir = "."
|
28 |
+
character_list = sorted(glob(os.path.join(input_dir, "character", "*.fbx")))
|
29 |
+
# animation_list = sorted(glob(os.path.join(input_dir, "animation", "*.fbx")))
|
30 |
+
for filepath in tqdm(character_list, dynamic_ncols=True):
|
31 |
+
try:
|
32 |
+
with HiddenPrints():
|
33 |
+
bpy.ops.import_scene.fbx(filepath=filepath)
|
34 |
+
except Exception as e:
|
35 |
+
tqdm.write(filepath)
|
36 |
+
with open("character_old_fbx.txt", "a") as f:
|
37 |
+
f.write(f"{filepath}\n")
|
38 |
+
|
39 |
+
# https://aps.autodesk.com/developer/overview/fbx-converter-archives
|
40 |
+
# Manually convert and replace FBX in the txt
|